init
This commit is contained in:
453
include/raknet/RakNetSocket2.hpp
Normal file
453
include/raknet/RakNetSocket2.hpp
Normal file
@ -0,0 +1,453 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RAKNET_SOCKET_2_H
|
||||
#define __RAKNET_SOCKET_2_H
|
||||
|
||||
#include "RakNetTypes.hpp"
|
||||
#include "MTUSize.hpp"
|
||||
#include "LocklessTypes.hpp"
|
||||
#include "RakThread.hpp"
|
||||
#include "DS_ThreadsafeAllocatingQueue.hpp"
|
||||
#include "Export.hpp"
|
||||
|
||||
// For CFSocket
|
||||
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFSocketRef/Reference/reference.html
|
||||
// Reason: http://sourceforge.net/p/open-dis/discussion/683284/thread/0929d6a0
|
||||
#if defined(__APPLE__)
|
||||
#import <CoreFoundation/CoreFoundation.hpp>
|
||||
#include <sys/socket.hpp>
|
||||
#include <netinet/in.hpp>
|
||||
#endif
|
||||
|
||||
// #define TEST_NATIVE_CLIENT_ON_WINDOWS
|
||||
|
||||
#ifdef TEST_NATIVE_CLIENT_ON_WINDOWS
|
||||
#define __native_client__
|
||||
typedef int PP_Resource;
|
||||
#endif
|
||||
|
||||
namespace RakNet
|
||||
{
|
||||
|
||||
class RakNetSocket2;
|
||||
struct RNS2_BerkleyBindParameters;
|
||||
struct RNS2_SendParameters;
|
||||
typedef int RNS2Socket;
|
||||
|
||||
enum RNS2BindResult
|
||||
{
|
||||
BR_SUCCESS,
|
||||
BR_REQUIRES_RAKNET_SUPPORT_IPV6_DEFINE,
|
||||
BR_FAILED_TO_BIND_SOCKET,
|
||||
BR_FAILED_SEND_TEST,
|
||||
};
|
||||
|
||||
typedef int RNS2SendResult;
|
||||
|
||||
enum RNS2Type
|
||||
{
|
||||
RNS2T_WINDOWS_STORE_8,
|
||||
RNS2T_PS3,
|
||||
RNS2T_PS4,
|
||||
RNS2T_CHROME,
|
||||
RNS2T_VITA,
|
||||
RNS2T_XBOX_360,
|
||||
RNS2T_XBOX_720,
|
||||
RNS2T_WINDOWS,
|
||||
RNS2T_LINUX
|
||||
};
|
||||
|
||||
struct RNS2_SendParameters
|
||||
{
|
||||
RNS2_SendParameters() {ttl=0;}
|
||||
char *data;
|
||||
int length;
|
||||
SystemAddress systemAddress;
|
||||
int ttl;
|
||||
};
|
||||
|
||||
struct RNS2RecvStruct
|
||||
{
|
||||
|
||||
|
||||
|
||||
char data[MAXIMUM_MTU_SIZE];
|
||||
|
||||
int bytesRead;
|
||||
SystemAddress systemAddress;
|
||||
RakNet::TimeUS timeRead;
|
||||
RakNetSocket2 *socket;
|
||||
};
|
||||
|
||||
class RakNetSocket2Allocator
|
||||
{
|
||||
public:
|
||||
static RakNetSocket2* AllocRNS2(void);
|
||||
static void DeallocRNS2(RakNetSocket2 *s);
|
||||
};
|
||||
|
||||
class RAK_DLL_EXPORT RNS2EventHandler
|
||||
{
|
||||
public:
|
||||
RNS2EventHandler() {}
|
||||
virtual ~RNS2EventHandler() {}
|
||||
|
||||
// bufferedPackets.Push(recvFromStruct);
|
||||
// quitAndDataEvents.SetEvent();
|
||||
virtual void OnRNS2Recv(RNS2RecvStruct *recvStruct)=0;
|
||||
virtual void DeallocRNS2RecvStruct(RNS2RecvStruct *s, const char *file, unsigned int line)=0;
|
||||
virtual RNS2RecvStruct *AllocRNS2RecvStruct(const char *file, unsigned int line)=0;
|
||||
|
||||
// recvFromStruct=bufferedPackets.Allocate( _FILE_AND_LINE_ );
|
||||
// DataStructures::ThreadsafeAllocatingQueue<RNS2RecvStruct> bufferedPackets;
|
||||
};
|
||||
|
||||
class RakNetSocket2
|
||||
{
|
||||
public:
|
||||
RakNetSocket2();
|
||||
virtual ~RakNetSocket2();
|
||||
|
||||
// In order for the handler to trigger, some platforms must call PollRecvFrom, some platforms this create an internal thread.
|
||||
void SetRecvEventHandler(RNS2EventHandler *_eventHandler);
|
||||
virtual RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line )=0;
|
||||
RNS2Type GetSocketType(void) const;
|
||||
void SetSocketType(RNS2Type t);
|
||||
bool IsBerkleySocket(void) const;
|
||||
SystemAddress GetBoundAddress(void) const;
|
||||
unsigned int GetUserConnectionSocketIndex(void) const;
|
||||
void SetUserConnectionSocketIndex(unsigned int i);
|
||||
RNS2EventHandler * GetEventHandler(void) const;
|
||||
|
||||
// ----------- STATICS ------------
|
||||
static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
static void DomainNameToIP( const char *domainName, char ip[65] );
|
||||
|
||||
protected:
|
||||
RNS2EventHandler *eventHandler;
|
||||
RNS2Type socketType;
|
||||
SystemAddress boundAddress;
|
||||
unsigned int userConnectionSocketIndex;
|
||||
};
|
||||
|
||||
#if defined(WINDOWS_STORE_RT)
|
||||
|
||||
ref class ListenerContext;
|
||||
|
||||
// #include <collection.hpp>
|
||||
//#include <map>
|
||||
#include "DS_List.hpp"
|
||||
class RNS2_WindowsStore8 : public RakNetSocket2
|
||||
{
|
||||
public:
|
||||
RNS2_WindowsStore8();
|
||||
~RNS2_WindowsStore8();
|
||||
|
||||
virtual RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
|
||||
RNS2BindResult Bind( Platform::String ^localServiceName );
|
||||
// ----------- STATICS ------------
|
||||
static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
static void DomainNameToIP( const char *domainName, char ip[65] );
|
||||
|
||||
static int WinRTInet_Addr(const char * cp);
|
||||
|
||||
static int WinRTSetSockOpt(Windows::Networking::Sockets::DatagramSocket ^s,
|
||||
int level,
|
||||
int optname,
|
||||
const char * optval,
|
||||
socklen_t optlen);
|
||||
|
||||
static int WinRTIOCTLSocket(Windows::Networking::Sockets::DatagramSocket ^s,
|
||||
long cmd,
|
||||
unsigned long *argp);
|
||||
|
||||
static int WinRTGetSockName(Windows::Networking::Sockets::DatagramSocket ^s,
|
||||
struct sockaddr *name,
|
||||
socklen_t* namelen);
|
||||
|
||||
static RNS2_WindowsStore8 *GetRNS2FromDatagramSocket(Windows::Networking::Sockets::DatagramSocket^ s);
|
||||
protected:
|
||||
static DataStructures::List<RNS2_WindowsStore8*> rns2List;
|
||||
static SimpleMutex rns2ListMutex;
|
||||
|
||||
Windows::Networking::Sockets::DatagramSocket^ listener;
|
||||
// Platform::Collections::Map<Windows::Storage::Streams::IOutputStream> ^outputStreamMap;
|
||||
// Platform::Collections::Map<String^, int>^ m;
|
||||
//std::map<> m;
|
||||
ListenerContext^ listenerContext;
|
||||
};
|
||||
#elif defined(__native_client__)
|
||||
struct NativeClientBindParameters
|
||||
{
|
||||
_PP_Instance_ nativeClientInstance;
|
||||
unsigned short port;
|
||||
const char *forceHostAddress;
|
||||
bool is_ipv6;
|
||||
RNS2EventHandler *eventHandler;
|
||||
};
|
||||
class RNS2_NativeClient;
|
||||
struct RNS2_SendParameters_NativeClient : public RNS2_SendParameters
|
||||
{
|
||||
RNS2_NativeClient *socket2;
|
||||
};
|
||||
class RNS2_NativeClient : public RakNetSocket2
|
||||
{
|
||||
public:
|
||||
RNS2_NativeClient();
|
||||
virtual ~RNS2_NativeClient();
|
||||
RNS2BindResult Bind( NativeClientBindParameters *bindParameters, const char *file, unsigned int line );
|
||||
RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
|
||||
const NativeClientBindParameters *GetBindings(void) const;
|
||||
|
||||
// ----------- STATICS ------------
|
||||
static bool IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type );
|
||||
static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
|
||||
// RNS2_NativeClient doesn't automatically call recvfrom in a thread - user must call Update() from the main thread
|
||||
// This causes buffered sends to send, until send is asynch pending
|
||||
// It causes recvfrom events to trigger the callback, and push a message to the event handler
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// DataStructures::List< RakNet::RakNetSocket2* > sockets;
|
||||
// rakPeerInterface->GetSockets(sockets);
|
||||
// for (unsigned int i=0; i < sockets.Size(); i++)
|
||||
// {
|
||||
// ((RNS2_NativeClient*)sockets[i])->Update();
|
||||
// }
|
||||
|
||||
void Update(void);
|
||||
protected:
|
||||
void ProcessBufferedSend(void);
|
||||
static void SendImmediate(RNS2_SendParameters_NativeClient *sp);
|
||||
static void DeallocSP(RNS2_SendParameters_NativeClient *sp);
|
||||
static RNS2_SendParameters_NativeClient* CloneSP(RNS2_SendParameters *sp, RNS2_NativeClient *socket2, const char *file, unsigned int line);
|
||||
static void onRecvFrom(void* pData, int32_t dataSize);
|
||||
void IssueReceiveCall(void);
|
||||
static void onSocketBound(void* pData, int32_t dataSize);
|
||||
static void onSendTo(void* pData, int32_t dataSize);
|
||||
void BufferSend( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
|
||||
PP_Resource rns2Socket;
|
||||
NativeClientBindParameters binding;
|
||||
bool sendInProgress;
|
||||
SimpleMutex sendInProgressMutex;
|
||||
|
||||
enum BindState
|
||||
{
|
||||
BS_UNBOUND,
|
||||
BS_IN_PROGRESS,
|
||||
BS_BOUND,
|
||||
BS_FAILED
|
||||
} bindState;
|
||||
DataStructures::Queue<RNS2_SendParameters_NativeClient*> bufferedSends;
|
||||
SimpleMutex bufferedSendsMutex;
|
||||
};
|
||||
#else // defined(WINDOWS_STORE_RT)
|
||||
|
||||
struct RNS2_BerkleyBindParameters
|
||||
{
|
||||
// Input parameters
|
||||
unsigned short port;
|
||||
char *hostAddress;
|
||||
unsigned short addressFamily; // AF_INET or AF_INET6
|
||||
int type; // SOCK_DGRAM
|
||||
int protocol; // 0
|
||||
bool nonBlockingSocket;
|
||||
int setBroadcast;
|
||||
int setIPHdrIncl;
|
||||
int doNotFragment;
|
||||
int pollingThreadPriority;
|
||||
RNS2EventHandler *eventHandler;
|
||||
unsigned short remotePortRakNetWasStartedOn_PS3_PS4_PSP2;
|
||||
};
|
||||
|
||||
// Every platform except Windows Store 8 can use the Berkley sockets interface
|
||||
class IRNS2_Berkley : public RakNetSocket2
|
||||
{
|
||||
public:
|
||||
// ----------- STATICS ------------
|
||||
// For addressFamily, use AF_INET
|
||||
// For type, use SOCK_DGRAM
|
||||
static bool IsPortInUse(unsigned short port, const char *hostAddress, unsigned short addressFamily, int type );
|
||||
|
||||
// ----------- MEMBERS ------------
|
||||
virtual RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line )=0;
|
||||
};
|
||||
// Every platform that uses Berkley sockets, except native client, can compile some common functions
|
||||
class RNS2_Berkley : public IRNS2_Berkley
|
||||
{
|
||||
public:
|
||||
RNS2_Berkley();
|
||||
virtual ~RNS2_Berkley();
|
||||
int CreateRecvPollingThread(int threadPriority);
|
||||
void SignalStopRecvPollingThread(void);
|
||||
void BlockOnStopRecvPollingThread(void);
|
||||
const RNS2_BerkleyBindParameters *GetBindings(void) const;
|
||||
RNS2Socket GetSocket(void) const;
|
||||
void SetDoNotFragment( int opt );
|
||||
|
||||
protected:
|
||||
// Used by other classes
|
||||
RNS2BindResult BindShared( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
|
||||
RNS2BindResult BindSharedIPV4( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
|
||||
RNS2BindResult BindSharedIPV4And6( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
|
||||
|
||||
static void GetSystemAddressIPV4 ( RNS2Socket rns2Socket, SystemAddress *systemAddressOut );
|
||||
static void GetSystemAddressIPV4And6 ( RNS2Socket rns2Socket, SystemAddress *systemAddressOut );
|
||||
|
||||
// Internal
|
||||
void SetNonBlockingSocket(unsigned long nonblocking);
|
||||
void SetSocketOptions(void);
|
||||
void SetBroadcastSocket(int broadcast);
|
||||
void SetIPHdrIncl(int ipHdrIncl);
|
||||
void RecvFromBlocking(RNS2RecvStruct *recvFromStruct);
|
||||
void RecvFromBlockingIPV4(RNS2RecvStruct *recvFromStruct);
|
||||
void RecvFromBlockingIPV4And6(RNS2RecvStruct *recvFromStruct);
|
||||
|
||||
RNS2Socket rns2Socket;
|
||||
RNS2_BerkleyBindParameters binding;
|
||||
|
||||
unsigned RecvFromLoopInt(void);
|
||||
RakNet::LocklessUint32_t isRecvFromLoopThreadActive;
|
||||
volatile bool endThreads;
|
||||
// Constructor not called!
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// http://sourceforge.net/p/open-dis/discussion/683284/thread/0929d6a0
|
||||
CFSocketRef _cfSocket;
|
||||
#endif
|
||||
|
||||
static RAK_THREAD_DECLARATION(RecvFromLoop);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__)
|
||||
class RNS2_Windows_Linux_360
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
static RNS2SendResult Send_Windows_Linux_360NoVDP( RNS2Socket rns2Socket, RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
class RAK_DLL_EXPORT SocketLayerOverride
|
||||
{
|
||||
public:
|
||||
SocketLayerOverride() {}
|
||||
virtual ~SocketLayerOverride() {}
|
||||
|
||||
/// Called when SendTo would otherwise occur.
|
||||
virtual int RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress )=0;
|
||||
|
||||
/// Called when RecvFrom would otherwise occur. Return number of bytes read. Write data into dataOut
|
||||
// Return -1 to use RakNet's normal recvfrom, 0 to abort RakNet's normal recvfrom, and positive to return data
|
||||
virtual int RakNetRecvFrom( char dataOut[ MAXIMUM_MTU_SIZE ], SystemAddress *senderOut, bool calledFromMainThread )=0;
|
||||
};
|
||||
|
||||
class RNS2_Windows : public RNS2_Berkley, public RNS2_Windows_Linux_360
|
||||
{
|
||||
public:
|
||||
RNS2_Windows();
|
||||
virtual ~RNS2_Windows();
|
||||
RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
|
||||
RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
|
||||
void SetSocketLayerOverride(SocketLayerOverride *_slo);
|
||||
SocketLayerOverride* GetSocketLayerOverride(void);
|
||||
// ----------- STATICS ------------
|
||||
static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
protected:
|
||||
static void GetMyIPIPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
static void GetMyIPIPV4And6( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
SocketLayerOverride *slo;
|
||||
};
|
||||
|
||||
#else
|
||||
class RNS2_Linux : public RNS2_Berkley, public RNS2_Windows_Linux_360
|
||||
{
|
||||
public:
|
||||
RNS2BindResult Bind( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line );
|
||||
RNS2SendResult Send( RNS2_SendParameters *sendParameters, const char *file, unsigned int line );
|
||||
|
||||
// ----------- STATICS ------------
|
||||
static void GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
protected:
|
||||
static void GetMyIPIPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
static void GetMyIPIPV4And6( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] );
|
||||
};
|
||||
|
||||
#endif // Linux
|
||||
|
||||
#endif // #elif !defined(WINDOWS_STORE_RT)
|
||||
|
||||
} // namespace RakNet
|
||||
|
||||
#endif // __RAKNET_SOCKET_2_H
|
Reference in New Issue
Block a user