Skip to content

Commit 32b1804

Browse files
Timothy Redaelli23rd
authored andcommitted
fix IPv6 proxy connectivity
The proxy code path in ConnectionSocket::openConnection() hardcoded socket(AF_INET, ...) before the proxy address was parsed. When the proxy address is an IPv6 literal, the later inet_pton(AF_INET6, ...) fills socketAddress6 and flips ipv6 = true, but the subsequent openConnectionInternal() then calls connect() with sockaddr_in6 on an AF_INET fd and fails with EAFNOSUPPORT. Likewise onHostNameResolved() only tried inet_pton(AF_INET, ...), so proxy hostnames the Android delegate resolved to an IPv6 address also failed. Move socket() creation into openConnectionInternal() so it uses the final ipv6 flag, pre-init socketAddress6.sin6_family/sin6_port in the proxy branch, and derive ipv6 in onHostNameResolved() by cascading inet_pton(AF_INET) -> inet_pton(AF_INET6) on the resolved IP. Ports DrKLO/Telegram PR DrKLO#1959 with light cleanup (hoisted ip.empty() short-circuit, no parameter shadow). Drop on next rebase once upstream merges. Fixes bugs.telegram.org/c/16335, /c/19197, /c/29697, /c/60319.
1 parent 5ec2a64 commit 32b1804

1 file changed

Lines changed: 21 additions & 13 deletions

File tree

TMessagesProj/jni/tgnet/ConnectionSocket.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,6 @@ void ConnectionSocket::openConnection(std::string address, uint16_t port, std::s
496496

497497
if (!proxyAddress->empty()) {
498498
if (LOGS_ENABLED) DEBUG_D("connection(%p) connecting via proxy %s:%d secret[%d]", this, proxyAddress->c_str(), proxyPort, (int) proxySecret->size());
499-
if ((socketFd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
500-
if (LOGS_ENABLED) DEBUG_E("connection(%p) can't create proxy socket", this);
501-
closeSocket(1, -1);
502-
return;
503-
}
504499
uint32_t tempBuffLength;
505500
if (proxySecret->empty()) {
506501
proxyAuthState = 1;
@@ -524,6 +519,8 @@ void ConnectionSocket::openConnection(std::string address, uint16_t port, std::s
524519
}
525520
socketAddress.sin_family = AF_INET;
526521
socketAddress.sin_port = htons(proxyPort);
522+
socketAddress6.sin6_family = AF_INET6;
523+
socketAddress6.sin6_port = htons(proxyPort);
527524
bool continueCheckAddress;
528525
if (inet_pton(AF_INET, proxyAddress->c_str(), &socketAddress.sin_addr.s_addr) != 1) {
529526
continueCheckAddress = true;
@@ -567,11 +564,6 @@ void ConnectionSocket::openConnection(std::string address, uint16_t port, std::s
567564
}
568565
} else {
569566
proxyAuthState = 0;
570-
if ((socketFd = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0)) < 0) {
571-
if (LOGS_ENABLED) DEBUG_E("connection(%p) can't create socket", this);
572-
closeSocket(1, -1);
573-
return;
574-
}
575567
if (ipv6) {
576568
socketAddress6.sin6_family = AF_INET6;
577569
socketAddress6.sin6_port = htons(port);
@@ -613,6 +605,11 @@ void ConnectionSocket::openConnection(std::string address, uint16_t port, std::s
613605
}
614606

615607
void ConnectionSocket::openConnectionInternal(bool ipv6) {
608+
if ((socketFd = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0)) < 0) {
609+
if (LOGS_ENABLED) DEBUG_E("connection(%p) can't create socket", this);
610+
closeSocket(1, -1);
611+
return;
612+
}
616613
int epolFd = ConnectionsManager::getInstance(instanceNum).epolFd;
617614
int yes = 1;
618615
if (setsockopt(socketFd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(int))) {
@@ -1150,16 +1147,27 @@ void ConnectionSocket::setOverrideProxy(std::string address, uint16_t port, std:
11501147
}
11511148

11521149
void ConnectionSocket::onHostNameResolved(std::string host, std::string ip, bool ipv6) {
1153-
ConnectionsManager::getInstance(instanceNum).scheduleTask([&, host, ip, ipv6] {
1150+
(void) ipv6;
1151+
ConnectionsManager::getInstance(instanceNum).scheduleTask([&, host, ip] {
11541152
if (waitingForHostResolve == host) {
11551153
waitingForHostResolve = "";
1156-
if (ip.empty() || inet_pton(AF_INET, ip.c_str(), &socketAddress.sin_addr.s_addr) != 1) {
1154+
if (ip.empty()) {
1155+
if (LOGS_ENABLED) DEBUG_E("connection(%p) can't resolve host %s address via delegate", this, host.c_str());
1156+
closeSocket(1, -1);
1157+
return;
1158+
}
1159+
bool resolvedIpv6;
1160+
if (inet_pton(AF_INET, ip.c_str(), &socketAddress.sin_addr.s_addr) == 1) {
1161+
resolvedIpv6 = false;
1162+
} else if (inet_pton(AF_INET6, ip.c_str(), &socketAddress6.sin6_addr.s6_addr) == 1) {
1163+
resolvedIpv6 = true;
1164+
} else {
11571165
if (LOGS_ENABLED) DEBUG_E("connection(%p) can't resolve host %s address via delegate", this, host.c_str());
11581166
closeSocket(1, -1);
11591167
return;
11601168
}
11611169
if (LOGS_ENABLED) DEBUG_D("connection(%p) resolved host %s address %s via delegate", this, host.c_str(), ip.c_str());
1162-
openConnectionInternal(ipv6);
1170+
openConnectionInternal(resolvedIpv6);
11631171
}
11641172
});
11651173
}

0 commit comments

Comments
 (0)