Added support for IPv6 peer addresses
authorFelix Morgner <felix.morgner@gmail.com>
Wed, 30 Apr 2014 18:19:44 +0000 (20:19 +0200)
committerFelix Morgner <felix.morgner@gmail.com>
Thu, 1 May 2014 05:37:40 +0000 (07:37 +0200)
src/ban.c
src/ban.h
src/client.h
src/log.c
src/messagehandler.c

index e1855de2cb830be0c4d9ff12ab15c8031c90d6a9..e5294ba3f45f2d2229a7d3a45decb5a1377e71cb 100644 (file)
--- 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);
 }
 
 
index 89cd14099c5924ec705ce271acf3ce12189feb5e..98550a4dca5fc9b0f462f2ba5807a37a742fea6b 100644 (file)
--- 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;
index c6085d298e6563779f4763f60d4d6f9b0ab284dd..66470de3fb2177f4dea9558b79e36e20b1003d25 100644 (file)
@@ -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);
index ebb5cd1c0ae1e4b4965da971df41a3484f538928..17bbe14a56e804bd9aea4b9b68475e06a3cbc088 100644 (file)
--- 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)
index f1a753f9e81495764d20f120f9e371ea51959b34..696cad3c6d750f90f642ee2c5aa734b07b9f0be1 100644 (file)
@@ -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 */