diff --git a/contrib/tcploop/tcploop.c b/contrib/tcploop/tcploop.c index f9f5f6307..55b793658 100644 --- a/contrib/tcploop/tcploop.c +++ b/contrib/tcploop/tcploop.c @@ -105,6 +105,7 @@ __attribute__((noreturn)) void usage(int code, const char *arg0) " Note: fd=socket,bind(fd),listen(fd)\n" " C : Connects to ip:port\n" " Note: fd=socket,connect(fd)\n" + " D : Disconnect (connect to AF_UNSPEC)\n" " A[] : Accepts incoming sockets and closes count-1\n" " Note: fd=accept(fd)\n" " J : Jump back to oldest post-fork/post-accept action\n" @@ -443,6 +444,14 @@ int tcp_connect(const struct sockaddr_storage *sa, const char *arg) return -1; } +/* Try to disconnect by connecting to AF_UNSPEC. Return >=0 on success, -1 in case of error */ +int tcp_disconnect(int sock) +{ + const struct sockaddr sa = { .sa_family = AF_UNSPEC }; + + return connect(sock, &sa, sizeof(sa)); +} + /* receives N bytes from the socket and returns 0 (or -1 in case of a recv * error, or -2 in case of an argument error). When no arg is passed, receives * anything and stops. Otherwise reads the requested amount of data. 0 means @@ -787,6 +796,13 @@ int main(int argc, char **argv) dolog("connect\n"); break; + case 'D': + /* silently ignore non-existing connections */ + if (sock >= 0 && tcp_disconnect(sock) < 0) + die(1, "Fatal: tcp_connect() failed.\n"); + dolog("disconnect\n"); + break; + case 'A': if (sock < 0) die(1, "Fatal: tcp_accept() on non-socket.\n");