mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 16:12:01 +00:00
Merge pull request #62978 from ClickHouse/fix-grpc-ipv6-crash
gRPC: fix crash on IPv6 peer connection
This commit is contained in:
commit
64de52397e
@ -1,6 +1,7 @@
|
||||
#include "GRPCServer.h"
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <Poco/Net/SocketAddress.h>
|
||||
#if USE_GRPC
|
||||
|
||||
#include <Columns/ColumnString.h>
|
||||
@ -320,8 +321,27 @@ namespace
|
||||
|
||||
Poco::Net::SocketAddress getClientAddress() const
|
||||
{
|
||||
String peer = grpc_context.peer();
|
||||
return Poco::Net::SocketAddress{peer.substr(peer.find(':') + 1)};
|
||||
/// Returns a string like ipv4:127.0.0.1:55930 or ipv6:%5B::1%5D:55930
|
||||
String uri_encoded_peer = grpc_context.peer();
|
||||
|
||||
constexpr const std::string_view ipv4_prefix = "ipv4:";
|
||||
constexpr const std::string_view ipv6_prefix = "ipv6:";
|
||||
|
||||
bool ipv4 = uri_encoded_peer.starts_with(ipv4_prefix);
|
||||
bool ipv6 = uri_encoded_peer.starts_with(ipv6_prefix);
|
||||
|
||||
if (!ipv4 && !ipv6)
|
||||
throw Exception(ErrorCodes::LOGICAL_ERROR, "Expected ipv4 or ipv6 protocol in peer address, got {}", uri_encoded_peer);
|
||||
|
||||
auto prefix = ipv4 ? ipv4_prefix : ipv6_prefix;
|
||||
auto family = ipv4 ? Poco::Net::AddressFamily::Family::IPv4 : Poco::Net::AddressFamily::Family::IPv6;
|
||||
|
||||
uri_encoded_peer= uri_encoded_peer.substr(prefix.length());
|
||||
|
||||
String peer;
|
||||
Poco::URI::decode(uri_encoded_peer, peer);
|
||||
|
||||
return Poco::Net::SocketAddress{family, peer};
|
||||
}
|
||||
|
||||
std::optional<String> getClientHeader(const String & key) const
|
||||
|
@ -27,6 +27,8 @@ if is_arm():
|
||||
|
||||
# Utilities
|
||||
|
||||
IPV6_ADDRESS = "2001:3984:3989::1:1111"
|
||||
|
||||
config_dir = os.path.join(script_dir, "./configs")
|
||||
cluster = ClickHouseCluster(__file__)
|
||||
node = cluster.add_instance(
|
||||
@ -36,12 +38,15 @@ node = cluster.add_instance(
|
||||
env_variables={
|
||||
"TSAN_OPTIONS": "report_atomic_races=0 " + os.getenv("TSAN_OPTIONS", default="")
|
||||
},
|
||||
ipv6_address=IPV6_ADDRESS,
|
||||
)
|
||||
main_channel = None
|
||||
|
||||
|
||||
def create_channel():
|
||||
node_ip_with_grpc_port = cluster.get_instance_ip("node") + ":" + str(GRPC_PORT)
|
||||
def create_channel(hostname=None):
|
||||
if not hostname:
|
||||
hostname = cluster.get_instance_ip("node")
|
||||
node_ip_with_grpc_port = hostname + ":" + str(GRPC_PORT)
|
||||
channel = grpc.insecure_channel(node_ip_with_grpc_port)
|
||||
grpc.channel_ready_future(channel).result(timeout=10)
|
||||
global main_channel
|
||||
@ -204,6 +209,11 @@ def test_select_one():
|
||||
assert query("SELECT 1") == "1\n"
|
||||
|
||||
|
||||
def test_ipv6_select_one():
|
||||
with create_channel(f"[{IPV6_ADDRESS}]") as channel:
|
||||
assert query("SELECT 1", channel=channel) == "1\n"
|
||||
|
||||
|
||||
def test_ordinary_query():
|
||||
assert query("SELECT count() FROM numbers(100)") == "100\n"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user