//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// // net.h -- Half-Life's interface to the networking layer // For banning IP addresses (or allowing private games) #ifndef NET_H #define NET_H #ifdef _WIN32 #pragma once #endif #include "common.h" #include "bitbuf.h" #include "netadr.h" #include "inetchannel.h" #include "networksystem/inetworksystem.h" class ISteamDatagramTransportClient; // Flow control bytes per second limits: // 16,000 bytes per second = 128kbps // default rate: 192kbytes per second = 1.5mbps // 0.75Mbytes per second = 6mbps #define MIN_RATE 16000 #define DEFAULT_RATE 196608 #define MAX_RATE 786432 #ifdef _GAMECONSOLE #define SIGNON_TIME_OUT 75.0f // signon disconnect timeout #else #define SIGNON_TIME_OUT 300.0f // signon disconnect timeout #endif #define SIGNON_TIME_OUT_360 75.0f #define FRAGMENT_BITS 8 #define FRAGMENT_SIZE (1<<FRAGMENT_BITS) #define MAX_FILE_SIZE_BITS 26 #define MAX_FILE_SIZE ((1<<MAX_FILE_SIZE_BITS)-1) // maximum transferable size is 64MB // 0 == regular, 1 == file stream #define MAX_STREAMS 2 #define FRAG_NORMAL_STREAM 0 #define FRAG_FILE_STREAM 1 #define TCP_CONNECT_TIMEOUT 4.0f #define PORT_ANY -1 #define PORT_TRY_MAX 10 // the number of different ports to try to find an unused one #define PORT_TRY_MAX_FORKED 150 // the number to try when we are running as a forked child process (for the server farm) #define TCP_MAX_ACCEPTS 8 #define LOOPBACK_SOCKETS 2 #define STREAM_CMD_NONE 0 // waiting for next blob #define STREAM_CMD_AUTH 1 // first command, send back challengenr #define STREAM_CMD_DATA 2 // receiving a data blob #define STREAM_CMD_FILE 3 // receiving a file blob #define STREAM_CMD_ACKN 4 // acknowledged a recveived blob // NETWORKING INFO class INetChannel; enum ESocketIndex_t { NS_INVALID = -1, NS_CLIENT = 0, // client socket NS_SERVER, // server socket #ifdef _X360 NS_X360_SYSTEMLINK, NS_X360_LOBBY, NS_X360_TEAMLINK, #endif NS_HLTV, NS_HLTV1, // Note: NS_HLTV1 must follow NS_HLTV, NS_HLTV2 must follow NS_HLTV1, etc. #if defined( REPLAY_ENABLED ) NS_REPLAY, #endif MAX_SOCKETS }; extern netadr_t net_local_adr; extern double net_time; class INetChannelHandler; class IConnectionlessPacketHandler; class CMsgSteamDatagramGameServerAuthTicket; class ISteamDatagramTransportClient; // Start up networking void NET_Init( bool bDedicated ); // initialize queued packet sender. must do after fork(), not before void NET_InitPostFork( void ); // Shut down networking void NET_Shutdown (void); // Read any incoming packets, dispatch to known netchannels and call handler for connectionless packets void NET_ProcessSocket( int sock, IConnectionlessPacketHandler * handler ); // Set a port to listen mode void NET_ListenSocket( int sock, bool listen ); // Send connectionsless string over the wire void NET_OutOfBandPrintf(int sock, const ns_address &adr, PRINTF_FORMAT_STRING const char *format, ...) FMTFUNCTION( 3, 4 ); void NET_OutOfBandDelayedPrintf(int sock, const ns_address &adr, uint32 unMillisecondsDelay, PRINTF_FORMAT_STRING const char *format, ...) FMTFUNCTION( 4, 5 ); // Send a raw packet, connectionless must be provided (chan can be NULL) int NET_SendPacket ( INetChannel *chan, int sock, const ns_address &to, const unsigned char *data, int length, bf_write *pVoicePayload = NULL, bool bUseCompression = false, uint32 unMillisecondsDelay = 0u ); // Called periodically to maybe send any queued packets (up to 4 per frame) void NET_SendQueuedPackets(); // Start set current network configuration void NET_SetMultiplayer(bool multiplayer); // Set net_time void NET_SetTime( double realtime ); // RunFrame must be called each system frame before reading/sending on any socket void NET_RunFrame( double realtime ); // Check configuration state bool NET_IsMultiplayer( void ); bool NET_IsDedicated( void ); #ifdef SERVER_XLSP bool NET_IsDedicatedForXbox( void ); #else FORCEINLINE bool NET_IsDedicatedForXbox( void ) { return false; } #endif // Writes a error file with bad packet content void NET_LogBadPacket(netpacket_t * packet); // bForceNew (used for bots) tells it not to share INetChannels (bots will crash when disconnecting if they // share an INetChannel). INetChannel *NET_CreateNetChannel( int socketnumber, const ns_address *adr, const char * name, INetChannelHandler * handler, const byte *pbEncryptionKey, bool bForceNew ); void NET_RemoveNetChannel(INetChannel *netchan, bool bDeleteNetChan); void NET_PrintChannelStatus( INetChannel * chan ); void NET_WriteStringCmd( const char * cmd, bf_write *buf ); // Address conversion bool NET_StringToAdr ( const char *s, netadr_t *a); // Convert from host to network byte ordering unsigned short NET_HostToNetShort( unsigned short us_in ); // and vice versa unsigned short NET_NetToHostShort( unsigned short us_in ); // Find out what port is mapped to a local socket unsigned short NET_GetUDPPort(int socket); // add/remove extra sockets for testing int NET_AddExtraSocket( int port ); void NET_RemoveAllExtraSockets(); const char *NET_ErrorString (int code); // translate a socket error into a friendly string // Returns true if compression succeeded, false otherwise bool NET_BufferToBufferCompress( char *dest, unsigned int *destLen, char *source, unsigned int sourceLen ); bool NET_BufferToBufferDecompress( char *dest, unsigned int *destLen, char *source, unsigned int sourceLen ); netadr_t NET_InitiateSteamConnection(int sock, uint64 uSteamID, PRINTF_FORMAT_STRING const char *format, ...) FMTFUNCTION( 3, 4 ); void NET_TerminateConnection(int sock, const ns_address &peer ); void NET_TerminateSteamConnection(int sock, uint64 uSteamID ); void NET_SleepUntilMessages( int nMilliseconds ); // If net_public_adr convar is set then returns that, otherwise, checks with steam if we are a dedicated server (eventually will work for the client) and returns that // Returns false if not able to deduce address bool NET_GetPublicAdr( netadr_t &adr ); /// Start listening for Steam datagram, if the convar tells us to void NET_SteamDatagramServerListen(); /// Called when we receive a ticket to play on a particular gameserver #ifndef DEDICATED /// Make sure we are setup to talk to this gameserver bool NET_InitSteamDatagramProxiedGameserverConnection( const ns_address &adr ); #endif //============================================================================ // // Encrypted network channel communication support // #define NET_CRYPT_KEY_LENGTH 16 bool NET_CryptVerifyServerCertificateAndAllocateSessionKey( bool bOfficial, const ns_address &from, const byte *pchKeyPub, int numKeyPub, const byte *pchKeySgn, int numKeySgn, byte **pbAllocatedKey, int *pnAllocatedCryptoBlockSize ); bool NET_CryptVerifyClientSessionKey( bool bOfficial, const byte *pchKeyPri, int numKeyPri, const byte *pbEncryptedKey, int numEncryptedBytes, byte *pbPlainKey, int numPlainKeyBytes ); enum ENetworkCertificate_t { k_ENetworkCertificate_PublicKey, k_ENetworkCertificate_PrivateKey, k_ENetworkCertificate_Signature, k_ENetworkCertificate_Max }; bool NET_CryptGetNetworkCertificate( ENetworkCertificate_t eType, const byte **pbData, int *pnumBytes ); //============================================================================ // Message data typedef struct { // Size of message sent/received int size; // Time that message was sent/received float time; } flowstats_t; struct sockaddr; class ISteamSocketMgr { public: enum ESteamCnxType { ESCT_NEVER = 0, ESCT_ASBACKUP, ESCT_ALWAYS, ESCT_MAXTYPE, }; enum { STEAM_CNX_PORT = 1, }; virtual void Init() = 0; virtual void Shutdown() = 0; virtual ESteamCnxType GetCnxType() = 0; virtual void OpenSocket( int s, int nModule, int nSetPort, int nDefaultPort, const char *pName, int nProtocol, bool bTryAny ) = 0; virtual void CloseSocket( int s, int nModule ) = 0; virtual int sendto( int s, const char * buf, int len, int flags, const ns_address &to ) = 0; virtual int recvfrom( int s, char * buf, int len, int flags, ns_address * from ) = 0; virtual uint64 GetSteamIDForRemote( const ns_address &remote ) = 0; }; extern ISteamSocketMgr *g_pSteamSocketMgr; // Some hackery to avoid using va() in constructor since we cache off the pointer to the string in the ConVar!!! #define NET_STRINGIZE( x ) #x #define NET_MAKESTRING( macro, val ) macro(val) #define NETSTRING( val ) NET_MAKESTRING( NET_STRINGIZE, val ) #endif // !NET_H