From: Vadim Fedorenko Date: Thu, 13 Apr 2023 14:11:00 +0000 (-0700) Subject: netevent: parse and store rcv timestamp from sock X-Git-Tag: release-1.18.0rc1~24^2~51^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e6ddd603279cab26e3ee344a1ba26a7ba428e2c;p=thirdparty%2Funbound.git netevent: parse and store rcv timestamp from sock Add special field in comm_point to store the software receive timestamp for every particular UDP packet. Aux data parser is updated to read values and the whole callback is switched to use recvmsg form. Signed-off-by: Vadim Fedorenko --- diff --git a/daemon/worker.c b/daemon/worker.c index a4d6b8247..85709af6e 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -68,6 +68,7 @@ #include "util/fptr_wlist.h" #include "util/tube.h" #include "util/edns.h" +#include "util/timeval_func.h" #include "iterator/iter_fwd.h" #include "iterator/iter_hints.h" #include "iterator/iter_utils.h" diff --git a/util/netevent.c b/util/netevent.c index 5558e52ca..ca5b9e165 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -46,6 +46,7 @@ #include "util/tcp_conn_limit.h" #include "util/fptr_wlist.h" #include "util/proxy_protocol.h" +#include "util/timeval_func.h" #include "sldns/pkthdr.h" #include "sldns/sbuffer.h" #include "sldns/str2wire.h" @@ -114,6 +115,16 @@ /** timeout in millisec to wait for write to unblock, packets dropped after.*/ #define SEND_BLOCKED_WAIT_TIMEOUT 200 +/** Let's make timestamping code cleaner and redefine SO_TIMESTAMP* */ +#ifndef SO_TIMESTAMP +#define SO_TIMESTAMP 29 +#endif +#ifndef SO_TIMESTAMPNS +#define SO_TIMESTAMPNS 35 +#endif +#ifndef SO_TIMESTAMPING +#define SO_TIMESTAMPING 37 +#endif /** * The internal event structure for keeping ub_event info for the event. * Possibly other structures (list, tree) this is part of. @@ -833,6 +844,8 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) #ifndef S_SPLINT_S struct cmsghdr* cmsg; #endif /* S_SPLINT_S */ + struct timespec *ts; + rep.c = (struct comm_point*)arg; log_assert(rep.c->type == comm_udp); @@ -842,7 +855,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) ub_comm_base_now(rep.c->ev->base); for(i=0; ibuffer); - memset(&rep.c->recv_tv, 0, sizeof(rep.c->recv_tv)); + timeval_clear(&rep.c->recv_tv); rep.remote_addrlen = (socklen_t)sizeof(rep.remote_addr); log_assert(fd != -1); log_assert(sldns_buffer_remaining(rep.c->buffer) > 0); @@ -894,8 +907,20 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) sizeof(struct in_addr)); break; #endif /* IP_PKTINFO or IP_RECVDSTADDR */ + } else if( cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SO_TIMESTAMPNS) { + ts = (struct timespec *)CMSG_DATA(cmsg); + TIMESPEC_TO_TIMEVAL(&rep.c->recv_tv, ts); + } else if( cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SO_TIMESTAMPING) { + ts = (struct timespec *)CMSG_DATA(cmsg); + TIMESPEC_TO_TIMEVAL(&rep.c->recv_tv, ts); + } else if( cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SO_TIMESTAMP) { + memmove(&rep.c->recv_tv, CMSG_DATA(cmsg), sizeof(struct timeval)); } } + if(verbosity >= VERB_ALGO) p_ancil("receive_udp on interface", &rep); #endif /* S_SPLINT_S */ @@ -3809,7 +3834,11 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer, evbits = UB_EV_READ | UB_EV_PERSIST; /* ub_event stuff */ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits, +#ifdef USE_WINSOCK comm_point_udp_callback, c); +#else + comm_point_udp_ancil_callback, c); +#endif if(c->ev->ev == NULL) { log_err("could not baseset udp event"); comm_point_delete(c); diff --git a/util/netevent.h b/util/netevent.h index 433c14c3c..761b8539c 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -383,7 +383,8 @@ struct comm_point { /** number of queries outstanding on this socket, used by * outside network for udp ports */ int inuse; - + /** the timestamp when the packet was received by the kernel */ + struct timeval recv_tv; /** callback when done. tcp_accept does not get called back, is NULL then. If a timeout happens, callback with timeout=1 is called.