Skip to content

Commit 34076ec

Browse files
committed
add InetAddress::resolve for sync DNS resolving with gethostbyname_r
1 parent 48e877e commit 34076ec

6 files changed

Lines changed: 80 additions & 17 deletions

File tree

‎examples/ace/ttcp/ttcp.cc‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp time)
103103

104104
void transmit(const Options& opt)
105105
{
106-
InetAddress addr(resolveOrDie(opt.host.c_str(), opt.port));
106+
InetAddress addr(opt.port);
107+
if (!InetAddress::resolve(opt.host.c_str(), &addr))
108+
{
109+
LOG_FATAL << "Unable to resolve " << opt.host;
110+
}
107111
muduo::Timestamp start(muduo::Timestamp::now());
108112
EventLoop loop;
109113
g_loop = &loop;

‎examples/socks4a/socks4a.cc‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ void onServerMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp)
4848
char cmd = buf->peek()[1];
4949
const void* port = buf->peek() + 2;
5050
const void* ip = buf->peek() + 4;
51+
5152
sockaddr_in addr;
5253
bzero(&addr, sizeof addr);
5354
addr.sin_family = AF_INET;
5455
addr.sin_port = *static_cast<const in_port_t*>(port);
5556
addr.sin_addr.s_addr = *static_cast<const uint32_t*>(ip);
57+
5658
bool socks4a = sockets::networkToHost32(addr.sin_addr.s_addr) < 256;
5759
bool okay = false;
5860
if (socks4a)
@@ -63,10 +65,10 @@ void onServerMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp)
6365
string hostname = where+1;
6466
where = endOfHostName;
6567
LOG_INFO << "Socks4a host name " << hostname;
66-
struct hostent* hent = gethostbyname(hostname.c_str());
67-
if (hent)
68+
InetAddress tmp(0);
69+
if (InetAddress::resolve(hostname.c_str(), &tmp))
6870
{
69-
addr.sin_addr = *reinterpret_cast<in_addr*>(hent->h_addr);
71+
addr.sin_addr.s_addr = tmp.ipNetEndian();
7072
okay = true;
7173
}
7274
}

‎muduo/net/InetAddress.cc‎

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88

99
#include <muduo/net/InetAddress.h>
1010

11+
#include <muduo/base/Logging.h>
1112
#include <muduo/net/Endian.h>
1213
#include <muduo/net/SocketsOps.h>
1314

15+
#include <netdb.h>
1416
#include <strings.h> // bzero
1517
#include <netinet/in.h>
1618

@@ -19,6 +21,7 @@
1921
// INADDR_ANY use (type)value casting.
2022
#pragma GCC diagnostic ignored "-Wold-style-cast"
2123
static const in_addr_t kInaddrAny = INADDR_ANY;
24+
static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK;
2225
#pragma GCC diagnostic error "-Wold-style-cast"
2326

2427
// /* Structure describing an Internet socket address. */
@@ -39,11 +42,12 @@ using namespace muduo::net;
3942

4043
BOOST_STATIC_ASSERT(sizeof(InetAddress) == sizeof(struct sockaddr_in));
4144

42-
InetAddress::InetAddress(uint16_t port)
45+
InetAddress::InetAddress(uint16_t port, bool lookbackOnly)
4346
{
4447
bzero(&addr_, sizeof addr_);
4548
addr_.sin_family = AF_INET;
46-
addr_.sin_addr.s_addr = sockets::hostToNetwork32(kInaddrAny);
49+
in_addr_t ip = lookbackOnly ? kInaddrLoopback : kInaddrAny;
50+
addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip);
4751
addr_.sin_port = sockets::hostToNetwork16(port);
4852
}
4953

@@ -67,3 +71,29 @@ string InetAddress::toIp() const
6771
return buf;
6872
}
6973

74+
static __thread char t_resolveBuffer[64 * 1024];
75+
76+
bool InetAddress::resolve(const char* hostname, InetAddress* out)
77+
{
78+
assert(out != NULL);
79+
struct hostent hent;
80+
struct hostent* he = NULL;
81+
int herrno = 0;
82+
bzero(&hent, sizeof(hent));
83+
84+
int ret = gethostbyname_r(hostname, &hent, t_resolveBuffer, sizeof t_resolveBuffer, &he, &herrno);
85+
if (ret == 0 && he != NULL)
86+
{
87+
assert(he->h_addrtype == AF_INET && he->h_length == sizeof(uint32_t));
88+
out->addr_.sin_addr = *reinterpret_cast<struct in_addr*>(he->h_addr);
89+
return true;
90+
}
91+
else
92+
{
93+
if (ret)
94+
{
95+
LOG_SYSERR << "InetAddress::resolve";
96+
}
97+
return false;
98+
}
99+
}

‎muduo/net/InetAddress.h‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class InetAddress : public muduo::copyable
3030
public:
3131
/// Constructs an endpoint with given port number.
3232
/// Mostly used in TcpServer listening.
33-
explicit InetAddress(uint16_t port);
33+
explicit InetAddress(uint16_t port, bool loopbackOnly = false);
3434

3535
/// Constructs an endpoint with given ip and port.
3636
/// @c ip should be "1.2.3.4"
@@ -55,6 +55,12 @@ class InetAddress : public muduo::copyable
5555
uint32_t ipNetEndian() const { return addr_.sin_addr.s_addr; }
5656
uint16_t portNetEndian() const { return addr_.sin_port; }
5757

58+
// resolve hostname to IP address, not changing port or sin_family
59+
// return true on success.
60+
// thread safe
61+
static bool resolve(const char* hostname, InetAddress* result);
62+
// static std::vector<InetAddress> resolveAll(const char* hostname, uint16_t port = 0);
63+
5864
private:
5965
struct sockaddr_in addr_;
6066
};

‎muduo/net/SocketsOps.cc‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,12 @@ void sockets::shutdownWrite(int sockfd)
179179
void sockets::toIpPort(char* buf, size_t size,
180180
const struct sockaddr_in& addr)
181181
{
182-
char host[INET_ADDRSTRLEN] = "INVALID";
183-
toIp(host, sizeof host, addr);
182+
assert(size >= INET_ADDRSTRLEN);
183+
::inet_ntop(AF_INET, &addr.sin_addr, buf, static_cast<socklen_t>(size));
184+
size_t end = ::strlen(buf);
184185
uint16_t port = sockets::networkToHost16(addr.sin_port);
185-
snprintf(buf, size, "%s:%u", host, port);
186+
assert(size > end);
187+
snprintf(buf+end, size-end, ":%u", port);
186188
}
187189

188190
void sockets::toIp(char* buf, size_t size,
@@ -193,7 +195,7 @@ void sockets::toIp(char* buf, size_t size,
193195
}
194196

195197
void sockets::fromIpPort(const char* ip, uint16_t port,
196-
struct sockaddr_in* addr)
198+
struct sockaddr_in* addr)
197199
{
198200
addr->sin_family = AF_INET;
199201
addr->sin_port = hostToNetwork16(port);
Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include <muduo/net/InetAddress.h>
22

3+
#include <muduo/base/Logging.h>
4+
35
//#define BOOST_TEST_MODULE InetAddressTest
46
#define BOOST_TEST_MAIN
57
#define BOOST_TEST_DYN_LINK
@@ -10,15 +12,32 @@ using muduo::net::InetAddress;
1012

1113
BOOST_AUTO_TEST_CASE(testInetAddress)
1214
{
13-
InetAddress addr1(1234);
14-
BOOST_CHECK_EQUAL(addr1.toIp(), string("0.0.0.0"));
15-
BOOST_CHECK_EQUAL(addr1.toIpPort(), string("0.0.0.0:1234"));
15+
InetAddress addr0(1234);
16+
BOOST_CHECK_EQUAL(addr0.toIp(), string("0.0.0.0"));
17+
BOOST_CHECK_EQUAL(addr0.toIpPort(), string("0.0.0.0:1234"));
18+
19+
InetAddress addr1(4321, true);
20+
BOOST_CHECK_EQUAL(addr1.toIp(), string("127.0.0.1"));
21+
BOOST_CHECK_EQUAL(addr1.toIpPort(), string("127.0.0.1:4321"));
1622

1723
InetAddress addr2("1.2.3.4", 8888);
1824
BOOST_CHECK_EQUAL(addr2.toIp(), string("1.2.3.4"));
1925
BOOST_CHECK_EQUAL(addr2.toIpPort(), string("1.2.3.4:8888"));
2026

21-
InetAddress addr3("255.255.255.255", 65535);
22-
BOOST_CHECK_EQUAL(addr3.toIp(), string("255.255.255.255"));
23-
BOOST_CHECK_EQUAL(addr3.toIpPort(), string("255.255.255.255:65535"));
27+
InetAddress addr3("255.254.253.252", 65535);
28+
BOOST_CHECK_EQUAL(addr3.toIp(), string("255.254.253.252"));
29+
BOOST_CHECK_EQUAL(addr3.toIpPort(), string("255.254.253.252:65535"));
30+
}
31+
32+
BOOST_AUTO_TEST_CASE(testInetAddressResolve)
33+
{
34+
InetAddress addr(80);
35+
if (InetAddress::resolve("google.com", &addr))
36+
{
37+
LOG_INFO << "google.com resolved to " << addr.toIpPort();
38+
}
39+
else
40+
{
41+
LOG_ERROR << "Unable to resolve google.com";
42+
}
2443
}

0 commit comments

Comments
 (0)