From 917d506b64519a06a5f09b63363d02d2978ccb92 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 3 Jan 2016 17:53:09 +0100 Subject: [PATCH 1/3] Add support for IPv6 to cacaserver --- src/cacaserver.c | 113 +++++++++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 44 deletions(-) diff --git a/src/cacaserver.c b/src/cacaserver.c index 825c3d4..357c731 100644 --- a/src/cacaserver.c +++ b/src/cacaserver.c @@ -31,6 +31,7 @@ #endif #include #include +#include #include #include #include @@ -94,13 +95,19 @@ struct client int start, stop; }; +#define MAXSOCKS 16 + +struct sock { + int sockfd; + struct sockaddr_in my_addr; +}; + struct server { unsigned int width, height; unsigned int port; - int sockfd; - struct sockaddr_in my_addr; - socklen_t sin_size; + int sock_count; + struct sock socks[MAXSOCKS]; /* Input buffer */ uint8_t *input; @@ -118,14 +125,17 @@ struct server RETSIGTYPE (*sigpipe_handler)(int); }; -static void manage_connections(struct server *server); +void print_ip(struct sockaddr *ai); +static void manage_connections(struct server *server, int sockfd); static int send_data(struct server *server, struct client *c); ssize_t nonblock_write(int fd, void *buf, size_t len); int main(void) { - int i, yes = 1, flags; + int i, yes = 1, flags, fd, error; struct server *server; + struct addrinfo ai_hints, *ai, *res; + char port_str[6]; char *tmp; #if USE_WINSOCK @@ -152,40 +162,39 @@ int main(void) tmp[2] = (uint8_t) (server->height & 0xff00) >> 8; tmp[3] = (uint8_t) server->height & 0xff; - if((server->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) - { - perror("socket"); - return -1; - } - - if(setsockopt(server->sockfd, SOL_SOCKET, - SO_REUSEADDR, &yes, sizeof(int)) == -1) - { - perror("setsockopt SO_REUSEADDR"); - return -1; - } - - server->my_addr.sin_family = AF_INET; - server-> my_addr.sin_port = htons(server->port); - server->my_addr.sin_addr.s_addr = INADDR_ANY; - memset(&(server->my_addr.sin_zero), '\0', 8); - - if(bind(server->sockfd, (struct sockaddr *)&server->my_addr, - sizeof(struct sockaddr)) == -1) - { - perror("bind"); - return -1; + memset(&ai_hints, 0, sizeof(ai_hints)); + ai_hints.ai_family = AF_UNSPEC; + ai_hints.ai_socktype = SOCK_STREAM; + ai_hints.ai_flags = AI_PASSIVE; + memset(port_str, 0, sizeof(port_str)); + snprintf(port_str, 6, "%d", server->port); + error = getaddrinfo(NULL, port_str, &ai_hints, &ai); + if (error) + perror("getaddrinfo"); + + for (res = ai; res && server->sock_count < MAXSOCKS; res = res->ai_next) { + if ((fd = socket(res->ai_addr->sa_family, SOCK_STREAM, 0)) == -1) + perror("socket"); + if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) + perror("setsockopt: SO_REUSEADDR"); + if (res->ai_addr->sa_family == AF_INET6) + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int)) == -1) + perror("setsockopt: IPV6_V6ONLY"); + if (bind(fd, res->ai_addr, res->ai_addrlen) == -1) + perror("bind"); + flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if(listen(fd, BACKLOG) == -1) + perror("listen"); + + server->socks[server->sock_count].sockfd = fd; + server->sock_count++; + fprintf(stderr, "listening on "); + print_ip(res->ai_addr); + fprintf(stderr, "\n"); } + freeaddrinfo(ai); - /* Non blocking socket */ - flags = fcntl(server->sockfd, F_GETFL, 0); - fcntl(server->sockfd, F_SETFL, flags | O_NONBLOCK); - - if(listen(server->sockfd, BACKLOG) == -1) - { - perror("listen"); - return -1; - } server->canvas = caca_create_canvas(0, 0); server->buffer = NULL; @@ -202,7 +211,8 @@ int main(void) restart: /* Manage new connections as this function will be called sometimes * more often than display */ - manage_connections(server); + for (i = 0; i < server->sock_count; i++) + manage_connections(server, server->socks[i].sockfd); /* Read data from stdin */ if(server->read < 12) @@ -288,6 +298,9 @@ restart: /* Restore SIGPIPE handler */ signal(SIGPIPE, server->sigpipe_handler); + for (i = 0; i < server->sock_count; i++) + close(server->socks[i].sockfd); + free(server); #if USE_WINSOCK @@ -300,18 +313,30 @@ restart: * XXX: The following functions are local */ -static void manage_connections(struct server *server) +void print_ip(struct sockaddr *ai) +{ + char buffer[INET6_ADDRSTRLEN]; + int err = getnameinfo(ai, (ai->sa_family==AF_INET)?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6), buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST); + if (err != 0) { + fprintf(stderr, "n/a"); + } + fprintf(stderr, "%s",buffer); +} + + +static void manage_connections(struct server *server, int sockfd) { int fd, flags; - struct sockaddr_in remote_addr; - socklen_t len = sizeof(struct sockaddr_in); + struct sockaddr_in6 remote_addr; + socklen_t len = sizeof(struct sockaddr_in6); - fd = accept(server->sockfd, (struct sockaddr *)&remote_addr, &len); + fd = accept(sockfd, (struct sockaddr*)&remote_addr, &len); if(fd == -1) return; - fprintf(stderr, "[%i] connected from %s\n", - fd, inet_ntoa(remote_addr.sin_addr)); + fprintf(stderr, "[%i] connected from ", fd); + print_ip((struct sockaddr*)&remote_addr); + fprintf(stderr, "\n"); /* Non blocking socket */ flags = fcntl(fd, F_SETFL, 0); From 0b9f50ec478d9e2069cd614157cfb82e7f297071 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 3 Jan 2016 20:56:31 +0100 Subject: [PATCH 2/3] - return -1 on error - make sure at least one listener is set - reformat code --- src/cacaserver.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/cacaserver.c b/src/cacaserver.c index 357c731..2890593 100644 --- a/src/cacaserver.c +++ b/src/cacaserver.c @@ -54,7 +54,7 @@ "\xff\xfd\x31" /* DO NAWS */ \ "\xff\x1f\xfa____" /* SB NAWS */ \ "\xff\xf0" /* SE */ \ - "\033]2;caca for the network\x07" /* Change window title */ \ + "\033]2;AuvernIX\x07" /* Change window title */ \ "\033[H\033[J" /* Clear screen */ /*"\033[?25l"*/ /* Hide cursor */ @@ -152,7 +152,7 @@ int main(void) server->client_count = 0; server->clients = NULL; - server->port = 0xCACA; /* 51914 */ + server->port = 23; /* 51914 */ /* FIXME, handle >255 sizes */ memcpy(server->prefix, INIT_PREFIX, sizeof(INIT_PREFIX)); @@ -170,22 +170,41 @@ int main(void) snprintf(port_str, 6, "%d", server->port); error = getaddrinfo(NULL, port_str, &ai_hints, &ai); if (error) + { perror("getaddrinfo"); + return -1; + } - for (res = ai; res && server->sock_count < MAXSOCKS; res = res->ai_next) { + for (res = ai; res && server->sock_count < MAXSOCKS; res = res->ai_next) + { if ((fd = socket(res->ai_addr->sa_family, SOCK_STREAM, 0)) == -1) + { perror("socket"); + continue; + } if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) + { perror("setsockopt: SO_REUSEADDR"); + continue; + } if (res->ai_addr->sa_family == AF_INET6) if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int)) == -1) + { perror("setsockopt: IPV6_V6ONLY"); + continue; + } if (bind(fd, res->ai_addr, res->ai_addrlen) == -1) + { perror("bind"); + continue; + } flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); if(listen(fd, BACKLOG) == -1) + { perror("listen"); + continue; + } server->socks[server->sock_count].sockfd = fd; server->sock_count++; @@ -195,6 +214,11 @@ int main(void) } freeaddrinfo(ai); + if (server->sock_count == 0) + { + fprintf(stderr, "Not listening\n"); + return -1; + } server->canvas = caca_create_canvas(0, 0); server->buffer = NULL; @@ -316,7 +340,13 @@ restart: void print_ip(struct sockaddr *ai) { char buffer[INET6_ADDRSTRLEN]; - int err = getnameinfo(ai, (ai->sa_family==AF_INET)?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6), buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST); + socklen_t len = sizeof(struct sockaddr_in6); + + if (ai->sa_family == AF_INET) + len = sizeof(struct sockaddr_in); + + int err = getnameinfo(ai, len, buffer, sizeof(buffer), NULL, 0, + NI_NUMERICHOST); if (err != 0) { fprintf(stderr, "n/a"); } From d39b77ead19f5ac64d809831d5695245782d134a Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 3 Jan 2016 21:00:23 +0100 Subject: [PATCH 3/3] Reverse local changes --- src/cacaserver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cacaserver.c b/src/cacaserver.c index 2890593..4187c6b 100644 --- a/src/cacaserver.c +++ b/src/cacaserver.c @@ -54,7 +54,7 @@ "\xff\xfd\x31" /* DO NAWS */ \ "\xff\x1f\xfa____" /* SB NAWS */ \ "\xff\xf0" /* SE */ \ - "\033]2;AuvernIX\x07" /* Change window title */ \ + "\033]2;caca for the network\x07" /* Change window title */ \ "\033[H\033[J" /* Clear screen */ /*"\033[?25l"*/ /* Hide cursor */ @@ -152,7 +152,7 @@ int main(void) server->client_count = 0; server->clients = NULL; - server->port = 23; /* 51914 */ + server->port = 0xCACA; /* 51914 */ /* FIXME, handle >255 sizes */ memcpy(server->prefix, INIT_PREFIX, sizeof(INIT_PREFIX));