From 1cff992ad4640c0714b728a4e2aa9a76a978a463 Mon Sep 17 00:00:00 2001 From: Maximilian Fridrich Date: Thu, 12 Dec 2024 13:39:17 +0100 Subject: [PATCH] test/udp: Add TOS test --- test/test.c | 1 + test/test.h | 1 + test/udp.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 166 insertions(+), 1 deletion(-) diff --git a/test/test.c b/test/test.c index 1ec985d46..881b466dd 100644 --- a/test/test.c +++ b/test/test.c @@ -236,6 +236,7 @@ static const struct test tests[] = { TEST(test_turn), TEST(test_turn_tcp), TEST(test_udp), + TEST(test_udp_tos), TEST(test_unixsock), TEST(test_uri), TEST(test_uri_encode), diff --git a/test/test.h b/test/test.h index 303b84166..52fb80a93 100644 --- a/test/test.h +++ b/test/test.h @@ -343,6 +343,7 @@ int test_turn(void); int test_turn_tcp(void); int test_turn_thread(void); int test_udp(void); +int test_udp_tos(void); int test_unixsock(void); int test_uri(void); int test_uri_encode(void); diff --git a/test/udp.c b/test/udp.c index 22a8d3243..b1222f4fd 100644 --- a/test/udp.c +++ b/test/udp.c @@ -6,13 +6,48 @@ #include #include #include "test.h" - +#if defined(WIN32) +#include +#include +#else +#include +#ifndef _BSD_SOCKLEN_T_ +#define _BSD_SOCKLEN_T_ int /**< Defines the BSD socket length type */ +#endif +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_IO_H +#include +#endif +#if !defined(WIN32) +#include +#endif #define DEBUG_MODULE "udptest" #define DEBUG_LEVEL 5 #include +/** Platform independent buffer type cast */ +#ifdef WIN32 +#define BUF_CAST (char *) +#define SIZ_CAST (int) +#define close closesocket +#else +#define BUF_CAST +#define SIZ_CAST +#endif + + +enum { + UDP_RXSZ = 1024 +}; + + struct udp_test { struct udp_sock *usc; struct udp_sock *uss; @@ -21,6 +56,8 @@ struct udp_test { struct sa srv; int tindex; int err; + re_sock_t fds; + int tos; }; @@ -213,3 +250,129 @@ int test_udp(void) return err; } + + +static void udp_read_msg_handler(int flags, void *arg) +{ + struct cmsghdr *cmh; + struct iovec iov; + ssize_t n; + struct msghdr msg = {0}; + char control_buffer[1024] = {0}; + struct udp_test *ut = arg; + struct mbuf *mb = mbuf_alloc(UDP_RXSZ); + int tos = 0; + int err = 0; + + (void)flags; + + if (!mb) + return; + + iov.iov_base = mbuf_buf(mb); + iov.iov_len = UDP_RXSZ; + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = control_buffer; + msg.msg_controllen = sizeof(control_buffer); + + n = recvmsg(ut->fds, &msg, 0); + if (n < 0) + goto out; + + for (cmh = CMSG_FIRSTHDR(&msg); cmh != NULL; + cmh = CMSG_NXTHDR(&msg, cmh)) { + if (cmh->cmsg_level == IPPROTO_IP && cmh->cmsg_type == IP_TOS) + tos = *(unsigned char *)CMSG_DATA(cmh); + } + + TEST_EQUALS(ut->tos, tos); + + out: + if (err) + ut->err = err; + mem_deref(mb); + re_cancel(); +} + + +int test_udp_tos(void) +{ + struct udp_test *ut; + int err; + const int recvtos = 1; + struct re_fhs *fhss = NULL; + char addr[64]; + char serv[6]; + struct addrinfo hints, *res = NULL; + + ut = mem_zalloc(sizeof(*ut), destructor); + if (!ut) + return ENOMEM; + + ut->tos = 120; + + err = sa_set_str(&ut->cli, "127.0.0.1", 0); + err |= sa_set_str(&ut->srv, "127.0.0.1", 0); + TEST_ERR(err) + + err = udp_open(&ut->usc, AF_INET); + err |= udp_open(&ut->uss, AF_INET); + TEST_ERR(err) + + err = udp_settos(ut->usc, ut->tos); + TEST_ERR(err) + + /* Setup server */ + memset(&hints, 0, sizeof(hints)); + /* set-up hints structure */ + hints.ai_family = AF_INET; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + udp_rxsz_set(ut->uss, UDP_RXSZ); + + (void)re_snprintf(addr, sizeof(addr), "%H", sa_print_addr, &ut->srv); + (void)re_snprintf(serv, sizeof(serv), "%u", sa_port(&ut->srv)); + + ut->fds = udp_sock_fd(ut->uss, 0); + TEST_NOT_EQUALS(RE_BAD_SOCK, ut->fds); + + err = setsockopt(ut->fds, IPPROTO_IP, IP_RECVTOS, &recvtos, + sizeof(recvtos)); + TEST_ERR(err); + + err = net_sockopt_blocking_set(ut->fds, false); + TEST_ERR(err); + + err = getaddrinfo(addr, serv, &hints, &res); + TEST_ERR(err); + + err = bind(ut->fds, res->ai_addr, SIZ_CAST res->ai_addrlen); + TEST_ERR(err); + + err = fd_listen(&fhss, ut->fds, FD_READ, udp_read_msg_handler, ut); + TEST_ERR(err); + + err = udp_local_get(ut->uss, &ut->srv); + TEST_ERR(err) + + err = send_data(ut->usc, &ut->srv, data0); + TEST_ERR(err) + + err = re_main_timeout(100); + TEST_ERR(err) + + if (ut->err) + err = ut->err; + + out: + freeaddrinfo(res); + (void)close(ut->fds); + + mem_deref(fhss); + mem_deref(ut); + + return err; +}