diff --git a/library/net.c b/library/net.c index 97b193d13..d02e3f269 100644 --- a/library/net.c +++ b/library/net.c @@ -228,6 +228,64 @@ int net_connect( int *fd, const char *host, int port ) */ int net_bind( int *fd, const char *bind_ip, int port ) { +#if defined(POLARSSL_HAVE_IPV6) + int ret = POLARSSL_ERR_NET_UNKNOWN_HOST; + struct addrinfo hints, *addr_list, *cur; + char port_str[6]; + + net_prepare(); + + /* getaddrinfo expects port as a string */ + memset( port_str, 0, sizeof( port_str ) ); + snprintf( port_str, sizeof( port_str ), "%d", port ); + + /* Bind to IPv6 and/or IPv4, but only in TCP */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if( bind_ip == NULL ) + hints.ai_flags = AI_PASSIVE; + + if( getaddrinfo( bind_ip, port_str, &hints, &addr_list ) != 0 ) + return( POLARSSL_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a binding succeeds */ + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + *fd = socket( cur->ai_family, cur->ai_socktype, cur->ai_protocol ); + if( *fd < 0 ) + { + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + if( bind( *fd, cur->ai_addr, cur->ai_addrlen ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_BIND_FAILED; + continue; + } + + if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_LISTEN_FAILED; + continue; + } + + /* I we ever get there, it's a success */ + ret = 0; + break; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +#else + /* Legacy IPv4-only version */ + int n, c[4]; struct sockaddr_in server_addr; @@ -275,6 +333,7 @@ int net_bind( int *fd, const char *bind_ip, int port ) } return( 0 ); +#endif /* POLARSSL_HAVE_IPV6 */ } /*