@@ -940,29 +940,36 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
940 for (int i = 0, size = env->GetArrayLength(endpoints); i < size; i++) {
940 for (int i = 0, size = env->GetArrayLength(endpoints); i < size; i++) {
941 JavaObject endpointObject(env, env->GetObjectArrayElement(endpoints, i));
941 JavaObject endpointObject(env, env->GetObjectArrayElement(endpoints, i));
942 bool isRtc = endpointObject.getBooleanField("isRtc");
942 bool isRtc = endpointObject.getBooleanField("isRtc");
943− if (isRtc) {
943+ const auto ipv4 = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv4"));
944+ const auto ipv6 = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv6"));
945+ // Push each server for both address families (same id), like tdesktop does,
946+ // so relays stay reachable on IPv6-only networks where IPv4 sockets fail.
947+ const auto pushServer = [&](const std::string &host, bool isTurn, bool isTcp) {
944 RtcServer rtcServer;
951 RtcServer rtcServer;
945 rtcServer.id = static_cast<uint8_t>(endpointObject.getIntField("reflectorId"));
952 rtcServer.id = static_cast<uint8_t>(endpointObject.getIntField("reflectorId"));
946− rtcServer.host = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv4"));
953+ rtcServer.host = host;
947 rtcServer.port = static_cast<uint16_t>(endpointObject.getIntField("port"));
954 rtcServer.port = static_cast<uint16_t>(endpointObject.getIntField("port"));
948 rtcServer.login = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("username"));
955 rtcServer.login = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("username"));
949 rtcServer.password = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("password"));
956 rtcServer.password = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("password"));
950− rtcServer.isTurn = endpointObject.getBooleanField("turn");
957+ rtcServer.isTurn = isTurn;
958+ rtcServer.isTcp = isTcp;
951 descriptor.rtcServers.push_back(std::move(rtcServer));
959 descriptor.rtcServers.push_back(std::move(rtcServer));
962+ const auto isTurn = endpointObject.getBooleanField("turn");
963+ pushServer(ipv4, isTurn, false);
964+ pushServer(ipv6, isTurn, false);
953− RtcServer rtcServer;
954− rtcServer.id = static_cast<uint8_t>(endpointObject.getIntField("reflectorId"));
955− rtcServer.host = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv4"));
956− rtcServer.port = static_cast<uint16_t>(endpointObject.getIntField("port"));
957− rtcServer.login = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("username"));
958− rtcServer.password = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("password"));
959− rtcServer.isTurn = true;
960− rtcServer.isTcp = endpointObject.getBooleanField("tcp");
966+ const auto isTcp = endpointObject.getBooleanField("tcp");
961− descriptor.rtcServers.push_back(std::move(rtcServer));
967+ pushServer(ipv4, true, isTcp);
968+ pushServer(ipv6, true, isTcp);
963 Endpoint endpoint;
970 Endpoint endpoint;
964 endpoint.endpointId = endpointObject.getLongField("id");
971 endpoint.endpointId = endpointObject.getLongField("id");
965− endpoint.host = EndpointHost{tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv4")), tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv6"))};
972+ endpoint.host = EndpointHost{ipv4, ipv6};
966 endpoint.port = static_cast<uint16_t>(endpointObject.getIntField("port"));
973 endpoint.port = static_cast<uint16_t>(endpointObject.getIntField("port"));
967 endpoint.type = parseEndpointType(env, endpointObject.getIntField("type"));
974 endpoint.type = parseEndpointType(env, endpointObject.getIntField("type"));
968 jbyteArray peerTag = endpointObject.getByteArrayField("peerTag");
975 jbyteArray peerTag = endpointObject.getByteArrayField("peerTag");