evapi: use getaddrinfo() instead of gethostbyname()
authorDaniel-Constantin Mierla <miconda@gmail.com>
Wed, 20 May 2020 11:35:32 +0000 (13:35 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Wed, 20 May 2020 11:35:32 +0000 (13:35 +0200)
- the later is marked as deprecated
- GH #1714

src/modules/evapi/evapi_dispatch.c

index e16d4c5..4d25386 100644 (file)
@@ -618,9 +618,10 @@ void evapi_recv_notify(struct ev_loop *loop, struct ev_io *watcher, int revents)
 int evapi_run_dispatcher(char *laddr, int lport)
 {
        int evapi_srv_sock;
-       struct sockaddr_in evapi_srv_addr;
        struct ev_loop *loop;
-       struct hostent *h = NULL;
+       struct addrinfo ai_hints;
+       struct addrinfo *ai_res = NULL;
+       int ai_ret = 0;
        struct ev_io io_server;
        struct ev_io io_notify;
        int yes_true = 1;
@@ -646,39 +647,37 @@ int evapi_run_dispatcher(char *laddr, int lport)
                return -1;
        }
 
-       h = gethostbyname(laddr);
-       if (h == NULL || (h->h_addrtype != AF_INET && h->h_addrtype != AF_INET6)) {
-               LM_ERR("cannot resolve local server address [%s]\n", laddr);
+       memset(&ai_hints, 0, sizeof(struct addrinfo));
+       ai_hints.ai_family = AF_UNSPEC;         /* allow IPv4 or IPv6 */
+       ai_hints.ai_socktype = SOCK_STREAM;     /* stream socket */
+       ai_ret = getaddrinfo(laddr, NULL, &ai_hints, &ai_res);
+       if (ai_ret != 0) {
+               LM_ERR("getaddrinfo failed: %d %s\n", ai_ret, gai_strerror(ai_ret));
                return -1;
        }
-       if(h->h_addrtype == AF_INET) {
-               evapi_srv_sock = socket(PF_INET, SOCK_STREAM, 0);
-       } else {
-               evapi_srv_sock = socket(PF_INET6, SOCK_STREAM, 0);
-       }
-       if( evapi_srv_sock < 0 )
-       {
-               LM_ERR("cannot create server socket (family %d)\n", h->h_addrtype);
+       evapi_srv_sock = socket(ai_res->ai_family, ai_res->ai_socktype,
+                       ai_res->ai_protocol);
+       if( evapi_srv_sock < 0 ) {
+               LM_ERR("cannot create server socket (family %d)\n", ai_res->ai_family);
+               freeaddrinfo(ai_res);
                return -1;
        }
+
        /* set non-blocking flag */
        fflags = fcntl(evapi_srv_sock, F_GETFL);
        if(fflags<0) {
                LM_ERR("failed to get the srv socket flags\n");
                close(evapi_srv_sock);
+               freeaddrinfo(ai_res);
                return -1;
        }
        if (fcntl(evapi_srv_sock, F_SETFL, fflags | O_NONBLOCK)<0) {
                LM_ERR("failed to set srv socket flags\n");
                close(evapi_srv_sock);
+               freeaddrinfo(ai_res);
                return -1;
        }
 
-       bzero(&evapi_srv_addr, sizeof(evapi_srv_addr));
-       evapi_srv_addr.sin_family = h->h_addrtype;
-       evapi_srv_addr.sin_port   = htons(lport);
-       evapi_srv_addr.sin_addr  = *(struct in_addr*)h->h_addr;
-
        /* Set SO_REUSEADDR option on listening socket so that we don't
         * have to wait for connections in TIME_WAIT to go away before
         * re-binding.
@@ -688,15 +687,16 @@ int evapi_run_dispatcher(char *laddr, int lport)
                &yes_true, sizeof(int)) < 0) {
                LM_ERR("cannot set SO_REUSEADDR option on descriptor\n");
                close(evapi_srv_sock);
+               freeaddrinfo(ai_res);
                return -1;
        }
 
-       if (bind(evapi_srv_sock, (struct sockaddr*)&evapi_srv_addr,
-                               sizeof(evapi_srv_addr)) < 0) {
+       if (bind(evapi_srv_sock, ai_res->ai_addr, ai_res->ai_addrlen) < 0) {
                LM_ERR("cannot bind to local address and port [%s:%d]\n", laddr, lport);
                close(evapi_srv_sock);
                return -1;
        }
+       freeaddrinfo(ai_res);
        if (listen(evapi_srv_sock, 4) < 0) {
                LM_ERR("listen error\n");
                close(evapi_srv_sock);