Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize IPv6 used in Endpoint.equivalent #3428

Merged
merged 7 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions cpp/src/Ice/IPEndpointI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ IceInternal::IPEndpointI::equivalent(const EndpointIPtr& endpoint) const
{
return false;
}
return ipEndpointI->type() == type() && ipEndpointI->_host == _host && ipEndpointI->_port == _port;
return ipEndpointI->type() == type() && ipEndpointI->_normalizedHost == _normalizedHost &&
ipEndpointI->_port == _port;
}

size_t
Expand Down Expand Up @@ -306,12 +307,14 @@ IceInternal::IPEndpointI::initWithOptions(vector<string>& args, bool oaEndpoint)
if (_host.empty())
{
const_cast<string&>(_host) = _instance->defaultHost();
const_cast<string&>(_normalizedHost) = normalizeIPv6Address(_host);
}
else if (_host == "*")
{
if (oaEndpoint)
{
const_cast<string&>(_host) = string();
const_cast<string&>(_host) = string{};
const_cast<string&>(_normalizedHost) = string{};
}
else
{
Expand Down Expand Up @@ -348,6 +351,7 @@ IceInternal::IPEndpointI::checkOption(const string& option, const string& argume
"no argument provided for -h option in endpoint '" + endpoint + "'");
}
const_cast<string&>(_host) = argument;
const_cast<string&>(_normalizedHost) = normalizeIPv6Address(_host);
}
else if (option == "-p")
{
Expand Down Expand Up @@ -407,6 +411,7 @@ IceInternal::IPEndpointI::IPEndpointI(
string connectionId)
: _instance(std::move(instance)),
_host(std::move(host)),
_normalizedHost(normalizeIPv6Address(_host)),
_port(port),
_sourceAddr(sourceAddr),
_connectionId(std::move(connectionId))
Expand All @@ -420,6 +425,7 @@ IceInternal::IPEndpointI::IPEndpointI(ProtocolInstancePtr instance, InputStream*
_port(0)
{
s->read(const_cast<string&>(_host), false);
const_cast<string&>(_normalizedHost) = normalizeIPv6Address(_host);
s->read(const_cast<int32_t&>(_port));
}

Expand Down
1 change: 1 addition & 0 deletions cpp/src/Ice/IPEndpointI.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace IceInternal

const ProtocolInstancePtr _instance;
const std::string _host;
const std::string _normalizedHost;
const int _port;
const Address _sourceAddr;
const std::string _connectionId;
Expand Down
21 changes: 21 additions & 0 deletions cpp/src/Ice/Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,27 @@ IceInternal::getNumericAddress(const std::string& address)
}
}

string
IceInternal::normalizeIPv6Address(const string& host)
{
if (host.find(':') != string::npos)
{
struct in6_addr result;
if (inet_pton(AF_INET6, host.c_str(), &result) == 1)
{
// Normalize the address
char buf[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET6, &result, buf, sizeof(buf)) != nullptr)
{
return string{buf};
}
// else conversion to string failed, keep host as is
}
// else it's not a valid IPv6 address keep host as is
}
return host;
}

SyscallException::ErrorCode
IceInternal::getSocketErrno()
{
Expand Down
1 change: 1 addition & 0 deletions cpp/src/Ice/Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ namespace IceInternal
ICE_API Ice::SyscallException::ErrorCode getSocketErrno();

ICE_API Address getNumericAddress(const std::string&);
ICE_API std::string normalizeIPv6Address(const std::string&);

#if defined(ICE_USE_IOCP)
ICE_API void doConnectAsync(SOCKET, const Address&, const Address&, AsyncInfo&);
Expand Down
28 changes: 27 additions & 1 deletion csharp/src/Ice/Internal/IPEndpointI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ protected IPEndpointI(ProtocolInstance instance, string host, int port, EndPoint
{
instance_ = instance;
host_ = host;
_normalizedHost = normalizeHost(host_);
port_ = port;
sourceAddr_ = sourceAddr;
connectionId_ = connectionId;
Expand All @@ -20,6 +21,7 @@ protected IPEndpointI(ProtocolInstance instance)
{
instance_ = instance;
host_ = null;
_normalizedHost = null;
port_ = 0;
sourceAddr_ = null;
connectionId_ = "";
Expand All @@ -29,6 +31,7 @@ protected IPEndpointI(ProtocolInstance instance, Ice.InputStream s)
{
instance_ = instance;
host_ = s.readString();
_normalizedHost = normalizeHost(host_);
port_ = s.readInt();
sourceAddr_ = null;
connectionId_ = "";
Expand Down Expand Up @@ -117,7 +120,7 @@ public override bool equivalent(EndpointI endpoint)
}
IPEndpointI ipEndpointI = (IPEndpointI)endpoint;
return ipEndpointI.type() == type() &&
ipEndpointI.host_.Equals(host_, StringComparison.Ordinal) &&
ipEndpointI._normalizedHost == _normalizedHost &&
ipEndpointI.port_ == port_;
}

Expand Down Expand Up @@ -245,12 +248,14 @@ public virtual void initWithOptions(List<string> args, bool oaEndpoint)
if (host_ == null || host_.Length == 0)
{
host_ = instance_.defaultHost();
_normalizedHost = normalizeHost(host_);
}
else if (host_ == "*")
{
if (oaEndpoint)
{
host_ = "";
_normalizedHost = "";
}
else
{
Expand All @@ -261,6 +266,7 @@ public virtual void initWithOptions(List<string> args, bool oaEndpoint)
if (host_ == null)
{
host_ = "";
_normalizedHost = normalizeHost(host_);
}

if (sourceAddr_ != null)
Expand All @@ -285,6 +291,7 @@ protected override bool checkOption(string option, string argument, string endpo
throw new ParseException($"no argument provided for -h option in endpoint '{endpoint}'");
}
host_ = argument;
_normalizedHost = normalizeHost(host_);
}
else if (option == "-p")
{
Expand Down Expand Up @@ -327,6 +334,23 @@ protected override bool checkOption(string option, string argument, string endpo
return true;
}

private static string normalizeHost(string host)
{
if (host is not null && host.Contains(':', StringComparison.Ordinal))
{
// Could be an IPv6 address that we need to normalize.
try
{
return IPAddress.Parse(host).ToString(); // normalized host
}
catch
{
// Ignore - don't normalize host.
}
}
return host;
}

protected abstract Connector createConnector(EndPoint addr, NetworkProxy proxy);

protected abstract IPEndpointI createEndpoint(string host, int port, string connectionId);
Expand All @@ -336,4 +360,6 @@ protected override bool checkOption(string option, string argument, string endpo
protected int port_;
protected EndPoint sourceAddr_;
protected string connectionId_;
// Set when we set _host; used by the implementation of equivalent.
private string _normalizedHost;
}
Loading