M
M
Mikhail Yurievich2017-04-24 10:28:08
linux
Mikhail Yurievich, 2017-04-24 10:28:08

Linux, socket loopback after process crash, why?

Hello everyone, I ran into the following problem:
- debian 8
- REST service on nodejs (listens on port, 50100)
- PHP (curl) client, connects quite often, makes a request, disconnects

Everything works fine until the service is turned off (or it won't crash on its own for some reason), then the following happens:
$ netstat -apne|grep 50100
tcp 0 0 127.0.0.1:50100 127.0.0.1:50100 ESTABLISHED 10000 2375204860 8054/php

php process that was connected (or tried to connect?) at the time of disconnection, the service becomes connected to itself , while it goes to the eternal poll:
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7fc404f7d8d0}, 8) =
0
[{fd=9, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7fc404f7d8d0}, NULL, 8) = 0
poll([{fd=9, events=POLLIN}], 1, 1000) = 0 (Timeout)
rt_sigaction(SIGPIPE, NULL, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7fc404f7d8d0}, 8) = 0
rt_sigaction( SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7fc404f7d8d0}, NULL, 8) = 0
poll([{fd=9, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout )
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART, 0x7fc404f7d8d0}, NULL, 8) = 0
poll([{fd=9, events=POLLIN}], 1, 1000) = 0 (Timeout)

The main problem is - raise the service back, the port is busy - until you kill the php process, the port is free
. Moreover, periodically different php processes can occupy this port on all interfaces, including ipv6

Why does this happen and how to deal with it?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
neol, 2017-04-24
@Forbidden

Ports for outgoing connections are by default selected from the range 32768-60999 (set by sysctl net.ipv4.ip_local_port_range).
The port 50100 you're using falls into this range, and when PHP tries to connect to a downed service, it eventually hits that port and connects to itself.
You can solve the problem by setting the port range in curl:
curl_setopt($ch, CURLOPT_LOCALPORT, 12345); // Start port
curl_setopt($ch, CURLOPT_LOCALPORTRANGE, 10); // Number of ports in the range
In this example, ports 12345 to 12355 will be used.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question