udp port unreachable - what behavior ?

Cedric ROUX (roux@ecoledoc.lip6.fr)
Thu, 8 Apr 1999 14:41:38 +0200


/*
Hi kernel hackers.

The following program shows a strange behavior
of the udp handling of the kernel.
In the source, it is said that to an udp packet
sent to an unreachable port, it SHOULD be returned
and icmp packet (don't remember what) as stated by rfc XXX (don't remember).

But, on my system, this program sometimes runs 5 turns (on 2.2.1) sometimes
less, sometimes even 0 (ie no ICMP reply). Try it very quickly.

So my question is, what does this "SHOULD" mean ? It is not "always", it
is not "never", but it doesn't seem to be "at least one".

In fact, all this comes from the libc with the resolver. I had a bad
configuration with /etc/host.conf, and it did a connect to port domain
of localhost where no named runs (i don't need one). So i changed
/etc/host.conf to point to an non-existing host so now i don't have
unreachable port but unreachable host or something like that, and it
does reply (well, in fact it doesn't block anymore, don't really know what's
going on).

So is it the kernel that is wrong or me ?

Sed, not on the list, a CC is welcome.
*/

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void)
{
fd_set set;
int nb;
int turn=0;
char buf[1000];
struct sockaddr_in add;
int fd;

while(1) {
fprintf(stderr, "turn %d begins\n", turn);
fd=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd==-1) {
perror("socket");
return -1;
}
add.sin_port=htons(31435);
add.sin_family=AF_INET;
if (inet_aton("0.0.0.0", &add.sin_addr)==-1) {
perror("inet_aton");
return -1;
}
if (connect(fd, &add, sizeof(add))==-1) {
perror("connect");
return -1;
}
if (send(fd, buf, 27, 0)==-1) {
perror("send");
return -1;
}
FD_ZERO(&set);
FD_SET(fd, &set);
if ((nb=select(fd+1, &set, 0, 0, 0))==-1) {
perror("select");
return -1;
}
if (!nb) {
fprintf(stderr, "huh huh, nb=0, bad (impossible in fact)\n");
return -1;
} else {
struct sockaddr from;
int fromlen=sizeof(from);
if (recvfrom(fd, buf, 1000, 0, &from, &fromlen)==-1)
perror("recvfrom");
}
close(fd);
fprintf(stderr, "turn %d ends\n", turn++);
}
return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/