static int create_and_bind ( const char * host , const char * port , int protocol ) {
 struct addrinfo hints ;
 struct addrinfo * result , * rp , * ipv4v6bindall ;
 int s , listen_sock = - 1 ;
 memset ( & hints , 0 , sizeof ( struct addrinfo ) ) ;
 hints . ai_family = AF_UNSPEC ;
 hints . ai_socktype = protocol == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM ;
 hints . ai_flags = AI_PASSIVE | AI_ADDRCONFIG ;
 hints . ai_protocol = protocol ;
 s = getaddrinfo ( host , port , & hints , & result ) ;
 if ( s != 0 ) {
 LOGE ( "getaddrinfo: %s" , gai_strerror ( s ) ) ;
 return - 1 ;
 }
 rp = result ;
 if ( ! host ) {
 ipv4v6bindall = result ;
 while ( ipv4v6bindall ) {
 if ( ipv4v6bindall -> ai_family == AF_INET6 ) {
 rp = ipv4v6bindall ;
 break ;
 }
 ipv4v6bindall = ipv4v6bindall -> ai_next ;
 }
 }
 for ( ;
 rp != NULL ;
 rp = rp -> ai_next ) {
 listen_sock = socket ( rp -> ai_family , rp -> ai_socktype , rp -> ai_protocol ) ;
 if ( listen_sock == - 1 ) {
 continue ;
 }
 if ( rp -> ai_family == AF_INET6 ) {
 int ipv6only = host ? 1 : 0 ;
 setsockopt ( listen_sock , IPPROTO_IPV6 , IPV6_V6ONLY , & ipv6only , sizeof ( ipv6only ) ) ;
 }
 int opt = 1 ;
 setsockopt ( listen_sock , SOL_SOCKET , SO_REUSEADDR , & opt , sizeof ( opt ) ) ;
 # ifdef SO_NOSIGPIPE setsockopt ( listen_sock , SOL_SOCKET , SO_NOSIGPIPE , & opt , sizeof ( opt ) ) ;
 # endif s = bind ( listen_sock , rp -> ai_addr , rp -> ai_addrlen ) ;
 if ( s == 0 ) {
 close ( listen_sock ) ;
 break ;
 }
 else {
 ERROR ( "bind" ) ;
 }
 }
 if ( ! result ) {
 freeaddrinfo ( result ) ;
 }
 if ( rp == NULL ) {
 LOGE ( "Could not bind" ) ;
 return - 1 ;
 }
 return listen_sock ;
 }
static int create_and_bind ( const char * host , const char * port , int protocol ) {
 struct addrinfo hints ;
 struct addrinfo * result , * rp , * ipv4v6bindall ;
 int s , listen_sock = - 1 ;
 memset ( & hints , 0 , sizeof ( struct addrinfo ) ) ;
 hints . ai_family = AF_UNSPEC ;
 hints . ai_socktype = protocol == IPPROTO_TCP ? SOCK_STREAM : SOCK_DGRAM ;
 hints . ai_flags = AI_PASSIVE | AI_ADDRCONFIG ;
 hints . ai_protocol = protocol ;
 s = getaddrinfo ( host , port , & hints , & result ) ;
 if ( s != 0 ) {
 LOGE ( "getaddrinfo: %s" , gai_strerror ( s ) ) ;
 return - 1 ;
 }
 rp = result ;
 if ( ! host ) {
 ipv4v6bindall = result ;
 while ( ipv4v6bindall ) {
 if ( ipv4v6bindall -> ai_family == AF_INET6 ) {
 rp = ipv4v6bindall ;
 break ;
 }
 ipv4v6bindall = ipv4v6bindall -> ai_next ;
 }
 }
 for ( ;
 rp != NULL ;
 rp = rp -> ai_next ) {
 listen_sock = socket ( rp -> ai_family , rp -> ai_socktype , rp -> ai_protocol ) ;
 if ( listen_sock == - 1 ) {
 continue ;
 }
 if ( rp -> ai_family == AF_INET6 ) {
 int ipv6only = host ? 1 : 0 ;
 setsockopt ( listen_sock , IPPROTO_IPV6 , IPV6_V6ONLY , & ipv6only , sizeof ( ipv6only ) ) ;
 }
 int opt = 1 ;
 setsockopt ( listen_sock , SOL_SOCKET , SO_REUSEADDR , & opt , sizeof ( opt ) ) ;
 # ifdef SO_NOSIGPIPE setsockopt ( listen_sock , SOL_SOCKET , SO_NOSIGPIPE , & opt , sizeof ( opt ) ) ;
 # endif s = bind ( listen_sock , rp -> ai_addr , rp -> ai_addrlen ) ;
 if ( s == 0 ) {
 close ( listen_sock ) ;
 break ;
 }
 else {
 ERROR ( "bind" ) ;
 }
 }
 if ( ! result ) {
 freeaddrinfo ( result ) ;
 }
 if ( rp == NULL ) {
 LOGE ( "Could not bind" ) ;
 return - 1 ;
 }
 return listen_sock ;
 }