Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!cbatt!cbosgd!ulysses!ucbvax!PURDUE.EDU!narten From: narten@PURDUE.EDU.UUCP Newsgroups: mod.protocols.tcp-ip Subject: UDP vs. ICMP dest unreachable messages Message-ID: <8702101934.AA04710@gwen.cs.purdue.edu> Date: Tue, 10-Feb-87 14:34:19 EST Article-I.D.: gwen.8702101934.AA04710 Posted: Tue Feb 10 14:34:19 1987 Date-Received: Thu, 12-Feb-87 02:01:46 EST Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 70 Approved: tcp-ip@sri-nic.arpa This note is prompted by the observation that lots of nameservers still contact usc-isib (10.3.0.52), even though the machine no longer exists. A related problem that is appearing a lot more now has to do with reactions in general to ICMP dest unreachable messages. Now that name server traffic is picking up, it really hurts to see UDP implementations ignoring ICMP errors. It is not uncommon to see half a dozen (or more) packets sent to some remote nameserver even though the first packet causes an ICMP dest unreachable to be returned. In some cases this is not too serious (but still undesirable), since the message comes from a gateway one hop away with a LAN in between. Other times, the message comes from some distant gateway on the other side of the ARPANET. The problem with letting UDP see these errors lies with the stateless nature of datagram delivery at that level. With TCP, there has to be a connection block that the error packet can be matched up against. Hence, TCP can do something intelligent (but often doesn't). With UDP, the packet gets sent with no guarantees about delivery. Furthermore the user process might well be sending data to several destinations via the same "socket", and it is not clear how to return errors to the user. I see three basic approaches. 1) Do nothing, a favorite among current implementations. 2) Pass errors back to the user process. This is hard to do, since the kernel may well have no idea of what process sent the packet. In some cases, the kernel would have to keep a log of all UDP packets it sends in order to pass back errors to the user. 3) Cache errors in the routing tables for short periods of time. This can be done by adding a flag to route table entries that says "Not really reachable". That way, the user would not get an error on the first packet, but the retransmission of that packet could cause the route lookup to note that the destination is unreachable and the user could be informed. This would be a significant improvement because now the user process could elect to use a different address as the jprimary. Furthermore, the user process could elect not to use the "bad route" for a long time (say 30 minutes or several hours), long after the record of the unreachable message has been flushed from routing tables. This has the desired effect of: 1) Processes using UDP can get feedback about unreachable destinations. 2) It doesn't drastically change the semantics of the UDP interface. E.g. the user is not notified asyncronously or forced to ask explicitely whether a route works. On return from the sendpacket() routine, a flag could be returned. In addition, sending packets to an unreachable destination doesn't have to mean that the packet didn't get sent, it just means "I got an dest unreachable a while ago. It is not likely that the packet will get there". The user can choose to ignore this (though he/she really shouldn't). 3) The length of time dest unreachable messages are cached can (and probably needs to be) an adjustable parameter. It may well be that caching such a message for 10-30 seconds would be sufficient to cut down on the number of useless packets sent, yet would not keep users from reaching hosts that were down but just came back up. 4) Programs don't have to rely on timeouts to decide that a host or list of hosts is unreachable. This will often times give users a quicker response. Comments? Thomas