From db236e90925b4183fb0bb7fc9aa0cfc8544f89e0 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Mon, 7 May 2018 16:31:15 -0400 Subject: [PATCH 1/2] Merge wincompat/test_common_win.c into test_common.c The macro soup in test_common.c acquired a few more fingernails, but this is better than maintaining (or, rather, forgetting to maintain) two versions of the same code. --- CMakeLists.txt | 2 +- test/prog.c | 18 +- test/test_common.c | 478 ++++++++--------- test/test_common.h | 4 - wincompat/test_common_win.c | 1013 ----------------------------------- 5 files changed, 236 insertions(+), 1279 deletions(-) delete mode 100644 wincompat/test_common_win.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b854e2..18ee662 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,7 +127,7 @@ ELSE() add_executable(http_client test/http_client.c test/prog.c - wincompat/test_common_win.c + test/test_common.c wincompat/getopt.c wincompat/getopt1.c ) diff --git a/test/prog.c b/test/prog.c index 86099aa..3289eda 100644 --- a/test/prog.c +++ b/test/prog.c @@ -257,19 +257,6 @@ prog_init_client (struct prog *prog) } -static int -prog_init_server (struct prog *prog) -{ - struct service_port *sport; - - TAILQ_FOREACH(sport, prog->prog_sports, next_sport) - if (0 != sport_init_server(sport, prog->prog_engine, prog->prog_eb)) - return -1; - - return 0; -} - - void prog_process_conns (struct prog *prog) { @@ -399,10 +386,7 @@ prog_prep (struct prog *prog) prog->prog_timer = event_new(prog->prog_eb, -1, 0, prog_timer_handler, prog); - if (prog->prog_engine_flags & LSENG_SERVER) - s = prog_init_server(prog); - else - s = prog_init_client(prog); + s = prog_init_client(prog); if (s != 0) return -1; diff --git a/test/test_common.c b/test/test_common.c index 2550f4f..88dc5ee 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -1,5 +1,7 @@ /* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc. See LICENSE. */ +#if __GNUC__ #define _GNU_SOURCE /* For struct in6_pktinfo */ +#endif #include #include #include @@ -17,6 +19,7 @@ #else #include #include +#include #include #pragma warning(disable:4996)//posix name deprecated #define close closesocket @@ -35,6 +38,20 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#ifndef WIN32 +# define SOCKET_TYPE int +# define CLOSE_SOCKET close +# define CHAR_CAST +#else + + /* XXX detect these using cmake? */ +# define HAVE_IP_DONTFRAG 1 +# define HAVE_IP_MTU_DISCOVER 1 + +# define SOCKET_TYPE SOCKET +# define CLOSE_SOCKET closesocket +# define CHAR_CAST (char *) +#endif #if __linux__ # define NDROPPED_SZ CMSG_SPACE(sizeof(uint32_t)) /* SO_RXQ_OVFL */ @@ -44,6 +61,8 @@ #if __linux__ && defined(IP_RECVORIGDSTADDR) # define DST_MSG_SZ sizeof(struct sockaddr_in) +#elif WIN32 +# define DST_MSG_SZ sizeof(struct sockaddr_in) #elif __linux__ # define DST_MSG_SZ sizeof(struct in_pktinfo) #else @@ -66,7 +85,11 @@ struct packets_in { unsigned char *packet_data; unsigned char *ctlmsg_data; +#ifndef WIN32 struct iovec *vecs; +#else + WSABUF *vecs; +#endif struct sockaddr_storage *local_addresses, *peer_addresses; unsigned n_alloc; @@ -74,8 +97,58 @@ struct packets_in }; +#if WIN32 +LPFN_WSARECVMSG pfnWSARecvMsg; +GUID recvGuid = WSAID_WSARECVMSG; +LPFN_WSASENDMSG pfnWSASendMsg; +GUID sendGuid = WSAID_WSASENDMSG; + +CRITICAL_SECTION initLock; +LONG initialized = 0; + +static void getExtensionPtrs() +{ + if (InterlockedCompareExchange(&initialized, 1, 0) == 0) + { + InitializeCriticalSection(&initLock); + } + EnterCriticalSection(&initLock); + if(pfnWSARecvMsg == NULL|| pfnWSASendMsg == NULL) + { + SOCKET sock= socket(PF_INET, SOCK_DGRAM, 0); + DWORD dwBytes; + int rc = 0; + if (pfnWSARecvMsg == NULL) + { + rc = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &recvGuid, + sizeof(recvGuid), &pfnWSARecvMsg, sizeof(pfnWSARecvMsg), + &dwBytes, NULL, NULL); + } + if (rc != SOCKET_ERROR) + { + if (pfnWSASendMsg == NULL) + { + rc = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, + &sendGuid, sizeof(sendGuid), &pfnWSASendMsg, + sizeof(pfnWSASendMsg), &dwBytes, NULL, NULL); + } + } + if (rc == SOCKET_ERROR) + { + LSQ_ERROR("Can't get extension function pointers: %d", + WSAGetLastError()); + } + closesocket(sock); + } + LeaveCriticalSection(&initLock); +} + + +#endif + + static struct packets_in * -allocate_packets_in (int fd) +allocate_packets_in (SOCKET_TYPE fd) { struct packets_in *packs_in; unsigned n_alloc; @@ -127,7 +200,7 @@ sport_destroy (struct service_port *sport) event_free(sport->ev); } if (sport->fd >= 0) - (void) close(sport->fd); + (void) CLOSE_SOCKET(sport->fd); if (sport->packs_in) free_packets_in(sport->packs_in); free(sport); @@ -194,7 +267,13 @@ sport_new (const char *optarg, struct prog *prog) * in `msg'. */ static void -proc_ancillary (struct msghdr *msg, struct sockaddr_storage *storage +proc_ancillary ( +#ifndef WIN32 + struct msghdr +#else + WSAMSG +#endif + *msg, struct sockaddr_storage *storage #if __linux__ , uint32_t *n_dropped #endif @@ -209,7 +288,7 @@ proc_ancillary (struct msghdr *msg, struct sockaddr_storage *storage cmsg->cmsg_type == #if __linux__ && defined(IP_RECVORIGDSTADDR) IP_ORIGDSTADDR -#elif __linux__ +#elif __linux__ || WIN32 IP_PKTINFO #else IP_RECVDSTADDR @@ -218,6 +297,10 @@ proc_ancillary (struct msghdr *msg, struct sockaddr_storage *storage { #if __linux__ && defined(IP_RECVORIGDSTADDR) memcpy(storage, CMSG_DATA(cmsg), sizeof(struct sockaddr_in)); +#elif WIN32 + const struct in_pktinfo *in_pkt; + in_pkt = (void *) WSA_CMSG_DATA(cmsg); + ((struct sockaddr_in *) storage)->sin_addr = in_pkt->ipi_addr; #elif __linux__ const struct in_pktinfo *in_pkt; in_pkt = (void *) CMSG_DATA(cmsg); @@ -230,7 +313,11 @@ proc_ancillary (struct msghdr *msg, struct sockaddr_storage *storage else if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { +#ifndef WIN32 in6_pkt = (void *) CMSG_DATA(cmsg); +#else + in6_pkt = (void *) WSA_CMSG_DATA(cmsg); +#endif ((struct sockaddr_in6 *) storage)->sin6_addr = in6_pkt->ipi6_addr; } @@ -261,7 +348,12 @@ read_one_packet (struct read_iter *iter) #if __linux__ uint32_t n_dropped; #endif +#ifndef WIN32 ssize_t nread; +#else + DWORD nread; + int socket_ret; +#endif struct sockaddr_storage *local_addr; struct service_port *sport; @@ -275,10 +367,17 @@ read_one_packet (struct read_iter *iter) return ROP_NOROOM; } +#ifndef WIN32 packs_in->vecs[iter->ri_idx].iov_base = packs_in->packet_data + iter->ri_off; packs_in->vecs[iter->ri_idx].iov_len = MAX_PACKET_SZ; +#else + packs_in->vecs[iter->ri_idx].buf = (char*)packs_in->packet_data + iter->ri_off; + packs_in->vecs[iter->ri_idx].len = MAX_PACKET_SZ; +#endif + ctl_buf = packs_in->ctlmsg_data + iter->ri_idx * CTL_SZ; +#ifndef WIN32 struct msghdr msg = { .msg_name = &packs_in->peer_addresses[iter->ri_idx], .msg_namelen = sizeof(packs_in->peer_addresses[iter->ri_idx]), @@ -293,6 +392,21 @@ read_one_packet (struct read_iter *iter) LSQ_ERROR("recvmsg: %s", strerror(errno)); return ROP_ERROR; } +#else + WSAMSG msg = { + .name = (LPSOCKADDR)&packs_in->peer_addresses[iter->ri_idx], + .namelen = sizeof(packs_in->peer_addresses[iter->ri_idx]), + .lpBuffers = &packs_in->vecs[iter->ri_idx], + .dwBufferCount = 1, + .Control = {CTL_SZ,(char*)ctl_buf} + }; + socket_ret = pfnWSARecvMsg(sport->fd, &msg, &nread, NULL, NULL); + if (SOCKET_ERROR == socket_ret) { + if (WSAEWOULDBLOCK != WSAGetLastError()) + LSQ_ERROR("recvmsg: %d", WSAGetLastError()); + return ROP_ERROR; + } +#endif local_addr = &packs_in->local_addresses[iter->ri_idx]; memcpy(local_addr, &sport->sas, sizeof(*local_addr)); @@ -315,7 +429,11 @@ read_one_packet (struct read_iter *iter) sport->n_dropped = n_dropped; #endif +#ifndef WIN32 packs_in->vecs[iter->ri_idx].iov_len = nread; +#else + packs_in->vecs[iter->ri_idx].len = nread; +#endif iter->ri_off += nread; iter->ri_idx += 1; @@ -349,8 +467,13 @@ read_handler (int fd, short flags, void *ctx) for (n = 0; n < iter.ri_idx; ++n) if (0 != lsquic_engine_packet_in(engine, +#ifndef WIN32 packs_in->vecs[n].iov_base, packs_in->vecs[n].iov_len, +#else + (const unsigned char *) packs_in->vecs[n].buf, + packs_in->vecs[n].len, +#endif (struct sockaddr *) &packs_in->local_addresses[n], (struct sockaddr *) &packs_in->peer_addresses[n], sport)) @@ -371,6 +494,7 @@ read_handler (int fd, short flags, void *ctx) static int add_to_event_loop (struct service_port *sport, struct event_base *eb) { +#pragma warning(suppress:4028) sport->ev = event_new(eb, sport->fd, EV_READ|EV_PERSIST, read_handler, sport); if (sport->ev) @@ -383,229 +507,16 @@ add_to_event_loop (struct service_port *sport, struct event_base *eb) } -int -sport_init_server (struct service_port *sport, struct lsquic_engine *engine, - struct event_base *eb) -{ - const struct sockaddr *sa_local = (struct sockaddr *) &sport->sas; - int sockfd, saved_errno, flags, s, on; - socklen_t socklen; - char addr_str[0x20]; - - switch (sa_local->sa_family) - { - case AF_INET: - socklen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - socklen = sizeof(struct sockaddr_in6); - break; - default: - errno = EINVAL; - return -1; - } - - sockfd = socket(sa_local->sa_family, SOCK_DGRAM, 0); - if (-1 == sockfd) - return -1; - - if (0 != bind(sockfd, sa_local, socklen)) { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - - /* Make socket non-blocking */ -#ifndef WIN32 - flags = fcntl(sockfd, F_GETFL); - if (-1 == flags) { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - flags |= O_NONBLOCK; - if (0 != fcntl(sockfd, F_SETFL, flags)) { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } -#else - { - on = 1; - ioctlsocket(sockfd, FIONBIO, &on); - } -#endif - - on = 1; - if (AF_INET == sa_local->sa_family) - s = setsockopt(sockfd, IPPROTO_IP, -#if __linux__ && defined(IP_RECVORIGDSTADDR) - IP_RECVORIGDSTADDR, -#elif __linux__ - IP_PKTINFO, -#else - IP_RECVDSTADDR, -#endif - &on, sizeof(on)); - else - s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - -#if (__linux__ && !defined(IP_RECVORIGDSTADDR)) || __APPLE__ - /* Need to set IP_PKTINFO for sending */ - if (AF_INET == sa_local->sa_family) - { - on = 1; - s = setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - } -#elif IP_RECVDSTADDR != IP_SENDSRCADDR - /* On FreeBSD, IP_RECVDSTADDR is the same as IP_SENDSRCADDR, but I do not - * know about other BSD systems. - */ - if (AF_INET == sa_local->sa_family) - { - on = 1; - s = setsockopt(sockfd, IPPROTO_IP, IP_SENDSRCADDR, &on, sizeof(on)); - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - } -#endif - -#if __linux__ && defined(SO_RXQ_OVFL) - on = 1; - s = setsockopt(sockfd, SOL_SOCKET, SO_RXQ_OVFL, &on, sizeof(on)); - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } -#endif - -#if __linux__ - if (sport->if_name[0] && - 0 != setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, sport->if_name, - IFNAMSIZ)) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } -#endif - -#if LSQUIC_DONTFRAG_SUPPORTED - if (sport->sp_flags & SPORT_DONT_FRAGMENT) - { - if (AF_INET == sa_local->sa_family) - { -#if __linux__ - on = IP_PMTUDISC_DO; - s = setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &on, - sizeof(on)); -#else - on = 1; - s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, &on, sizeof(on)); -#endif - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - } - } -#endif - - if (sport->sp_flags & SPORT_SET_SNDBUF) - { - s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sport->sp_sndbuf, - sizeof(sport->sp_sndbuf)); - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - } - - if (sport->sp_flags & SPORT_SET_RCVBUF) - { - s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &sport->sp_rcvbuf, - sizeof(sport->sp_rcvbuf)); - if (0 != s) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - } - - if (0 != getsockname(sockfd, (struct sockaddr *) sa_local, &socklen)) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - - sport->packs_in = allocate_packets_in(sockfd); - if (!sport->packs_in) - { - saved_errno = errno; - close(sockfd); - errno = saved_errno; - return -1; - } - - switch (sa_local->sa_family) { - case AF_INET: - LSQ_DEBUG("local address: %s:%d", - inet_ntop(AF_INET, &((struct sockaddr_in *) sa_local)->sin_addr, - addr_str, sizeof(addr_str)), - ntohs(((struct sockaddr_in *) sa_local)->sin_port)); - break; - } - - sport->engine = engine; - sport->fd = sockfd; - sport->sp_flags |= SPORT_SERVER; - - return add_to_event_loop(sport, eb); -} - - int sport_init_client (struct service_port *sport, struct lsquic_engine *engine, struct event_base *eb) { const struct sockaddr *sa_peer = (struct sockaddr *) &sport->sas; - int sockfd, saved_errno, flags, s; + int saved_errno, s; +#ifndef WIN32 + int flags; +#endif + SOCKET_TYPE sockfd; socklen_t socklen; union { struct sockaddr_in sin; @@ -632,32 +543,42 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, return -1; } +#if WIN32 + getExtensionPtrs(); +#endif sockfd = socket(sa_peer->sa_family, SOCK_DGRAM, 0); if (-1 == sockfd) return -1; if (0 != bind(sockfd, sa_local, socklen)) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } /* Make socket non-blocking */ +#ifndef WIN32 flags = fcntl(sockfd, F_GETFL); if (-1 == flags) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } flags |= O_NONBLOCK; if (0 != fcntl(sockfd, F_SETFL, flags)) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } +#else + { + u_long on = 1; + ioctlsocket(sockfd, FIONBIO, &on); + } +#endif #if LSQUIC_DONTFRAG_SUPPORTED if (sport->sp_flags & SPORT_DONT_FRAGMENT) @@ -669,6 +590,9 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, on = IP_PMTUDISC_DO; s = setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &on, sizeof(on)); +#elif WIN32 + on = 1; + s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAGMENT, (char*)&on, sizeof(on)); #else on = 1; s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, &on, sizeof(on)); @@ -676,7 +600,7 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, if (0 != s) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } @@ -686,12 +610,12 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, if (sport->sp_flags & SPORT_SET_SNDBUF) { - s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sport->sp_sndbuf, - sizeof(sport->sp_sndbuf)); + s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, + CHAR_CAST &sport->sp_sndbuf, sizeof(sport->sp_sndbuf)); if (0 != s) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } @@ -699,12 +623,12 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, if (sport->sp_flags & SPORT_SET_RCVBUF) { - s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &sport->sp_rcvbuf, - sizeof(sport->sp_rcvbuf)); + s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, + CHAR_CAST &sport->sp_rcvbuf, sizeof(sport->sp_rcvbuf)); if (0 != s) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } @@ -713,7 +637,7 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, if (0 != getsockname(sockfd, sa_local, &socklen)) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } @@ -722,7 +646,7 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, if (!sport->packs_in) { saved_errno = errno; - close(sockfd); + CLOSE_SOCKET(sockfd); errno = saved_errno; return -1; } @@ -743,19 +667,30 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine, static void -setup_control_msg (struct msghdr *msg, const struct lsquic_out_spec *spec, +setup_control_msg ( +#ifndef WIN32 + struct msghdr +#else + WSAMSG +#endif + *msg, const struct lsquic_out_spec *spec, unsigned char *buf, size_t bufsz) { struct cmsghdr *cmsg; struct sockaddr_in *local_sa; struct sockaddr_in6 *local_sa6; -#if __linux__ || __APPLE__ +#if __linux__ || __APPLE__ || WIN32 struct in_pktinfo info; #endif struct in6_pktinfo info6; +#ifndef WIN32 msg->msg_control = buf; msg->msg_controllen = bufsz; +#else + msg->Control.buf = (char*)buf; + msg->Control.len = bufsz; +#endif cmsg = CMSG_FIRSTHDR(msg); if (AF_INET == spec->dest_sa->sa_family) @@ -768,6 +703,13 @@ setup_control_msg (struct msghdr *msg, const struct lsquic_out_spec *spec, cmsg->cmsg_type = IP_PKTINFO; cmsg->cmsg_len = CMSG_LEN(sizeof(info)); memcpy(CMSG_DATA(cmsg), &info, sizeof(info)); +#elif WIN32 + memset(&info, 0, sizeof(info)); + info.ipi_addr = local_sa->sin_addr; + cmsg->cmsg_level = IPPROTO_IP; + cmsg->cmsg_type = IP_PKTINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(info)); + memcpy(WSA_CMSG_DATA(cmsg), &info, sizeof(info)); #else cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_SENDSRCADDR; @@ -784,10 +726,18 @@ setup_control_msg (struct msghdr *msg, const struct lsquic_out_spec *spec, cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; cmsg->cmsg_len = CMSG_LEN(sizeof(info6)); +#ifndef WIN32 memcpy(CMSG_DATA(cmsg), &info6, sizeof(info6)); +#else + memcpy(WSA_CMSG_DATA(cmsg), &info6, sizeof(info6)); +#endif } +#ifndef WIN32 msg->msg_controllen = cmsg->cmsg_len; +#else + msg->Control.len = cmsg->cmsg_len; +#endif } @@ -796,22 +746,29 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count) { const struct service_port *sport; unsigned n; - int s; + int s = 0; +#ifndef WIN32 struct msghdr msg; +#else + DWORD bytes; + WSAMSG msg; +#endif union { /* cmsg(3) recommends union for proper alignment */ - unsigned char buf[ CMSG_SPACE( - MAX( -#if __linux__ - sizeof(struct in_pktinfo) +#if __linux__ || WIN32 +# define SIZE1 sizeof(struct in_pktinfo) #else - sizeof(struct in_addr) +# define SIZE1 sizeof(struct in_addr) #endif - , sizeof(struct in6_pktinfo)) - )]; + unsigned char buf[ + CMSG_SPACE(MAX(SIZE1, sizeof(struct in6_pktinfo)))]; struct cmsghdr cmsg; } ancil; +#ifndef WIN32 struct iovec iov; +#else + WSABUF iov; +#endif if (0 == count) return 0; @@ -820,6 +777,7 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count) for (n = 0; n < count; ++n) { sport = specs[n].peer_ctx; +#ifndef WIN32 iov.iov_base = (void *) specs[n].buf; iov.iov_len = specs[n].sz; msg.msg_name = (void *) specs[n].dest_sa; @@ -829,17 +787,41 @@ send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count) msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; +#else + iov.buf = (void *) specs[n].buf; + iov.len = specs[n].sz; + msg.name = (void *) specs[n].dest_sa; + msg.namelen = (AF_INET == specs[n].dest_sa->sa_family ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)), + msg.lpBuffers = &iov; + msg.dwBufferCount = 1; + msg.dwFlags = 0; +#endif if (sport->sp_flags & SPORT_SERVER) setup_control_msg(&msg, &specs[n], ancil.buf, sizeof(ancil.buf)); else { +#ifndef WIN32 msg.msg_control = NULL; msg.msg_controllen = 0; +#else + msg.Control.buf = NULL; + msg.Control.len = 0; +#endif } +#ifndef WIN32 s = sendmsg(sport->fd, &msg, 0); +#else + s = pfnWSASendMsg(sport->fd, &msg, 0, &bytes, NULL, NULL); +#endif if (s < 0) { +#ifndef WIN32 LSQ_INFO("sendto failed: %s", strerror(errno)); +#else + LSQ_INFO("sendto failed: %s", WSAGetLastError()); +#endif break; } } @@ -1103,7 +1085,11 @@ test_reader_read (void *void_ctx, void *buf, size_t count) if (count > test_reader_size(ctx)) count = test_reader_size(ctx); +#ifndef WIN32 nread = read(ctx->fd, buf, count); +#else + nread = _read(ctx->fd, buf, count); +#endif if (nread >= 0) { ctx->nread += nread; @@ -1124,7 +1110,11 @@ create_lsquic_reader_ctx (const char *filename) int fd; struct stat st; +#ifndef WIN32 fd = open(filename, O_RDONLY); +#else + fd = _open(filename, _O_RDONLY); +#endif if (fd < 0) { LSQ_ERROR("cannot open %s for reading: %s", filename, strerror(errno)); diff --git a/test/test_common.h b/test/test_common.h index d2fdc39..3e8ffff 100644 --- a/test/test_common.h +++ b/test/test_common.h @@ -62,10 +62,6 @@ sport_new (const char *optarg, struct prog *); void sport_destroy (struct service_port *); -int -sport_init_server (struct service_port *, struct lsquic_engine *, - struct event_base *); - int sport_init_client (struct service_port *, struct lsquic_engine *, struct event_base *); diff --git a/wincompat/test_common_win.c b/wincompat/test_common_win.c deleted file mode 100644 index be93d7d..0000000 --- a/wincompat/test_common_win.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define HAVE_IP_DONTFRAG 1 -#define HAVE_IP_MTU_DISCOVER 1 -#include "../test/test_config.h" -#include "../test/test_common.h" -#include "lsquic.h" -#include "../test/prog.h" - -#include "../src/liblsquic/lsquic_logger.h" - - - -LPFN_WSARECVMSG pfnWSARecvMsg; -GUID recvGuid = WSAID_WSARECVMSG; -LPFN_WSASENDMSG pfnWSASendMsg; -GUID sendGuid = WSAID_WSASENDMSG; - -CRITICAL_SECTION initLock; -LONG initialized = 0; - -void getExtensionPtrs() -{ - if (InterlockedCompareExchange(&initialized, 1, 0) == 0) - { - InitializeCriticalSection(&initLock); - } - EnterCriticalSection(&initLock); - if(pfnWSARecvMsg == NULL|| pfnWSASendMsg == NULL) - { - SOCKET sock= socket(PF_INET, SOCK_DGRAM, 0); - DWORD dwBytes; - int rc = 0; - if (pfnWSARecvMsg == NULL) - { - rc = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &recvGuid, sizeof(recvGuid), &pfnWSARecvMsg, sizeof(pfnWSARecvMsg), &dwBytes, NULL, NULL); - } - if (rc != SOCKET_ERROR) - { - if (pfnWSASendMsg == NULL) - { - rc = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &sendGuid, sizeof(sendGuid), &pfnWSASendMsg, sizeof(pfnWSASendMsg), &dwBytes, NULL, NULL); - } - } - if (rc == SOCKET_ERROR) - { - LSQ_ERROR("Can't get extension function pointers: %d", WSAGetLastError()); - } - closesocket(sock); - } - LeaveCriticalSection(&initLock); -} - -#define WINMAX(a, b) ((a) > (b) ? (a) : (b)) - - -#define NDROPPED_SZ 0 - -#define DST_MSG_SZ sizeof(struct sockaddr_in) - -#define MAX_PACKET_SZ 1370 - -#define CTL_SZ (CMSG_SPACE(WINMAX(DST_MSG_SZ, sizeof(struct in6_pktinfo))) + NDROPPED_SZ) - -/* There are `n_alloc' elements in `vecs', `local_addresses', and - * `peer_addresses' arrays. `ctlmsg_data' is n_alloc * CTL_SZ. Each packets - * gets a single `vecs' element that points somewhere into `packet_data'. - * - * `n_alloc' is calculated at run-time based on the socket's receive buffer - * size. - */ -struct packets_in -{ - unsigned char *packet_data; - unsigned char *ctlmsg_data; - WSABUF *vecs; - struct sockaddr_storage *local_addresses, - *peer_addresses; - unsigned n_alloc; - unsigned data_sz; -}; - - -static struct packets_in * -allocate_packets_in (SOCKET fd) -{ - struct packets_in *packs_in; - unsigned n_alloc; - socklen_t opt_len; - int recvsz; - - opt_len = sizeof(recvsz); - if (0 != getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&recvsz, &opt_len)) - { - LSQ_ERROR("getsockopt failed: %s", strerror(errno)); - return NULL; - } - - n_alloc = (unsigned) recvsz / MAX_PACKET_SZ * 2; - LSQ_INFO("socket buffer size: %d bytes; max # packets is set to %u", - recvsz, n_alloc); - - packs_in = malloc(sizeof(*packs_in)); - packs_in->data_sz = recvsz; - packs_in->n_alloc = n_alloc; - packs_in->packet_data = malloc(recvsz); - packs_in->ctlmsg_data = malloc(n_alloc * CTL_SZ); - packs_in->vecs = malloc(n_alloc * sizeof(packs_in->vecs[0])); - packs_in->local_addresses = malloc(n_alloc * sizeof(packs_in->local_addresses[0])); - packs_in->peer_addresses = malloc(n_alloc * sizeof(packs_in->peer_addresses[0])); - - return packs_in; -} - - -static void -free_packets_in (struct packets_in *packs_in) -{ - free(packs_in->peer_addresses); - free(packs_in->local_addresses); - free(packs_in->ctlmsg_data); - free(packs_in->vecs); - free(packs_in->packet_data); - free(packs_in); -} - - -void -sport_destroy (struct service_port *sport) -{ - if (sport->ev) - { - event_del(sport->ev); - event_free(sport->ev); - } - if (sport->fd >= 0) - (void) closesocket(sport->fd); - if (sport->packs_in) - free_packets_in(sport->packs_in); - free(sport); -} - - -struct service_port * -sport_new (const char *optarg, struct prog *prog) -{ - struct service_port *const sport = malloc(sizeof(*sport)); - sport->ev = NULL; - sport->packs_in = NULL; - sport->fd = -1; - char *const addr = strdup(optarg); - char *port = strrchr(addr, ':'); - if (!port) - goto err; - *port = '\0'; - ++port; - if ((uintptr_t) port - (uintptr_t) addr > sizeof(sport->host)) - goto err; - memcpy(sport->host, addr, port - addr); - - struct sockaddr_in *const sa4 = (void *) &sport->sas; - struct sockaddr_in6 *const sa6 = (void *) &sport->sas; - if (inet_pton(AF_INET, addr, &sa4->sin_addr)) { - sa4->sin_family = AF_INET; - sa4->sin_port = htons(atoi(port)); - } else if (memset(sa6, 0, sizeof(*sa6)), - inet_pton(AF_INET6, addr, &sa6->sin6_addr)) { - sa6->sin6_family = AF_INET6; - sa6->sin6_port = htons(atoi(port)); - } else - goto err; - - free(addr); - sport->sp_prog = prog; - return sport; - - err: - free(sport); - free(addr); - return NULL; -} - - -/* Replace IP address part of `sa' with that provided in ancillary messages - * in `msg'. - */ -static void -proc_ancillary (WSAMSG*msg, struct sockaddr_storage *storage ) -{ - const struct in6_pktinfo *in6_pkt; - struct cmsghdr *cmsg; - - for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO ) - { - const struct in_pktinfo *in_pkt; - in_pkt = (void *) WSA_CMSG_DATA(cmsg); - ((struct sockaddr_in *) storage)->sin_addr = in_pkt->ipi_addr; - } - else if (cmsg->cmsg_level == IPPROTO_IPV6 && - cmsg->cmsg_type == IPV6_PKTINFO) - { - in6_pkt = (void *) WSA_CMSG_DATA(cmsg); - ((struct sockaddr_in6 *) storage)->sin6_addr = - in6_pkt->ipi6_addr; - } - } -} - - -struct read_iter -{ - struct service_port *ri_sport; - unsigned ri_idx; /* Current element */ - unsigned ri_off; /* Offset into packet_data */ -}; - - -enum rop { ROP_OK, ROP_NOROOM, ROP_ERROR, }; - -static enum rop -read_one_packet (struct read_iter *iter) -{ - unsigned char *ctl_buf; - struct packets_in *packs_in; - DWORD nread; - int socket_ret; - struct sockaddr_storage *local_addr; - struct service_port *sport; - - sport = iter->ri_sport; - packs_in = sport->packs_in; - - if (iter->ri_idx >= packs_in->n_alloc || - iter->ri_off + MAX_PACKET_SZ > packs_in->data_sz) - { - LSQ_DEBUG("out of room in packets_in"); - return ROP_NOROOM; - } - - packs_in->vecs[iter->ri_idx].buf = (char*)packs_in->packet_data + iter->ri_off; - packs_in->vecs[iter->ri_idx].len = MAX_PACKET_SZ; - ctl_buf = packs_in->ctlmsg_data + iter->ri_idx * CTL_SZ; - - WSAMSG msg = { - .name = (LPSOCKADDR)&packs_in->peer_addresses[iter->ri_idx], - .namelen = sizeof(packs_in->peer_addresses[iter->ri_idx]), - .lpBuffers = &packs_in->vecs[iter->ri_idx], - .dwBufferCount = 1, - .Control = {CTL_SZ,(char*)ctl_buf} - }; - socket_ret = pfnWSARecvMsg(sport->fd, &msg,&nread,NULL,NULL); - if (SOCKET_ERROR == socket_ret) { - if (WSAEWOULDBLOCK != WSAGetLastError()) - LSQ_ERROR("recvmsg: %d", WSAGetLastError()); - return ROP_ERROR; - } - - local_addr = &packs_in->local_addresses[iter->ri_idx]; - memcpy(local_addr, &sport->sas, sizeof(*local_addr)); - proc_ancillary(&msg, local_addr ); - - packs_in->vecs[iter->ri_idx].len = nread; - iter->ri_off += nread; - iter->ri_idx += 1; - - return ROP_OK; -} - - -static void -read_handler (SOCKET fd, short flags, void *ctx) -{ - struct service_port *sport = ctx; - lsquic_engine_t *const engine = sport->engine; - struct packets_in *packs_in = sport->packs_in; - struct read_iter iter; - unsigned n, n_batches; - enum rop rop; - - n_batches = 0; - iter.ri_sport = sport; - - do - { - iter.ri_off = 0; - iter.ri_idx = 0; - - do - rop = read_one_packet(&iter); - while (ROP_OK == rop); - - n_batches += iter.ri_idx > 0; - - for (n = 0; n < iter.ri_idx; ++n) - if (0 != lsquic_engine_packet_in(engine, - (const unsigned char*)packs_in->vecs[n].buf, - packs_in->vecs[n].len, - (struct sockaddr *) &packs_in->local_addresses[n], - (struct sockaddr *) &packs_in->peer_addresses[n], - sport)) - break; - } - while (ROP_NOROOM == rop); - - if (n_batches) - n += packs_in->n_alloc * (n_batches - 1); - - if (!prog_is_stopped()) - prog_process_conns(sport->sp_prog); - - LSQ_DEBUG("read %u packet%.*s in %u batch%s", n, n != 1, "s", n_batches, n_batches != 1 ? "es" : ""); -} - - -static int -add_to_event_loop (struct service_port *sport, struct event_base *eb) -{ -#pragma warning(suppress:4028) - sport->ev = event_new( eb, sport->fd, EV_READ|EV_PERSIST, read_handler, sport); - if (sport->ev) - { - event_add(sport->ev, NULL); - return 0; - } - else - return -1; -} - - -int -sport_init_server (struct service_port *sport, struct lsquic_engine *engine, - struct event_base *eb) -{ - const struct sockaddr *sa_local = (struct sockaddr *) &sport->sas; - SOCKET sockfd; - int saved_errno, s, on; - socklen_t socklen; - char addr_str[0x20]; - - switch (sa_local->sa_family) - { - case AF_INET: - socklen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - socklen = sizeof(struct sockaddr_in6); - break; - default: - errno = EINVAL; - return -1; - } - - getExtensionPtrs(); - sockfd = socket(sa_local->sa_family, SOCK_DGRAM, 0); - if (-1 == sockfd) - return -1; - - if (0 != bind(sockfd, sa_local, socklen)) { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - /* Make socket non-blocking */ - { - on = 1; - ioctlsocket(sockfd, FIONBIO,(u_long*) &on); - } - - on = 1; - if (AF_INET == sa_local->sa_family) - s = setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, (char*)&on, sizeof(on)); - else - s = setsockopt(sockfd, IPPROTO_IPV6, IPV6_PKTINFO, (char*)&on, sizeof(on)); - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - - - - if (sport->sp_flags & SPORT_DONT_FRAGMENT) - { - if (AF_INET == sa_local->sa_family) - { - on = 1; - s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAGMENT, (char*)&on, sizeof(on)); - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - } - } - - if (sport->sp_flags & SPORT_SET_SNDBUF) - { - s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&sport->sp_sndbuf, sizeof(sport->sp_sndbuf)); - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - } - - if (sport->sp_flags & SPORT_SET_RCVBUF) - { - s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char*)&sport->sp_rcvbuf, sizeof(sport->sp_rcvbuf)); - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - } - - if (0 != getsockname(sockfd, (struct sockaddr *) sa_local, &socklen)) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - sport->packs_in = allocate_packets_in(sockfd); - if (!sport->packs_in) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - switch (sa_local->sa_family) { - case AF_INET: - LSQ_DEBUG("local address: %s:%d", - inet_ntop(AF_INET, &((struct sockaddr_in *) sa_local)->sin_addr, - addr_str, sizeof(addr_str)), - ntohs(((struct sockaddr_in *) sa_local)->sin_port)); - break; - } - - sport->engine = engine; - sport->fd = sockfd; - sport->sp_flags |= SPORT_SERVER; - - return add_to_event_loop(sport, eb); -} - - -int -sport_init_client (struct service_port *sport, struct lsquic_engine *engine, - struct event_base *eb) -{ - const struct sockaddr *sa_peer = (struct sockaddr *) &sport->sas; - SOCKET sockfd; - int saved_errno, s; - socklen_t socklen; - union { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } u; - struct sockaddr *sa_local = (struct sockaddr *) &u; - char addr_str[0x20]; - - switch (sa_peer->sa_family) - { - case AF_INET: - socklen = sizeof(struct sockaddr_in); - u.sin.sin_family = AF_INET; - u.sin.sin_addr.s_addr = INADDR_ANY; - u.sin.sin_port = 0; - break; - case AF_INET6: - socklen = sizeof(struct sockaddr_in6); - memset(&u.sin6, 0, sizeof(u.sin6)); - u.sin6.sin6_family = AF_INET6; - break; - default: - errno = EINVAL; - return -1; - } - - getExtensionPtrs(); - sockfd = socket(sa_peer->sa_family, SOCK_DGRAM, 0); - if (-1 == sockfd) - return -1; - - if (0 != bind(sockfd, sa_local, socklen)) { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - { - u_long on = 1; - ioctlsocket(sockfd, FIONBIO, &on); - } - - -#if LSQUIC_DONTFRAG_SUPPORTED - if (sport->sp_flags & SPORT_DONT_FRAGMENT) - { - if (AF_INET == sa_local->sa_family) - { - int on; -#if __linux__ - on = IP_PMTUDISC_DO; - s = setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &on, - sizeof(on)); -#else - on = 1; - s = setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAGMENT, (char*)&on, sizeof(on)); -#endif - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - } - } -#endif - - if (sport->sp_flags & SPORT_SET_SNDBUF) - { - s = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&sport->sp_sndbuf, sizeof(sport->sp_sndbuf)); - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - } - - if (sport->sp_flags & SPORT_SET_RCVBUF) - { - s = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char*)&sport->sp_rcvbuf, sizeof(sport->sp_rcvbuf)); - if (0 != s) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - } - - if (0 != getsockname(sockfd, sa_local, &socklen)) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - sport->packs_in = allocate_packets_in(sockfd); - if (!sport->packs_in) - { - saved_errno = errno; - closesocket(sockfd); - errno = saved_errno; - return -1; - } - - switch (sa_local->sa_family) { - case AF_INET: - LSQ_DEBUG("local address: %s:%d", - inet_ntop(AF_INET, &u.sin.sin_addr, addr_str, sizeof(addr_str)), - ntohs(u.sin.sin_port)); - break; - } - - sport->engine = engine; - sport->fd = sockfd; - - return add_to_event_loop(sport, eb); -} - - -static void -setup_control_msg (WSAMSG *msg, const struct lsquic_out_spec *spec, - unsigned char *buf, size_t bufsz) -{ - struct cmsghdr *cmsg; - struct sockaddr_in *local_sa; - struct sockaddr_in6 *local_sa6; - struct in_pktinfo info; - struct in6_pktinfo info6; - - msg->Control.buf = (char*)buf; - msg->Control.len = bufsz; - cmsg = CMSG_FIRSTHDR(msg); - - if (AF_INET == spec->dest_sa->sa_family) - { - local_sa = (struct sockaddr_in *) spec->local_sa; - memset(&info, 0, sizeof(info)); - info.ipi_addr = local_sa->sin_addr; - cmsg->cmsg_level = IPPROTO_IP; - cmsg->cmsg_type = IP_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(info)); - memcpy(WSA_CMSG_DATA(cmsg), &info, sizeof(info)); - } - else - { - local_sa6 = (struct sockaddr_in6 *) spec->local_sa; - memset(&info6, 0, sizeof(info6)); - info6.ipi6_addr = local_sa6->sin6_addr; - cmsg->cmsg_level = IPPROTO_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(info6)); - memcpy(WSA_CMSG_DATA(cmsg), &info6, sizeof(info6)); - } - - msg->Control.len = cmsg->cmsg_len; -} - - -static int -send_packets_one_by_one (const struct lsquic_out_spec *specs, unsigned count) -{ - const struct service_port *sport; - unsigned n; - DWORD bytes,socket_ret = 0; - WSAMSG msg; - union { - unsigned char buf[ CMSG_SPACE( WINMAX( sizeof(struct in_pktinfo) , sizeof(struct in6_pktinfo)) )]; - struct cmsghdr cmsg; - } ancil; - WSABUF iov; - - if (0 == count) - return 0; - - - for (n = 0; n < count; ++n) - { - sport = specs[n].peer_ctx; - iov.buf = (void *) specs[n].buf; - iov.len = specs[n].sz; - msg.name = (void *) specs[n].dest_sa; - msg.namelen = (AF_INET == specs[n].dest_sa->sa_family ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)), - msg.lpBuffers = &iov; - msg.dwBufferCount = 1; - msg.dwFlags = 0; - if (sport->sp_flags & SPORT_SERVER) - setup_control_msg(&msg, &specs[n], ancil.buf, sizeof(ancil.buf)); - else - { - msg.Control.buf = NULL; - msg.Control.len = 0; - } - socket_ret = pfnWSASendMsg(sport->fd, &msg, 0,&bytes,NULL,NULL); - if (socket_ret < 0) - { - LSQ_INFO("sendto failed: %d", WSAGetLastError()); - break; - } - } - - if (n > 0) - return n; - else if (socket_ret < 0) - return -1; - else - return 0; -} - - -int -sport_packets_out (void *ctx, const struct lsquic_out_spec *specs, - unsigned count) -{ - return send_packets_one_by_one(specs, count); -} - - -int -set_engine_option (struct lsquic_engine_settings *settings, - int *version_cleared, const char *name) -{ - int len; - const char *val = strchr(name, '='); - if (!val) - return -1; - len = val - name; - ++val; - - switch (len) - { - case 2: - if (0 == strncmp(name, "ua", 2)) - { - settings->es_ua = val; - return 0; - } - break; - case 4: - if (0 == strncmp(name, "cfcw", 4)) - { - settings->es_cfcw = atoi(val); - return 0; - } - if (0 == strncmp(name, "sfcw", 4)) - { - settings->es_sfcw = atoi(val); - return 0; - } - if (0 == strncmp(name, "srej", 4)) - { - settings->es_support_srej = atoi(val); - return 0; - } - break; - case 7: - if (0 == strncmp(name, "version", 7)) - { - if (!*version_cleared) - { - *version_cleared = 1; - settings->es_versions = 0; - } - if (0 == strcmp(val, "Q035")) - { - settings->es_versions |= 1 << LSQVER_035; - return 0; - } - if (0 == strcmp(val, "Q037")) - { - settings->es_versions |= 1 << LSQVER_037; - return 0; - } - if (0 == strcmp(val, "Q038")) - { - settings->es_versions |= 1 << LSQVER_038; - return 0; - } - if (0 == strcmp(val, "Q039")) - { - settings->es_versions |= 1 << LSQVER_039; - return 0; - } - if (0 == strcmp(val, "Q041")) - { - settings->es_versions |= 1 << LSQVER_041; - return 0; - } - } - else if (0 == strncmp(name, "rw_once", 7)) - { - settings->es_rw_once = atoi(val); - return 0; - } - break; - case 8: - if (0 == strncmp(name, "max_cfcw", 8)) - { - settings->es_max_cfcw = atoi(val); - return 0; - } - if (0 == strncmp(name, "max_sfcw", 8)) - { - settings->es_max_sfcw = atoi(val); - return 0; - } - break; - case 10: - if (0 == strncmp(name, "honor_prst", 10)) - { - settings->es_honor_prst = atoi(val); - return 0; - } - break; - case 12: - if (0 == strncmp(name, "idle_conn_to", 12)) - { - settings->es_idle_conn_to = atoi(val); - return 0; - } - if (0 == strncmp(name, "silent_close", 12)) - { - settings->es_silent_close = atoi(val); - return 0; - } - if (0 == strncmp(name, "support_nstp", 12)) - { - settings->es_support_nstp = atoi(val); - return 0; - } - if (0 == strncmp(name, "pace_packets", 12)) - { - settings->es_pace_packets = atoi(val); - return 0; - } - break; - case 13: - if (0 == strncmp(name, "support_tcid0", 13)) - { - settings->es_support_tcid0 = atoi(val); - return 0; - } - break; - case 14: - if (0 == strncmp(name, "max_streams_in", 14)) - { - settings->es_max_streams_in = atoi(val); - return 0; - } - if (0 == strncmp(name, "progress_check", 14)) - { - settings->es_progress_check = atoi(val); - return 0; - } - break; - case 16: - if (0 == strncmp(name, "proc_time_thresh", 16)) - { - settings->es_proc_time_thresh = atoi(val); - return 0; - } - break; - case 20: - if (0 == strncmp(name, "max_header_list_size", 20)) - { - settings->es_max_header_list_size = atoi(val); - return 0; - } - break; - } - - return -1; -} - - -#define MAX_PACKOUT_BUF_SZ MAX_PACKET_SZ - -struct packout_buf -{ - SLIST_ENTRY(packout_buf) next_free_pb; -}; - - -void -pba_init (struct packout_buf_allocator *pba, unsigned max) -{ - SLIST_INIT(&pba->free_packout_bufs); - pba->max = max; - pba->n_out = 0; -} - - -void * -pba_allocate (void *packout_buf_allocator, size_t size) -{ - struct packout_buf_allocator *const pba = packout_buf_allocator; - struct packout_buf *pb; - - if (size > MAX_PACKOUT_BUF_SZ) - { - fprintf(stderr, "packout buf size too large: %zd", size); - abort(); - } - - if (pba->max && pba->n_out >= pba->max) - { - LSQ_DEBUG("# outstanding packout bufs reached the limit of %u, " - "returning NULL", pba->max); - return NULL; - } - - pb = SLIST_FIRST(&pba->free_packout_bufs); - if (pb) - SLIST_REMOVE_HEAD(&pba->free_packout_bufs, next_free_pb); - else - pb = malloc(MAX_PACKOUT_BUF_SZ); - - if (pb) - ++pba->n_out; - - return pb; -} - - -void -pba_release (void *packout_buf_allocator, void *obj) -{ - struct packout_buf_allocator *const pba = packout_buf_allocator; - struct packout_buf *const pb = obj; - SLIST_INSERT_HEAD(&pba->free_packout_bufs, pb, next_free_pb); - --pba->n_out; -} - - -void -pba_cleanup (struct packout_buf_allocator *pba) -{ - unsigned n = 0; - struct packout_buf *pb; - - if (pba->n_out) - LSQ_WARN("%u packout bufs outstanding at deinit", pba->n_out); - - while ((pb = SLIST_FIRST(&pba->free_packout_bufs))) - { - SLIST_REMOVE_HEAD(&pba->free_packout_bufs, next_free_pb); - free(pb); - ++n; - } - - LSQ_INFO("pba deinitialized, freed %u packout bufs", n); -} - - -struct reader_ctx -{ - size_t file_size; - size_t nread; - int fd; -}; - - -size_t -test_reader_size (void *void_ctx) -{ - struct reader_ctx *const ctx = void_ctx; - return ctx->file_size - ctx->nread; -} - - -size_t -test_reader_read (void *void_ctx, void *buf, size_t count) -{ - struct reader_ctx *const ctx = void_ctx; - ssize_t nread; - - if (count > test_reader_size(ctx)) - count = test_reader_size(ctx); - - nread = _read(ctx->fd, buf, count); - if (nread >= 0) - { - ctx->nread += nread; - return nread; - } - else - { - LSQ_WARN("%s: error reading from file: %s", __func__, strerror(errno)); - ctx->nread = ctx->file_size = 0; - return 0; - } -} - - -struct reader_ctx * -create_lsquic_reader_ctx (const char *filename) -{ - int fd; - struct stat st; - - fd = _open(filename, _O_RDONLY); - if (fd < 0) - { - LSQ_ERROR("cannot open %s for reading: %s", filename, strerror(errno)); - return NULL; - } - - if (0 != fstat(fd, &st)) - { - LSQ_ERROR("cannot fstat(%s) failed: %s", filename, strerror(errno)); - (void) closesocket(fd); - return NULL; - } - struct reader_ctx *ctx = malloc(sizeof(*ctx)); - ctx->file_size = st.st_size; - ctx->nread = 0; - ctx->fd = fd; - return ctx; -} - - -void -destroy_lsquic_reader_ctx (struct reader_ctx *ctx) -{ - (void) closesocket(ctx->fd); - free(ctx); -} - - From 3f050ae322fc99306096821a678998aa0f9d1e8f Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Mon, 7 May 2018 16:58:14 -0400 Subject: [PATCH 2/2] Drop MSVC-specific #pragma by fixing function type --- test/test_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test_common.c b/test/test_common.c index 88dc5ee..2949d6a 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -442,7 +442,7 @@ read_one_packet (struct read_iter *iter) static void -read_handler (int fd, short flags, void *ctx) +read_handler (evutil_socket_t fd, short flags, void *ctx) { struct service_port *sport = ctx; lsquic_engine_t *const engine = sport->engine; @@ -494,7 +494,6 @@ read_handler (int fd, short flags, void *ctx) static int add_to_event_loop (struct service_port *sport, struct event_base *eb) { -#pragma warning(suppress:4028) sport->ev = event_new(eb, sport->fd, EV_READ|EV_PERSIST, read_handler, sport); if (sport->ev)