mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-17 20:10:23 +03:00
* Initial commit.
:)
This commit is contained in:
244
thirdparty/raknet/NatTypeDetectionClient.cpp
vendored
Normal file
244
thirdparty/raknet/NatTypeDetectionClient.cpp
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oculus VR, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "NativeFeatureIncludes.h"
|
||||
#if _RAKNET_SUPPORT_NatTypeDetectionClient==1
|
||||
|
||||
#include "NatTypeDetectionClient.h"
|
||||
#include "RakNetSmartPtr.h"
|
||||
#include "BitStream.h"
|
||||
#include "SocketIncludes.h"
|
||||
#include "RakString.h"
|
||||
#include "RakPeerInterface.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
#include "SocketLayer.h"
|
||||
#include "SocketDefines.h"
|
||||
|
||||
using namespace RakNet;
|
||||
|
||||
STATIC_FACTORY_DEFINITIONS(NatTypeDetectionClient,NatTypeDetectionClient);
|
||||
|
||||
NatTypeDetectionClient::NatTypeDetectionClient()
|
||||
{
|
||||
c2=0;
|
||||
}
|
||||
NatTypeDetectionClient::~NatTypeDetectionClient()
|
||||
{
|
||||
if (c2!=0)
|
||||
{
|
||||
RakNet::OP_DELETE(c2,_FILE_AND_LINE_);
|
||||
}
|
||||
}
|
||||
void NatTypeDetectionClient::DetectNATType(SystemAddress _serverAddress)
|
||||
{
|
||||
if (IsInProgress())
|
||||
return;
|
||||
|
||||
if (c2==0)
|
||||
{
|
||||
DataStructures::List<RakNetSocket2* > sockets;
|
||||
rakPeerInterface->GetSockets(sockets);
|
||||
//SystemAddress sockAddr;
|
||||
//SocketLayer::GetSystemAddress(sockets[0], &sockAddr);
|
||||
char str[64];
|
||||
//sockAddr.ToString(false,str);
|
||||
sockets[0]->GetBoundAddress().ToString(false,str);
|
||||
c2=CreateNonblockingBoundSocket(str
|
||||
#ifdef __native_client__
|
||||
, sockets[0]->chromeInstance
|
||||
#endif
|
||||
,this
|
||||
);
|
||||
//c2Port=SocketLayer::GetLocalPort(c2);
|
||||
}
|
||||
|
||||
#if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
|
||||
if (c2->IsBerkleySocket())
|
||||
((RNS2_Berkley*) c2)->CreateRecvPollingThread(0);
|
||||
#endif
|
||||
|
||||
serverAddress=_serverAddress;
|
||||
|
||||
RakNet::BitStream bs;
|
||||
bs.Write((unsigned char)ID_NAT_TYPE_DETECTION_REQUEST);
|
||||
bs.Write(true); // IsRequest
|
||||
bs.Write(c2->GetBoundAddress().GetPort());
|
||||
rakPeerInterface->Send(&bs,MEDIUM_PRIORITY,RELIABLE,0,serverAddress,false);
|
||||
}
|
||||
void NatTypeDetectionClient::OnCompletion(NATTypeDetectionResult result)
|
||||
{
|
||||
Packet *p = AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)*2);
|
||||
//printf("Returning nat detection result to the user\n");
|
||||
p->data[0]=ID_NAT_TYPE_DETECTION_RESULT;
|
||||
p->systemAddress=serverAddress;
|
||||
p->systemAddress.systemIndex=(SystemIndex)-1;
|
||||
p->guid=rakPeerInterface->GetGuidFromSystemAddress(serverAddress);
|
||||
p->data[1]=(unsigned char) result;
|
||||
p->wasGeneratedLocally=true;
|
||||
rakPeerInterface->PushBackPacket(p, true);
|
||||
|
||||
// Symmetric and port restricted are determined by server, so no need to notify server we are done
|
||||
if (result!=NAT_TYPE_PORT_RESTRICTED && result!=NAT_TYPE_SYMMETRIC)
|
||||
{
|
||||
// Otherwise tell the server we got this message, so it stops sending tests to us
|
||||
RakNet::BitStream bs;
|
||||
bs.Write((unsigned char)ID_NAT_TYPE_DETECTION_REQUEST);
|
||||
bs.Write(false); // Done
|
||||
rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,serverAddress,false);
|
||||
}
|
||||
|
||||
Shutdown();
|
||||
}
|
||||
bool NatTypeDetectionClient::IsInProgress(void) const
|
||||
{
|
||||
return serverAddress!=UNASSIGNED_SYSTEM_ADDRESS;
|
||||
}
|
||||
void NatTypeDetectionClient::Update(void)
|
||||
{
|
||||
if (IsInProgress())
|
||||
{
|
||||
RNS2RecvStruct *recvStruct;
|
||||
bufferedPacketsMutex.Lock();
|
||||
if (bufferedPackets.Size()>0)
|
||||
recvStruct=bufferedPackets.Pop();
|
||||
else
|
||||
recvStruct=0;
|
||||
bufferedPacketsMutex.Unlock();
|
||||
while (recvStruct)
|
||||
{
|
||||
if (recvStruct->bytesRead==1 && recvStruct->data[0]==NAT_TYPE_NONE)
|
||||
{
|
||||
OnCompletion(NAT_TYPE_NONE);
|
||||
RakAssert(IsInProgress()==false);
|
||||
}
|
||||
DeallocRNS2RecvStruct(recvStruct, _FILE_AND_LINE_);
|
||||
|
||||
bufferedPacketsMutex.Lock();
|
||||
if (bufferedPackets.Size()>0)
|
||||
recvStruct=bufferedPackets.Pop();
|
||||
else
|
||||
recvStruct=0;
|
||||
bufferedPacketsMutex.Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
PluginReceiveResult NatTypeDetectionClient::OnReceive(Packet *packet)
|
||||
{
|
||||
if (IsInProgress())
|
||||
{
|
||||
switch (packet->data[0])
|
||||
{
|
||||
case ID_OUT_OF_BAND_INTERNAL:
|
||||
{
|
||||
if (packet->length>=3 && packet->data[1]==ID_NAT_TYPE_DETECT)
|
||||
{
|
||||
OnCompletion((NATTypeDetectionResult)packet->data[2]);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ID_NAT_TYPE_DETECTION_RESULT:
|
||||
if (packet->wasGeneratedLocally==false)
|
||||
{
|
||||
OnCompletion((NATTypeDetectionResult)packet->data[1]);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
case ID_NAT_TYPE_DETECTION_REQUEST:
|
||||
OnTestPortRestricted(packet);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
}
|
||||
}
|
||||
|
||||
return RR_CONTINUE_PROCESSING;
|
||||
}
|
||||
void NatTypeDetectionClient::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
|
||||
{
|
||||
(void) lostConnectionReason;
|
||||
(void) rakNetGUID;
|
||||
|
||||
if (IsInProgress() && systemAddress==serverAddress)
|
||||
Shutdown();
|
||||
}
|
||||
void NatTypeDetectionClient::OnRakPeerShutdown(void)
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
void NatTypeDetectionClient::OnDetach(void)
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
void NatTypeDetectionClient::OnTestPortRestricted(Packet *packet)
|
||||
{
|
||||
RakNet::BitStream bsIn(packet->data,packet->length,false);
|
||||
bsIn.IgnoreBytes(sizeof(MessageID));
|
||||
RakNet::RakString s3p4StrAddress;
|
||||
bsIn.Read(s3p4StrAddress);
|
||||
unsigned short s3p4Port;
|
||||
bsIn.Read(s3p4Port);
|
||||
|
||||
DataStructures::List<RakNetSocket2* > sockets;
|
||||
rakPeerInterface->GetSockets(sockets);
|
||||
SystemAddress s3p4Addr = sockets[0]->GetBoundAddress();
|
||||
s3p4Addr.FromStringExplicitPort(s3p4StrAddress.C_String(), s3p4Port);
|
||||
|
||||
// Send off the RakNet socket to the specified address, message is unformatted
|
||||
// Server does this twice, so don't have to unduly worry about packetloss
|
||||
RakNet::BitStream bsOut;
|
||||
bsOut.Write((MessageID) NAT_TYPE_PORT_RESTRICTED);
|
||||
bsOut.Write(rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS));
|
||||
// SocketLayer::SendTo_PC( sockets[0], (const char*) bsOut.GetData(), bsOut.GetNumberOfBytesUsed(), s3p4Addr, __FILE__, __LINE__ );
|
||||
|
||||
RNS2_SendParameters bsp;
|
||||
bsp.data = (char*) bsOut.GetData();
|
||||
bsp.length = bsOut.GetNumberOfBytesUsed();
|
||||
bsp.systemAddress=s3p4Addr;
|
||||
sockets[0]->Send(&bsp, _FILE_AND_LINE_);
|
||||
|
||||
}
|
||||
void NatTypeDetectionClient::Shutdown(void)
|
||||
{
|
||||
serverAddress=UNASSIGNED_SYSTEM_ADDRESS;
|
||||
if (c2!=0)
|
||||
{
|
||||
#if !defined(__native_client__) && !defined(WINDOWS_STORE_RT)
|
||||
if (c2->IsBerkleySocket())
|
||||
((RNS2_Berkley *)c2)->BlockOnStopRecvPollingThread();
|
||||
#endif
|
||||
|
||||
RakNet::OP_DELETE(c2, _FILE_AND_LINE_);
|
||||
c2=0;
|
||||
}
|
||||
|
||||
bufferedPacketsMutex.Lock();
|
||||
while (bufferedPackets.Size())
|
||||
RakNet::OP_DELETE(bufferedPackets.Pop(), _FILE_AND_LINE_);
|
||||
bufferedPacketsMutex.Unlock();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
void NatTypeDetectionClient::DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line)
|
||||
{
|
||||
RakNet::OP_DELETE(s, file, line);
|
||||
}
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
RNS2RecvStruct *NatTypeDetectionClient::AllocRNS2RecvStruct(const char *file, unsigned int line)
|
||||
{
|
||||
return RakNet::OP_NEW<RNS2RecvStruct>(file,line);
|
||||
}
|
||||
void NatTypeDetectionClient::OnRNS2Recv(RNS2RecvStruct *recvStruct)
|
||||
{
|
||||
bufferedPacketsMutex.Lock();
|
||||
bufferedPackets.Push(recvStruct,_FILE_AND_LINE_);
|
||||
bufferedPacketsMutex.Unlock();
|
||||
}
|
||||
|
||||
#endif // _RAKNET_SUPPORT_*
|
||||
Reference in New Issue
Block a user