mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 08:02:02 +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 "GRPCServer.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <Poco/Net/SocketAddress.h>
|
||||||
#if USE_GRPC
|
#if USE_GRPC
|
||||||
|
|
||||||
#include <Columns/ColumnString.h>
|
#include <Columns/ColumnString.h>
|
||||||
@ -320,8 +321,27 @@ namespace
|
|||||||
|
|
||||||
Poco::Net::SocketAddress getClientAddress() const
|
Poco::Net::SocketAddress getClientAddress() const
|
||||||
{
|
{
|
||||||
String peer = grpc_context.peer();
|
/// Returns a string like ipv4:127.0.0.1:55930 or ipv6:%5B::1%5D:55930
|
||||||
return Poco::Net::SocketAddress{peer.substr(peer.find(':') + 1)};
|
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
|
std::optional<String> getClientHeader(const String & key) const
|
||||||
|
@ -27,6 +27,8 @@ if is_arm():
|
|||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
|
|
||||||
|
IPV6_ADDRESS = "2001:3984:3989::1:1111"
|
||||||
|
|
||||||
config_dir = os.path.join(script_dir, "./configs")
|
config_dir = os.path.join(script_dir, "./configs")
|
||||||
cluster = ClickHouseCluster(__file__)
|
cluster = ClickHouseCluster(__file__)
|
||||||
node = cluster.add_instance(
|
node = cluster.add_instance(
|
||||||
@ -36,12 +38,15 @@ node = cluster.add_instance(
|
|||||||
env_variables={
|
env_variables={
|
||||||
"TSAN_OPTIONS": "report_atomic_races=0 " + os.getenv("TSAN_OPTIONS", default="")
|
"TSAN_OPTIONS": "report_atomic_races=0 " + os.getenv("TSAN_OPTIONS", default="")
|
||||||
},
|
},
|
||||||
|
ipv6_address=IPV6_ADDRESS,
|
||||||
)
|
)
|
||||||
main_channel = None
|
main_channel = None
|
||||||
|
|
||||||
|
|
||||||
def create_channel():
|
def create_channel(hostname=None):
|
||||||
node_ip_with_grpc_port = cluster.get_instance_ip("node") + ":" + str(GRPC_PORT)
|
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)
|
channel = grpc.insecure_channel(node_ip_with_grpc_port)
|
||||||
grpc.channel_ready_future(channel).result(timeout=10)
|
grpc.channel_ready_future(channel).result(timeout=10)
|
||||||
global main_channel
|
global main_channel
|
||||||
@ -204,6 +209,11 @@ def test_select_one():
|
|||||||
assert query("SELECT 1") == "1\n"
|
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():
|
def test_ordinary_query():
|
||||||
assert query("SELECT count() FROM numbers(100)") == "100\n"
|
assert query("SELECT count() FROM numbers(100)") == "100\n"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user