int lagscope_server_listen()

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;
}