From 3259f4bdcaa61a9bcde732df3f930ee3f278b563 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 31 May 1996 04:00:21 +0000 Subject: Use the setsockopt for IP_PORTRANGE to cause rresvport() to allocate a privileged port within a single bind(), rather than looping through attempts to bind over and over again over progressively lower ports. This should speed up rlogin/rsh etc, and will probably cure some of the strange rlogin hangs that have been reported in the past where rresvport() managed to bind() to a port address that it shouldn't have. --- lib/libc/net/rcmd.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'lib/libc') diff --git a/lib/libc/net/rcmd.c b/lib/libc/net/rcmd.c index 405dd8e..3d6c649 100644 --- a/lib/libc/net/rcmd.c +++ b/lib/libc/net/rcmd.c @@ -222,28 +222,40 @@ rresvport(alport) int *alport; { struct sockaddr_in sin; - int s; + int s, on, len; sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = 0; + s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) return (-1); - for (;;) { - sin.sin_port = htons((u_short)*alport); - if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) - return (s); - if (errno != EADDRINUSE) { - (void)close(s); - return (-1); - } - (*alport)--; - if (*alport == IPPORT_RESERVED/2) { + + on = IP_PORTRANGE_LOW; + if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, (char*)&on, sizeof(on)) < 0) + { + (void)close(s); + return(-1); + } + + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) { + /* attempt to find the port that we were assigned */ + len = sizeof(sin); + if (getsockname(s, (struct sockaddr *)&sin, &len) >= 0) + *alport = ntohs(sin.sin_port); + else { (void)close(s); - errno = EAGAIN; /* close */ return (-1); } + + return (s); } + if (errno == EADDRNOTAVAIL) /* no available ports? */ + errno = EAGAIN; /* "official" return for this case */ + + (void)close(s); + return (-1); } int __check_rhosts_file = 1; -- cgit v1.1