[erlang-questions] inet_res:getbyname/2 and udp:connect/3

Per Hedeland per@REDACTED
Tue Jun 15 00:51:50 CEST 2010


Raimo Niskanen <raimo+erlang-questions@REDACTED> wrote:
>
>gen_udp:connect/3 calls
>
>    int connect(int socket, const struct sockaddr *address,
>              socklen_t address_len);
>
>on the socket. Excerpt from man connect:
>
>    If the initiating socket is not connection-mode, then connect()
>    shall set the socket's peer address, and no connection  is  made.  For
>    SOCK_DGRAM  sockets,  the  peer  address identifies where all datagrams
>    are sent on subsequent send() functions, and limits the remote
>    sender for subsequent recv() functions. If address is a null address
>    for the protocol, the socket's peer address shall be reset.
>
>i.e default destination is set and reception is limited. I think
>it is receiving from only the inteded DNS server that is the purpose.

Hm, in general the purpose of calling connect() for a UDP socket is
this:

1> {ok,S}=gen_udp:open(0).
{ok,#Port<0.427>}
2> gen_udp:send(S,"127.0.0.1",12345,<<>>).  
ok
3> flush().
ok
4> gen_udp:connect(S,"127.0.0.1",12345).
ok
5> gen_udp:send(S,"127.0.0.1",12345,<<>>).  
ok
6> flush().                               
Shell got {udp_error,#Port<0.427>,econnrefused}
ok

I.e. if you send to a port that doesn't have a listener (on a host that
is running), you get an "immediate" "reply" instead of having to time
out waiting for a *real* reply that never arrives (to get into the gory
details, the kernel can match the ICMP Port Unreachable message to your
socket because it is connected, and delivers it as an error when you try
to receive from the socket).

However this does not seem to work in passive mode with gen_udp (recv/3
always blocks until Timeout), and since that is what inet_res uses, the
purpose of the connect() is unclear. Responses from the wrong IP/Port
are thrown away though, and enetunreach/econnrefused errors are handled,
so I would guess that at some point this worked for passive mode too (or
maybe it was just assumed to work:-) and *is* the purpose.

If gen_udp:connect/3 was documented, I think the non-working-as-above in
passive mode should be considered a bug...

--Per Hedeland


More information about the erlang-questions mailing list