예제 #1
0
////////////////////////////////////////////////////////////////////////////////
// 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;
}
예제 #2
0
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;
}