Messages in this thread | | | Date | Thu, 13 Aug 2015 11:35:41 +0530 | Subject | SOCK_STREAM socket + bind without calling listen makes address hidden | From | Manvendra Bhangui <> |
| |
Stumbled on an issue of imap server refusing to start on TCP port 993 with error EADDRINUSE inspite of netstat, lsof, ss programs indicating no process has bound on tcp port 993
On debugging found the issue to be with portreserve program. http://linux.die.net/man/1/portreserve
But portreserve is not the issue. It is doing what it is expected to do - grab and reserve a port
None of the programs - netstat, lsof, ss could show that the portreserve port has bound on the socket 993. Killing the portreserve program or calling portrelease program resolves the issue.
I can simulate the same issue by writing a code which just calls socket() and bind() and nothing that I know of can find out which program has bound on an address
Shouldn't there be a socket state which netstat / lsof / ss can reveal which process has bound on an address without calling listen()? I could think of rogue programs which calls socket() + bind(), without calling listen(), to prevent programs from starting up and left with a clueless admin trying to figure out which process has bound an address
start portreserve service to reserve imaps port
# systemctl enable portreserve
## get the pid of portreserve # ps -ef|grep portreserve root 29771 1 0 11:14 ? 00:00:00 /sbin/portreserve root 29773 28654 0 11:14 pts/1 00:00:00 grep --color=auto portreserve
run lsof to find all open ports. You can see that for TCP socket, the address is not shown. it just shows "protocol: TCP" For UDP it shows the address
# lsof -p 29771 lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs Output information may be incomplete. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME portreser 29771 root cwd DIR 253,0 4096 2 / portreser 29771 root rtd DIR 253,0 4096 2 / portreser 29771 root txt REG 253,0 15792 2112388 /usr/sbin/portreserve portreser 29771 root mem REG 253,0 62072 2109005 /usr/lib64/libnss_files-2.20.so portreser 29771 root mem REG 253,0 2082456 2101348 /usr/lib64/libc-2.20.so portreser 29771 root mem REG 253,0 163176 2098678 /usr/lib64/ld-2.20.so portreser 29771 root 0uW REG 0,19 6 175038 /run/portreserve.pid portreser 29771 root 1u unix 0xffff8801fd24c600 0t0 175039 /var/run/portreserve/socket portreser 29771 root 4u sock 0,8 0t0 175043 protocol: TCP portreser 29771 root 5u IPv4 175044 0t0 UDP *:imaps
same with the netstat program which shows only the udp port
# netstat -anp |grep 993 udp 0 0 0.0.0.0:993 0.0.0.0:* 29771/portreserve
same with the ss program which also shows only the udp port # ss -a| egrep "993|imaps" udp UNCONN 0 0 *:ipproto-993 *:*
try is a simple program which binds on both tcp port 993 (ipv4 as well as ipv6)
# ./try bind: Address already in use #
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=60}, 8) = 0 bind(3, {sa_family=AF_INET, sin_port=htons(993), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EADDRINUSE (Address already in use) close(3) = 0 socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=60}, 8) = 0 bind(3, {sa_family=AF_INET6, sin6_port=htons(993), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EADDRINUSE (Address already in use)
-- Regards Manvendra - http://www.indimail.org
| |