diff --git a/protocol/icmp.c b/protocol/icmp.c index 864a83908..bec0f124e 100644 --- a/protocol/icmp.c +++ b/protocol/icmp.c @@ -10,7 +10,7 @@ int ping(const char* host, int cnt) { static uint16_t seq = 0; uint16_t pid16 = (uint16_t)getpid(); char ip[64] = {0}; - uint32_t start_tick, end_tick; + uint32_t start_tick, end_tick, cur_ping_start_tick; uint64_t start_hrtime, end_hrtime; int timeout = 0; int sendbytes = 64; @@ -64,7 +64,9 @@ int ping(const char* host, int cnt) { icmp_req->icmp_data[i] = i; } start_tick = gettick_ms(); + while (cnt-- > 0) { + cur_ping_start_tick = gettick_ms(); // NOTE: checksum icmp_req->icmp_seq = ++seq; icmp_req->icmp_cksum = 0; @@ -78,29 +80,38 @@ int ping(const char* host, int cnt) { } ++send_cnt; addrlen = sizeof(peeraddr); + _read_again: + if(gettick_ms() - cur_ping_start_tick >= PING_TIMEOUT) { + // recv timeout, send ping again. + continue; + } + int nrecv = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, &peeraddr.sa, &addrlen); if (nrecv < 0) { perror("recvfrom"); - continue; + goto _read_again; } - ++recv_cnt; + end_hrtime = gethrtime_us(); // check valid - bool valid = false; int iphdr_len = ipheader->ihl * 4; int icmp_len = nrecv - iphdr_len; - if (icmp_len == sendbytes) { - icmp_res = (icmp_t*)(recvbuf + ipheader->ihl*4); - if (icmp_res->icmp_type == ICMP_ECHOREPLY && - icmp_res->icmp_id == pid16 && - icmp_res->icmp_seq == seq) { - valid = true; - } + if (icmp_len != sendbytes) { + // not our ping + goto _read_again; } - if (valid == false) { - printd("recv invalid icmp packet!\n"); - continue; + + icmp_res = (icmp_t*)(recvbuf + ipheader->ihl*4); + if (icmp_res->icmp_type != ICMP_ECHOREPLY || + icmp_res->icmp_id != pid16 || + icmp_res->icmp_seq != seq) { + // not our ping + goto _read_again; } + + end_hrtime = gethrtime_us(); + ++recv_cnt; + rtt = (end_hrtime-start_hrtime) / 1000.0f; min_rtt = MIN(rtt, min_rtt); max_rtt = MAX(rtt, max_rtt);