//===========================================================================// // File: l4nettransport.h // // Project: MUNGA Brick: Network Transport Seam // // Contents: The wire interface under the network manager // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #pragma once #include "..\munga\style.h" #include //######################################################################## // NetTransport - the seam between the network manager's mesh/console // logic and the wire (see context/steamification.md). Mirrors // the RIOBase pattern: L4NET keeps hosts, message queues, and the // deterministic mesh ordering; only connect/listen/send/recv live // behind this interface. // // Implementations: // WinsockNetTransport (l4nettransport.cpp) - TCP; the arcade/LAN wire // SteamNetTransport (future) - ISteamNetworkingSockets // P2P over SDR // // Addresses stay SOCKADDR_IN-shaped on purpose: Steam's FakeIP system // hands out fake IPv4 addresses for exactly this kind of engine, so // the [pilots] list keeps working as ip[:port] strings in both worlds. //######################################################################## class NetTransport { public: // Opaque connection handle. SOCKET for Winsock (SOCKET is UINT_PTR), // HSteamNetConnection for Steam - both fit; callers must not // interpret it. typedef UINT_PTR Connection; static const Connection InvalidConnection = (Connection) ~0; // == INVALID_SOCKET // Receive() results when no payload came back enum { ReceiveDisconnected = 0, // orderly close or connection reset ReceiveNoData = -1 // nothing pending (connections are nonblocking) }; virtual ~NetTransport() { } //--------------------------------------------------------------- // Lifecycle //--------------------------------------------------------------- virtual Logical Startup() = 0; virtual void Cleanup() = 0; //--------------------------------------------------------------- // Addressing: the local interface list (the mesh identifies // "which [pilots] entry is me" against it) and numeric ip[:port] // parsing. Port 0 in the result means "caller applies default". //--------------------------------------------------------------- virtual int GetLocalAddresses( unsigned long *addresses, int max_count ) = 0; virtual Logical Resolve( const char *host_name, SOCKADDR_IN *address ) = 0; //--------------------------------------------------------------- // Connections (the deterministic mesh + the console channel). // Connect blocks until the remote end accepts (the mesh relies // on retry-until-up ordering), then goes nonblocking. Listeners // are nonblocking from the start; Accept polls one. //--------------------------------------------------------------- virtual Connection Connect( const SOCKADDR_IN *remote, int local_port ) = 0; virtual Connection Listen( int local_port, int backlog ) = 0; virtual Connection Accept(Connection listener) = 0; virtual void Close(Connection connection) = 0; //--------------------------------------------------------------- // Data plane (nonblocking) //--------------------------------------------------------------- virtual int Send( Connection connection, const void *data, int size ) = 0; virtual int Receive( Connection connection, void *buffer, int size ) = 0; // remote endpoint of a live connection (mesh identity checks) virtual Logical GetRemoteAddress( Connection connection, SOCKADDR_IN *address ) = 0; }; // The process-wide transport. Defaults to Winsock TCP; a Steam build // installs its transport BEFORE the network manager comes up. NetTransport * NetTransport_Get(); void NetTransport_Set(NetTransport *transport);