//////////////////////////////////////////////////////////////////////////////// // doSTUN BcBool GaMatchmakingState::doSTUN() { // Perform STUN to get our local address. BcBool GotPort = BcFalse; BcPrintf("Connecting to STUN server..\n"); if( stunParseServerName( "stunserver.org", StunAddress_ ) ) { int BasePort = 6000; for( BcU32 TryIdx = 0; TryIdx < 10; ++TryIdx ) { // Set port & NIC. int SrcPort = stunRandomPort(); StunAddress4 NICAddr; NICAddr.addr = 0; NICAddr.port = SrcPort; // Open port for NAT punchthrough. BcPrintf("Opening socket on port %u..\n", SrcPort); SocketFileDescriptor_ = stunOpenSocket( StunAddress_, &MappedAddress_, SrcPort, &NICAddr, false ); // Ok, we got one. if( SocketFileDescriptor_ > 0 ) { // RakNet only. closesocket( SocketFileDescriptor_ ); SocketFileDescriptor_ = 0; // GotPort = BcTrue; BcPrintf("Got socket %u!\n", SrcPort); LocalHandshakeAddr_ = 0; LocalHandshakePort_ = SrcPort; // Store mapped. MappedHandshakeAddr_ = MappedAddress_.addr; MappedHandshakePort_ = MappedAddress_.port; break; } } } return GotPort; }
STUN_NAT_TYPE_T StunResolver::ResolveInternal(const std::string &server) { STUN_NAT_TYPE_T type = STUN_NAT_TYPE_UNKNOWN; do { StunAddress4 stunServerAddr; stunServerAddr.addr = 0; // resolve server address bool ret = stunParseServerName(const_cast<char *>(server.c_str()), stunServerAddr); if (!ret || 0 == stunServerAddr.addr) { LOGE("Cannot parser stun server address: %s", server.c_str()); break; } int srcPort = stunRandomPort(); bool presPort = false; bool hairpin = false; StunAddress4 sAddr; sAddr.addr = 0; sAddr.port = 0; NatType stype = stunNatType(stunServerAddr, false, &presPort, &hairpin, srcPort, &sAddr); switch (stype) { case StunTypeIndependentFilter: LOGD("Independent Mapping, Independent Filter: presPort %d hairpin %d", presPort, hairpin); type = STUN_NAT_TYPE_CONE; break; case StunTypeDependentFilter: LOGD("Independent Mapping, Address Dependent Filter: presPort %d hairpin %d", presPort, hairpin); type = STUN_NAT_TYPE_RESTRICTED; break; case StunTypePortDependedFilter: LOGD("Independent Mapping, Port Dependent Filter: presPort %d hairpin %d", presPort, hairpin); type = STUN_NAT_TYPE_PORT_RESTRICTED; break; case StunTypeDependentMapping: LOGD("Dependent Mapping: presPort %d hairpin %d", presPort, hairpin); type = STUN_NAT_TYPE_SYM; break; case StunTypeFailure: LOGE("Some stun error detetecting NAT type"); break; case StunTypeUnknown: LOGE("Some unknown type error detetecting NAT type"); break; case StunTypeOpen: LOGE("Open stun type"); break; case StunTypeFirewall: cout << "Firewall"; break; case StunTypeBlocked: cout << "Blocked or could not reach STUN server"; break; default: LOGD("Unknown NAT stype: %d", stype); break; } } while (false); return type; }