This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! Unless the caller of bindresvport is lucky, the first bindresvport that sees all STARTPORT .. ENDPORT ports (i.e. 600 .. 1023) used will fail. While subsequent bindresvport calls would probably succeed again (as 512 .. 1023 range would be scanned next time), most programs bail out on the first failure. The reason why the bindresvport call that changes startport variable usually fails is that unless port ends with a value > (ENDPORT - (STARTPORT - LOWPORT)) == 935, after jumping to again label it will try all ports in the range portN .. portN+87 (where portN is value of port variable on the startport = LOWPORT; statement), but those usually have been already checked previously to be already bound. The fix can be either to set nports not to STARTPORT - LOWPORT, but ENDPORT - LOWPORT + 1 (guess solution shortest for code size, but might scan up to 423 ports unnecessarily again), or startport = LOWPORT: nports = STARTPORT - 1; port = LOWPORT; (the disadvantage would be that in case of overflowing the 600 .. 1023 area it would always start with port 512), or as done in the patch below, setting port to something in between LOWPORT and STARTPORT - 1 and making sure that wrapping in that loop will be when port >= STARTPORT. 2005-11-21 Jakub Jelinek <jakub@redhat.com> * sunrpc/bindrsvprt.c (bindresvport): Wrap around to startport in the loop if port is bigger than endport, initially set to ENDPORT. When changing startport, set endport and port appropriately. --- libc/sunrpc/bindrsvprt.c 23 May 2005 19:03:43 -0000 1.11 +++ libc/sunrpc/bindrsvprt.c 21 Nov 2005 19:52:27 -0000 @@ -74,14 +74,13 @@ bindresvport (int sd, struct sockaddr_in int res = -1; int nports = ENDPORT - startport + 1; + int endport = ENDPORT; again: for (i = 0; i < nports; ++i) { sin->sin_port = htons (port++); - if (port > ENDPORT) - { - port = startport; - } + if (port > endport) + port = startport; res = __bind (sd, sin, sizeof (struct sockaddr_in)); if (res >= 0 || errno != EADDRINUSE) break; @@ -90,7 +89,9 @@ bindresvport (int sd, struct sockaddr_in if (i == nports && startport != LOWPORT) { startport = LOWPORT; + endport = STARTPORT - 1; nports = STARTPORT - LOWPORT; + port = LOWPORT + port % (STARTPORT - LOWPORT); goto again; } Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |