]> arthur.barton.de Git - netdata.git/commitdiff
proper IPv6 handling
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 25 Mar 2015 21:33:07 +0000 (23:33 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Wed, 25 Mar 2015 21:33:07 +0000 (23:33 +0200)
src/web_client.c
src/web_client.h
src/web_server.c

index b6af4c872ef358c274daecbe8b8e71c149c9d810..2e10135e657787697a0aa023261c3f03d3721a94 100755 (executable)
@@ -5,9 +5,10 @@
 #include <arpa/inet.h>
 
 #include "global_statistics.h"
-#include "web_client.h"
 #include "log.h"
 
+#include "web_client.h"
+
 #define INITIAL_WEB_DATA_LENGTH 65536
 
 struct web_client *web_clients = NULL;
@@ -16,7 +17,6 @@ unsigned long long web_clients_count = 0;
 struct web_client *web_client_create(int listener)
 {
        struct web_client *w;
-       socklen_t addrlen;
        
        w = calloc(1, sizeof(struct web_client));
        if(!w) {
@@ -27,22 +27,46 @@ struct web_client *web_client_create(int listener)
        w->id = ++web_clients_count;
        w->mode = WEB_CLIENT_MODE_NORMAL;
 
-       addrlen = sizeof(w->clientaddr);
-       w->ifd = accept(listener, (struct sockaddr *)&w->clientaddr, &addrlen);
-       if (w->ifd == -1) {
-               error("%llu: Cannot accept new incoming connection.", w->id);
-               free(w);
-               return NULL;
-       }
-       w->ofd = w->ifd;
-
-       strncpy(w->client_ip, inet_ntoa(w->clientaddr.sin_addr), 100);
-       w->client_ip[100] = '\0';
-
-       debug(D_WEB_CLIENT_ACCESS, "%llu: New web client from %s on socket %d.", w->id, w->client_ip, w->ifd);
-
        {
-               int flag = 1; 
+               struct sockaddr *sadr;
+               socklen_t addrlen;
+
+               sadr = (struct sockaddr*) &w->clientaddr;
+               addrlen = sizeof(w->clientaddr);
+
+               w->ifd = accept(listener, sadr, &addrlen);
+               if (w->ifd == -1) {
+                       error("%llu: Cannot accept new incoming connection.", w->id);
+                       free(w);
+                       return NULL;
+               }
+               w->ofd = w->ifd;
+
+               if(getnameinfo(sadr, addrlen, w->client_ip, NI_MAXHOST, w->client_port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
+                       error("Cannot getnameinfo() on received client connection.");
+                       strncpy(w->client_ip,   "UNKNOWN", NI_MAXHOST);
+                       strncpy(w->client_port, "UNKNOWN", NI_MAXSERV);
+               }
+               w->client_ip[NI_MAXHOST]   = '\0';
+               w->client_port[NI_MAXSERV] = '\0';
+
+               switch(sadr->sa_family) {
+               case AF_INET:
+                       debug(D_WEB_CLIENT_ACCESS, "%llu: New IPv4 web client from %s port %s on socket %d.", w->id, w->client_ip, w->client_port, w->ifd);
+                       break;
+               case AF_INET6:
+                       if(strncmp(w->client_ip, "::ffff:", 7) == 0) {
+                               strcpy(w->client_ip, &w->client_ip[7]);
+                               debug(D_WEB_CLIENT_ACCESS, "%llu: New IPv4 web client from %s port %s on socket %d.", w->id, w->client_ip, w->client_port, w->ifd);
+                       }
+                       debug(D_WEB_CLIENT_ACCESS, "%llu: New IPv6 web client from %s port %s on socket %d.", w->id, w->client_ip, w->client_port, w->ifd);
+                       break;
+               default:
+                       debug(D_WEB_CLIENT_ACCESS, "%llu: New UNKNOWN web client from %s port %s on socket %d.", w->id, w->client_ip, w->client_port, w->ifd);
+                       break;
+               }
+
+               int flag = 1;
                if(setsockopt(w->ifd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int)) != 0) error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
        }
 
@@ -68,7 +92,7 @@ struct web_client *web_client_free(struct web_client *w)
 {
        struct web_client *n = w->next;
 
-       debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s.", w->id, inet_ntoa(w->clientaddr.sin_addr));
+       debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s port %s.", w->id, w->client_ip, w->client_port);
 
        if(w->prev)     w->prev->next = w->next;
        if(w->next) w->next->prev = w->prev;
index bc343ce84953f7f637cda8a6cbac59f79c7e5522..b72bccfe7cb7f7bfd259d8902d011f46ae015140 100755 (executable)
@@ -4,6 +4,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netdb.h>
 
 #include "web_buffer.h"
 
 
 struct web_client {
        unsigned long long id;
-       char client_ip[101];
+
+       char client_ip[NI_MAXHOST+1];
+       char client_port[NI_MAXSERV+1];
+
        char last_url[URL_MAX+1];
 
        struct timeval tv_in, tv_ready;
@@ -27,7 +31,7 @@ struct web_client {
        int mode;
        int keepalive;
 
-       struct sockaddr_in clientaddr;
+       struct sockaddr_storage clientaddr;
 
        pthread_t thread;                               // the thread servicing this client
        int obsolete;                                   // if set to 1, the listener will remove this client
index 084d652e24659bd76042ec6d200488d2e96865f3..3cfc4058501ce6d735b8f445b0cd3aa54dcf1093 100755 (executable)
@@ -1296,7 +1296,7 @@ void *socket_listen_main(void *ptr)
                                        w->obsolete = 1;
                                }
 
-                               log_access("%llu: %s connected", w->id, w->client_ip);
+                               log_access("%llu: %s port %s connected", w->id, w->client_ip, w->client_port);
                        }
                        else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
 
@@ -1308,7 +1308,7 @@ void *socket_listen_main(void *ptr)
                // cleanup unused clients
                for(w = web_clients; w ; w = w?w->next:NULL) {
                        if(w->obsolete) {
-                               log_access("%llu: %s disconnected", w->id, w->client_ip);
+                               log_access("%llu: %s port %s disconnected", w->id, w->client_ip, w->client_port);
                                debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
                                // pthread_join(w->thread,  NULL);
                                w = web_client_free(w);