[erlang-questions] Sending a tcp packet containing null data

Nahuel Greco <>
Mon Jun 27 16:53:08 CEST 2011


The operating system TCP keepalive support is just what you want. It
sends an empty-data TCP packet with the ACK flag on. You need to
enable it with the flag {keepalive, true} when creating the socket.
But also you need to specify the timing parameters (the default to
detect disconnection is two hours in Linux, unusable for most
purposes); inets.erl currently doesn't support them but you can pass
raw setsockopt() parameters. So, on Linux, you need to do something
like:

get_tcp_keepalive_opts(KeepIdle, KeepInterval, KeepCount) ->
    [{keepalive, true},
     {raw, 1, 4, <<KeepIdle:32/native>>},       % SOL_SOCKET, TCP_KEEPIDLE
     {raw, 1, 5, <<KeepInterval:32/native>>},   % SOL_SOCKET, TCP_KEEPINTVL
     {raw, 1, 6, <<KeepCount:32/native>>}       % SOL_SOCKET, TCP_KEEPCNT
     ].


test_socket() ->
    gen_tcp:connect("127.0.0.1", 22, [binary, {packet, 0}] ++
get_tcp_keepalive_opts(2,2,2)).

See "man 7 tcp". Btw, would be nice to patch inets.erl to support this.

Saludos,
Nahuel Greco.



On Mon, Jun 27, 2011 at 11:12 AM, Valentin Micic <> wrote:
> Hi
>
> I'd like to implement a generic link-test facility for TCP connections -- something that would work similarly to TCP keep-alive; however, under complete control of the calling ERLANG process with respect to sending and receiving of control packets.
> By the same token, I'd like this test to be transparent (as in: non-intrusive) to the peer application. In other words, I would *not* like such an empty (null data) packet to be propagated to the remote peer application, but expect the remote TCP stack to issue an equally empty "ACK" packet (or stream of data, if available), which would be propagated back to the caller.
>
> Thus,  I have a number of problems on multiple levels, but first and foremost, I have no idea how to achieve this (other than hoping that TCP keep-alive would be supported on a particular machine) :-)
>
> So, how can I force a null data packet to leave the local machine. Did try gen_tcp:send(Socket, <<>>), however, this didn't work (well... why should it?)
>
> Maybe the whole problem can be reduced to the above -- if the remote TCP stack receives such a packet, it will be obliged to send an ACK, failing which the local TCP driver would eventually tear-down the connection, therefore informing the local ERLANG process about such an action, right? (as it would in a case of TCP keep-alive)
>
> Another valid question can be: Is it worth-while going to a trouble of trying to do this?
>
> My current feeling is -- Yes; largely because I had (did I say had? I meant still have) to do application-level link testing with almost every project that requires some form of connection pool management.
> Why is this important? Well, not much if you prefer to ignore the golden rule about customer always being right (and we all know they can be quite left from time to time); unfortunately, if one is to observe important (evolution related) rules, one would need to consider easier ways to do this -- that is, provide for a link-testing even if the remote peer application does not support a link testing primitive.
>
> Kind regards,
>
> V/
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list