Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!sdd.hp.com!elroy.jpl.nasa.gov!ncar!asuvax!noao!rstevens From: rstevens@noao.edu (Rich Stevens) Newsgroups: comp.protocols.tcp-ip Subject: Re: why UDP send ICMP port unreachable message? Message-ID: <1991Mar1.181515.12734@noao.edu> Date: 1 Mar 91 18:15:15 GMT References: <9103011243.AA10028@ucbvax.Berkeley.EDU> Organization: National Optical Astronomy Observatories, Tucson AZ Lines: 33 In article <9103011243.AA10028@ucbvax.Berkeley.EDU> TAYBENGH@NUSDISCS.BITNET writes: > According to my understanding, this ICMP message > is never received by UDP, nor is reported to the user if the user send a > UDP message to a non-existent server (destination port). UDP does indeed receive this message. It's not documented well, so you really need to go to the sources to see what's going on. The publicly available "BSD Networking Release" suffices. The sequence of events is: icmp_input() receives the ICMP error. The ICMP "type" is ICMP_UNREACH and the ICMP "code" is "port unreachable". This code is converted to PRC_UNREACH_PORT and udp_ctlinput() is called to process the error. udp_ctlinput() calls in_pcbnotify(), converting the PRC_UNREACH_PORT error into the ECONNREFUSED errno value, using the table inetctlerrmap[] (in the file ip_input.c). A 32-bit internet address is passed to udp_ctlinput() and this address is passed again to in_pcbnotify(). This address is the address that the datagram was sent to that generated the ICMP error. The routine in_pcbnotify() is interesting because it looks at this address and finds *every* socket that is connect()ed to this address and sends those sockets the asynchronous error ECONNREFUSED. So there are three caveats: (1) you'll only know about the error if you've done a connect(); (2) not only will you find out about the error, but *every* process on your host that is UDP "connect()ed" to the host that sends the ICMP port unreachable gets a ECONNREFUSED error; (3) you usually don't find out about the error when you send() the datagram to the port that no one is reading from, in most cases you'll find out when you do a recv() on that socket (assuming the classic send-a-datagram, receive-a-datagram scenario). Rich Stevens (rstevens@noao.edu)