summaryrefslogtreecommitdiff
path: root/Userland/ping.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-13 13:13:23 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-13 13:15:05 +0100
commit562663df7c13d27834adacaa1fa5cb9a4ef47c2e (patch)
treed53cf5b0d3b8037183844ffdcc321e25560b0336 /Userland/ping.cpp
parent7bcd3863382c4151e322a01a8ba573817879bd42 (diff)
downloadserenity-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.cpp20
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;
}