diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-13 13:13:23 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-13 13:15:05 +0100 |
commit | 562663df7c13d27834adacaa1fa5cb9a4ef47c2e (patch) | |
tree | d53cf5b0d3b8037183844ffdcc321e25560b0336 /Userland/ping.cpp | |
parent | 7bcd3863382c4151e322a01a8ba573817879bd42 (diff) | |
download | serenity-562663df7c13d27834adacaa1fa5cb9a4ef47c2e.zip |
Add support for socket send/receive timeouts.
Only the receive timeout is hooked up yet. You can change the timeout by
calling setsockopt(..., SOL_SOCKET, SO_RCVTIMEO, ...).
Use this mechanism to make /bin/ping report timeouts.
Diffstat (limited to 'Userland/ping.cpp')
-rw-r--r-- | Userland/ping.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/Userland/ping.cpp b/Userland/ping.cpp index b39855cab2..73ce7222b8 100644 --- a/Userland/ping.cpp +++ b/Userland/ping.cpp @@ -39,6 +39,13 @@ int main(int argc, char** argv) return 1; } + struct timeval timeout { 1, 0 }; + int rc = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + if (rc < 0) { + perror("setsockopt"); + return 1; + } + const char* addr_str = "192.168.5.1"; if (argc > 1) addr_str = argv[1]; @@ -50,7 +57,7 @@ int main(int argc, char** argv) peer_address.sin_family = AF_INET; peer_address.sin_port = 0; - int rc = inet_pton(AF_INET, addr_str, &peer_address.sin_addr); + rc = inet_pton(AF_INET, addr_str, &peer_address.sin_addr); struct PingPacket { struct icmphdr header; @@ -84,6 +91,10 @@ int main(int argc, char** argv) for (;;) { rc = recvfrom(fd, &pong_packet, sizeof(PingPacket), 0, (const struct sockaddr*)&peer_address, sizeof(sockaddr_in)); if (rc < 0) { + if (errno == EAGAIN) { + printf("Request (seq=%u) timed out.\n", ntohs(ping_packet.header.un.echo.sequence)); + break; + } perror("recvfrom"); return 1; } @@ -104,12 +115,17 @@ int main(int argc, char** argv) int ms = tv_diff.tv_sec * 1000 + tv_diff.tv_usec / 1000; char addr_buf[64]; - printf("Pong from %s: id=%u, seq=%u, time=%dms\n", + printf("Pong from %s: id=%u, seq=%u%s, time=%dms\n", inet_ntop(AF_INET, &peer_address.sin_addr, addr_buf, sizeof(addr_buf)), ntohs(pong_packet.header.un.echo.id), ntohs(pong_packet.header.un.echo.sequence), + pong_packet.header.un.echo.sequence != ping_packet.header.un.echo.sequence ? "(!)" : "", ms ); + + // If this was a response to an earlier packet, we still need to wait for the current one. + if (pong_packet.header.un.echo.sequence != ping_packet.header.un.echo.sequence) + continue; break; } |