Why is connect() missing from inet_udp.erl?

Scott Lystig Fritchie scott@REDACTED
Wed Feb 9 23:07:39 CET 2000


The inet_drv.c code in the source distribution for R6B
(${SRC_DISTRO_TOP}/erts/emulator/drivers/common/inet_drv.c) contains
the comment:

    case UDP_REQ_CONNECT: 
        /* XXX this code is not used but leave it we may use it AGAIN ? */

I'm just guessing, but since the driver supports connected UDP
sockets, and since the comment says what it does, did inet_udp once
support connected UDP sockets?  If so, why doesn't it now?

I haven't used UDP all that much, so it was a bit of a surprise to
find out that, if you send data via un-connected UDP socket to an
unreachable port, e.g.

    machine-a -> machine-b  UDP D=777 S=2346 LEN=23
 machine-b -> machine-a     ICMP Destination unreachable (Bad port)

... then the code on machine-a will not be aware of the ICMP message.
Upon reflection, this makes sense.  If the socket is not connected,
how can the OS know who to notify when the ICMP message arrives?

It's certainly possible to have machine-a simply time out waiting for
a response, but if there's a way of knowing that the destination is
bad, why wait?  Included below is a small patch for adding
connect(Socket, IPAddress, Port) and send(Socket, Data) to
inet_udp.erl.  It seems to work, but I haven't given it an
industrial-strength thrashing yet.

-Scott
---
Scott Lystig Fritchie, <scott@REDACTED>
5401 - 10th Ave S, Minneapolis, MN 55417 USA
Professional Governing: Is It Faked?

--- snip --- snip --- snip --- snip --- snip --- snip --- snip --- 

--- inet_udp.erl.orig	Fri Nov 26 16:23:26 1999
+++ inet_udp.erl	Wed Feb  9 15:49:06 2000
@@ -18,7 +18,7 @@
 -module(inet_udp).
 
 -export([open/1, open/2, close/1]).
--export([send/4, recv/2]).
+-export([send/4, recv/2, connect/3, send/2]).
 -export([controlling_process/2]).
 
 -export([getserv/1, getaddr/1]).
@@ -60,9 +60,15 @@
 send(S,{A,B,C,D},P,Data) when integer(A+B+C+D),P>=0,P=<16#ffff ->
     call(S, {sendto, {A,B,C,D}, P, Data}).
 
+send(S,Data) ->
+    call(S, {send, Data}).
+
 recv(S,Len) ->
     gen_udp:recv(S, Len).
 
+connect(S,{A,B,C,D},P) when integer(A+B+C+D),P>=0,P=<16#ffff ->
+    call(S, {connect, {A,B,C,D}, P}).
+
 close(S) ->
     gen_udp:close(S).
 
@@ -155,6 +161,10 @@
 	    reply(From, Tag, ok),
 	    handle_output(St#sock.fs, {IP,Port,Data}, Udp, Owner, St);
 
+	{call, From, Tag, {send,Data}} ->
+	    reply(From, Tag, ok),
+	    handle_output(St#sock.fs, {Data}, Udp, Owner, St);
+
 	{call, From, Tag, Request} ->
 	    case handle_call(Request, Udp, St) of
 		{reply, Value, St1} ->
@@ -286,6 +296,9 @@
 handle_output([], Called, {IP,UP,Data}, Port, Owner, St) ->
     ll_sendto(Port, IP, UP, Data),
     socket_loop(Port, Owner, St#sock { fs = reverse(Called) });
+handle_output([], Called, {Data}, Port, Owner, St) ->
+    ll_send(Port, Data),
+    socket_loop(Port, Owner, St#sock { fs = reverse(Called) });
 handle_output([{Fun,S} | Fs], Called, Data, Port, Owner, St) ->
     case Fun(output, Data, S) of
 	{output, Data1, S1} ->
@@ -339,6 +352,10 @@
 ll_sendto(Udp,{A,B,C,D},UdpPort,Data) when integer(UdpPort) ->
     Udp ! {self(), {command, [?UDP_REQ_SENDTO, ?int16(UdpPort),
 			      [A,B,C,D], Data]}},
+    ok.
+
+ll_send(Udp,Data) ->
+    Udp ! {self(), {command, [?UDP_REQ_SEND, Data]}},
     ok.
 
 sync_cmd(Port, Cmd, Rep) ->



More information about the erlang-questions mailing list