From 128aba0397fcf5847da81d85974428d5c5b5e04a Mon Sep 17 00:00:00 2001 From: springliao Date: Thu, 24 Feb 2022 19:48:48 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- polaris/grpc/http2.cpp | 45 +++++++++++++++++++++++++++++----- test/grpc/grpc_client_test.cpp | 4 +-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/polaris/grpc/http2.cpp b/polaris/grpc/http2.cpp index 12bf7cf..cc207cb 100644 --- a/polaris/grpc/http2.cpp +++ b/polaris/grpc/http2.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -347,6 +348,34 @@ Http2Client::~Http2Client() { } } +// TryLookup 尝试进行 host 解析 +// step 1. 判断当前的 host 是否是域名 +// step 2. 不是域名,则直接返回 +// step 3. 是域名,进行一次域名解析,然后从返回的IPList中随机选取一个IP进行链接 +static std::string TryLookup(const std::string& address) { + POLARIS_LOG(LOG_INFO, "try lookup address=[%s]", address.c_str()); + struct hostent* host = gethostbyname(address.c_str()); + if (!host) { + POLARIS_LOG(LOG_ERROR, "try lookup address=[%s] error, maybe address is ip", address.c_str()); + return address; + } + + POLARIS_LOG(LOG_TRACE, "address=[%s] type: [%s]", address.c_str(), + (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6"); + + int total = sizeof(host->h_addr_list); + if (total < 1) { + return address; + } + + std::string target_address = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]); + + POLARIS_LOG(LOG_TRACE, "address=[%s] select one by random [%s]", address.c_str(), + target_address.c_str()); + + return target_address; +} + // 向指定地址发起非阻塞连接 static int TryConnectTo(const std::string& host, int port, int& fd) { if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { @@ -368,6 +397,7 @@ static int TryConnectTo(const std::string& host, int port, int& fd) { bzero(static_cast(&addr), sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(port); + if (inet_pton(AF_INET, host.c_str(), &addr.sin_addr) != 1) { return -1; } @@ -375,23 +405,26 @@ static int TryConnectTo(const std::string& host, int port, int& fd) { } bool Http2Client::ConnectTo(const std::string& host, int port) { + std::string server_ip = TryLookup(host); + POLARIS_ASSERT(state_ == kConnectionInit); - GRPC_LOG(LOG_INFO, "try to nonblocking connect to server[%s:%d]", host.c_str(), port); + GRPC_LOG(LOG_INFO, "try to nonblocking connect to server[%s:%d]", server_ip.c_str(), port); int retcode = TryConnectTo(host, port, fd_); if (retcode == 0) { // 异步连接立即成功了,一般本地连接才有可能发生。 - GRPC_LOG(LOG_TRACE, "nonblocking connect to service[%s:%d] success immediately", host.c_str(), - port); + GRPC_LOG(LOG_TRACE, "nonblocking connect to service[%s:%d] success immediately", + server_ip.c_str(), port); state_ = kConnectionConnecting; // 即使立刻连接成功了也放在epoll写事件中去更新状态 } else if (errno == EINPROGRESS) { // tcp connect return -1 state_ = kConnectionConnecting; GRPC_LOG(LOG_TRACE, "nonblocking connect to server[%s:%d] with connection in progress", - host.c_str(), port); + server_ip.c_str(), port); retcode = 0; } else { state_ = kConnectionDisconnected; - GRPC_LOG(LOG_ERROR, "nonblocking connect to %s:%d with error: %d", host.c_str(), port, errno); + GRPC_LOG(LOG_ERROR, "nonblocking connect to %s:%d with error: %d", server_ip.c_str(), port, + errno); } - current_server_ = host + ":" + StringUtils::TypeToStr(port); + current_server_ = server_ip + ":" + StringUtils::TypeToStr(port); return retcode == 0; } diff --git a/test/grpc/grpc_client_test.cpp b/test/grpc/grpc_client_test.cpp index fc7ab29..038530a 100644 --- a/test/grpc/grpc_client_test.cpp +++ b/test/grpc/grpc_client_test.cpp @@ -15,9 +15,9 @@ // language governing permissions and limitations under the License. // -#include "grpc/client.h" - #include +#include "grpc/client.h" +#include "grpc/http2.cpp" #include "mock/fake_net_server.h" #include "reactor/reactor.h" From e3711aae6d81b6b23a240da403c63c563f534789 Mon Sep 17 00:00:00 2001 From: springliao Date: Thu, 24 Feb 2022 19:51:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20=E8=B0=83=E6=95=B4TryLookup?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E7=AD=89=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- polaris/grpc/http2.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/polaris/grpc/http2.cpp b/polaris/grpc/http2.cpp index cc207cb..47515b1 100644 --- a/polaris/grpc/http2.cpp +++ b/polaris/grpc/http2.cpp @@ -353,15 +353,15 @@ Http2Client::~Http2Client() { // step 2. 不是域名,则直接返回 // step 3. 是域名,进行一次域名解析,然后从返回的IPList中随机选取一个IP进行链接 static std::string TryLookup(const std::string& address) { - POLARIS_LOG(LOG_INFO, "try lookup address=[%s]", address.c_str()); + GRPC_LOG(LOG_DEBUG, "try lookup address=[%s]", address.c_str()); struct hostent* host = gethostbyname(address.c_str()); if (!host) { - POLARIS_LOG(LOG_ERROR, "try lookup address=[%s] error, maybe address is ip", address.c_str()); + GRPC_LOG(LOG_ERROR, "try lookup address=[%s] error, maybe address is ip", address.c_str()); return address; } - POLARIS_LOG(LOG_TRACE, "address=[%s] type: [%s]", address.c_str(), - (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6"); + GRPC_LOG(LOG_DEBUG, "address=[%s] type: [%s]", address.c_str(), + (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6"); int total = sizeof(host->h_addr_list); if (total < 1) { @@ -370,8 +370,8 @@ static std::string TryLookup(const std::string& address) { std::string target_address = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]); - POLARIS_LOG(LOG_TRACE, "address=[%s] select one by random [%s]", address.c_str(), - target_address.c_str()); + GRPC_LOG(LOG_TRACE, "address=[%s] select one by random [%s]", address.c_str(), + target_address.c_str()); return target_address; } From 2e54e9516dee7f1aaf590fb575eed343c59d9068 Mon Sep 17 00:00:00 2001 From: springliao Date: Thu, 10 Mar 2022 19:29:33 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=88=A4=E6=96=AD=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E6=98=AF=E5=9F=9F=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- polaris/grpc/http2.cpp | 12 ++++++++++ test/grpc/domain_test.cpp | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 test/grpc/domain_test.cpp diff --git a/polaris/grpc/http2.cpp b/polaris/grpc/http2.cpp index 47515b1..1388807 100644 --- a/polaris/grpc/http2.cpp +++ b/polaris/grpc/http2.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -354,6 +355,17 @@ Http2Client::~Http2Client() { // step 3. 是域名,进行一次域名解析,然后从返回的IPList中随机选取一个IP进行链接 static std::string TryLookup(const std::string& address) { GRPC_LOG(LOG_DEBUG, "try lookup address=[%s]", address.c_str()); + + std::string domain_reg = + "^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?$"; + re2::RE2 domain(domain_reg.c_str()); + bool is_domain = domain.ok() && re2::RE2::PartialMatch(address.c_str(), domain); + + // 使用正则表达式判断是否是域名, 不是域名,直接返回 address + if (!is_domain) { + return address; + } + struct hostent* host = gethostbyname(address.c_str()); if (!host) { GRPC_LOG(LOG_ERROR, "try lookup address=[%s] error, maybe address is ip", address.c_str()); diff --git a/test/grpc/domain_test.cpp b/test/grpc/domain_test.cpp new file mode 100644 index 0000000..2fd0632 --- /dev/null +++ b/test/grpc/domain_test.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use +// this file +// except in compliance with the License. You may obtain a copy of the License +// at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software +// distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific +// language governing permissions and limitations under the License. +// + +#include "grpc/buffer.h" + +#include +#include +#include +#include + +namespace polaris { +namespace grpc { + +class GrpcDomainTest : public ::testing::Test { +protected: + virtual void SetUp() {} + + virtual void TearDown() {} + +protected: +}; + +TEST_F(GrpcDomainTest, DomainJudge) { + std::string domain_reg = "^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?$"; + re2::RE2 regex_(domain_reg.c_str()); + ASSERT_TRUE((regex_).ok()); + std::string str_1 = "baidu.com"; + ASSERT_TRUE(re2::RE2::PartialMatch(str_1.c_str(), regex_)); + + std::string str_2 = "polaris.default.svc.local"; + ASSERT_TRUE(re2::RE2::PartialMatch(str_2.c_str(), regex_)); +} + +} // namespace grpc +} // namespace polaris \ No newline at end of file