added IPv6 support.

This commit is contained in:
Steinar Hamre 2008-10-11 02:23:32 +00:00
parent 6c9d05433f
commit 9a73ba8e77

View File

@ -11,6 +11,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
#include <netdb.h>
#include "net.h" #include "net.h"
#include "server.h" #include "server.h"
@ -19,9 +20,11 @@
struct client { struct client {
int fd; int fd;
char buf[BUFSIZ];
int bufend; int bufend;
int linetoolong; int linetoolong;
int port;
char hostname[NI_MAXHOST];
char buf[BUFSIZ];
}; };
int servsock; int servsock;
@ -45,19 +48,24 @@ parse_linetoolong(int clientid, char *line) {
void void
net_server(int port) { net_server(int port) {
struct sockaddr_in serveraddr; struct sockaddr_in6 serveraddr = {
serveraddr.sin_family = AF_INET; .sin6_family = AF_INET6,
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); .sin6_addr = IN6ADDR_ANY_INIT,
serveraddr.sin_port = htons(port); .sin6_port = htons(port) };
servsock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); servsock=socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (servsock<0) if (servsock<0)
errx(1, "socket: %s\n", strerror(errno)); errx(1, "socket: %s\n", strerror(errno));
int i=1; int opt;
if (setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0) opt=1;
if (setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
errx(1, "setsockopt SO_REUSEADDR: %s\n", strerror(errno)); errx(1, "setsockopt SO_REUSEADDR: %s\n", strerror(errno));
opt=0;
if (setsockopt(servsock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) < 0)
errx(1, "setsockopt IPV6_V6ONLY: %s\n", strerror(errno));
if (bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) if (bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
errx(1, "bind port %d: %s\n", port, strerror(errno)); errx(1, "bind port %d: %s\n", port, strerror(errno));
@ -143,7 +151,7 @@ net_poll() {
void void
net_client_accept(int servsock) { net_client_accept(int servsock) {
struct sockaddr_in clientaddr; struct sockaddr_in6 clientaddr;
int cfd; int cfd;
socklen_t slen; socklen_t slen;
cfd=accept(servsock, (struct sockaddr *)&clientaddr, &slen); cfd=accept(servsock, (struct sockaddr *)&clientaddr, &slen);
@ -159,7 +167,6 @@ net_client_accept(int servsock) {
for (clientid=0; clientid<MAX_CLIENTS; clientid++) for (clientid=0; clientid<MAX_CLIENTS; clientid++)
if (pollfds[SRV_FDS+clientid].fd == -1) break; if (pollfds[SRV_FDS+clientid].fd == -1) break;
printf("Client %d connected...\n", clientid);
pollfds[SRV_FDS+clientid].fd=cfd; pollfds[SRV_FDS+clientid].fd=cfd;
pollfds[SRV_FDS+clientid].events=POLLIN|POLLERR|POLLHUP; pollfds[SRV_FDS+clientid].events=POLLIN|POLLERR|POLLHUP;
@ -167,6 +174,18 @@ net_client_accept(int servsock) {
clients[clientid].linetoolong = 0; clients[clientid].linetoolong = 0;
clients[clientid].bufend = 0; clients[clientid].bufend = 0;
strcpy(clients[clientid].hostname, "unknown");
char serv[NI_MAXSERV];
int e=getnameinfo((struct sockaddr *)&clientaddr, sizeof(clientaddr),
clients[clientid].hostname, NI_MAXHOST,
serv, NI_MAXSERV, NI_NUMERICSERV);
if (e)
fprintf(stderr, "client lookup failed: %s\n", gai_strerror(e));
clients[clientid].port = atoi(serv);
printf("Client %d connected from %s:%d\n", clientid,
clients[clientid].hostname, clients[clientid].port);
server_client_connect(clientid); server_client_connect(clientid);
nclients++; nclients++;