From b331021d492fd5febb576a61717a489c5cc875ff Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 30 Apr 2014 20:19:44 +0200 Subject: [PATCH] Added support for IPv6 peer addresses --- src/ban.c | 19 ++++++++++++++++--- src/ban.h | 2 +- src/client.h | 10 ++++++---- src/log.c | 11 +++++++++-- src/messagehandler.c | 5 ++++- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/ban.c b/src/ban.c index e1855de..e5294ba 100644 --- a/src/ban.c +++ b/src/ban.c @@ -74,8 +74,13 @@ void Ban_UserBan(client_t *client, char *reason) memset(ban, 0, sizeof(ban_t)); memcpy(ban->hash, client->hash, 20); - memcpy(&ban->address, &client->remote_tcp.sin_addr, sizeof(in_addr_t)); - ban->mask = 128; + if (client->remote_tcp.ss_family == AF_INET) { + memcpy(&ban->address, &(((struct sockaddr_in*)&client->remote_tcp)->sin_addr), sizeof(in_addr_t)); + ban->mask = sizeof(in_addr_t); + } else { + memcpy(&ban->address, &(((struct sockaddr_in6*)&client->remote_tcp)->sin6_addr), 4 * sizeof(in_addr_t)); + ban->mask = 4 * sizeof(in_addr_t); + } ban->reason = strdup(reason); ban->name = strdup(client->username); ban->time = time(NULL); @@ -88,8 +93,16 @@ void Ban_UserBan(client_t *client, char *reason) Ban_saveBanFile(); SSLi_hash2hex(ban->hash, hexhash); + + char addressPresentation[INET6_ADDRSTRLEN]; + + if(client->remote_tcp.ss_family == AF_INET) + inet_ntop(AF_INET, &((struct sockaddr_in*)&client->remote_tcp)->sin_addr, addressPresentation, INET6_ADDRSTRLEN); + else + inet_ntop(AF_INET6, &((struct sockaddr_in6*)&client->remote_tcp)->sin6_addr, addressPresentation, INET6_ADDRSTRLEN); + Log_info_client(client, "User kickbanned. Reason: '%s' Hash: %s IP: %s Banned for: %d seconds", - ban->reason, hexhash, inet_ntoa(*((struct in_addr *)&ban->address)), ban->duration); + ban->reason, hexhash, addressPresentation, ban->duration); } diff --git a/src/ban.h b/src/ban.h index 89cd140..98550a4 100644 --- a/src/ban.h +++ b/src/ban.h @@ -38,7 +38,7 @@ typedef struct { uint8_t hash[20]; - in_addr_t address; + uint8_t address[16]; uint32_t mask; char *reason; char *name; diff --git a/src/client.h b/src/client.h index c6085d2..66470de 100644 --- a/src/client.h +++ b/src/client.h @@ -55,6 +55,7 @@ #define MAX_CODECS 10 #define MAX_TOKENSIZE 64 #define MAX_TOKENS 32 +#define KEY_LENGTH sizeof(uint16_t) + 4 * sizeof(in_addr_t) #define IS_AUTH(_a_) ((_a_)->authenticated) @@ -66,12 +67,13 @@ typedef struct { cryptState_t cryptState; bool_t readBlockedOnWrite, writeBlockedOnRead; - struct sockaddr_in remote_tcp; - struct sockaddr_in remote_udp; + struct sockaddr_storage remote_tcp; + struct sockaddr_storage remote_udp; + char addressString[INET6_ADDRSTRLEN]; uint8_t rxbuf[BUFSIZE], txbuf[BUFSIZE]; uint32_t rxcount, msgsize, drainleft, txcount, txsize; int sessionId; - uint64_t key; + uint8_t key[KEY_LENGTH]; char *username; bool_t bUDP, authenticated, deaf, mute, self_deaf, self_mute, recording, bOpus; char *os, *release, *os_version; @@ -109,7 +111,7 @@ typedef struct { void Client_init(); int Client_getfds(struct pollfd *pollfds); void Client_janitor(); -int Client_add(int fd, struct sockaddr_in *remote); +int Client_add(int fd, struct sockaddr_storage *remote); int Client_read_fd(int fd); int Client_write_fd(int fd); int Client_send_message(client_t *client, message_t *msg); diff --git a/src/log.c b/src/log.c index ebb5cd1..17bbe14 100644 --- a/src/log.c +++ b/src/log.c @@ -182,6 +182,7 @@ void Log_info_client(client_t *client, const char *logstring, ...) va_list argp; char buf[STRSIZE + 1]; int offset = 0; + uint16_t port; if (termprint || logfile) offset = sprintf(buf, "INFO: "); @@ -190,11 +191,17 @@ void Log_info_client(client_t *client, const char *logstring, ...) offset += vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp); va_end(argp); + if(client->remote_tcp.ss_family == AF_INET) + port = ntohs(((struct sockaddr_in*)&client->remote_tcp)->sin_port); + else + port = ntohs(((struct sockaddr_in6*)&client->remote_tcp)->sin6_port); + offset += snprintf(&buf[offset], STRSIZE - offset, " - [%d] %s@%s:%d", client->sessionId, client->username == NULL ? "" : client->username, - inet_ntoa(client->remote_tcp.sin_addr), - ntohs(client->remote_tcp.sin_port)); + client->addressString, + port); + if (termprint) fprintf(stderr, "%s\n", buf); else if (logfile) diff --git a/src/messagehandler.c b/src/messagehandler.c index f1a753f..696cad3 100644 --- a/src/messagehandler.c +++ b/src/messagehandler.c @@ -878,8 +878,11 @@ void Mh_handle_message(client_t *client, message_t *msg) Log_fatal("Out of memory"); memset(sendmsg->payload.userStats->address.data, 0, 16); /* ipv4 representation as ipv6 address. Supposedly correct. */ - memcpy(&sendmsg->payload.userStats->address.data[12], &target->remote_tcp.sin_addr, 4); memset(&sendmsg->payload.userStats->address.data[10], 0xff, 2); /* IPv4 */ + if(target->remote_tcp.ss_family == AF_INET) + memcpy(&sendmsg->payload.userStats->address.data[12], &((struct sockaddr_in*)&target->remote_tcp)->sin_addr, 4); + else + memcpy(&sendmsg->payload.userStats->address.data[0], &((struct sockaddr_in6*)&target->remote_tcp)->sin6_addr, 16); sendmsg->payload.userStats->address.len = 16; } /* BW */ -- 2.30.2