/* Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef unsigned char u_char; #include #include "cmsg_private.h" #include "relay.h" static struct event accept_event; void get_addr_name(char *namebuf, size_t buflen, struct sockaddr_in const *sin) { unsigned char *addr = (unsigned char *) &sin->sin_addr.s_addr; struct hostent *h = gethostbyaddr(addr, 4, AF_INET); if (h == NULL) { snprintf(namebuf, buflen, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]); } else { snprintf(namebuf, buflen, "%s", h->h_name); } } void endpoint_name(struct sockaddr_in const *peername, cmsg_bytes_t result) { char name[256]; get_addr_name(name, sizeof(name), peername); snprintf((char *) result.bytes, result.len, "%s:%d", name, ntohs(peername->sin_port)); } static void accept_connection(int servfd, short what, void *arg) { struct sockaddr_in s; socklen_t addrlen = sizeof(s); int fd = accept(servfd, (struct sockaddr *) &s, &addrlen); if (fd == -1) { if (errno != EAGAIN && errno != EINTR) { warn("accept: errno %d (%s)\n", errno, strerror(errno)); } return; } { int i = 1; ICHECK(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i)), "setsockopt TCP_NODELAY"); } start_relay(&s, fd); } void start_net(int listen_port) { int servfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in s; if (servfd < 0) { die("Could not open listen socket.\n"); } s.sin_family = AF_INET; s.sin_addr.s_addr = htonl(INADDR_ANY); s.sin_port = htons(listen_port); { int i = 1; setsockopt(servfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); // don't care if this fails } if (bind(servfd, (struct sockaddr *) &s, sizeof(s)) < 0) { die("Could not bind listen socket.\n"); } if (listen(servfd, 5) < 0) { int savedErrno = errno; die("Could not listen on listen socket (errno %d: %s).\n", savedErrno, strerror(savedErrno)); } event_set(&accept_event, servfd, EV_READ | EV_PERSIST, accept_connection, NULL); if (event_add(&accept_event, NULL) == -1) { die("Could not add accept_event."); } info("Accepting connections on port %d.\n", listen_port); }