in src/tcpstream.c [276:371]
int ntttcp_server_listen(struct ntttcp_stream_server *ss)
{
char *log;
int i = 0; /* hold function return value */
int opt = 1;
int sockfd = 0; /* socket file descriptor */
char *local_addr_str; /* used to get local ip address */
int ip_addr_max_size; /* used to get local ip address */
char *port_str; /* used to get port number string for getaddrinfo() */
struct addrinfo hints, *serv_info, *p; /* to get local sockaddr for bind() */
/* get receiver/itself address */
memset(&hints, 0, sizeof hints);
hints.ai_family = ss->domain;
hints.ai_socktype = ss->protocol;
ASPRINTF(&port_str, "%d", ss->server_port);
if (getaddrinfo(ss->bind_address, port_str, &hints, &serv_info) != 0) {
PRINT_ERR("cannot get address info for receiver");
return -1;
}
free(port_str);
ip_addr_max_size = (ss->domain == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN);
if ((local_addr_str = (char *)malloc(ip_addr_max_size)) == (char *)NULL) {
PRINT_ERR("cannot allocate memory for ip address string");
freeaddrinfo(serv_info);
return -1;
}
/* get the first entry to bind and listen */
for (p = serv_info; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
PRINT_ERR("cannot create socket endpoint");
freeaddrinfo(serv_info);
free(local_addr_str);
return -1;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) {
ASPRINTF(&log, "cannot set socket options: %d", sockfd);
PRINT_ERR_FREE(log);
freeaddrinfo(serv_info);
free(local_addr_str);
close(sockfd);
return -1;
}
if (set_socket_non_blocking(sockfd) == -1) {
ASPRINTF(&log, "cannot set socket as non-blocking: %d", sockfd);
PRINT_ERR_FREE(log);
freeaddrinfo(serv_info);
free(local_addr_str);
close(sockfd);
return -1;
}
if ((i = bind(sockfd, p->ai_addr, p->ai_addrlen)) < 0) {
ASPRINTF(&log,
"failed to bind the socket to local address: %s on socket: %d. return = %d",
local_addr_str = retrive_ip_address_str((struct sockaddr_storage *)p->ai_addr, local_addr_str, ip_addr_max_size),
sockfd, i);
if (i == -1) /* append more info to log */
ASPRINTF(&log, "%s. errcode = %d", log, errno);
PRINT_DBG_FREE(log);
continue;
} else {
break; /* connected */
}
}
freeaddrinfo(serv_info);
free(local_addr_str);
if (p == NULL) {
ASPRINTF(&log, "cannot bind the socket on address: %s", ss->bind_address);
PRINT_ERR_FREE(log);
close(sockfd);
return -1;
}
ss->listener = sockfd;
if (listen(ss->listener, MAX_THREADS_PER_SERVER_PORT) < 0) {
ASPRINTF(&log, "failed to listen on address: %s: %d", ss->bind_address, ss->server_port);
PRINT_ERR_FREE(log);
close(ss->listener);
return -1;
}
FD_ZERO(&ss->read_set);
FD_ZERO(&ss->write_set);
FD_SET(ss->listener, &ss->read_set);
if (ss->listener > ss->max_fd)
ss->max_fd = ss->listener;
ASPRINTF(&log, "ntttcp server is listening on %s:%d", ss->bind_address, ss->server_port);
PRINT_DBG_FREE(log);
return ss->listener;
}