in src/main.c [321:449]
int lagscope_server_listen(struct lagscope_test_server *server)
{
char *log;
struct lagscope_test *test = server->test;
bool verbose_log = test->verbose;
int opt = 1;
int sendbuff, recvbuff = 0; //receive buffer size
char *ip_address_str; //used to get local ip address
int ip_address_max_size; //used to get local ip address
char *port_str; //to get remote peer's port number for getaddrinfo()
struct addrinfo hints, *serv_info, *p; //to get remote peer's sockaddr for bind()
int i = 0; //just for debug purpose
INIT_SOCKFD_VAR();
/* get receiver/itself address */
memset(&hints, 0, sizeof hints);
hints.ai_family = test->domain;
hints.ai_socktype = test->protocol;
ASPRINTF(&port_str, "%d", test->server_port);
if (getaddrinfo(test->bind_address, port_str, &hints, &serv_info) != 0) {
PRINT_ERR("cannot get address info for receiver");
WSACLEAN();
return -1;
}
free(port_str);
ip_address_max_size = (test->domain == AF_INET? INET_ADDRSTRLEN : INET6_ADDRSTRLEN);
if ((ip_address_str = (char *)malloc(ip_address_max_size)) == (char *)NULL) {
PRINT_ERR("cannot allocate memory for ip address string");
freeaddrinfo(serv_info);
WSACLEAN();
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 ednpoint");
freeaddrinfo(serv_info);
free(ip_address_str);
WSACLEAN();
return -1;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)) < 0) {
ASPRINTF(&log, "cannot set socket options SO_REUSEADDR: %d", sockfd);
PRINT_ERR_FREE(log);
freeaddrinfo(serv_info);
free(ip_address_str);
CLOSE(sockfd);
WSACLEAN();
return -1;
}
sendbuff = test->send_buf_size;
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *) &sendbuff, sizeof(sendbuff)) < 0) {
ASPRINTF(&log, "cannot set socket send buffer size to: %d", sendbuff);
PRINT_ERR_FREE(log);
freeaddrinfo(serv_info);
free(ip_address_str);
CLOSE(sockfd);
WSACLEAN();
return -1;
}
recvbuff = test->recv_buf_size;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *) &recvbuff, sizeof(recvbuff)) < 0) {
ASPRINTF(&log, "cannot set socket receive buffer size to: %d", recvbuff);
PRINT_ERR_FREE(log);
freeaddrinfo(serv_info);
free(ip_address_str);
CLOSE(sockfd);
WSACLEAN();
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(ip_address_str);
CLOSE(sockfd);
WSACLEAN();
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. errcode = %d",
ip_address_str = retrive_ip_address_str((struct sockaddr_storage *)p->ai_addr, ip_address_str, ip_address_max_size), sockfd, i);
if (i == -1)
ASPRINTF(&log, "%s. errcode = %d", log, errno);
PRINT_DBG_FREE(log);
continue;
}
else {
break; //connected
}
}
freeaddrinfo(serv_info);
free(ip_address_str);
if (p == NULL) {
ASPRINTF(&log, "cannot bind the socket on address: %s", test->bind_address);
PRINT_ERR_FREE(log);
CLOSE(sockfd);
WSACLEAN();
return -1;
}
server->listener = sockfd;
if (listen(server->listener, MAX_CONNECTIONS_PER_THREAD) < 0) {
ASPRINTF(&log, "failed to listen on address: %s: %d", test->bind_address, test->server_port);
PRINT_ERR_FREE(log);
CLOSE(server->listener);
WSACLEAN();
return -1;
}
FD_ZERO(&server->read_set);
FD_ZERO(&server->write_set);
FD_SET(server->listener, &server->read_set);
if (server->listener > server->max_fd)
server->max_fd = server->listener;
ASPRINTF(&log, "lagscope server is listening on %s:%d", test->bind_address, test->server_port);
PRINT_DBG_FREE(log);
return server->listener;
}