1616#include < arpa/inet.h>
1717#include < errno.h>
1818#include < fcntl.h>
19+ #include < netdb.h>
1920#include < netinet/in.h>
2021#include < netinet/tcp.h>
2122#include < poll.h>
23+ #include < re2/re2.h>
2224#include < stdarg.h>
2325#include < stdint.h>
2426#include < stdlib.h>
@@ -347,6 +349,45 @@ Http2Client::~Http2Client() {
347349 }
348350}
349351
352+ // TryLookup 尝试进行 host 解析
353+ // step 1. 判断当前的 host 是否是域名
354+ // step 2. 不是域名,则直接返回
355+ // step 3. 是域名,进行一次域名解析,然后从返回的IPList中随机选取一个IP进行链接
356+ static std::string TryLookup (const std::string& address) {
357+ GRPC_LOG (LOG_DEBUG, " try lookup address=[%s]" , address.c_str ());
358+
359+ std::string domain_reg =
360+ " ^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\ .[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\ .?$" ;
361+ re2::RE2 domain (domain_reg.c_str ());
362+ bool is_domain = domain.ok () && re2::RE2::PartialMatch (address.c_str (), domain);
363+
364+ // 使用正则表达式判断是否是域名, 不是域名,直接返回 address
365+ if (!is_domain) {
366+ return address;
367+ }
368+
369+ struct hostent * host = gethostbyname (address.c_str ());
370+ if (!host) {
371+ GRPC_LOG (LOG_ERROR, " try lookup address=[%s] error, maybe address is ip" , address.c_str ());
372+ return address;
373+ }
374+
375+ GRPC_LOG (LOG_DEBUG, " address=[%s] type: [%s]" , address.c_str (),
376+ (host->h_addrtype == AF_INET) ? " AF_INET" : " AF_INET6" );
377+
378+ int total = sizeof (host->h_addr_list );
379+ if (total < 1 ) {
380+ return address;
381+ }
382+
383+ std::string target_address = inet_ntoa (*(struct in_addr *)host->h_addr_list [0 ]);
384+
385+ GRPC_LOG (LOG_TRACE, " address=[%s] select one by random [%s]" , address.c_str (),
386+ target_address.c_str ());
387+
388+ return target_address;
389+ }
390+
350391// 向指定地址发起非阻塞连接
351392static int TryConnectTo (const std::string& host, int port, int & fd) {
352393 if ((fd = socket (AF_INET, SOCK_STREAM, 0 )) < 0 ) {
@@ -368,30 +409,34 @@ static int TryConnectTo(const std::string& host, int port, int& fd) {
368409 bzero (static_cast <void *>(&addr), sizeof (struct sockaddr_in ));
369410 addr.sin_family = AF_INET;
370411 addr.sin_port = htons (port);
412+
371413 if (inet_pton (AF_INET, host.c_str (), &addr.sin_addr ) != 1 ) {
372414 return -1 ;
373415 }
374416 return connect (fd, (struct sockaddr *)&addr, sizeof (addr));
375417}
376418
377419bool Http2Client::ConnectTo (const std::string& host, int port) {
420+ std::string server_ip = TryLookup (host);
421+
378422 POLARIS_ASSERT (state_ == kConnectionInit );
379- GRPC_LOG (LOG_INFO, " try to nonblocking connect to server[%s:%d]" , host .c_str (), port);
423+ GRPC_LOG (LOG_INFO, " try to nonblocking connect to server[%s:%d]" , server_ip .c_str (), port);
380424 int retcode = TryConnectTo (host, port, fd_);
381425 if (retcode == 0 ) { // 异步连接立即成功了,一般本地连接才有可能发生。
382- GRPC_LOG (LOG_TRACE, " nonblocking connect to service[%s:%d] success immediately" , host. c_str (),
383- port);
426+ GRPC_LOG (LOG_TRACE, " nonblocking connect to service[%s:%d] success immediately" ,
427+ server_ip. c_str (), port);
384428 state_ = kConnectionConnecting ; // 即使立刻连接成功了也放在epoll写事件中去更新状态
385429 } else if (errno == EINPROGRESS) { // tcp connect return -1
386430 state_ = kConnectionConnecting ;
387431 GRPC_LOG (LOG_TRACE, " nonblocking connect to server[%s:%d] with connection in progress" ,
388- host .c_str (), port);
432+ server_ip .c_str (), port);
389433 retcode = 0 ;
390434 } else {
391435 state_ = kConnectionDisconnected ;
392- GRPC_LOG (LOG_ERROR, " nonblocking connect to %s:%d with error: %d" , host.c_str (), port, errno);
436+ GRPC_LOG (LOG_ERROR, " nonblocking connect to %s:%d with error: %d" , server_ip.c_str (), port,
437+ errno);
393438 }
394- current_server_ = host + " :" + StringUtils::TypeToStr<int >(port);
439+ current_server_ = server_ip + " :" + StringUtils::TypeToStr<int >(port);
395440 return retcode == 0 ;
396441}
397442
0 commit comments