diff --git a/libowlps/libowlps.c b/libowlps/libowlps.c index 5ddcf02..a589ba2 100644 --- a/libowlps/libowlps.c +++ b/libowlps/libowlps.c @@ -481,32 +481,48 @@ int owl_create_udp_trx_socket(const char *const server_address, */ int owl_create_udp_listening_socket(const uint_fast16_t port) { + char port_str[6] ; + struct addrinfo + gai_hints, + *gai_results = NULL, + *gai_res = NULL ; + int gai_ret ; // Return value of getaddrinfo() int sockfd ; // Socket descriptor - struct sockaddr_in server_description ; // Server structure - int ret = 0 ; // Return value - /* Create the UDP socket */ - sockfd = socket(AF_INET, SOCK_DGRAM, 0) ; - if (sockfd < 0) + /* Get the server information */ + sprintf(port_str, "%"PRIuFAST16, port) ; + memset(&gai_hints, 0, sizeof(struct addrinfo)) ; + gai_hints.ai_family = AF_INET ; // IPv4 only + gai_hints.ai_socktype = SOCK_DGRAM ; + gai_hints.ai_flags = AI_PASSIVE ; + gai_ret = getaddrinfo(NULL, port_str, &gai_hints, &gai_results) ; + if (gai_ret) { - perror("UDP socket creation failed") ; + fprintf(stderr, "UDP socket creation failed: getaddrinfo(): %s\n", + gai_strerror(gai_ret)) ; return -OWL_ERR_SOCKET_CREATE ; } - /* Initialise the server structure */ - memset(&server_description, 0, sizeof(server_description)) ; - server_description.sin_family = AF_INET ; // INET socket - // All the connections are accepted: - server_description.sin_addr.s_addr = htonl(INADDR_ANY) ; - server_description.sin_port = htons(port) ; // Listening port - - /* Port reservation */ - ret = bind(sockfd, (struct sockaddr*) &server_description, - sizeof(server_description)) ; - if (ret < 0) + /* Create the UDP socket: + * loop until both socket() and bind() succeed */ + for (gai_res = gai_results ; gai_res != NULL ; + gai_res = gai_res->ai_next) { - perror("Cannot bind the UDP socket") ; + sockfd = socket(gai_res->ai_family, gai_res->ai_socktype, + gai_res->ai_protocol) ; + if (sockfd == -1) + continue ; + + if (! bind(sockfd, gai_res->ai_addr, gai_res->ai_addrlen)) + break ; // Success! + close(sockfd) ; + } + + if (gai_res == NULL) + { + fprintf(stderr, + "UDP socket creation failed: socket() or bind().\n") ; return -OWL_ERR_SOCKET_CREATE ; }