16
16
#include < arpa/inet.h>
17
17
#include < errno.h>
18
18
#include < fcntl.h>
19
+ #include < netdb.h>
19
20
#include < netinet/in.h>
20
21
#include < netinet/tcp.h>
21
22
#include < poll.h>
23
+ #include < re2/re2.h>
22
24
#include < stdarg.h>
23
25
#include < stdint.h>
24
26
#include < stdlib.h>
@@ -347,6 +349,45 @@ Http2Client::~Http2Client() {
347
349
}
348
350
}
349
351
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
+
350
391
// 向指定地址发起非阻塞连接
351
392
static int TryConnectTo (const std::string& host, int port, int & fd) {
352
393
if ((fd = socket (AF_INET, SOCK_STREAM, 0 )) < 0 ) {
@@ -368,30 +409,34 @@ static int TryConnectTo(const std::string& host, int port, int& fd) {
368
409
bzero (static_cast <void *>(&addr), sizeof (struct sockaddr_in ));
369
410
addr.sin_family = AF_INET;
370
411
addr.sin_port = htons (port);
412
+
371
413
if (inet_pton (AF_INET, host.c_str (), &addr.sin_addr ) != 1 ) {
372
414
return -1 ;
373
415
}
374
416
return connect (fd, (struct sockaddr *)&addr, sizeof (addr));
375
417
}
376
418
377
419
bool Http2Client::ConnectTo (const std::string& host, int port) {
420
+ std::string server_ip = TryLookup (host);
421
+
378
422
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);
380
424
int retcode = TryConnectTo (host, port, fd_);
381
425
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);
384
428
state_ = kConnectionConnecting ; // 即使立刻连接成功了也放在epoll写事件中去更新状态
385
429
} else if (errno == EINPROGRESS) { // tcp connect return -1
386
430
state_ = kConnectionConnecting ;
387
431
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);
389
433
retcode = 0 ;
390
434
} else {
391
435
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);
393
438
}
394
- current_server_ = host + " :" + StringUtils::TypeToStr<int >(port);
439
+ current_server_ = server_ip + " :" + StringUtils::TypeToStr<int >(port);
395
440
return retcode == 0 ;
396
441
}
397
442
0 commit comments