46
46
#include "server.h"
47
47
#include "tcpserver.h"
49
int tcpserver(const struct optstruct *opts)
49
int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struct optstruct *opts)
51
struct sockaddr_in server;
51
struct addrinfo hints, *info, *p;
52
53
int sockfd, backlog;
56
if (cfg_tcpsock(opts, &server, INADDR_ANY) == -1) {
57
logg("!TCP: Couldn't configure socket, check your configuration\n");
61
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
62
estr = strerror(errno);
63
logg("!TCP: socket() error: %s\n", estr);
67
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &true, sizeof(true)) == -1) {
68
logg("!TCP: setsocktopt(SO_REUSEADDR) error: %s\n", strerror(errno));
71
if(bind(sockfd, (struct sockaddr *) &server, (socklen_t)sizeof(struct sockaddr_in)) == -1) {
72
estr = strerror(errno);
73
logg("!TCP: bind() error: %s\n", estr);
77
const struct optstruct *taddr = optget(opts, "TCPAddr");
79
logg("#TCP: Bound to address %s on port %u\n", taddr->strarg, (unsigned int) optget(opts, "TCPSocket")->numarg);
81
logg("#TCP: Bound to port %u\n", (unsigned int) optget(opts, "TCPSocket")->numarg);
84
backlog = optget(opts, "MaxConnectionQueueLength")->numarg;
85
logg("#TCP: Setting connection queue length to %d\n", backlog);
87
if(listen(sockfd, backlog) == -1) {
88
estr = strerror(errno);
89
logg("!TCP: listen() error: %s\n", estr);
62
snprintf(port, sizeof(port), "%lld", optget(opts, "TCPSocket")->numarg);
64
memset(&hints, 0x00, sizeof(struct addrinfo));
65
hints.ai_family = AF_UNSPEC;
66
hints.ai_socktype = SOCK_STREAM;
67
hints.ai_flags = AI_PASSIVE;
72
* By default, getaddrinfo() will return 0.0.0.0 if NULL is passed in as the first parameter.
73
* Binding to 0.0.0.0 will prevent us from also binding IPv6 ::0 (errno = EADDRINUSE). However,
74
* if we bind to ::0 (or shorthand, ::), then Linux will bind to both IPv4 and IPv6.
80
if ((res = getaddrinfo(ipaddr, port, &hints, &info))) {
81
logg("!TCP: getaddrinfo: %s\n", gai_strerror(res));
85
for (p = info; p != NULL; p = p->ai_next, i++) {
86
t = realloc(sockets, sizeof(int) * (*nlsockets + 1));
88
for (i=0; i < *nlsockets; i++)
95
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
96
estr = strerror(errno);
97
logg("!TCP: socket() error: %s\n", estr);
101
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &yes, sizeof(yes)) == -1) {
102
logg("!TCP: setsocktopt(SO_REUSEADDR) error: %s\n", strerror(errno));
105
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
106
estr = strerror(errno);
107
if (ipaddr || i == 0)
108
logg("!TCP: bind() error when trying to listen on [%s]:%s: %s\n", ipaddr, port, estr);
114
logg("#TCP: Bound to address %s on port %u\n", ipaddr, (unsigned int) optget(opts, "TCPSocket")->numarg);
116
logg("#TCP: Bound to port %u\n", (unsigned int) optget(opts, "TCPSocket")->numarg);
119
backlog = optget(opts, "MaxConnectionQueueLength")->numarg;
120
logg("#TCP: Setting connection queue length to %d\n", backlog);
122
if(listen(sockfd, backlog) == -1) {
123
estr = strerror(errno);
124
logg("!TCP: listen() error: %s\n", estr);
130
sockets[*nlsockets] = sockfd;