public/steam/isteamnetworking.h
author Nicholas Hastings <nshastings@gmail.com>
Sun Nov 03 09:37:43 2013 -0500 (2013-11-03)
changeset 29 e827f56d0c8f
permissions -rw-r--r--
Recompile linux and mac tier1.
     1 //========= Copyright Valve Corporation, All rights reserved. ============//
     2 //
     3 // Purpose: interface to steam managing network connections between game clients & servers
     4 //
     5 //=============================================================================
     6 
     7 #ifndef ISTEAMNETWORKING
     8 #define ISTEAMNETWORKING
     9 #ifdef _WIN32
    10 #pragma once
    11 #endif
    12 
    13 #include "steamtypes.h"
    14 #include "steamclientpublic.h"
    15 
    16 
    17 // list of possible errors returned by SendP2PPacket() API
    18 // these will be posted in the P2PSessionConnectFail_t callback
    19 enum EP2PSessionError
    20 {
    21 	k_EP2PSessionErrorNone = 0,
    22 	k_EP2PSessionErrorNotRunningApp = 1,			// target is not running the same game
    23 	k_EP2PSessionErrorNoRightsToApp = 2,			// local user doesn't own the app that is running
    24 	k_EP2PSessionErrorDestinationNotLoggedIn = 3,	// target user isn't connected to Steam
    25 	k_EP2PSessionErrorTimeout = 4,					// target isn't responding, perhaps not calling AcceptP2PSessionWithUser()
    26 													// corporate firewalls can also block this (NAT traversal is not firewall traversal)
    27 													// make sure that UDP ports 3478, 4379, and 4380 are open in an outbound direction
    28 	k_EP2PSessionErrorMax = 5
    29 };
    30 
    31 // SendP2PPacket() send types
    32 // Typically k_EP2PSendUnreliable is what you want for UDP-like packets, k_EP2PSendReliable for TCP-like packets
    33 enum EP2PSend
    34 {
    35 	// Basic UDP send. Packets can't be bigger than 1200 bytes (your typical MTU size). Can be lost, or arrive out of order (rare).
    36 	// The sending API does have some knowledge of the underlying connection, so if there is no NAT-traversal accomplished or
    37 	// there is a recognized adjustment happening on the connection, the packet will be batched until the connection is open again.
    38 	k_EP2PSendUnreliable = 0,
    39 
    40 	// As above, but if the underlying p2p connection isn't yet established the packet will just be thrown away. Using this on the first
    41 	// packet sent to a remote host almost guarantees the packet will be dropped.
    42 	// This is only really useful for kinds of data that should never buffer up, i.e. voice payload packets
    43 	k_EP2PSendUnreliableNoDelay = 1,
    44 
    45 	// Reliable message send. Can send up to 1MB of data in a single message. 
    46 	// Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for efficient sends of large chunks of data. 
    47 	k_EP2PSendReliable = 2,
    48 
    49 	// As above, but applies the Nagle algorithm to the send - sends will accumulate 
    50 	// until the current MTU size (typically ~1200 bytes, but can change) or ~200ms has passed (Nagle algorithm). 
    51 	// Useful if you want to send a set of smaller messages but have the coalesced into a single packet
    52 	// Since the reliable stream is all ordered, you can do several small message sends with k_EP2PSendReliableWithBuffering and then
    53 	// do a normal k_EP2PSendReliable to force all the buffered data to be sent.
    54 	k_EP2PSendReliableWithBuffering = 3,
    55 
    56 };
    57 
    58 
    59 // connection state to a specified user, returned by GetP2PSessionState()
    60 // this is under-the-hood info about what's going on with a SendP2PPacket(), shouldn't be needed except for debuggin
    61 #if defined( VALVE_CALLBACK_PACK_SMALL )
    62 #pragma pack( push, 4 )
    63 #elif defined( VALVE_CALLBACK_PACK_LARGE )
    64 #pragma pack( push, 8 )
    65 #else
    66 #error isteamclient.h must be included
    67 #endif 
    68 struct P2PSessionState_t
    69 {
    70 	uint8 m_bConnectionActive;		// true if we've got an active open connection
    71 	uint8 m_bConnecting;			// true if we're currently trying to establish a connection
    72 	uint8 m_eP2PSessionError;		// last error recorded (see enum above)
    73 	uint8 m_bUsingRelay;			// true if it's going through a relay server (TURN)
    74 	int32 m_nBytesQueuedForSend;
    75 	int32 m_nPacketsQueuedForSend;
    76 	uint32 m_nRemoteIP;				// potential IP:Port of remote host. Could be TURN server. 
    77 	uint16 m_nRemotePort;			// Only exists for compatibility with older authentication api's
    78 };
    79 #pragma pack( pop )
    80 
    81 
    82 // handle to a socket
    83 typedef uint32 SNetSocket_t;		// CreateP2PConnectionSocket()
    84 typedef uint32 SNetListenSocket_t;	// CreateListenSocket()
    85 
    86 // connection progress indicators, used by CreateP2PConnectionSocket()
    87 enum ESNetSocketState
    88 {
    89 	k_ESNetSocketStateInvalid = 0,						
    90 
    91 	// communication is valid
    92 	k_ESNetSocketStateConnected = 1,				
    93 	
    94 	// states while establishing a connection
    95 	k_ESNetSocketStateInitiated = 10,				// the connection state machine has started
    96 
    97 	// p2p connections
    98 	k_ESNetSocketStateLocalCandidatesFound = 11,	// we've found our local IP info
    99 	k_ESNetSocketStateReceivedRemoteCandidates = 12,// we've received information from the remote machine, via the Steam back-end, about their IP info
   100 
   101 	// direct connections
   102 	k_ESNetSocketStateChallengeHandshake = 15,		// we've received a challenge packet from the server
   103 
   104 	// failure states
   105 	k_ESNetSocketStateDisconnecting = 21,			// the API shut it down, and we're in the process of telling the other end	
   106 	k_ESNetSocketStateLocalDisconnect = 22,			// the API shut it down, and we've completed shutdown
   107 	k_ESNetSocketStateTimeoutDuringConnect = 23,	// we timed out while trying to creating the connection
   108 	k_ESNetSocketStateRemoteEndDisconnected = 24,	// the remote end has disconnected from us
   109 	k_ESNetSocketStateConnectionBroken = 25,		// connection has been broken; either the other end has disappeared or our local network connection has broke
   110 
   111 };
   112 
   113 // describes how the socket is currently connected
   114 enum ESNetSocketConnectionType
   115 {
   116 	k_ESNetSocketConnectionTypeNotConnected = 0,
   117 	k_ESNetSocketConnectionTypeUDP = 1,
   118 	k_ESNetSocketConnectionTypeUDPRelay = 2,
   119 };
   120 
   121 
   122 //-----------------------------------------------------------------------------
   123 // Purpose: Functions for making connections and sending data between clients,
   124 //			traversing NAT's where possible
   125 //-----------------------------------------------------------------------------
   126 class ISteamNetworking
   127 {
   128 public:
   129 	////////////////////////////////////////////////////////////////////////////////////////////
   130 	// Session-less connection functions
   131 	//    automatically establishes NAT-traversing or Relay server connections
   132 
   133 	// Sends a P2P packet to the specified user
   134 	// UDP-like, unreliable and a max packet size of 1200 bytes
   135 	// the first packet send may be delayed as the NAT-traversal code runs
   136 	// if we can't get through to the user, an error will be posted via the callback P2PSessionConnectFail_t
   137 	// see EP2PSend enum above for the descriptions of the different ways of sending packets
   138 	//
   139 	// nChannel is a routing number you can use to help route message to different systems 	- you'll have to call ReadP2PPacket() 
   140 	// with the same channel number in order to retrieve the data on the other end
   141 	// using different channels to talk to the same user will still use the same underlying p2p connection, saving on resources
   142 	virtual bool SendP2PPacket( CSteamID steamIDRemote, const void *pubData, uint32 cubData, EP2PSend eP2PSendType, int nChannel = 0 ) = 0;
   143 
   144 	// returns true if any data is available for read, and the amount of data that will need to be read
   145 	virtual bool IsP2PPacketAvailable( uint32 *pcubMsgSize, int nChannel = 0 ) = 0;
   146 
   147 	// reads in a packet that has been sent from another user via SendP2PPacket()
   148 	// returns the size of the message and the steamID of the user who sent it in the last two parameters
   149 	// if the buffer passed in is too small, the message will be truncated
   150 	// this call is not blocking, and will return false if no data is available
   151 	virtual bool ReadP2PPacket( void *pubDest, uint32 cubDest, uint32 *pcubMsgSize, CSteamID *psteamIDRemote, int nChannel = 0 ) = 0;
   152 
   153 	// AcceptP2PSessionWithUser() should only be called in response to a P2PSessionRequest_t callback
   154 	// P2PSessionRequest_t will be posted if another user tries to send you a packet that you haven't talked to yet
   155 	// if you don't want to talk to the user, just ignore the request
   156 	// if the user continues to send you packets, another P2PSessionRequest_t will be posted periodically
   157 	// this may be called multiple times for a single user
   158 	// (if you've called SendP2PPacket() on the other user, this implicitly accepts the session request)
   159 	virtual bool AcceptP2PSessionWithUser( CSteamID steamIDRemote ) = 0;
   160 
   161 	// call CloseP2PSessionWithUser() when you're done talking to a user, will free up resources under-the-hood
   162 	// if the remote user tries to send data to you again, another P2PSessionRequest_t callback will be posted
   163 	virtual bool CloseP2PSessionWithUser( CSteamID steamIDRemote ) = 0;
   164 
   165 	// call CloseP2PChannelWithUser() when you're done talking to a user on a specific channel. Once all channels
   166 	// open channels to a user have been closed, the open session to the user will be closed and new data from this
   167 	// user will trigger a P2PSessionRequest_t callback
   168 	virtual bool CloseP2PChannelWithUser( CSteamID steamIDRemote, int nChannel ) = 0;
   169 
   170 	// fills out P2PSessionState_t structure with details about the underlying connection to the user
   171 	// should only needed for debugging purposes
   172 	// returns false if no connection exists to the specified user
   173 	virtual bool GetP2PSessionState( CSteamID steamIDRemote, P2PSessionState_t *pConnectionState ) = 0;
   174 
   175 	// Allow P2P connections to fall back to being relayed through the Steam servers if a direct connection
   176 	// or NAT-traversal cannot be established. Only applies to connections created after setting this value,
   177 	// or to existing connections that need to automatically reconnect after this value is set.
   178 	//
   179 	// P2P packet relay is allowed by default
   180 	virtual bool AllowP2PPacketRelay( bool bAllow ) = 0;
   181 
   182 
   183 	////////////////////////////////////////////////////////////////////////////////////////////
   184 	// LISTEN / CONNECT style interface functions
   185 	//
   186 	// This is an older set of functions designed around the Berkeley TCP sockets model
   187 	// it's preferential that you use the above P2P functions, they're more robust
   188 	// and these older functions will be removed eventually
   189 	//
   190 	////////////////////////////////////////////////////////////////////////////////////////////
   191 
   192 
   193 	// creates a socket and listens others to connect
   194 	// will trigger a SocketStatusCallback_t callback on another client connecting
   195 	// nVirtualP2PPort is the unique ID that the client will connect to, in case you have multiple ports
   196 	//		this can usually just be 0 unless you want multiple sets of connections
   197 	// unIP is the local IP address to bind to
   198 	//		pass in 0 if you just want the default local IP
   199 	// unPort is the port to use
   200 	//		pass in 0 if you don't want users to be able to connect via IP/Port, but expect to be always peer-to-peer connections only
   201 	virtual SNetListenSocket_t CreateListenSocket( int nVirtualP2PPort, uint32 nIP, uint16 nPort, bool bAllowUseOfPacketRelay ) = 0;
   202 
   203 	// creates a socket and begin connection to a remote destination
   204 	// can connect via a known steamID (client or game server), or directly to an IP
   205 	// on success will trigger a SocketStatusCallback_t callback
   206 	// on failure or timeout will trigger a SocketStatusCallback_t callback with a failure code in m_eSNetSocketState
   207 	virtual SNetSocket_t CreateP2PConnectionSocket( CSteamID steamIDTarget, int nVirtualPort, int nTimeoutSec, bool bAllowUseOfPacketRelay ) = 0;
   208 	virtual SNetSocket_t CreateConnectionSocket( uint32 nIP, uint16 nPort, int nTimeoutSec ) = 0;
   209 
   210 	// disconnects the connection to the socket, if any, and invalidates the handle
   211 	// any unread data on the socket will be thrown away
   212 	// if bNotifyRemoteEnd is set, socket will not be completely destroyed until the remote end acknowledges the disconnect
   213 	virtual bool DestroySocket( SNetSocket_t hSocket, bool bNotifyRemoteEnd ) = 0;
   214 	// destroying a listen socket will automatically kill all the regular sockets generated from it
   215 	virtual bool DestroyListenSocket( SNetListenSocket_t hSocket, bool bNotifyRemoteEnd ) = 0;
   216 
   217 	// sending data
   218 	// must be a handle to a connected socket
   219 	// data is all sent via UDP, and thus send sizes are limited to 1200 bytes; after this, many routers will start dropping packets
   220 	// use the reliable flag with caution; although the resend rate is pretty aggressive,
   221 	// it can still cause stalls in receiving data (like TCP)
   222 	virtual bool SendDataOnSocket( SNetSocket_t hSocket, void *pubData, uint32 cubData, bool bReliable ) = 0;
   223 
   224 	// receiving data
   225 	// returns false if there is no data remaining
   226 	// fills out *pcubMsgSize with the size of the next message, in bytes
   227 	virtual bool IsDataAvailableOnSocket( SNetSocket_t hSocket, uint32 *pcubMsgSize ) = 0; 
   228 
   229 	// fills in pubDest with the contents of the message
   230 	// messages are always complete, of the same size as was sent (i.e. packetized, not streaming)
   231 	// if *pcubMsgSize < cubDest, only partial data is written
   232 	// returns false if no data is available
   233 	virtual bool RetrieveDataFromSocket( SNetSocket_t hSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize ) = 0; 
   234 
   235 	// checks for data from any socket that has been connected off this listen socket
   236 	// returns false if there is no data remaining
   237 	// fills out *pcubMsgSize with the size of the next message, in bytes
   238 	// fills out *phSocket with the socket that data is available on
   239 	virtual bool IsDataAvailable( SNetListenSocket_t hListenSocket, uint32 *pcubMsgSize, SNetSocket_t *phSocket ) = 0;
   240 
   241 	// retrieves data from any socket that has been connected off this listen socket
   242 	// fills in pubDest with the contents of the message
   243 	// messages are always complete, of the same size as was sent (i.e. packetized, not streaming)
   244 	// if *pcubMsgSize < cubDest, only partial data is written
   245 	// returns false if no data is available
   246 	// fills out *phSocket with the socket that data is available on
   247 	virtual bool RetrieveData( SNetListenSocket_t hListenSocket, void *pubDest, uint32 cubDest, uint32 *pcubMsgSize, SNetSocket_t *phSocket ) = 0;
   248 
   249 	// returns information about the specified socket, filling out the contents of the pointers
   250 	virtual bool GetSocketInfo( SNetSocket_t hSocket, CSteamID *pSteamIDRemote, int *peSocketStatus, uint32 *punIPRemote, uint16 *punPortRemote ) = 0;
   251 
   252 	// returns which local port the listen socket is bound to
   253 	// *pnIP and *pnPort will be 0 if the socket is set to listen for P2P connections only
   254 	virtual bool GetListenSocketInfo( SNetListenSocket_t hListenSocket, uint32 *pnIP, uint16 *pnPort ) = 0;
   255 
   256 	// returns true to describe how the socket ended up connecting
   257 	virtual ESNetSocketConnectionType GetSocketConnectionType( SNetSocket_t hSocket ) = 0;
   258 
   259 	// max packet size, in bytes
   260 	virtual int GetMaxPacketSize( SNetSocket_t hSocket ) = 0;
   261 };
   262 #define STEAMNETWORKING_INTERFACE_VERSION "SteamNetworking005"
   263 
   264 // callbacks
   265 #if defined( VALVE_CALLBACK_PACK_SMALL )
   266 #pragma pack( push, 4 )
   267 #elif defined( VALVE_CALLBACK_PACK_LARGE )
   268 #pragma pack( push, 8 )
   269 #else
   270 #error isteamclient.h must be included
   271 #endif 
   272 
   273 // callback notification - a user wants to talk to us over the P2P channel via the SendP2PPacket() API
   274 // in response, a call to AcceptP2PPacketsFromUser() needs to be made, if you want to talk with them
   275 struct P2PSessionRequest_t
   276 { 
   277 	enum { k_iCallback = k_iSteamNetworkingCallbacks + 2 };
   278 	CSteamID m_steamIDRemote;			// user who wants to talk to us
   279 };
   280 
   281 
   282 // callback notification - packets can't get through to the specified user via the SendP2PPacket() API
   283 // all packets queued packets unsent at this point will be dropped
   284 // further attempts to send will retry making the connection (but will be dropped if we fail again)
   285 struct P2PSessionConnectFail_t
   286 { 
   287 	enum { k_iCallback = k_iSteamNetworkingCallbacks + 3 };
   288 	CSteamID m_steamIDRemote;			// user we were sending packets to
   289 	uint8 m_eP2PSessionError;			// EP2PSessionError indicating why we're having trouble
   290 };
   291 
   292 
   293 // callback notification - status of a socket has changed
   294 // used as part of the CreateListenSocket() / CreateP2PConnectionSocket() 
   295 struct SocketStatusCallback_t
   296 { 
   297 	enum { k_iCallback = k_iSteamNetworkingCallbacks + 1 };
   298 	SNetSocket_t m_hSocket;				// the socket used to send/receive data to the remote host
   299 	SNetListenSocket_t m_hListenSocket;	// this is the server socket that we were listening on; NULL if this was an outgoing connection
   300 	CSteamID m_steamIDRemote;			// remote steamID we have connected to, if it has one
   301 	int m_eSNetSocketState;				// socket state, ESNetSocketState
   302 };
   303 
   304 #pragma pack( pop )
   305 
   306 #endif // ISTEAMNETWORKING