@cryptotaxi247 / netdata-1 / commits / 222f3dd7a

proper IPv6 handling

Costa Tsaousis (ktsaou) committed Mar 25, 2015 at 23:33 UTC 222f3dd7a3b910df9cd703f69fcf6b49b229a45d
3 files changed +50 -22
src/web_client.c
+42 -18
@@ -5,9 +5,10 @@
5 #include <arpa/inet.h>
6
7 #include "global_statistics.h"
8 -#include "web_client.h"
8 #include "log.h"
9
10 +#include "web_client.h"
11 +
12 #define INITIAL_WEB_DATA_LENGTH 65536
13
14 struct web_client *web_clients = NULL;
@@ -16,7 +17,6 @@ unsigned long long web_clients_count = 0;
17 struct web_client *web_client_create(int listener)
18 {
19 struct web_client *w;
19 - socklen_t addrlen;
20
21 w = calloc(1, sizeof(struct web_client));
22 if(!w) {
@@ -27,22 +27,46 @@ struct web_client *web_client_create(int listener)
27 w->id = ++web_clients_count;
28 w->mode = WEB_CLIENT_MODE_NORMAL;
29
30 - addrlen = sizeof(w->clientaddr);
31 - w->ifd = accept(listener, (struct sockaddr *)&w->clientaddr, &addrlen);
32 - if (w->ifd == -1) {
33 - error("%llu: Cannot accept new incoming connection.", w->id);
34 - free(w);
35 - return NULL;
36 - }
37 - w->ofd = w->ifd;
38 -
39 - strncpy(w->client_ip, inet_ntoa(w->clientaddr.sin_addr), 100);
40 - w->client_ip[100] = '\0';
41 -
42 - debug(D_WEB_CLIENT_ACCESS, "%llu: New web client from %s on socket %d.", w->id, w->client_ip, w->ifd);
43 -
30 {
45 - int flag = 1;
31 + struct sockaddr *sadr;
32 + socklen_t addrlen;
33 +
34 + sadr = (struct sockaddr*) &w->clientaddr;
35 + addrlen = sizeof(w->clientaddr);
36 +
37 + w->ifd = accept(listener, sadr, &addrlen);
38 + if (w->ifd == -1) {
39 + error("%llu: Cannot accept new incoming connection.", w->id);
40 + free(w);
41 + return NULL;
42 + }
43 + w->ofd = w->ifd;
44 +
45 + if(getnameinfo(sadr, addrlen, w->client_ip, NI_MAXHOST, w->client_port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
46 + error("Cannot getnameinfo() on received client connection.");
47 + strncpy(w->client_ip, "UNKNOWN", NI_MAXHOST);
48 + strncpy(w->client_port, "UNKNOWN", NI_MAXSERV);
49 + }
50 + w->client_ip[NI_MAXHOST] = '\0';
51 + w->client_port[NI_MAXSERV] = '\0';
52 +
53 + switch(sadr->sa_family) {
54 + case AF_INET:
55 + 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);
56 + break;
57 + case AF_INET6:
58 + if(strncmp(w->client_ip, "::ffff:", 7) == 0) {
59 + strcpy(w->client_ip, &w->client_ip[7]);
60 + 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);
61 + }
62 + 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);
63 + break;
64 + default:
65 + 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);
66 + break;
67 + }
68 +
69 + int flag = 1;
70 if(setsockopt(w->ifd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int)) != 0) error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
71 }
72
@@ -68,7 +92,7 @@ struct web_client *web_client_free(struct web_client *w)
92 {
93 struct web_client *n = w->next;
94
71 - debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s.", w->id, inet_ntoa(w->clientaddr.sin_addr));
95 + debug(D_WEB_CLIENT_ACCESS, "%llu: Closing web client from %s port %s.", w->id, w->client_ip, w->client_port);
96
97 if(w->prev) w->prev->next = w->next;
98 if(w->next) w->next->prev = w->prev;
src/web_client.h
+6 -2
@@ -4,6 +4,7 @@
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 #include <arpa/inet.h>
7 +#include <netdb.h>
8
9 #include "web_buffer.h"
10
@@ -19,7 +20,10 @@
20
21 struct web_client {
22 unsigned long long id;
22 - char client_ip[101];
23 +
24 + char client_ip[NI_MAXHOST+1];
25 + char client_port[NI_MAXSERV+1];
26 +
27 char last_url[URL_MAX+1];
28
29 struct timeval tv_in, tv_ready;
@@ -27,7 +31,7 @@ struct web_client {
31 int mode;
32 int keepalive;
33
30 - struct sockaddr_in clientaddr;
34 + struct sockaddr_storage clientaddr;
35
36 pthread_t thread; // the thread servicing this client
37 int obsolete; // if set to 1, the listener will remove this client
src/web_server.c
+2 -2
@@ -1296,7 +1296,7 @@ void *socket_listen_main(void *ptr)
1296 w->obsolete = 1;
1297 }
1298
1299 - log_access("%llu: %s connected", w->id, w->client_ip);
1299 + log_access("%llu: %s port %s connected", w->id, w->client_ip, w->client_port);
1300 }
1301 else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
1302
@@ -1308,7 +1308,7 @@ void *socket_listen_main(void *ptr)
1308 // cleanup unused clients
1309 for(w = web_clients; w ; w = w?w->next:NULL) {
1310 if(w->obsolete) {
1311 - log_access("%llu: %s disconnected", w->id, w->client_ip);
1311 + log_access("%llu: %s port %s disconnected", w->id, w->client_ip, w->client_port);
1312 debug(D_WEB_CLIENT, "%llu: Removing client.", w->id);
1313 // pthread_join(w->thread, NULL);
1314 w = web_client_free(w);