Open agadsby opened 5 years ago
Here is what appears in the LINUX dmesg output reflecting how the LINUX kernel deals with the issue with the listen() backlog set to 0. If SYN_COOKIE handling is disabled connections to sockdev fail, I believe this is because the kernel has no mechanism for the partial connection to be queued without cookies being disabled.
On Ubuntu with UFW turned on: With /proc/sys/net/ipv4/tcp_syncookies => 0 [ 8185.119105] TCP: request_sock_TCP: Possible SYN flooding on port 3214. Dropping request. Check SNMP counters. [ 8186.119441] TCP: request_sock_TCP: Possible SYN flooding on port 3215. Dropping request. Check SNMP counters. [ 8244.161950] TCP: request_sock_TCP: Possible SYN flooding on port 3505. Dropping request. Check SNMP counters.
with /proc/sys/net/ipv4/tcp_syncookies => 1 [ 8751.773684] TCP: request_sock_TCP: Possible SYN flooding on port 3202. Sending cookies. Check SNMP counters. [ 8752.774388] TCP: request_sock_TCP: Possible SYN flooding on port 3214. Sending cookies. Check SNMP counters. [ 8753.775755] TCP: request_sock_TCP: Possible SYN flooding on port 3215. Sending cookies. Check SNMP counters.
On pi out of the box: With /proc/sys/net/ipv4/tcp_syncookies => 1 [ 1552.669488] TCP: request_sock_TCP: Possible SYN flooding on port 3202. Sending cookies. Check SNMP counters. [ 1553.676287] TCP: request_sock_TCP: Possible SYN flooding on port 3214. Sending cookies. Check SNMP counters. [ 1554.677974] TCP: request_sock_TCP: Possible SYN flooding on port 3215. Sending cookies. Check SNMP counters. [ 1784.566635] TCP: request_sock_TCP: Possible SYN flooding on port 3505. Sending cookies. Check SNMP counters.
From the Opengroup definition for listen(): A backlog argument of 0 may allow the socket to accept connections, in which case the length of the listen queue may be set to an implementation-defined minimum value.
Therefore I believe the portable solution is to set the backlog to 1. As that will always work according to the definition.
@agadsby
FYI: hercules-390/hyperion appears to no longer be under active development.
Active Hercules development is now being done on SDL-Hercules-390/hyperion:
Your GitHub Issue was copied to SDL-Hercules-390 as SDL-Hercules-390/hyperion#198 "Using sockdev as device endpoint fails in certain LINUX configurations" and was closed (completed/fixed) by commit https://github.com/SDL-Hercules-390/hyperion/commit/776a254688b1ebb85f9a8dcf6b0bc23b00c67529.
Thanks.
p.s. Adding a name and email address to your GitHub account would be appreciated.
The use of sockdev as a device endpoint appears to not work on LINUX versions without syn_cookies being enabled. On system such as the Raspberry Pi messages relating to sync cookies being used are also issued in the operating system log.
The problem presents as external processes such as Hercrdr and Hercprt cannot connect to any sockdev(s) defined in the conf/tk4-.cnf . After tracing this through the problem appeared to be that the LINUX kernel did not pass the socket connection to Hercules: a netstat -a showed the connection to the socket e.g. 3505, as hanging in SYN sent and dmesg showed messages like: "kernel: possible SYN flooding on port 3505."
The workaround that address this problem is to enable SYN Cookies for the running image:
echo "1" > /proc/sys/net/ipv4/tcp_syncookies
However, this is only a workaround. I believe, the correct solution requires a change to the listen() call used in inet_socket() in sockdev.c.
if (0 || bind (sd, (struct sockaddr*) &sin, sizeof(sin)) == -1 || listen (sd, 0) == -1
The second argument to listen being the backlog, i.e. number of connections that can be pending at any point in time. Reading the manual page, and history, for listen indicates that the use of 0 may be problematic and is likely to be the cause of the socket hanging during the connection. Setting the backlog to 1 will fix the problem in a general way.