Ich versuche TCP-Reset auf einer Verbindung zu erzwingen. Die vorgeschlagene Möglichkeit besteht darin, SO_LINGER auf 0 und den Aufruf close() zu setzen.Schließen() mit SO_LINGER wird nicht senden RST
Ich mache genau das, aber die Verbindung bleibt im Zustand ESTABLISHED. Die Buchse arbeitet im nicht blockierenden Modus. Das Betriebssystem ist Raspbian.
Der Code:
struct linger l;
l.l_onoff = 1;
l.l_linger = 0;
if (setsockopt(server->connection_socket, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) {
LOG_E(tcp, "setting SO_LINGER failed");
}
if (close(server->connection_socket) != 0) {
LOG_E(tcp, "closing socket failed");
}
server->connection_socket = 0;
LOG_I(tcp, "current TCP connection was closed");
Wireshark Spur zeigt auch keine RST.
Keine anderen Threads der Anwendung führen einen Vorgang an diesem Socket durch.
Ich kann nicht herausfinden, was falsch ist, würde jeder Vorschlag sehr geschätzt werden.
GELöST
Das Problem war mit Dateideskriptoren Kindern undichten durch system()
Anruf erstellt. In der Tat, als ich alle TCP-Socket-Deskriptoren mit lsof -i tcp
aufgelistet, fand ich heraus, dass untergeordnete Prozesse Dateideskriptor aus dem übergeordneten Prozess geöffnet hatte (obwohl Eltern bereits nicht).
Die Lösung forderte, dass der Dateideskriptor in einem gegabelten Prozess geschlossen wird (direkt nach accept()
).
fcntl(server->connection_socket, F_SETFD, FD_CLOEXEC)
Haben Sie einen Prozess gegabelt? 'close()' wird nur tun, was es tut, wenn es das * letzte * Ende ist, wenn es Gabeln gab. – EJP