Linux free port allocation algorithm

This is a discussion on Linux free port allocation algorithm within the Linux Networking forums, part of the Linux Forums category; There seems to have been a change in the Linux free port allocation algorithm somewhere between kernel 2.6.9 ...


Go Back   Usenet Forums > Linux Forums > Linux Networking

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 01-05-2008
kreide@gmail.com
 
Posts: n/a
Default Linux free port allocation algorithm

There seems to have been a change in the Linux free port allocation
algorithm somewhere between kernel 2.6.9 and 2.6.17.

When a socket is allocated (with the bind() system call) with
sin_port = 0 in 2.6.9 it seems that free ports are handed out
sequentially, while 2.6.17 will hand them out in random order.

Unfortunately this breaks a program I use, which depends on being able
to allocate a port, free it and then allocate it again shortly
thereafter; if ports are handed out randomly and there are several
programs on the machine doing the same thing the allocation will fail
fairly often (this is the birthday paradox).

Does anyone know when the algorithm was changed? Is there a way to
restore the old behavior in newer kernels?

Thanks!
Reply With Quote
  #2 (permalink)  
Old 01-05-2008
Unruh
 
Posts: n/a
Default Re: Linux free port allocation algorithm

kreide@gmail.com writes:

>There seems to have been a change in the Linux free port allocation
>algorithm somewhere between kernel 2.6.9 and 2.6.17.


>When a socket is allocated (with the bind() system call) with
>sin_port = 0 in 2.6.9 it seems that free ports are handed out
>sequentially, while 2.6.17 will hand them out in random order.


>Unfortunately this breaks a program I use, which depends on being able


Well, then that program should be changed. It has a bug in it.

>to allocate a port, free it and then allocate it again shortly
>thereafter; if ports are handed out randomly and there are several
>programs on the machine doing the same thing the allocation will fail
>fairly often (this is the birthday paradox).


Have you found such failures or are you just guessing?


>Does anyone know when the algorithm was changed? Is there a way to
>restore the old behavior in newer kernels?


Reply With Quote
  #3 (permalink)  
Old 01-05-2008
kreide@gmail.com
 
Posts: n/a
Default Re: Linux free port allocation algorithm

> >Unfortunately this breaks a program I use, which depends on being able
> Well, then that program should be changed. It has a bug in it.


I agree, however, I do not have the option of changing the program in
question, thus unless I can find a way to preserve the old behavior on
newer kernels I am stuck with 2.6.9.

> >programs on the machine doing the same thing the allocation will fail
> >fairly often (this is the birthday paradox).

> Have you found such failures or are you just guessing?


Yes, unfortunately this does happen in practice, which is why I am
trying to find a solution.
Reply With Quote
  #4 (permalink)  
Old 01-06-2008
David Schwartz
 
Posts: n/a
Default Re: Linux free port allocation algorithm

On Jan 5, 1:22 pm, kre...@gmail.com wrote:

> Yes, unfortunately this does happen in practice, which is why I am
> trying to find a solution.


Preload a library that changes the 'bind' wrapper so that a 'bind'
with a port of zero uses a port that you select using whatever
algorithm you like. Google for 'LD_PRELOAD' for more information.

DS
Reply With Quote
  #5 (permalink)  
Old 01-07-2008
kreide@gmail.com
 
Posts: n/a
Default Re: Linux free port allocation algorithm

> Preload a library that changes the 'bind' wrapper so that a 'bind'

Actually that is a great idea, and what is even better it turned out
to work great in practice. Thank you for the help!
Reply With Quote
  #6 (permalink)  
Old 01-07-2008
Chris Davies
 
Posts: n/a
Default Re: Linux free port allocation algorithm

On Jan 5, 1:22 pm, kre...@gmail.com wrote:
> Yes, unfortunately this does happen in practice, which is why I am
> trying to find a solution.


David Schwartz <davids@webmaster.com> wrote:
> Preload a library that changes the 'bind' wrapper so that a 'bind'
> with a port of zero uses a port that you select using whatever
> algorithm you like.


Alternatively, change your program (since that's the one with the
incorrect expectation) to give bind() a specific port number.

Chris
Reply With Quote
  #7 (permalink)  
Old 01-07-2008
Pascal Hambourg
 
Posts: n/a
Default Re: Linux free port allocation algorithm

Hello,

kreide@gmail.com a écrit :
> There seems to have been a change in the Linux free port allocation
> algorithm somewhere between kernel 2.6.9 and 2.6.17.
>
> When a socket is allocated (with the bind() system call) with
> sin_port = 0 in 2.6.9 it seems that free ports are handed out
> sequentially, while 2.6.17 will hand them out in random order.


[cut description of application with broken behaviour]

> Does anyone know when the algorithm was changed?


2.6.11 :
[TCP]: Efficient port randomization

Provide port randomization for incoming connections using
variation of existing sequence number hash.

2.6.15 :
[TCP/DCCP]: Randomize port selection

This patch randomizes the port selected on bind() for connections
to help with possible security attacks. It should also be faster
in most cases because there is no need for a global lock.

> Is there a way to restore the old behavior in newer kernels?


I haven't found any sysctl which does that.
Reply With Quote
  #8 (permalink)  
Old 01-07-2008
kreide@gmail.com
 
Posts: n/a
Default Re: Linux free port allocation algorithm

> Preload a library that changes the 'bind' wrapper so that a 'bind'

In case someone else is interested I am posting the source code for
the program that I came up with. It has been a while since I did low-
level C programming, but hopefully someone here can do a code review
and point out any flaws or suggest improvements.

#include <stdio.h>
#include <errno.h>

// avoid duplicate definition of bind()
#define _SYS_SOCKET_H 1
#include <netinet/in.h>

// required to get RTLD_NEXT
#ifndef __USE_GNU
#define __USE_GNU 1
#endif
#include <dlfcn.h>

#define LOW_PORT 32768
#define HIGH_PORT 60999

volatile static int next_port = LOW_PORT;

int bind(int __fd, struct sockaddr * __addr, socklen_t __len) {
static off_t (*funcptr)(int, struct sockaddr *, socklen_t) = NULL;

if (!funcptr) {
funcptr = (off_t (*)(int, struct sockaddr *, socklen_t))
dlsym(RTLD_NEXT, "bind");
}

if ( __addr->sa_family == AF_INET) {
struct sockaddr_in * __addr_in = (struct sockaddr_in *) __addr;
if (__addr_in->sin_port == 0) {
int ret;
do {
if (next_port > HIGH_PORT) next_port = LOW_PORT;
int my_port = next_port++;
__addr_in->sin_port = htons(my_port);
ret = (*funcptr)(__fd, __addr, __len);
} while (ret < 0 && errno == EADDRINUSE);
return ret;
}
}
return (*funcptr)(__fd, __addr, __len);
}
Reply With Quote
  #9 (permalink)  
Old 01-07-2008
kreide@gmail.com
 
Posts: n/a
Default Re: Linux free port allocation algorithm

> [cut description of application with broken behavior]

Let me quickly describe why I need this; it is not as unreasonable as
one might think.

I have several server modules which are unit tested automatically; my
testing tool is integrated with the RCS (mercurial in case anyone is
curious) which checks out and tests all committed revisions. Since the
testing is somewhat time consuming and the machine has lots of spare
CPU cores many revisions are tested in parallel.

Some of the server modules are 3rd party and require a port number to
be specified when they are started; since many instances of each
server module is running on the same machine they need different port
numbers and the way I obtain these is by allocating a socket on a free
port, close the socket and give that port number to the server module.
There is of course a race condition here, but if free ports are handed
out sequentially this is not a problem in practice; if they are random
it is.

Changing the 3rd party modules is unfortunately not an option, and I
would like to avoid having to implement my own service to keep track
of allocated ports on the machine; depending on bind() behaving in a
certain way seems like the better option.
Reply With Quote
  #10 (permalink)  
Old 01-07-2008
David Schwartz
 
Posts: n/a
Default Re: Linux free port allocation algorithm

On Jan 7, 9:51 am, kre...@gmail.com wrote:

> Some of the server modules are 3rd party and require a port number to
> be specified when they are started; since many instances of each
> server module is running on the same machine they need different port
> numbers and the way I obtain these is by allocating a socket on a free
> port, close the socket and give that port number to the server module.
> There is of course a race condition here, but if free ports are handed
> out sequentially this is not a problem in practice; if they are random
> it is.


A better solution, IMO, is to use a range of ports that is outside the
range the system assigns from. So if the system assigns from, say,
33,000 to 55,000, you assign from 60,000 up sequentially, wrapping
around if you run out.

You don't seem to have any need for system-assigned port numbers here.

DS
Reply With Quote
Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT +1. The time now is 06:06 AM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0