diff --git a/VoIPController.cpp b/VoIPController.cpp index f60a024..f1c0370 100644 --- a/VoIPController.cpp +++ b/VoIPController.cpp @@ -1859,7 +1859,6 @@ void VoIPController::RunRecvThread() } while (runReceiver) { - if (proxyProtocol == PROXY_SOCKS5 && needReInitUdpProxy) { InitUDPProxy(); diff --git a/os/posix/NetworkSocketPosix.cpp b/os/posix/NetworkSocketPosix.cpp index 79aa530..d41053b 100644 --- a/os/posix/NetworkSocketPosix.cpp +++ b/os/posix/NetworkSocketPosix.cpp @@ -23,7 +23,7 @@ #include #include -extern JavaVM* sharedJVM; +extern JavaVM *sharedJVM; extern jclass jniUtilitiesClass; #else #include @@ -31,44 +31,50 @@ extern jclass jniUtilitiesClass; using namespace tgvoip; +NetworkSocketPosix::NetworkSocketPosix(NetworkProtocol protocol) : NetworkSocket(protocol) +{ + needUpdateNat64Prefix = true; + nat64Present = false; + switchToV6at = 0; + isV4Available = false; + fd = -1; + closing = false; -NetworkSocketPosix::NetworkSocketPosix(NetworkProtocol protocol) : NetworkSocket(protocol){ - needUpdateNat64Prefix=true; - nat64Present=false; - switchToV6at=0; - isV4Available=false; - fd=-1; - closing=false; + tcpConnectedPort = 0; - tcpConnectedPort=0; - - if(protocol==NetworkProtocol::TCP) - timeout=10.0; - lastSuccessfulOperationTime=VoIPController::GetCurrentTime(); + if (protocol == NetworkProtocol::TCP) + timeout = 10.0; + lastSuccessfulOperationTime = VoIPController::GetCurrentTime(); } -NetworkSocketPosix::~NetworkSocketPosix(){ - if(fd>=0){ +NetworkSocketPosix::~NetworkSocketPosix() +{ + if (fd >= 0) + { Close(); } } -void NetworkSocketPosix::SetMaxPriority(){ +void NetworkSocketPosix::SetMaxPriority() +{ #ifdef __APPLE__ - int prio=NET_SERVICE_TYPE_VO; - int res=setsockopt(fd, SOL_SOCKET, SO_NET_SERVICE_TYPE, &prio, sizeof(prio)); - if(res<0){ + int prio = NET_SERVICE_TYPE_VO; + int res = setsockopt(fd, SOL_SOCKET, SO_NET_SERVICE_TYPE, &prio, sizeof(prio)); + if (res < 0) + { LOGE("error setting darwin-specific net priority: %d / %s", errno, strerror(errno)); } #elif defined(__linux__) - int prio=6; - int res=setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)); - if(res<0){ + int prio = 6; + int res = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)); + if (res < 0) + { LOGE("error setting priority: %d / %s", errno, strerror(errno)); } - prio=46 << 2; - res=setsockopt(fd, SOL_IP, IP_TOS, &prio, sizeof(prio)); - if(res<0){ + prio = 46 << 2; + res = setsockopt(fd, SOL_IP, IP_TOS, &prio, sizeof(prio)); + if (res < 0) + { LOGE("error setting ip tos: %d / %s", errno, strerror(errno)); } #else @@ -76,353 +82,434 @@ void NetworkSocketPosix::SetMaxPriority(){ #endif } -void NetworkSocketPosix::Send(NetworkPacket packet){ - if(packet.data.IsEmpty() || (protocol==NetworkProtocol::UDP && packet.port==0)){ +void NetworkSocketPosix::Send(NetworkPacket packet) +{ + if (packet.data.IsEmpty() || (protocol == NetworkProtocol::UDP && packet.port == 0)) + { LOGW("tried to send null packet"); return; } int res; - if(protocol==NetworkProtocol::UDP){ + if (protocol == NetworkProtocol::UDP) + { sockaddr_in6 addr; - if(!packet.address.isIPv6){ - if(needUpdateNat64Prefix && !isV4Available && VoIPController::GetCurrentTime()>switchToV6at && switchToV6at!=0){ + if (!packet.address.isIPv6) + { + if (needUpdateNat64Prefix && !isV4Available && VoIPController::GetCurrentTime() > switchToV6at && switchToV6at != 0) + { LOGV("Updating NAT64 prefix"); - nat64Present=false; + nat64Present = false; addrinfo *addr0; - int res=getaddrinfo("ipv4only.arpa", NULL, NULL, &addr0); - if(res!=0){ + int res = getaddrinfo("ipv4only.arpa", NULL, NULL, &addr0); + if (res != 0) + { LOGW("Error updating NAT64 prefix: %d / %s", res, gai_strerror(res)); - }else{ + } + else + { addrinfo *addrPtr; - unsigned char *addr170=NULL; - unsigned char *addr171=NULL; - for(addrPtr=addr0; addrPtr; addrPtr=addrPtr->ai_next){ - if(addrPtr->ai_family==AF_INET6){ - sockaddr_in6 *translatedAddr=(sockaddr_in6 *) addrPtr->ai_addr; - uint32_t v4part=*((uint32_t *) &translatedAddr->sin6_addr.s6_addr[12]); - if(v4part==0xAA0000C0 && !addr170){ - addr170=translatedAddr->sin6_addr.s6_addr; + unsigned char *addr170 = NULL; + unsigned char *addr171 = NULL; + for (addrPtr = addr0; addrPtr; addrPtr = addrPtr->ai_next) + { + if (addrPtr->ai_family == AF_INET6) + { + sockaddr_in6 *translatedAddr = (sockaddr_in6 *)addrPtr->ai_addr; + uint32_t v4part = *((uint32_t *)&translatedAddr->sin6_addr.s6_addr[12]); + if (v4part == 0xAA0000C0 && !addr170) + { + addr170 = translatedAddr->sin6_addr.s6_addr; } - if(v4part==0xAB0000C0 && !addr171){ - addr171=translatedAddr->sin6_addr.s6_addr; + if (v4part == 0xAB0000C0 && !addr171) + { + addr171 = translatedAddr->sin6_addr.s6_addr; } char buf[INET6_ADDRSTRLEN]; LOGV("Got translated address: %s", inet_ntop(AF_INET6, &translatedAddr->sin6_addr, buf, sizeof(buf))); } } - if(addr170 && addr171 && memcmp(addr170, addr171, 12)==0){ - nat64Present=true; + if (addr170 && addr171 && memcmp(addr170, addr171, 12) == 0) + { + nat64Present = true; memcpy(nat64Prefix, addr170, 12); char buf[INET6_ADDRSTRLEN]; LOGV("Found nat64 prefix from %s", inet_ntop(AF_INET6, addr170, buf, sizeof(buf))); - }else{ + } + else + { LOGV("Didn't find nat64"); } freeaddrinfo(addr0); } - needUpdateNat64Prefix=false; + needUpdateNat64Prefix = false; } memset(&addr, 0, sizeof(sockaddr_in6)); - addr.sin6_family=AF_INET6; - *((uint32_t *) &addr.sin6_addr.s6_addr[12])=packet.address.addr.ipv4; - if(nat64Present) + addr.sin6_family = AF_INET6; + *((uint32_t *)&addr.sin6_addr.s6_addr[12]) = packet.address.addr.ipv4; + if (nat64Present) memcpy(addr.sin6_addr.s6_addr, nat64Prefix, 12); else - addr.sin6_addr.s6_addr[11]=addr.sin6_addr.s6_addr[10]=0xFF; - - }else{ + addr.sin6_addr.s6_addr[11] = addr.sin6_addr.s6_addr[10] = 0xFF; + } + else + { memcpy(addr.sin6_addr.s6_addr, packet.address.addr.ipv6, 16); - addr.sin6_family=AF_INET6; + addr.sin6_family = AF_INET6; } - addr.sin6_port=htons(packet.port); - res=(int)sendto(fd, *packet.data, packet.data.Length(), 0, (const sockaddr *) &addr, sizeof(addr)); - }else{ - res=(int)send(fd, *packet.data, packet.data.Length(), 0); + addr.sin6_port = htons(packet.port); + res = (int)sendto(fd, *packet.data, packet.data.Length(), 0, (const sockaddr *)&addr, sizeof(addr)); } - if(res<=0){ - if(errno==EAGAIN || errno==EWOULDBLOCK){ - if(!pendingOutgoingPacket.IsEmpty()){ + else + { + res = (int)send(fd, *packet.data, packet.data.Length(), 0); + } + if (res <= 0) + { + if (errno == EAGAIN || errno == EWOULDBLOCK) + { + if (!pendingOutgoingPacket.IsEmpty()) + { LOGE("Got EAGAIN but there's already a pending packet"); - failed=true; - }else{ - LOGV("Socket %d not ready to send", (int)fd); - pendingOutgoingPacket=std::move(packet); - readyToSend=false; + failed = true; + } + else + { + LOGV("Socket %d not ready to send", (int)fd); + pendingOutgoingPacket = std::move(packet); + readyToSend = false; } - }else{ - LOGE("error sending: %d / %s", errno, strerror(errno)); - if(errno==ENETUNREACH && !isV4Available && VoIPController::GetCurrentTime()0){ - if(!isV4Available && IN6_IS_ADDR_V4MAPPED(&srcAddr.sin6_addr)){ - isV4Available=true; + ssize_t len = recvfrom(fd, *recvBuffer, std::min(recvBuffer.Length(), maxLen), 0, (sockaddr *)&srcAddr, (socklen_t *)&addrLen); + if (len > 0) + { + if (!isV4Available && IN6_IS_ADDR_V4MAPPED(&srcAddr.sin6_addr)) + { + isV4Available = true; LOGI("Detected IPv4 connectivity, will not try IPv6"); } - NetworkAddress addr=NetworkAddress::Empty(); - if(IN6_IS_ADDR_V4MAPPED(&srcAddr.sin6_addr) || (nat64Present && memcmp(nat64Prefix, srcAddr.sin6_addr.s6_addr, 12)==0)){ - in_addr v4addr=*((in_addr *) &srcAddr.sin6_addr.s6_addr[12]); - addr=NetworkAddress::IPv4(v4addr.s_addr); - }else{ - addr=NetworkAddress::IPv6(srcAddr.sin6_addr.s6_addr); + NetworkAddress addr = NetworkAddress::Empty(); + if (IN6_IS_ADDR_V4MAPPED(&srcAddr.sin6_addr) || (nat64Present && memcmp(nat64Prefix, srcAddr.sin6_addr.s6_addr, 12) == 0)) + { + in_addr v4addr = *((in_addr *)&srcAddr.sin6_addr.s6_addr[12]); + addr = NetworkAddress::IPv4(v4addr.s_addr); + } + else + { + addr = NetworkAddress::IPv6(srcAddr.sin6_addr.s6_addr); } return NetworkPacket{ Buffer::CopyOf(recvBuffer, 0, (size_t)len), addr, ntohs(srcAddr.sin6_port), - NetworkProtocol::UDP - }; - }else{ + NetworkProtocol::UDP}; + } + else + { LOGE("error receiving %d / %s", errno, strerror(errno)); return NetworkPacket::Empty(); } //LOGV("Received %d bytes from %s:%d at %.5lf", len, inet_ntoa(srcAddr.sin_addr), ntohs(srcAddr.sin_port), GetCurrentTime()); - }else if(protocol==NetworkProtocol::TCP){ - ssize_t res=(int)recv(fd, *recvBuffer, std::min(recvBuffer.Length(), maxLen), 0); - if(res<=0){ + } + else if (protocol == NetworkProtocol::TCP) + { + ssize_t res = (int)recv(fd, *recvBuffer, std::min(recvBuffer.Length(), maxLen), 0); + if (res <= 0) + { LOGE("Error receiving from TCP socket: %d / %s", errno, strerror(errno)); - failed=true; + failed = true; return NetworkPacket::Empty(); - }else{ + } + else + { return NetworkPacket{ - Buffer::CopyOf(recvBuffer, 0, (size_t)res), - tcpConnectedAddress, - tcpConnectedPort, - NetworkProtocol::TCP - }; + Buffer::CopyOf(recvBuffer, 0, (size_t)res), + tcpConnectedAddress, + tcpConnectedPort, + NetworkProtocol::TCP}; } } return NetworkPacket::Empty(); } -void NetworkSocketPosix::Open(){ - if(protocol!=NetworkProtocol::UDP) +void NetworkSocketPosix::Open() +{ + if (protocol != NetworkProtocol::UDP) return; - fd=socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if(fd<0){ + fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) + { LOGE("error creating socket: %d / %s", errno, strerror(errno)); - failed=true; + failed = true; return; } - int flag=0; - int res=setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)); - if(res<0){ + int flag = 0; + int res = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)); + if (res < 0) + { LOGE("error enabling dual stack socket: %d / %s", errno, strerror(errno)); - failed=true; + failed = true; return; } SetMaxPriority(); - if(fcntl(fd, F_SETFL, O_NONBLOCK)==-1){ + if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) + { LOGE("error setting nonblock flag on socket: %d / %s", errno, strerror(errno)); - failed=true; + failed = true; return; } #ifdef __APPLE__ - flag=1; + flag = 1; setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag)); #endif - int tries=0; + int tries = 0; sockaddr_in6 addr; //addr.sin6_addr.s_addr=0; memset(&addr, 0, sizeof(sockaddr_in6)); //addr.sin6_len=sizeof(sa_family_t); - addr.sin6_family=AF_INET6; - for(tries=0;tries<10;tries++){ - addr.sin6_port=htons(GenerateLocalPort()); - res=::bind(fd, (sockaddr *) &addr, sizeof(sockaddr_in6)); + addr.sin6_family = AF_INET6; + for (tries = 0; tries < 10; tries++) + { + addr.sin6_port = htons(GenerateLocalPort()); + res = ::bind(fd, (sockaddr *)&addr, sizeof(sockaddr_in6)); LOGV("trying bind to port %u", ntohs(addr.sin6_port)); - if(res<0){ + if (res < 0) + { LOGE("error binding to port %u: %d / %s", ntohs(addr.sin6_port), errno, strerror(errno)); - }else{ + } + else + { break; } } - if(tries==10){ - addr.sin6_port=0; - res=::bind(fd, (sockaddr *) &addr, sizeof(sockaddr_in6)); - if(res<0){ + if (tries == 10) + { + addr.sin6_port = 0; + res = ::bind(fd, (sockaddr *)&addr, sizeof(sockaddr_in6)); + if (res < 0) + { LOGE("error binding to port %u: %d / %s", ntohs(addr.sin6_port), errno, strerror(errno)); //SetState(STATE_FAILED); - failed=true; + failed = true; return; } } - size_t addrLen=sizeof(sockaddr_in6); - getsockname(fd, (sockaddr*)&addr, (socklen_t*) &addrLen); + size_t addrLen = sizeof(sockaddr_in6); + getsockname(fd, (sockaddr *)&addr, (socklen_t *)&addrLen); LOGD("Bound to local UDP port %u", ntohs(addr.sin6_port)); - needUpdateNat64Prefix=true; - isV4Available=false; - switchToV6at=VoIPController::GetCurrentTime()+ipv6Timeout; + needUpdateNat64Prefix = true; + isV4Available = false; + switchToV6at = VoIPController::GetCurrentTime() + ipv6Timeout; } -void NetworkSocketPosix::Close(){ - if(closing){ +void NetworkSocketPosix::Close() +{ + if (closing) + { return; } - closing=true; - failed=true; - - if (fd>=0) { - shutdown(fd, SHUT_RDWR); - close(fd); - fd=-1; - } + closing = true; + failed = true; + + if (fd >= 0) + { + shutdown(fd, SHUT_RDWR); + close(fd); + fd = -1; + } } -void NetworkSocketPosix::Connect(const NetworkAddress address, uint16_t port){ - struct sockaddr_in v4={0}; - struct sockaddr_in6 v6={0}; - struct sockaddr* addr=NULL; - size_t addrLen=0; - if(!address.isIPv6){ - v4.sin_family=AF_INET; - v4.sin_addr.s_addr=address.addr.ipv4; - v4.sin_port=htons(port); - addr=reinterpret_cast(&v4); - addrLen=sizeof(v4); - }else{ - v6.sin6_family=AF_INET6; +void NetworkSocketPosix::Connect(const NetworkAddress address, uint16_t port) +{ + struct sockaddr_in v4 = {0}; + struct sockaddr_in6 v6 = {0}; + struct sockaddr *addr = NULL; + size_t addrLen = 0; + if (!address.isIPv6) + { + v4.sin_family = AF_INET; + v4.sin_addr.s_addr = address.addr.ipv4; + v4.sin_port = htons(port); + addr = reinterpret_cast(&v4); + addrLen = sizeof(v4); + } + else + { + v6.sin6_family = AF_INET6; memcpy(v6.sin6_addr.s6_addr, address.addr.ipv6, 16); - v6.sin6_flowinfo=0; - v6.sin6_scope_id=0; - v6.sin6_port=htons(port); - addr=reinterpret_cast(&v6); - addrLen=sizeof(v6); + v6.sin6_flowinfo = 0; + v6.sin6_scope_id = 0; + v6.sin6_port = htons(port); + addr = reinterpret_cast(&v6); + addrLen = sizeof(v6); } - fd=socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP); - if(fd<0){ + fd = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) + { LOGE("Error creating TCP socket: %d / %s", errno, strerror(errno)); - failed=true; + failed = true; return; } - int opt=1; + int opt = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); timeval timeout; - timeout.tv_sec=5; - timeout.tv_usec=0; + timeout.tv_sec = 5; + timeout.tv_usec = 0; setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); - timeout.tv_sec=60; + timeout.tv_sec = 60; setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); fcntl(fd, F_SETFL, O_NONBLOCK); - int res=(int)connect(fd, (const sockaddr*) addr, (socklen_t)addrLen); - if(res!=0 && errno!=EINVAL && errno!=EINPROGRESS){ + int res = (int)connect(fd, (const sockaddr *)addr, (socklen_t)addrLen); + if (res != 0 && errno != EINVAL && errno != EINPROGRESS) + { LOGW("error connecting TCP socket to %s:%u: %d / %s; %d / %s", address.ToString().c_str(), port, res, strerror(res), errno, strerror(errno)); close(fd); - failed=true; + failed = true; return; } - tcpConnectedAddress=address; - tcpConnectedPort=port; + tcpConnectedAddress = address; + tcpConnectedPort = port; LOGI("successfully connected to %s:%d", tcpConnectedAddress.ToString().c_str(), tcpConnectedPort); } -void NetworkSocketPosix::OnActiveInterfaceChanged(){ - needUpdateNat64Prefix=true; - isV4Available=false; - switchToV6at=VoIPController::GetCurrentTime()+ipv6Timeout; +void NetworkSocketPosix::OnActiveInterfaceChanged() +{ + needUpdateNat64Prefix = true; + isV4Available = false; + switchToV6at = VoIPController::GetCurrentTime() + ipv6Timeout; } -std::string NetworkSocketPosix::GetLocalInterfaceInfo(NetworkAddress *v4addr, NetworkAddress *v6addr){ - std::string name=""; +std::string NetworkSocketPosix::GetLocalInterfaceInfo(NetworkAddress *v4addr, NetworkAddress *v6addr) +{ + std::string name = ""; // Android doesn't support ifaddrs #ifdef __ANDROID__ - JNIEnv *env=NULL; - bool didAttach=false; - sharedJVM->GetEnv((void **) &env, JNI_VERSION_1_6); - if(!env){ + JNIEnv *env = NULL; + bool didAttach = false; + sharedJVM->GetEnv((void **)&env, JNI_VERSION_1_6); + if (!env) + { sharedJVM->AttachCurrentThread(&env, NULL); - didAttach=true; + didAttach = true; } - jmethodID getLocalNetworkAddressesAndInterfaceNameMethod=env->GetStaticMethodID(jniUtilitiesClass, "getLocalNetworkAddressesAndInterfaceName", "()[Ljava/lang/String;"); - jobjectArray jinfo=(jobjectArray) env->CallStaticObjectMethod(jniUtilitiesClass, getLocalNetworkAddressesAndInterfaceNameMethod); - if(jinfo){ - jstring jitfName=static_cast(env->GetObjectArrayElement(jinfo, 0)); - jstring jipv4=static_cast(env->GetObjectArrayElement(jinfo, 1)); - jstring jipv6=static_cast(env->GetObjectArrayElement(jinfo, 2)); - if(jitfName){ - const char *itfchars=env->GetStringUTFChars(jitfName, NULL); - name=std::string(itfchars); + jmethodID getLocalNetworkAddressesAndInterfaceNameMethod = env->GetStaticMethodID(jniUtilitiesClass, "getLocalNetworkAddressesAndInterfaceName", "()[Ljava/lang/String;"); + jobjectArray jinfo = (jobjectArray)env->CallStaticObjectMethod(jniUtilitiesClass, getLocalNetworkAddressesAndInterfaceNameMethod); + if (jinfo) + { + jstring jitfName = static_cast(env->GetObjectArrayElement(jinfo, 0)); + jstring jipv4 = static_cast(env->GetObjectArrayElement(jinfo, 1)); + jstring jipv6 = static_cast(env->GetObjectArrayElement(jinfo, 2)); + if (jitfName) + { + const char *itfchars = env->GetStringUTFChars(jitfName, NULL); + name = std::string(itfchars); env->ReleaseStringUTFChars(jitfName, itfchars); } - if(v4addr && jipv4){ - const char* ipchars=env->GetStringUTFChars(jipv4, NULL); - *v4addr=NetworkAddress::IPv4(ipchars); + if (v4addr && jipv4) + { + const char *ipchars = env->GetStringUTFChars(jipv4, NULL); + *v4addr = NetworkAddress::IPv4(ipchars); env->ReleaseStringUTFChars(jipv4, ipchars); } - if(v6addr && jipv6){ - const char* ipchars=env->GetStringUTFChars(jipv6, NULL); - *v6addr=NetworkAddress::IPv6(ipchars); + if (v6addr && jipv6) + { + const char *ipchars = env->GetStringUTFChars(jipv6, NULL); + *v6addr = NetworkAddress::IPv6(ipchars); env->ReleaseStringUTFChars(jipv6, ipchars); } - }else{ + } + else + { LOGW("Failed to get android network interface info"); } - if(didAttach){ + if (didAttach) + { sharedJVM->DetachCurrentThread(); } #else - struct ifaddrs* interfaces; - if(!getifaddrs(&interfaces)){ - struct ifaddrs* interface; - for(interface=interfaces;interface;interface=interface->ifa_next){ - if(!(interface->ifa_flags & IFF_UP) || !(interface->ifa_flags & IFF_RUNNING) || (interface->ifa_flags & IFF_LOOPBACK)) + struct ifaddrs *interfaces; + if (!getifaddrs(&interfaces)) + { + struct ifaddrs *interface; + for (interface = interfaces; interface; interface = interface->ifa_next) + { + if (!(interface->ifa_flags & IFF_UP) || !(interface->ifa_flags & IFF_RUNNING) || (interface->ifa_flags & IFF_LOOPBACK)) continue; - const struct sockaddr_in* addr=(const struct sockaddr_in*)interface->ifa_addr; - if(addr){ - if(addr->sin_family==AF_INET){ - if((ntohl(addr->sin_addr.s_addr) & 0xFFFF0000)==0xA9FE0000) + const struct sockaddr_in *addr = (const struct sockaddr_in *)interface->ifa_addr; + if (addr) + { + if (addr->sin_family == AF_INET) + { + if ((ntohl(addr->sin_addr.s_addr) & 0xFFFF0000) == 0xA9FE0000) continue; - if(v4addr) - *v4addr=NetworkAddress::IPv4(addr->sin_addr.s_addr); - name=interface->ifa_name; - }else if(addr->sin_family==AF_INET6){ - const struct sockaddr_in6* addr6=(const struct sockaddr_in6*)addr; - if((addr6->sin6_addr.s6_addr[0] & 0xF0)==0xF0) + if (v4addr) + *v4addr = NetworkAddress::IPv4(addr->sin_addr.s_addr); + name = interface->ifa_name; + } + else if (addr->sin_family == AF_INET6) + { + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; + if ((addr6->sin6_addr.s6_addr[0] & 0xF0) == 0xF0) continue; - if(v6addr) - *v6addr=NetworkAddress::IPv6(addr6->sin6_addr.s6_addr); - name=interface->ifa_name; + if (v6addr) + *v6addr = NetworkAddress::IPv6(addr6->sin6_addr.s6_addr); + name = interface->ifa_name; } } } @@ -432,22 +519,25 @@ std::string NetworkSocketPosix::GetLocalInterfaceInfo(NetworkAddress *v4addr, Ne return name; } -uint16_t NetworkSocketPosix::GetLocalPort(){ +uint16_t NetworkSocketPosix::GetLocalPort() +{ sockaddr_in6 addr; - size_t addrLen=sizeof(sockaddr_in6); - getsockname(fd, (sockaddr*)&addr, (socklen_t*) &addrLen); + size_t addrLen = sizeof(sockaddr_in6); + getsockname(fd, (sockaddr *)&addr, (socklen_t *)&addrLen); return ntohs(addr.sin6_port); } -std::string NetworkSocketPosix::V4AddressToString(uint32_t address){ +std::string NetworkSocketPosix::V4AddressToString(uint32_t address) +{ char buf[INET_ADDRSTRLEN]; in_addr addr; - addr.s_addr=address; + addr.s_addr = address; inet_ntop(AF_INET, &addr, buf, sizeof(buf)); return std::string(buf); } -std::string NetworkSocketPosix::V6AddressToString(const unsigned char *address){ +std::string NetworkSocketPosix::V6AddressToString(const unsigned char *address) +{ char buf[INET6_ADDRSTRLEN]; in6_addr addr; memcpy(addr.s6_addr, address, 16); @@ -455,30 +545,38 @@ std::string NetworkSocketPosix::V6AddressToString(const unsigned char *address){ return std::string(buf); } -uint32_t NetworkSocketPosix::StringToV4Address(std::string address){ +uint32_t NetworkSocketPosix::StringToV4Address(std::string address) +{ in_addr addr; inet_pton(AF_INET, address.c_str(), &addr); return addr.s_addr; } -void NetworkSocketPosix::StringToV6Address(std::string address, unsigned char *out){ +void NetworkSocketPosix::StringToV6Address(std::string address, unsigned char *out) +{ in6_addr addr; inet_pton(AF_INET6, address.c_str(), &addr); memcpy(out, addr.s6_addr, 16); } -NetworkAddress NetworkSocketPosix::ResolveDomainName(std::string name){ - addrinfo* addr0; - NetworkAddress ret=NetworkAddress::Empty(); - int res=getaddrinfo(name.c_str(), NULL, NULL, &addr0); - if(res!=0){ +NetworkAddress NetworkSocketPosix::ResolveDomainName(std::string name) +{ + addrinfo *addr0; + NetworkAddress ret = NetworkAddress::Empty(); + int res = getaddrinfo(name.c_str(), NULL, NULL, &addr0); + if (res != 0) + { LOGW("Error updating NAT64 prefix: %d / %s", res, gai_strerror(res)); - }else{ - addrinfo* addrPtr; - for(addrPtr=addr0;addrPtr;addrPtr=addrPtr->ai_next){ - if(addrPtr->ai_family==AF_INET){ - sockaddr_in* addr=(sockaddr_in*)addrPtr->ai_addr; - ret=NetworkAddress::IPv4(addr->sin_addr.s_addr); + } + else + { + addrinfo *addrPtr; + for (addrPtr = addr0; addrPtr; addrPtr = addrPtr->ai_next) + { + if (addrPtr->ai_family == AF_INET) + { + sockaddr_in *addr = (sockaddr_in *)addrPtr->ai_addr; + ret = NetworkAddress::IPv4(addr->sin_addr.s_addr); break; } } @@ -487,155 +585,186 @@ NetworkAddress NetworkSocketPosix::ResolveDomainName(std::string name){ return ret; } -NetworkAddress NetworkSocketPosix::GetConnectedAddress(){ +NetworkAddress NetworkSocketPosix::GetConnectedAddress() +{ return tcpConnectedAddress; } -uint16_t NetworkSocketPosix::GetConnectedPort(){ +uint16_t NetworkSocketPosix::GetConnectedPort() +{ return tcpConnectedPort; } -void NetworkSocketPosix::SetTimeouts(int sendTimeout, int recvTimeout){ +void NetworkSocketPosix::SetTimeouts(int sendTimeout, int recvTimeout) +{ timeval timeout; - timeout.tv_sec=sendTimeout; - timeout.tv_usec=0; + timeout.tv_sec = sendTimeout; + timeout.tv_usec = 0; setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); - timeout.tv_sec=recvTimeout; + timeout.tv_sec = recvTimeout; setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); } -bool NetworkSocketPosix::Select(std::vector &readFds, std::vector& writeFds, std::vector &errorFds, SocketSelectCanceller* _canceller){ +bool NetworkSocketPosix::Select(std::vector &readFds, std::vector &writeFds, std::vector &errorFds, SocketSelectCanceller *_canceller) +{ fd_set readSet; fd_set writeSet; fd_set errorSet; FD_ZERO(&readSet); FD_ZERO(&writeSet); FD_ZERO(&errorSet); - SocketSelectCancellerPosix* canceller=dynamic_cast(_canceller); - if(canceller) + SocketSelectCancellerPosix *canceller = dynamic_cast(_canceller); + if (canceller) FD_SET(canceller->pipeRead, &readSet); - int maxfd=canceller ? canceller->pipeRead : 0; + int maxfd = canceller ? canceller->pipeRead : 0; - for(NetworkSocket*& s:readFds){ - int sfd=GetDescriptorFromSocket(s); - if(sfd<=0){ + for (NetworkSocket *&s : readFds) + { + int sfd = GetDescriptorFromSocket(s); + if (sfd <= 0) + { LOGW("can't select on one of sockets because it's not a NetworkSocketPosix instance"); continue; } FD_SET(sfd, &readSet); - if(maxfdtimeout>0 && VoIPController::GetCurrentTime()-s->lastSuccessfulOperationTime>s->timeout){ + if (s->timeout > 0 && VoIPController::GetCurrentTime() - s->lastSuccessfulOperationTime > s->timeout) + { LOGW("Socket %d timed out", sfd); - s->failed=true; + s->failed = true; } anyFailed |= s->IsFailed(); FD_SET(sfd, &errorSet); - if(maxfdpipeRead, &readSet) && !anyFailed){ + if (canceller && FD_ISSET(canceller->pipeRead, &readSet) && !anyFailed) + { char c; - (void) read(canceller->pipeRead, &c, 1); + (void)read(canceller->pipeRead, &c, 1); return false; - }else if(anyFailed){ + } + else if (anyFailed) + { FD_ZERO(&readSet); FD_ZERO(&writeSet); } - std::vector::iterator itr=readFds.begin(); - while(itr!=readFds.end()){ - int sfd=GetDescriptorFromSocket(*itr); - if(FD_ISSET(sfd, &readSet)) - (*itr)->lastSuccessfulOperationTime=VoIPController::GetCurrentTime(); - if(sfd==0 || !FD_ISSET(sfd, &readSet) || !(*itr)->OnReadyToReceive()){ - itr=readFds.erase(itr); - }else{ + std::vector::iterator itr = readFds.begin(); + while (itr != readFds.end()) + { + int sfd = GetDescriptorFromSocket(*itr); + if (FD_ISSET(sfd, &readSet)) + (*itr)->lastSuccessfulOperationTime = VoIPController::GetCurrentTime(); + if (sfd == 0 || !FD_ISSET(sfd, &readSet) || !(*itr)->OnReadyToReceive()) + { + itr = readFds.erase(itr); + } + else + { ++itr; } } - itr=writeFds.begin(); - while(itr!=writeFds.end()){ - int sfd=GetDescriptorFromSocket(*itr); - if(sfd==0 || !FD_ISSET(sfd, &writeSet)){ - itr=writeFds.erase(itr); - }else{ + itr = writeFds.begin(); + while (itr != writeFds.end()) + { + int sfd = GetDescriptorFromSocket(*itr); + if (sfd == 0 || !FD_ISSET(sfd, &writeSet)) + { + itr = writeFds.erase(itr); + } + else + { LOGV("Socket %d is ready to send", sfd); - (*itr)->lastSuccessfulOperationTime=VoIPController::GetCurrentTime(); - if((*itr)->OnReadyToSend()) + (*itr)->lastSuccessfulOperationTime = VoIPController::GetCurrentTime(); + if ((*itr)->OnReadyToSend()) ++itr; else - itr=writeFds.erase(itr); + itr = writeFds.erase(itr); } } - itr=errorFds.begin(); - while(itr!=errorFds.end()){ - int sfd=GetDescriptorFromSocket(*itr); - if((sfd==0 || !FD_ISSET(sfd, &errorSet)) && !(*itr)->IsFailed()){ - itr=errorFds.erase(itr); - }else{ + itr = errorFds.begin(); + while (itr != errorFds.end()) + { + int sfd = GetDescriptorFromSocket(*itr); + if ((sfd == 0 || !FD_ISSET(sfd, &errorSet)) && !(*itr)->IsFailed()) + { + itr = errorFds.erase(itr); + } + else + { ++itr; } } //LOGV("select fds left: read=%d, write=%d, error=%d", (int)readFds.size(), (int)writeFds.size(), (int)errorFds.size()); - return readFds.size()>0 || errorFds.size()>0 || writeFds.size()>0; + return readFds.size() > 0 || errorFds.size() > 0 || writeFds.size() > 0; } -SocketSelectCancellerPosix::SocketSelectCancellerPosix(){ +SocketSelectCancellerPosix::SocketSelectCancellerPosix() +{ int p[2]; - int pipeRes=pipe(p); - if(pipeRes!=0){ + int pipeRes = pipe(p); + if (pipeRes != 0) + { LOGE("pipe() failed"); abort(); } - pipeRead=p[0]; - pipeWrite=p[1]; + pipeRead = p[0]; + pipeWrite = p[1]; } -SocketSelectCancellerPosix::~SocketSelectCancellerPosix(){ +SocketSelectCancellerPosix::~SocketSelectCancellerPosix() +{ close(pipeRead); close(pipeWrite); } -void SocketSelectCancellerPosix::CancelSelect(){ - char c=1; - (void) write(pipeWrite, &c, 1); +void SocketSelectCancellerPosix::CancelSelect() +{ + char c = 1; + (void)write(pipeWrite, &c, 1); } -int NetworkSocketPosix::GetDescriptorFromSocket(NetworkSocket *socket){ - NetworkSocketPosix* sp=dynamic_cast(socket); - if(sp) +int NetworkSocketPosix::GetDescriptorFromSocket(NetworkSocket *socket) +{ + NetworkSocketPosix *sp = dynamic_cast(socket); + if (sp) return sp->fd; - NetworkSocketWrapper* sw=dynamic_cast(socket); - if(sw) + NetworkSocketWrapper *sw = dynamic_cast(socket); + if (sw) return GetDescriptorFromSocket(sw->GetWrapped()); return 0; } diff --git a/os/windows/NetworkSocketWinsock.cpp b/os/windows/NetworkSocketWinsock.cpp index c0f7faa..9809693 100644 --- a/os/windows/NetworkSocketWinsock.cpp +++ b/os/windows/NetworkSocketWinsock.cpp @@ -7,7 +7,7 @@ #include #include #include "NetworkSocketWinsock.h" -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP #else #include @@ -20,185 +20,233 @@ using namespace tgvoip; -NetworkSocketWinsock::NetworkSocketWinsock(NetworkProtocol protocol) : NetworkSocket(protocol){ - needUpdateNat64Prefix=true; - nat64Present=false; - switchToV6at=0; - isV4Available=false; - closing=false; - fd=INVALID_SOCKET; +NetworkSocketWinsock::NetworkSocketWinsock(NetworkProtocol protocol) : NetworkSocket(protocol) +{ + needUpdateNat64Prefix = true; + nat64Present = false; + switchToV6at = 0; + isV4Available = false; + closing = false; + fd = INVALID_SOCKET; #ifdef TGVOIP_WINXP_COMPAT - DWORD version=GetVersion(); - isAtLeastVista=LOBYTE(LOWORD(version))>=6; // Vista is 6.0, XP is 5.1 and 5.2 + DWORD version = GetVersion(); + isAtLeastVista = LOBYTE(LOWORD(version)) >= 6; // Vista is 6.0, XP is 5.1 and 5.2 #else - isAtLeastVista=true; + isAtLeastVista = true; #endif WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); LOGD("Initialized winsock, version %d.%d", wsaData.wHighVersion, wsaData.wVersion); - if(protocol==NetworkProtocol::TCP) - timeout=10.0; - lastSuccessfulOperationTime=VoIPController::GetCurrentTime(); + if (protocol == NetworkProtocol::TCP) + timeout = 10.0; + lastSuccessfulOperationTime = VoIPController::GetCurrentTime(); } -NetworkSocketWinsock::~NetworkSocketWinsock(){ +NetworkSocketWinsock::~NetworkSocketWinsock() +{ } -void NetworkSocketWinsock::SetMaxPriority(){ - +void NetworkSocketWinsock::SetMaxPriority() +{ } -void NetworkSocketWinsock::Send(NetworkPacket packet){ - if(packet.IsEmpty() || (protocol==NetworkProtocol::UDP && packet.address.IsEmpty())){ +void NetworkSocketWinsock::Send(NetworkPacket packet) +{ + if (packet.IsEmpty() || (protocol == NetworkProtocol::UDP && packet.address.IsEmpty())) + { LOGW("tried to send null packet"); return; } int res; - if(protocol==NetworkProtocol::UDP){ - if(isAtLeastVista){ + if (protocol == NetworkProtocol::UDP) + { + if (isAtLeastVista) + { sockaddr_in6 addr; - if(!packet.address.isIPv6){ - if(needUpdateNat64Prefix && !isV4Available && VoIPController::GetCurrentTime()>switchToV6at && switchToV6at!=0){ + if (!packet.address.isIPv6) + { + if (needUpdateNat64Prefix && !isV4Available && VoIPController::GetCurrentTime() > switchToV6at && switchToV6at != 0) + { LOGV("Updating NAT64 prefix"); - nat64Present=false; + nat64Present = false; addrinfo *addr0; - int res=getaddrinfo("ipv4only.arpa", NULL, NULL, &addr0); - if(res!=0){ + int res = getaddrinfo("ipv4only.arpa", NULL, NULL, &addr0); + if (res != 0) + { LOGW("Error updating NAT64 prefix: %d / %s", res, gai_strerrorA(res)); - }else{ + } + else + { addrinfo *addrPtr; - unsigned char *addr170=NULL; - unsigned char *addr171=NULL; - for(addrPtr=addr0; addrPtr; addrPtr=addrPtr->ai_next){ - if(addrPtr->ai_family==AF_INET6){ - sockaddr_in6 *translatedAddr=(sockaddr_in6 *) addrPtr->ai_addr; - uint32_t v4part=*((uint32_t *) &translatedAddr->sin6_addr.s6_addr[12]); - if(v4part==0xAA0000C0 && !addr170){ - addr170=translatedAddr->sin6_addr.s6_addr; + unsigned char *addr170 = NULL; + unsigned char *addr171 = NULL; + for (addrPtr = addr0; addrPtr; addrPtr = addrPtr->ai_next) + { + if (addrPtr->ai_family == AF_INET6) + { + sockaddr_in6 *translatedAddr = (sockaddr_in6 *)addrPtr->ai_addr; + uint32_t v4part = *((uint32_t *)&translatedAddr->sin6_addr.s6_addr[12]); + if (v4part == 0xAA0000C0 && !addr170) + { + addr170 = translatedAddr->sin6_addr.s6_addr; } - if(v4part==0xAB0000C0 && !addr171){ - addr171=translatedAddr->sin6_addr.s6_addr; + if (v4part == 0xAB0000C0 && !addr171) + { + addr171 = translatedAddr->sin6_addr.s6_addr; } char buf[INET6_ADDRSTRLEN]; //LOGV("Got translated address: %s", inet_ntop(AF_INET6, &translatedAddr->sin6_addr, buf, sizeof(buf))); } } - if(addr170 && addr171 && memcmp(addr170, addr171, 12)==0){ - nat64Present=true; + if (addr170 && addr171 && memcmp(addr170, addr171, 12) == 0) + { + nat64Present = true; memcpy(nat64Prefix, addr170, 12); char buf[INET6_ADDRSTRLEN]; //LOGV("Found nat64 prefix from %s", inet_ntop(AF_INET6, addr170, buf, sizeof(buf))); - }else{ + } + else + { LOGV("Didn't find nat64"); } freeaddrinfo(addr0); } - needUpdateNat64Prefix=false; + needUpdateNat64Prefix = false; } memset(&addr, 0, sizeof(sockaddr_in6)); - addr.sin6_family=AF_INET6; - *((uint32_t *) &addr.sin6_addr.s6_addr[12])=packet.address.addr.ipv4; - if(nat64Present) + addr.sin6_family = AF_INET6; + *((uint32_t *)&addr.sin6_addr.s6_addr[12]) = packet.address.addr.ipv4; + if (nat64Present) memcpy(addr.sin6_addr.s6_addr, nat64Prefix, 12); else - addr.sin6_addr.s6_addr[11]=addr.sin6_addr.s6_addr[10]=0xFF; - - }else{ + addr.sin6_addr.s6_addr[11] = addr.sin6_addr.s6_addr[10] = 0xFF; + } + else + { memcpy(addr.sin6_addr.s6_addr, packet.address.addr.ipv6, 16); } - addr.sin6_port=htons(packet.port); - res=sendto(fd, (const char*)*packet.data, packet.data.Length(), 0, (const sockaddr *) &addr, sizeof(addr)); - }else{ - sockaddr_in addr; - addr.sin_addr.s_addr=packet.address.addr.ipv4; - addr.sin_port=htons(packet.port); - addr.sin_family=AF_INET; - res=sendto(fd, (const char*)*packet.data, packet.data.Length(), 0, (const sockaddr*)&addr, sizeof(addr)); + addr.sin6_port = htons(packet.port); + res = sendto(fd, (const char *)*packet.data, packet.data.Length(), 0, (const sockaddr *)&addr, sizeof(addr)); + } + else + { + sockaddr_in addr; + addr.sin_addr.s_addr = packet.address.addr.ipv4; + addr.sin_port = htons(packet.port); + addr.sin_family = AF_INET; + res = sendto(fd, (const char *)*packet.data, packet.data.Length(), 0, (const sockaddr *)&addr, sizeof(addr)); } - }else{ - res=send(fd, (const char*)*packet.data, packet.data.Length(), 0); } - if(res==SOCKET_ERROR){ - int error=WSAGetLastError(); - if(error==WSAEWOULDBLOCK){ - if(!pendingOutgoingPacket.IsEmpty()){ + else + { + res = send(fd, (const char *)*packet.data, packet.data.Length(), 0); + } + if (res == SOCKET_ERROR) + { + int error = WSAGetLastError(); + if (error == WSAEWOULDBLOCK) + { + if (!pendingOutgoingPacket.IsEmpty()) + { LOGE("Got EAGAIN but there's already a pending packet"); - failed=true; - }else{ - LOGV("Socket %d not ready to send", fd); - pendingOutgoingPacket=std::move(packet); - readyToSend=false; + failed = true; } - }else{ + else + { + LOGV("Socket %d not ready to send", fd); + pendingOutgoingPacket = std::move(packet); + readyToSend = false; + } + } + else + { LOGE("error sending: %d / %s", error, WindowsSpecific::GetErrorMessage(error).c_str()); - if(error==WSAENETUNREACH && !isV4Available && VoIPController::GetCurrentTime()sin6_port=port; + else + { + sockaddr_in addr4; + addr4.sin_addr.s_addr = 0; + addr4.sin_family = AF_INET; + addr = (sockaddr *)&addr4; + addrLen = sizeof(addr4); + } + for (tries = 0; tries < 10; tries++) + { + uint16_t port = htons(GenerateLocalPort()); + if (isAtLeastVista) + ((sockaddr_in6 *)addr)->sin6_port = port; else - ((sockaddr_in*)addr)->sin_port=port; - res=::bind(fd, addr, addrLen); + ((sockaddr_in *)addr)->sin_port = port; + res = ::bind(fd, addr, addrLen); LOGV("trying bind to port %u", ntohs(port)); - if(res<0){ + if (res < 0) + { LOGE("error binding to port %u: %d / %s", ntohs(port), errno, strerror(errno)); - }else{ + } + else + { break; } } - if(tries==10){ - if(isAtLeastVista) - ((sockaddr_in6*)addr)->sin6_port=0; + if (tries == 10) + { + if (isAtLeastVista) + ((sockaddr_in6 *)addr)->sin6_port = 0; else - ((sockaddr_in*)addr)->sin_port=0; - res=::bind(fd, addr, addrLen); - if(res<0){ + ((sockaddr_in *)addr)->sin_port = 0; + res = ::bind(fd, addr, addrLen); + if (res < 0) + { LOGE("error binding to port %u: %d / %s", 0, errno, strerror(errno)); //SetState(STATE_FAILED); return; } } - getsockname(fd, addr, (socklen_t*) &addrLen); + getsockname(fd, addr, (socklen_t *)&addrLen); uint16_t localUdpPort; - if(isAtLeastVista) - localUdpPort=ntohs(((sockaddr_in6*)addr)->sin6_port); + if (isAtLeastVista) + localUdpPort = ntohs(((sockaddr_in6 *)addr)->sin6_port); else - localUdpPort=ntohs(((sockaddr_in*)addr)->sin_port); + localUdpPort = ntohs(((sockaddr_in *)addr)->sin_port); LOGD("Bound to local UDP port %u", localUdpPort); - needUpdateNat64Prefix=true; - isV4Available=false; - switchToV6at=VoIPController::GetCurrentTime()+ipv6Timeout; + needUpdateNat64Prefix = true; + isV4Available = false; + switchToV6at = VoIPController::GetCurrentTime() + ipv6Timeout; } } -void NetworkSocketWinsock::Close(){ - closing=true; - failed=true; - if(fd!=INVALID_SOCKET) +void NetworkSocketWinsock::Close() +{ + closing = true; + failed = true; + if (fd != INVALID_SOCKET) closesocket(fd); } -void NetworkSocketWinsock::OnActiveInterfaceChanged(){ - needUpdateNat64Prefix=true; - isV4Available=false; - switchToV6at=VoIPController::GetCurrentTime()+ipv6Timeout; +void NetworkSocketWinsock::OnActiveInterfaceChanged() +{ + needUpdateNat64Prefix = true; + isV4Available = false; + switchToV6at = VoIPController::GetCurrentTime() + ipv6Timeout; } -std::string NetworkSocketWinsock::GetLocalInterfaceInfo(NetworkAddress *v4addr, NetworkAddress *v6addr){ -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP - Windows::Networking::Connectivity::ConnectionProfile^ profile=Windows::Networking::Connectivity::NetworkInformation::GetInternetConnectionProfile(); - if(profile){ - Windows::Foundation::Collections::IVectorView^ hostnames=Windows::Networking::Connectivity::NetworkInformation::GetHostNames(); - for(unsigned int i=0;iSize;i++){ - Windows::Networking::HostName^ n = hostnames->GetAt(i); - if(n->Type!=Windows::Networking::HostNameType::Ipv4 && n->Type!=Windows::Networking::HostNameType::Ipv6) +std::string NetworkSocketWinsock::GetLocalInterfaceInfo(NetworkAddress *v4addr, NetworkAddress *v6addr) +{ +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + Windows::Networking::Connectivity::ConnectionProfile ^ profile = Windows::Networking::Connectivity::NetworkInformation::GetInternetConnectionProfile(); + if (profile) + { + Windows::Foundation::Collections::IVectorView ^ hostnames = Windows::Networking::Connectivity::NetworkInformation::GetHostNames(); + for (unsigned int i = 0; i < hostnames->Size; i++) + { + Windows::Networking::HostName ^ n = hostnames->GetAt(i); + if (n->Type != Windows::Networking::HostNameType::Ipv4 && n->Type != Windows::Networking::HostNameType::Ipv6) continue; - if(n->IPInformation->NetworkAdapter->Equals(profile->NetworkAdapter)){ - if(v4addr && n->Type==Windows::Networking::HostNameType::Ipv4){ + if (n->IPInformation->NetworkAdapter->Equals(profile->NetworkAdapter)) + { + if (v4addr && n->Type == Windows::Networking::HostNameType::Ipv4) + { char buf[INET_ADDRSTRLEN]; WideCharToMultiByte(CP_UTF8, 0, n->RawName->Data(), -1, buf, sizeof(buf), NULL, NULL); - *v4addr=NetworkAddress::IPv4(buf); - }else if(v6addr && n->Type==Windows::Networking::HostNameType::Ipv6){ + *v4addr = NetworkAddress::IPv4(buf); + } + else if (v6addr && n->Type == Windows::Networking::HostNameType::Ipv6) + { char buf[INET6_ADDRSTRLEN]; WideCharToMultiByte(CP_UTF8, 0, n->RawName->Data(), -1, buf, sizeof(buf), NULL, NULL); - *v6addr=NetworkAddress::IPv6(buf); + *v6addr = NetworkAddress::IPv6(buf); } } } @@ -352,65 +426,80 @@ std::string NetworkSocketWinsock::GetLocalInterfaceInfo(NetworkAddress *v4addr, } return ""; #else - IP_ADAPTER_ADDRESSES* addrs=(IP_ADAPTER_ADDRESSES*)malloc(15*1024); - ULONG size=15*1024; - ULONG flags=GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME; + IP_ADAPTER_ADDRESSES *addrs = (IP_ADAPTER_ADDRESSES *)malloc(15 * 1024); + ULONG size = 15 * 1024; + ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME; - ULONG res=GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &size); - if(res==ERROR_BUFFER_OVERFLOW){ - addrs=(IP_ADAPTER_ADDRESSES*)realloc(addrs, size); - res=GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &size); + ULONG res = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &size); + if (res == ERROR_BUFFER_OVERFLOW) + { + addrs = (IP_ADAPTER_ADDRESSES *)realloc(addrs, size); + res = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addrs, &size); } - ULONG bestMetric=0; + ULONG bestMetric = 0; std::string bestName(""); - if(res==ERROR_SUCCESS){ - IP_ADAPTER_ADDRESSES* current=addrs; - while(current){ - char* name=current->AdapterName; + if (res == ERROR_SUCCESS) + { + IP_ADAPTER_ADDRESSES *current = addrs; + while (current) + { + char *name = current->AdapterName; LOGV("Adapter '%s':", name); - IP_ADAPTER_UNICAST_ADDRESS* curAddr=current->FirstUnicastAddress; - if(current->OperStatus!=IfOperStatusUp){ + IP_ADAPTER_UNICAST_ADDRESS *curAddr = current->FirstUnicastAddress; + if (current->OperStatus != IfOperStatusUp) + { LOGV("-> (down)"); - current=current->Next; + current = current->Next; continue; } - if(current->IfType==IF_TYPE_SOFTWARE_LOOPBACK){ + if (current->IfType == IF_TYPE_SOFTWARE_LOOPBACK) + { LOGV("-> (loopback)"); - current=current->Next; + current = current->Next; continue; } - if(isAtLeastVista) + if (isAtLeastVista) LOGV("v4 metric: %u, v6 metric: %u", current->Ipv4Metric, current->Ipv6Metric); - while(curAddr){ - sockaddr* addr=curAddr->Address.lpSockaddr; - if(addr->sa_family==AF_INET && v4addr){ - sockaddr_in* ipv4=(sockaddr_in*)addr; + while (curAddr) + { + sockaddr *addr = curAddr->Address.lpSockaddr; + if (addr->sa_family == AF_INET && v4addr) + { + sockaddr_in *ipv4 = (sockaddr_in *)addr; LOGV("-> V4: %s", V4AddressToString(ipv4->sin_addr.s_addr).c_str()); - uint32_t ip=ntohl(ipv4->sin_addr.s_addr); - if((ip & 0xFFFF0000)!=0xA9FE0000){ - if(isAtLeastVista){ - if(current->Ipv4Metric>bestMetric){ - bestMetric=current->Ipv4Metric; - bestName=std::string(current->AdapterName); - *v4addr=NetworkAddress::IPv4(ipv4->sin_addr.s_addr); + uint32_t ip = ntohl(ipv4->sin_addr.s_addr); + if ((ip & 0xFFFF0000) != 0xA9FE0000) + { + if (isAtLeastVista) + { + if (current->Ipv4Metric > bestMetric) + { + bestMetric = current->Ipv4Metric; + bestName = std::string(current->AdapterName); + *v4addr = NetworkAddress::IPv4(ipv4->sin_addr.s_addr); } - }else{ - bestName=std::string(current->AdapterName); - *v4addr=NetworkAddress::IPv4(ipv4->sin_addr.s_addr); + } + else + { + bestName = std::string(current->AdapterName); + *v4addr = NetworkAddress::IPv4(ipv4->sin_addr.s_addr); } } - }else if(addr->sa_family==AF_INET6 && v6addr){ - sockaddr_in6* ipv6=(sockaddr_in6*)addr; + } + else if (addr->sa_family == AF_INET6 && v6addr) + { + sockaddr_in6 *ipv6 = (sockaddr_in6 *)addr; LOGV("-> V6: %s", V6AddressToString(ipv6->sin6_addr.s6_addr).c_str()); - if(!IN6_IS_ADDR_LINKLOCAL(&ipv6->sin6_addr)){ - *v6addr=NetworkAddress::IPv6(ipv6->sin6_addr.s6_addr); + if (!IN6_IS_ADDR_LINKLOCAL(&ipv6->sin6_addr)) + { + *v6addr = NetworkAddress::IPv6(ipv6->sin6_addr.s6_addr); } } - curAddr=curAddr->Next; + curAddr = curAddr->Next; } - current=current->Next; + current = current->Next; } } @@ -419,146 +508,165 @@ std::string NetworkSocketWinsock::GetLocalInterfaceInfo(NetworkAddress *v4addr, #endif } -uint16_t NetworkSocketWinsock::GetLocalPort(){ - if(!isAtLeastVista){ +uint16_t NetworkSocketWinsock::GetLocalPort() +{ + if (!isAtLeastVista) + { sockaddr_in addr; - size_t addrLen=sizeof(sockaddr_in); - getsockname(fd, (sockaddr*)&addr, (socklen_t*)&addrLen); + size_t addrLen = sizeof(sockaddr_in); + getsockname(fd, (sockaddr *)&addr, (socklen_t *)&addrLen); return ntohs(addr.sin_port); } sockaddr_in6 addr; - size_t addrLen=sizeof(sockaddr_in6); - getsockname(fd, (sockaddr*)&addr, (socklen_t*) &addrLen); + size_t addrLen = sizeof(sockaddr_in6); + getsockname(fd, (sockaddr *)&addr, (socklen_t *)&addrLen); return ntohs(addr.sin6_port); } -std::string NetworkSocketWinsock::V4AddressToString(uint32_t address){ +std::string NetworkSocketWinsock::V4AddressToString(uint32_t address) +{ char buf[INET_ADDRSTRLEN]; sockaddr_in addr; ZeroMemory(&addr, sizeof(addr)); - addr.sin_family=AF_INET; - addr.sin_addr.s_addr=address; - DWORD len=sizeof(buf); -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = address; + DWORD len = sizeof(buf); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP wchar_t wbuf[INET_ADDRSTRLEN]; ZeroMemory(wbuf, sizeof(wbuf)); - WSAAddressToStringW((sockaddr*)&addr, sizeof(addr), NULL, wbuf, &len); + WSAAddressToStringW((sockaddr *)&addr, sizeof(addr), NULL, wbuf, &len); WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, sizeof(buf), NULL, NULL); #else - WSAAddressToStringA((sockaddr*)&addr, sizeof(addr), NULL, buf, &len); + WSAAddressToStringA((sockaddr *)&addr, sizeof(addr), NULL, buf, &len); #endif return std::string(buf); } -std::string NetworkSocketWinsock::V6AddressToString(const unsigned char *address){ +std::string NetworkSocketWinsock::V6AddressToString(const unsigned char *address) +{ char buf[INET6_ADDRSTRLEN]; sockaddr_in6 addr; ZeroMemory(&addr, sizeof(addr)); - addr.sin6_family=AF_INET6; + addr.sin6_family = AF_INET6; memcpy(addr.sin6_addr.s6_addr, address, 16); - DWORD len=sizeof(buf); -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + DWORD len = sizeof(buf); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP wchar_t wbuf[INET6_ADDRSTRLEN]; ZeroMemory(wbuf, sizeof(wbuf)); - WSAAddressToStringW((sockaddr*)&addr, sizeof(addr), NULL, wbuf, &len); + WSAAddressToStringW((sockaddr *)&addr, sizeof(addr), NULL, wbuf, &len); WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, sizeof(buf), NULL, NULL); #else - WSAAddressToStringA((sockaddr*)&addr, sizeof(addr), NULL, buf, &len); + WSAAddressToStringA((sockaddr *)&addr, sizeof(addr), NULL, buf, &len); #endif return std::string(buf); } -uint32_t NetworkSocketWinsock::StringToV4Address(std::string address){ +uint32_t NetworkSocketWinsock::StringToV4Address(std::string address) +{ sockaddr_in addr; ZeroMemory(&addr, sizeof(addr)); - addr.sin_family=AF_INET; - int size=sizeof(addr); -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + addr.sin_family = AF_INET; + int size = sizeof(addr); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP wchar_t buf[INET_ADDRSTRLEN]; MultiByteToWideChar(CP_UTF8, 0, address.c_str(), -1, buf, INET_ADDRSTRLEN); - WSAStringToAddressW(buf, AF_INET, NULL, (sockaddr*)&addr, &size); + WSAStringToAddressW(buf, AF_INET, NULL, (sockaddr *)&addr, &size); #else - WSAStringToAddressA((char*)address.c_str(), AF_INET, NULL, (sockaddr*)&addr, &size); + WSAStringToAddressA((char *)address.c_str(), AF_INET, NULL, (sockaddr *)&addr, &size); #endif return addr.sin_addr.s_addr; } -void NetworkSocketWinsock::StringToV6Address(std::string address, unsigned char *out){ +void NetworkSocketWinsock::StringToV6Address(std::string address, unsigned char *out) +{ sockaddr_in6 addr; ZeroMemory(&addr, sizeof(addr)); - addr.sin6_family=AF_INET6; - int size=sizeof(addr); -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + addr.sin6_family = AF_INET6; + int size = sizeof(addr); +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP wchar_t buf[INET6_ADDRSTRLEN]; MultiByteToWideChar(CP_UTF8, 0, address.c_str(), -1, buf, INET6_ADDRSTRLEN); - WSAStringToAddressW(buf, AF_INET, NULL, (sockaddr*)&addr, &size); + WSAStringToAddressW(buf, AF_INET, NULL, (sockaddr *)&addr, &size); #else - WSAStringToAddressA((char*)address.c_str(), AF_INET, NULL, (sockaddr*)&addr, &size); + WSAStringToAddressA((char *)address.c_str(), AF_INET, NULL, (sockaddr *)&addr, &size); #endif memcpy(out, addr.sin6_addr.s6_addr, 16); } -void NetworkSocketWinsock::Connect(const NetworkAddress address, uint16_t port){ +void NetworkSocketWinsock::Connect(const NetworkAddress address, uint16_t port) +{ sockaddr_in v4; sockaddr_in6 v6; - sockaddr* addr=NULL; - size_t addrLen=0; - if(!address.isIPv6){ - v4.sin_family=AF_INET; - v4.sin_addr.s_addr=address.addr.ipv4; - v4.sin_port=htons(port); - addr=reinterpret_cast(&v4); - addrLen=sizeof(v4); - }else{ - v6.sin6_family=AF_INET6; - memcpy(v6.sin6_addr.s6_addr, address.addr.ipv6, 16); - v6.sin6_flowinfo=0; - v6.sin6_scope_id=0; - v6.sin6_port=htons(port); - addr=reinterpret_cast(&v6); - addrLen=sizeof(v6); + sockaddr *addr = NULL; + size_t addrLen = 0; + if (!address.isIPv6) + { + v4.sin_family = AF_INET; + v4.sin_addr.s_addr = address.addr.ipv4; + v4.sin_port = htons(port); + addr = reinterpret_cast(&v4); + addrLen = sizeof(v4); } - fd=socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP); - if(fd==INVALID_SOCKET){ + else + { + v6.sin6_family = AF_INET6; + memcpy(v6.sin6_addr.s6_addr, address.addr.ipv6, 16); + v6.sin6_flowinfo = 0; + v6.sin6_scope_id = 0; + v6.sin6_port = htons(port); + addr = reinterpret_cast(&v6); + addrLen = sizeof(v6); + } + fd = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (fd == INVALID_SOCKET) + { LOGE("Error creating TCP socket: %d", WSAGetLastError()); - failed=true; + failed = true; return; } - u_long one=1; + u_long one = 1; ioctlsocket(fd, FIONBIO, &one); - int opt=1; - setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof(opt)); - DWORD timeout=5000; - setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout)); - timeout=60000; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)); - int res=connect(fd, (const sockaddr*) addr, addrLen); - if(res!=0){ - int error=WSAGetLastError(); - if(error!=WSAEINPROGRESS && error!=WSAEWOULDBLOCK){ + int opt = 1; + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&opt, sizeof(opt)); + DWORD timeout = 5000; + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + timeout = 60000; + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); + int res = connect(fd, (const sockaddr *)addr, addrLen); + if (res != 0) + { + int error = WSAGetLastError(); + if (error != WSAEINPROGRESS && error != WSAEWOULDBLOCK) + { LOGW("error connecting TCP socket to %s:%u: %d / %s", address.ToString().c_str(), port, error, WindowsSpecific::GetErrorMessage(error).c_str()); closesocket(fd); - failed=true; + failed = true; return; } } - tcpConnectedAddress=address; - tcpConnectedPort=port; + tcpConnectedAddress = address; + tcpConnectedPort = port; LOGI("successfully connected to %s:%d", tcpConnectedAddress.ToString().c_str(), tcpConnectedPort); } -NetworkAddress NetworkSocketWinsock::ResolveDomainName(std::string name){ - addrinfo* addr0; - NetworkAddress ret=NetworkAddress::Empty(); - int res=getaddrinfo(name.c_str(), NULL, NULL, &addr0); - if(res!=0){ +NetworkAddress NetworkSocketWinsock::ResolveDomainName(std::string name) +{ + addrinfo *addr0; + NetworkAddress ret = NetworkAddress::Empty(); + int res = getaddrinfo(name.c_str(), NULL, NULL, &addr0); + if (res != 0) + { LOGW("Error updating NAT64 prefix: %d / %s", res, gai_strerrorA(res)); - }else{ - addrinfo* addrPtr; - for(addrPtr=addr0;addrPtr;addrPtr=addrPtr->ai_next){ - if(addrPtr->ai_family==AF_INET){ - sockaddr_in* addr=(sockaddr_in*)addrPtr->ai_addr; - ret=NetworkAddress::IPv4(addr->sin_addr.s_addr); + } + else + { + addrinfo *addrPtr; + for (addrPtr = addr0; addrPtr; addrPtr = addrPtr->ai_next) + { + if (addrPtr->ai_family == AF_INET) + { + sockaddr_in *addr = (sockaddr_in *)addrPtr->ai_addr; + ret = NetworkAddress::IPv4(addr->sin_addr.s_addr); break; } } @@ -567,140 +675,171 @@ NetworkAddress NetworkSocketWinsock::ResolveDomainName(std::string name){ return ret; } -NetworkAddress NetworkSocketWinsock::GetConnectedAddress(){ +NetworkAddress NetworkSocketWinsock::GetConnectedAddress() +{ return tcpConnectedAddress; } -uint16_t NetworkSocketWinsock::GetConnectedPort(){ +uint16_t NetworkSocketWinsock::GetConnectedPort() +{ return tcpConnectedPort; } -void NetworkSocketWinsock::SetTimeouts(int sendTimeout, int recvTimeout){ - DWORD timeout=sendTimeout*1000; - setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout)); - timeout=recvTimeout*1000; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)); +void NetworkSocketWinsock::SetTimeouts(int sendTimeout, int recvTimeout) +{ + DWORD timeout = sendTimeout * 1000; + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + timeout = recvTimeout * 1000; + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); } -bool NetworkSocketWinsock::Select(std::vector &readFds, std::vector& writeFds, std::vector &errorFds, SocketSelectCanceller* _canceller){ +bool NetworkSocketWinsock::Select(std::vector &readFds, std::vector &writeFds, std::vector &errorFds, SocketSelectCanceller *_canceller) +{ fd_set readSet; fd_set errorSet; fd_set writeSet; - SocketSelectCancellerWin32* canceller=dynamic_cast(_canceller); - timeval timeout={0, 10000}; - bool anyFailed=false; - int res=0; + SocketSelectCancellerWin32 *canceller = dynamic_cast(_canceller); + timeval timeout = {0, 10000}; + bool anyFailed = false; + int res = 0; - do{ + do + { FD_ZERO(&readSet); FD_ZERO(&writeSet); FD_ZERO(&errorSet); - for(std::vector::iterator itr=readFds.begin();itr!=readFds.end();++itr){ - int sfd=GetDescriptorFromSocket(*itr); - if(sfd==0){ + for (std::vector::iterator itr = readFds.begin(); itr != readFds.end(); ++itr) + { + int sfd = GetDescriptorFromSocket(*itr); + if (sfd == 0) + { LOGW("can't select on one of sockets because it's not a NetworkSocketWinsock instance"); continue; } FD_SET(sfd, &readSet); } - for(NetworkSocket*& s:writeFds){ - int sfd=GetDescriptorFromSocket(s); - if(sfd==0){ + for (NetworkSocket *&s : writeFds) + { + int sfd = GetDescriptorFromSocket(s); + if (sfd == 0) + { LOGW("can't select on one of sockets because it's not a NetworkSocketWinsock instance"); continue; } FD_SET(sfd, &writeSet); } - for(std::vector::iterator itr=errorFds.begin();itr!=errorFds.end();++itr){ - int sfd=GetDescriptorFromSocket(*itr); - if(sfd==0){ + for (std::vector::iterator itr = errorFds.begin(); itr != errorFds.end(); ++itr) + { + int sfd = GetDescriptorFromSocket(*itr); + if (sfd == 0) + { LOGW("can't select on one of sockets because it's not a NetworkSocketWinsock instance"); continue; } - if((*itr)->timeout>0 && VoIPController::GetCurrentTime()-(*itr)->lastSuccessfulOperationTime>(*itr)->timeout){ + if ((*itr)->timeout > 0 && VoIPController::GetCurrentTime() - (*itr)->lastSuccessfulOperationTime > (*itr)->timeout) + { LOGW("Socket %d timed out", sfd); - (*itr)->failed=true; + (*itr)->failed = true; } anyFailed |= (*itr)->IsFailed(); FD_SET(sfd, &errorSet); } - if(canceller && canceller->canceled) + if (canceller && canceller->canceled) break; - res=select(0, &readSet, &writeSet, &errorSet, &timeout); + res = select(0, &readSet, &writeSet, &errorSet, &timeout); //LOGV("select result %d", res); - if(res==SOCKET_ERROR) + if (res == SOCKET_ERROR) LOGE("SELECT ERROR %d", WSAGetLastError()); - }while(res==0); + } while (res == 0); - - if(canceller && canceller->canceled && !anyFailed){ - canceller->canceled=false; + if (canceller && canceller->canceled && !anyFailed) + { + canceller->canceled = false; return false; - }else if(anyFailed){ + } + else if (anyFailed) + { FD_ZERO(&readSet); FD_ZERO(&errorSet); } - std::vector::iterator itr=readFds.begin(); - while(itr!=readFds.end()){ - int sfd=GetDescriptorFromSocket(*itr); - if(FD_ISSET(sfd, &readSet)) - (*itr)->lastSuccessfulOperationTime=VoIPController::GetCurrentTime(); - if(sfd==0 || !FD_ISSET(sfd, &readSet) || !(*itr)->OnReadyToReceive()){ - itr=readFds.erase(itr); - }else{ + std::vector::iterator itr = readFds.begin(); + while (itr != readFds.end()) + { + int sfd = GetDescriptorFromSocket(*itr); + if (FD_ISSET(sfd, &readSet)) + (*itr)->lastSuccessfulOperationTime = VoIPController::GetCurrentTime(); + if (sfd == 0 || !FD_ISSET(sfd, &readSet) || !(*itr)->OnReadyToReceive()) + { + itr = readFds.erase(itr); + } + else + { ++itr; } } - itr=writeFds.begin(); - while(itr!=writeFds.end()){ - int sfd=GetDescriptorFromSocket(*itr); - if(FD_ISSET(sfd, &writeSet)){ - (*itr)->lastSuccessfulOperationTime=VoIPController::GetCurrentTime(); + itr = writeFds.begin(); + while (itr != writeFds.end()) + { + int sfd = GetDescriptorFromSocket(*itr); + if (FD_ISSET(sfd, &writeSet)) + { + (*itr)->lastSuccessfulOperationTime = VoIPController::GetCurrentTime(); LOGI("Socket %d is ready to send", sfd); } - if(sfd==0 || !FD_ISSET(sfd, &writeSet) || !(*itr)->OnReadyToSend()){ - itr=writeFds.erase(itr); - }else{ + if (sfd == 0 || !FD_ISSET(sfd, &writeSet) || !(*itr)->OnReadyToSend()) + { + itr = writeFds.erase(itr); + } + else + { ++itr; } } - itr=errorFds.begin(); - while(itr!=errorFds.end()){ - int sfd=GetDescriptorFromSocket(*itr); - if((sfd==0 || !FD_ISSET(sfd, &errorSet)) && !(*itr)->IsFailed()){ - itr=errorFds.erase(itr); - }else{ + itr = errorFds.begin(); + while (itr != errorFds.end()) + { + int sfd = GetDescriptorFromSocket(*itr); + if ((sfd == 0 || !FD_ISSET(sfd, &errorSet)) && !(*itr)->IsFailed()) + { + itr = errorFds.erase(itr); + } + else + { ++itr; } } //LOGV("select fds left: read=%d, error=%d", readFds.size(), errorFds.size()); - return readFds.size()>0 || errorFds.size()>0; + return readFds.size() > 0 || errorFds.size() > 0; } -SocketSelectCancellerWin32::SocketSelectCancellerWin32(){ - canceled=false; +SocketSelectCancellerWin32::SocketSelectCancellerWin32() +{ + canceled = false; } -SocketSelectCancellerWin32::~SocketSelectCancellerWin32(){ +SocketSelectCancellerWin32::~SocketSelectCancellerWin32() +{ } -void SocketSelectCancellerWin32::CancelSelect(){ - canceled=true; +void SocketSelectCancellerWin32::CancelSelect() +{ + canceled = true; } -int NetworkSocketWinsock::GetDescriptorFromSocket(NetworkSocket *socket){ - NetworkSocketWinsock* sp=dynamic_cast(socket); - if(sp) +int NetworkSocketWinsock::GetDescriptorFromSocket(NetworkSocket *socket) +{ + NetworkSocketWinsock *sp = dynamic_cast(socket); + if (sp) return sp->fd; - NetworkSocketWrapper* sw=dynamic_cast(socket); - if(sw) + NetworkSocketWrapper *sw = dynamic_cast(socket); + if (sw) return GetDescriptorFromSocket(sw->GetWrapped()); return 0; }