0

When using curl and wget, when source port is not set manually (like with --local-port in curl), the source TCP port is always even, and will increment by 2, instead of 1.

EG: in tcpdump when I make a connection I see source port 45080 used, and then the next connection will use 45082, rather than 45801. Using local-port I can force it to use odd ports, and tcpdump confirms these are succesfully being used.

This is causing me problems in a network test bed, and I can't for the life of me figure out what is controlling the implicit tcp port selection. I can change the range, but I cant change the "incrementation".

Using centos7 and "3.10.0-514.el7.x86_64" kernel.

in tcpdump I see the same behavior using wget and curl, which leads me to believe this is not a curl specific problem, but rather whatever under the hood mechanism is being used to select ports.

Also, if I I see curl using port 45080 for example, I know the next port it will use is 45082. If I force a --local-port of 50000, then curl once more without the --local-port, it will be 45082, like a separate counter is increment it, that is not affected by whatever the "last" used port was.

Alternatively, if do the same thing as the above step, but instead of force port 50000, I force it to use 45082, the port it was presumebly going to pick, then i use curl again without forcing a local port, it will pick 45083, then if again it will pick 45084, then 45086...

The only other way I could get it to naturally pick an odd one is if I limited the range to an odd number of ports.

is there a sys call, or some kind of kernel operation for picking source ports, and is there a way to change it?

Thanks!

  • At least you have a pattern, technically, it could simply be random. There is nothing that requires it to step by one. – Ron Maupin Sep 25 '17 at 21:13
  • @RonMaupin yes but why the change? Whats controlling it, if anything? Is there a configuration item? And its definitely not random, If I bind to port 0, then its random, if I dont, it will be seqential by 2's – e wagness Sep 26 '17 at 17:40
  • It is up to the OS implementation. Often, there are protocols that use either the odd or even address for the data, and the other address for the control. That is why you see ranges in firewalls for things like VoIP. – Ron Maupin Sep 26 '17 at 17:43
0

I believe I was able to prove that the kernel itself is increment the ports this way.

Strace showed both wget and curl calling connect() without calling bind() to explicitly set the source port.

I wrote a python script to simulate the same thing, and it seems the 3.1 kernel increments by 2, and the 2.6 kernel does not.

Interestingly, this is only true when using connect(), if you bind on port 0, thus letting the kernel pick the next available port, it is pretty much random.

My script:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.28.0.2', 80))
addr = s.getsockname()
print addr[1]
s.close()

output:

$ python port_test.py
45008
$ python port_test.py
45010
$ python port_test.py
45012

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.