From 7790a617d8688188fb60ded3b64ffefdde42c83d Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sun, 14 Feb 2021 09:48:12 +0100 Subject: [PATCH] Remove all legacy IPv4 code. --- src/net.c | 21 +++++++++++++++++++++ src/net.h | 1 + src/rinetd.c | 21 ++++++++++++--------- src/types.h | 4 ++-- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/net.c b/src/net.c index 045f23c..dea9c6d 100644 --- a/src/net.c +++ b/src/net.c @@ -36,6 +36,27 @@ int getSocketType(int protocol) { return protocol == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; } +int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b) { + if (a->ss_family != b->ss_family) + return 0; + + switch (a->ss_family) { + case AF_INET: { + struct sockaddr_in *a4 = (struct sockaddr_in *)a; + struct sockaddr_in *b4 = (struct sockaddr_in *)b; + return a4->sin_port == b4->sin_port + && a4->sin_addr.s_addr == b4->sin_addr.s_addr; + } + case AF_INET6: { + struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)a; + struct sockaddr_in6 *b6 = (struct sockaddr_in6 *)b; + return a6->sin6_port == b6->sin6_port + && a6->sin6_addr.s6_addr == b6->sin6_addr.s6_addr; + } + } + return 0; +} + uint16_t getPort(struct addrinfo* ai) { switch (ai->ai_family) { case AF_INET: diff --git a/src/net.h b/src/net.h index c41c4d0..a043093 100644 --- a/src/net.h +++ b/src/net.h @@ -82,4 +82,5 @@ static inline int GetLastError(void) { void setSocketDefaults(SOCKET fd); int getSocketType(int protocol); +int sameSocketAddress(struct sockaddr_storage *a, struct sockaddr_storage *b); uint16_t getPort(struct addrinfo* ai); diff --git a/src/rinetd.c b/src/rinetd.c index da5f6f7..08b0672 100644 --- a/src/rinetd.c +++ b/src/rinetd.c @@ -697,13 +697,10 @@ static void handleAccept(ServerInfo const *srv) udpBytes = (int)ret; + /* Look for an existing connection with the same remote host and port. */ for (int i = 0; i < coTotal; ++i) { ConnectionInfo *cnx = &coInfo[i]; - struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; - if (cnx->remote.fd == nfd - && cnx->remoteAddress.sin_family == addr_in->sin_family - && cnx->remoteAddress.sin_port == addr_in->sin_port - && cnx->remoteAddress.sin_addr.s_addr == addr_in->sin_addr.s_addr) { + if (cnx->remote.fd == nfd && sameSocketAddress(&cnx->remoteAddress, &addr)) { cnx->remoteTimeout = time(NULL) + srv->serverTimeout; handleUdpRead(cnx, globalUdpBuffer, udpBytes); return; @@ -717,15 +714,17 @@ static void handleAccept(ServerInfo const *srv) } cnx->local.fd = INVALID_SOCKET; + cnx->local.family = srv->toAddrInfo->ai_family; cnx->local.protocol = srv->toAddrInfo->ai_protocol; cnx->local.recvPos = cnx->local.sentPos = 0; cnx->local.totalBytesIn = cnx->local.totalBytesOut = 0; cnx->remote.fd = nfd; + cnx->remote.family = srv->fromAddrInfo->ai_family; cnx->remote.protocol = srv->fromAddrInfo->ai_protocol; cnx->remote.recvPos = cnx->remote.sentPos = 0; cnx->remote.totalBytesIn = cnx->remote.totalBytesOut = 0; - cnx->remoteAddress = *(struct sockaddr_in *)&addr; + cnx->remoteAddress = addr; if (srv->fromAddrInfo->ai_protocol == IPPROTO_UDP) cnx->remoteTimeout = time(NULL) + srv->serverTimeout; @@ -815,7 +814,10 @@ static void handleAccept(ServerInfo const *srv) static int checkConnectionAllowed(ConnectionInfo const *cnx) { ServerInfo const *srv = cnx->server; - char const *addressText = inet_ntoa(cnx->remoteAddress.sin_addr); + + char addressText[NI_MAXHOST]; + getnameinfo((struct sockaddr *)&cnx->remoteAddress, sizeof(cnx->remoteAddress), + addressText, sizeof(addressText), NULL, 0, NI_NUMERICHOST); /* 1. Check global allow rules. If there are no global allow rules, it's presumed OK at @@ -938,6 +940,7 @@ static void logEvent(ConnectionInfo const *cnx, ServerInfo const *srv, int resul thanks folks */ int timz; char tstr[1024]; + char addressText[NI_MAXHOST] = { '?' }; struct tm *t = get_gmtoff(&timz); char sign = (timz < 0 ? '-' : '+'); if (timz < 0) { @@ -945,10 +948,10 @@ static void logEvent(ConnectionInfo const *cnx, ServerInfo const *srv, int resul } strftime(tstr, sizeof(tstr), "%d/%b/%Y:%H:%M:%S ", t); - char const *addressText = "?"; int64_t bytesOut = 0, bytesIn = 0; if (cnx != NULL) { - addressText = inet_ntoa(cnx->remoteAddress.sin_addr); + getnameinfo((struct sockaddr *)&cnx->remoteAddress, sizeof(cnx->remoteAddress), + addressText, sizeof(addressText), NULL, 0, NI_NUMERICHOST); bytesOut = cnx->remote.totalBytesOut; bytesIn = cnx->remote.totalBytesIn; } diff --git a/src/types.h b/src/types.h index 9261f84..44d9fcb 100644 --- a/src/types.h +++ b/src/types.h @@ -46,7 +46,7 @@ typedef struct _socket Socket; struct _socket { SOCKET fd; - int protocol; + int family, protocol; /* recv: received on this socket sent: sent through this socket from the other buffer */ int recvPos, sentPos; @@ -58,7 +58,7 @@ typedef struct _connection_info ConnectionInfo; struct _connection_info { Socket remote, local; - struct sockaddr_in remoteAddress; + struct sockaddr_storage remoteAddress; time_t remoteTimeout; int coClosing; int coLog;