[noPoll] Added ipv6 support and updated code to use getaddrinfo -- Re: Use of gethostbyname in noPoll library

Francis Brosnan Blázquez francis.brosnan en aspl.es
Jue Nov 3 20:04:05 CET 2016


Hello Kale,

Thanks for reporting and the follow up. 

I've been working these days on a patch to add full IPv6 support
to noPoll (adding new APIs to ensure current published API keeps working
the same). 

At the same time, that code update already replaced gethostbyname
by getaddrinfo, so next stable release, or current github stable release
(305)
[1] should also fix your issue.

Again, thanks for reporting,
Best Regards,

[1] https://github.com/ASPLes/nopoll

>  
> 
> Hello,
> 
>  
> 
> I have narrowed down the cause of intermittent failures in our stress
> 
> test cases to the use of gethostbyname() in noPoll library.
> 
> This function is not thread safe under Linux (possibly other platforms
> too).
> 
>  
> 
> I fixed this by modifying  function nopoll_conn_sock_connect_opts()
> 
> This function is used for outbound client connections. 
> 
> Our application makes multiple websocket connections to 
> 
> different hosts in one process. The problem was revealed when
> 
> I started using dns hosts names instead of IP addresses.
> 
> I updated the function to use getaddrinfo() instead of
> gethostbyname().
> 
> My modifications fixed the stress test failures.
> 
> There is another place gethostbyname is used that I did not
> 
> fix since we are not yet using the server (listen) mode.
> 
>  
> 
> Below is my modified function for reference:
> 
>  
> 
> NOPOLL_SOCKET nopoll_conn_sock_connect_opts (noPollCtx       * ctx,
> 
> 
> const char      * host,
> 
> 
> const char      * port,
> 
> 
> noPollConnOpts  * options)
> 
> {
> 
>                 NOPOLL_SOCKET        session;
> 
>                 struct addrinfo hints, *servinfo, *p;
> 
>                 int rc;
> 
>  
> 
>                 memset(&hints, 0, sizeof hints);
> 
>                 hints.ai_family = AF_INET; /* force IPv4 */
> 
>                 hints.ai_socktype = SOCK_STREAM; 
> 
>                 if ((rc = getaddrinfo(host, port, &hints,
> &servinfo)) != 0) {
> 
>                                 nopoll_log (ctx, NOPOLL_LEVEL_DEBUG,
> "unable to resolve host name %s", host);
> 
>                                 return -1;
> 
>                 }
> 
>                 p = servinfo;
> 
>                 if (p == NULL) {
> 
>                                 nopoll_log (ctx, NOPOLL_LEVEL_DEBUG,
> "unable to retrieve address for host name %s", host);
> 
>                                 return -1;
> 
>                 }
> 
>  
> 
>                 /* create the socket and check if it */
> 
>                 session      = socket (AF_INET, SOCK_STREAM, 0);
> 
>                 if (session == NOPOLL_INVALID_SOCKET) {
> 
>                                 nopoll_log (ctx,
> NOPOLL_LEVEL_CRITICAL, "unable to create socket");
> 
>                 freeaddrinfo(servinfo);
> 
>                                 return -1;
> 
>                 } /* end if */
> 
>  
> 
>                 /* disable nagle */
> 
>                 nopoll_conn_set_sock_tcp_nodelay (session,
> nopoll_true);
> 
>  
> 
>                 /* bind to specified interface */
> 
>                 if( nopoll_true != nopoll_conn_set_bind_interface
> (session, options) ) {
> 
>                                 nopoll_log (ctx,
> NOPOLL_LEVEL_CRITICAL, "unable to bind to specified interface");
> 
>                                 nopoll_close_socket (session);
> 
>                                 freeaddrinfo(servinfo);
> 
>                                 return -1;
> 
>                 } /* end if */
> 
>  
> 
>                 /* set non blocking status */
> 
>                 nopoll_conn_set_sock_block (session, nopoll_false);
> 
>  
> 
>                 /* do a tcp connect */
> 
>                 if (connect (session, p->ai_addr, p->ai_addrlen) < 0)
> {
> 
>                                 if(errno != NOPOLL_EINPROGRESS &&
> errno != NOPOLL_EWOULDBLOCK && errno != NOPOLL_ENOTCONN) {
> 
>                                         shutdown (session, SHUT_RDWR);
> 
>                         nopoll_close_socket (session);
> 
>  
> 
>                                                 nopoll_log (ctx,
> NOPOLL_LEVEL_WARNING, "unable to connect to remote host %s:%s errno=%
> d",
> 
> 
> host, port, errno);
> 
>                                 freeaddrinfo(servinfo);
> 
>                                                 return -1;
> 
>                                 } /* end if */
> 
>                 } /* end if */
> 
>  
> 
>                 freeaddrinfo(servinfo);
> 
>  
> 
>                 /* return socket created */
> 
>                 return session;
> 
> }
> 
>  
> 
>  
> 
> Regards,
> 
>  
> 
> Rahul
> 
>  
> 
>  
> 
>  
> 
>  
> 
> Rahul Kale
> 
>  
> 
> IP Video Systems
> 
> Barco, Inc
> 
> 1287 Anvilwood Ave
> 
> Sunnyvale, CA  94089
> 
>  
> 
> Tel  +1 408 400 4238
> 
>  
> 
> 
> 
> This message is subject to the following terms and conditions: MAIL
> DISCLAIMER
> 
> _______________________________________________
> noPoll mailing list
> noPoll en lists.aspl.es
> http://lists.aspl.es/cgi-bin/mailman/listinfo/nopoll


------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://lists.aspl.es/pipermail/nopoll/attachments/20161103/f5a8e2b9/attachment.html>


Más información sobre la lista de distribución noPoll