Skip to content

Commit 66f3357

Browse files
authored
Merge pull request #27 from chuntaojun/main
[ISSUE #28]: 支持域名解析
2 parents 8cc3a6d + 2e54e95 commit 66f3357

File tree

3 files changed

+102
-8
lines changed

3 files changed

+102
-8
lines changed

polaris/grpc/http2.cpp

+51-6
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
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
// 向指定地址发起非阻塞连接
351392
static 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

377419
bool 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

test/grpc/domain_test.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
2+
//
3+
// Licensed under the BSD 3-Clause License (the "License"); you may not use
4+
// this file
5+
// except in compliance with the License. You may obtain a copy of the License
6+
// at
7+
//
8+
// https://opensource.org/licenses/BSD-3-Clause
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed
12+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
14+
// specific
15+
// language governing permissions and limitations under the License.
16+
//
17+
18+
#include "grpc/buffer.h"
19+
20+
#include <gtest/gtest.h>
21+
#include <pthread.h>
22+
#include <re2/re2.h>
23+
#include <unistd.h>
24+
25+
namespace polaris {
26+
namespace grpc {
27+
28+
class GrpcDomainTest : public ::testing::Test {
29+
protected:
30+
virtual void SetUp() {}
31+
32+
virtual void TearDown() {}
33+
34+
protected:
35+
};
36+
37+
TEST_F(GrpcDomainTest, DomainJudge) {
38+
std::string domain_reg = "^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?$";
39+
re2::RE2 regex_(domain_reg.c_str());
40+
ASSERT_TRUE((regex_).ok());
41+
std::string str_1 = "baidu.com";
42+
ASSERT_TRUE(re2::RE2::PartialMatch(str_1.c_str(), regex_));
43+
44+
std::string str_2 = "polaris.default.svc.local";
45+
ASSERT_TRUE(re2::RE2::PartialMatch(str_2.c_str(), regex_));
46+
}
47+
48+
} // namespace grpc
49+
} // namespace polaris

test/grpc/grpc_client_test.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
// language governing permissions and limitations under the License.
1616
//
1717

18-
#include "grpc/client.h"
19-
2018
#include <gtest/gtest.h>
19+
#include "grpc/client.h"
20+
#include "grpc/http2.cpp"
2121

2222
#include "mock/fake_net_server.h"
2323
#include "reactor/reactor.h"

0 commit comments

Comments
 (0)