@@ -147,7 +147,6 @@ class SocketNetwork : public Network
147147 protected:
148148 int set_non_blocking ( Channel *channel );
149149 int set_reusable ( Channel *channel );
150- int resolve ( const char *host, void *address );
151150};
152151
153152std::shared_ptr<SocketNetwork> DEFAULT_NETWORK = std::make_shared<SocketNetwork>();
@@ -1631,11 +1630,13 @@ struct SocketChannel : public Channel
16311630 struct pollfd poll;
16321631};
16331632
1634- int SocketNetwork::resolve ( const char *host, void *address )
1633+ struct addrdel
16351634{
1636- int result = 0 ;
1635+ void operator ()( addrinfo *ptr ) { freeaddrinfo (ptr); };
1636+ };
16371637
1638- if (address == nullptr ) return WBERR_INVALID_ARGUMENT;
1638+ static std::shared_ptr<addrinfo[]> resolve ( const char *host )
1639+ {
16391640 if (host == nullptr || *host == 0 ) host = " 127.0.0.1" ;
16401641
16411642 // get an IPv4 address from hostname
@@ -1644,17 +1645,10 @@ int SocketNetwork::resolve( const char *host, void *address )
16441645 aiHints.ai_family = AF_INET;
16451646 aiHints.ai_socktype = SOCK_STREAM;
16461647 aiHints.ai_protocol = IPPROTO_TCP;
1647- result = getaddrinfo ( host, nullptr , &aiHints, &aiInfo );
1648- if (result != 0 || aiInfo->ai_addr ->sa_family != AF_INET)
1649- {
1650- if (result == 0 ) freeaddrinfo (aiInfo);
1651- return WBERR_INVALID_ADDRESS;
1652- }
1648+ int result = getaddrinfo (host, nullptr , &aiHints, &aiInfo);
1649+ if (result != 0 ) return nullptr ;
16531650 // copy address information
1654- memcpy (address, (struct sockaddr_in *) aiInfo->ai_addr , sizeof (struct sockaddr_in ));
1655- freeaddrinfo (aiInfo);
1656-
1657- return WBERR_OK;
1651+ return std::shared_ptr<addrinfo[]>(aiInfo, addrdel ());
16581652}
16591653
16601654SocketNetwork::SocketNetwork ()
@@ -1756,12 +1750,16 @@ int SocketNetwork::connect( Channel *channel, int scheme, const char *host, int
17561750
17571751 SocketChannel *chann = (SocketChannel*) channel;
17581752
1759- struct sockaddr_in address;
1760- int result = resolve (host, &address);
1761- if (result != WBERR_OK) return result;
1753+ auto addrs = resolve (host);
1754+ addrinfo *addr = nullptr ;
1755+ for (addr = addrs.get (); addr != nullptr && addr->ai_family != AF_INET; addr = addr->ai_next );
1756+ if (addr == nullptr ) return WBERR_INVALID_ADDRESS;
1757+
1758+ sockaddr_in address;
1759+ address = *((sockaddr_in*) addr->ai_addr );
17621760 address.sin_port = htons ( (uint16_t ) port );
17631761
1764- result = set_non_blocking (chann);
1762+ int result = set_non_blocking (chann);
17651763 if (result != WBERR_OK) return result;
17661764
17671765 result = ::connect (chann->socket , (const struct sockaddr *) &address, sizeof (const struct sockaddr_in ));
@@ -1774,7 +1772,6 @@ int SocketNetwork::connect( Channel *channel, int scheme, const char *host, int
17741772 chann->poll .events = POLLOUT;
17751773 result = webster::poll (chann->poll , timeout);
17761774 if (result != WBERR_OK) return result;
1777-
17781775 return WBERR_OK;
17791776}
17801777
@@ -1911,11 +1908,15 @@ int SocketNetwork::listen( Channel *channel, const char *host, int port, int max
19111908
19121909 SocketChannel *chann = (SocketChannel*) channel;
19131910
1914- struct sockaddr_in address;
1915- int result = resolve (host, &address);
1916- if (result != WBERR_OK) return result;
1911+ auto addrs = resolve (host);
1912+ addrinfo *addr = nullptr ;
1913+ for (addr = addrs.get (); addr != nullptr && addr->ai_family != AF_INET; addr = addr->ai_next );
1914+ if (addr == nullptr ) return WBERR_INVALID_ADDRESS;
19171915
1916+ sockaddr_in address;
1917+ address = *((sockaddr_in*) addr->ai_addr );
19181918 address.sin_port = htons ( (uint16_t ) port );
1919+
19191920 if (::bind (chann->socket , (const struct sockaddr *) &address, sizeof (struct sockaddr_in )) != 0 )
19201921 return translate_error ();
19211922
0 commit comments