News SF.net Project Frequently Asked Questions Documentation Downloads Mailing Lists How to Contribute

SourceForge.net Logo

Changing the way games are made and played.

TNL::NetInterface class Reference

TNL::NetInterface Class Reference

#include <tnlNetInterface.h>

Inheritance diagram for TNL::NetInterface:

TNL::Object TNLTest::TestNetInterface Zap::GameNetInterface

Detailed Description

NetInterface class.

Manages all valid and pending notify protocol connections for a port/IP. If you are providing multiple services or servicing multiple networks, you may have more than one NetInterface.

Connection handshaking basic overview:

TNL does a two phase connect handshake to prevent a several types of Denial-of-Service (DoS) attacks.

The initiator of the connection (client) starts the connection by sending a unique random nonce (number, used once) value to the server as part of the ConnectChallengeRequest packet. C->S: ConnectChallengeRequest, Nc

The server responds to the ConnectChallengeRequest with a "Client Puzzle" that has the property that verifying a solution to the puzzle is computationally simple, but can be of a specified computational, brute-force difficulty to compute the solution itself. The client puzzle is of the form: secureHash(Ic, Nc, Ns, X) = Y >> k, where Ic is the identity of the client, and X is a value computed by the client such that the high k bits of the value y are all zero. The client identity is computed by the server as a partial hash of the client's IP address and port and some random data on the server. its current nonce (Ns), Nc, k, and the server's authentication certificate. S->C: ConnectChallengeResponse, Nc, Ns, Ic, Cs

The client, upon receipt of the ConnectChallengeResponse, validates the packet sent by the server and computes a solution to the puzzle the server sent. If the connection is to be authenticated, the client can also validate the server's certificate (if it's been signed by a Certificate Authority), and then generates a shared secret from the client's key pair and the server's public key. The client response to the server consists of: C->S: ConnectRequest, Nc, Ns, X, Cc, sharedSecret(key1, sequence1, NetConnectionClass, class-specific sendData)

The server then can validation the solution to the puzzle the client submitted, along with the client identity (Ic). Until this point the server has allocated no memory for the client and has verified that the client is sending from a valid IP address, and that the client has done some amount of work to prove its willingness to start a connection. As the server load increases, the server may choose to increase the difficulty (k) of the client puzzle, thereby making a resource depletion DoS attack successively more difficult to launch.

If the server accepts the connection, it sends a connect accept packet that is encrypted and hashed using the shared secret. The contents of the packet are another sequence number (sequence2) and another key (key2). The sequence numbers are the initial send and receive sequence numbers for the connection, and the key2 value becomes the IV of the symmetric cipher. The connection subclass is also allowed to write any connection specific data into this packet.

This system can operate in one of 3 ways: unencrypted, encrypted key exchange (ECDH), or encrypted key exchange with server and/or client signed certificates (ECDSA).

The unencrypted communication mode is NOT secure. Packets en route between hosts can be modified without detection by the hosts at either end. Connections using the secure key exchange are still vulnerable to Man-in-the-middle attacks, but still much more secure than the unencrypted channels. Using certificate(s) signed by a trusted certificate authority (CA), makes the communications channel as securely trusted as the trust in the CA.

Arranged Connection handshaking:

NetInterface can also facilitate "arranged" connections. Arranged connections are necessary when both parties to the connection are behind firewalls or NAT routers. Suppose there are two clients, A and B that want to esablish a direct connection with one another. If A and B are both logged into some common server S, then S can send A and B the public (NAT'd) address, as well as the IP addresses each client detects for itself.

A and B then both send "Punch" packets to the known possible addresses of each other. The punch packet client A sends enables the punch packets client B sends to be delivered through the router or firewall since it will appear as though it is a service response to A's initial packet.

Upon receipt of the Punch packet by the "initiator" of the connection, an ArrangedConnectRequest packet is sent. if the non-initiator of the connection gets an ArrangedPunch packet, it simply sends another Punch packet to the remote host, but narrows down its Address range to the address it received the packet from. The ArrangedPunch packet from the intiator contains the nonce for the non-initiator, and the nonce for the initiator encrypted with the shared secret. The ArrangedPunch packet for the receiver of the connection contains all that, plus the public key/keysize or the certificate of the receiver.


Public Types

enum  PacketType {
  ConnectChallengeRequest = 0,
  ConnectChallengeResponse = 1,
  ConnectRequest = 2,
  ConnectReject = 3,
  ConnectAccept = 4,
  Disconnect = 5,
  Punch = 6,
  ArrangedConnectRequest = 7,
  FirstValidInfoPacketId = 8
}
 PacketType is encoded as the first byte of each packet. More...


Public Member Functions

 NetInterface (const Address &bindAddress)
 bindAddress Local network address to bind this interface to.

 ~NetInterface ()
Address getFirstBoundInterfaceAddress ()
 Returns the address of the first network interface in the list that the socket on this NetInterface is bound to.

void setPrivateKey (AsymmetricKey *theKey)
 Sets the private key this NetInterface will use for authentication and key exchange.

void setRequiresKeyExchange (bool requires)
 Requires that all connections use encryption and key exchange.

void setCertificate (Certificate *theCertificate)
 Sets the public certificate that validates the private key and stores information about this host.

bool doesAllowConnections ()
 Returns whether or not this NetInterface allows connections from remote hosts.

void setAllowsConnections (bool conn)
 Sets whether or not this NetInterface allows connections from remote hosts.

SocketgetSocket ()
 Returns the Socket associated with this NetInterface.

NetError sendto (const Address &address, BitStream *stream)
 Sends a packet to the remote address over this interface's socket.

void sendtoDelayed (const Address &address, BitStream *stream, U32 millisecondDelay)
 Sends a packet to the remote address after millisecondDelay time has elapsed.

void checkIncomingPackets ()
 Dispatch function for processing all network packets through this NetInterface.

virtual void processPacket (const Address &address, BitStream *packetStream)
 Processes a single packet, and dispatches either to handleInfoPacket or to the NetConnection associated with the remote address.

virtual void handleInfoPacket (const Address &address, U8 packetType, BitStream *stream)
 Handles all packets that don't fall into the category of connection handshake or game data.

void processConnections ()
 Checks all connections on this interface for packet sends, and for timeouts and all valid and pending connections.

Vector< NetConnection * > & getConnectionList ()
 Returns the list of connections on this NetInterface.

NetConnectionfindConnection (const Address &remoteAddress)
 looks up a connected connection on this NetInterface

U32 getCurrentTime ()
 returns the current process time for this NetInterface


Protected Types

enum  NetInterfaceConstants {
  ChallengeRetryCount = 4,
  ChallengeRetryTime = 2500,
  ConnectRetryCount = 4,
  ConnectRetryTime = 2500,
  PunchRetryCount = 6,
  PunchRetryTime = 2500,
  TimeoutCheckInterval = 1500,
  PuzzleSolutionTimeout = 30000
}

Protected Member Functions

U32 computeClientIdentityToken (const Address &theAddress, const Nonce &theNonce)
 Computes an identity token for the connecting client based on the address of the client and the client's unique nonce value.

NetConnectionfindPendingConnection (const Address &address)
 Finds a connection instance that this NetInterface has initiated.

void addPendingConnection (NetConnection *conn)
 Adds a connection the list of pending connections.

void removePendingConnection (NetConnection *conn)
 Removes a connection from the list of pending connections.

void findAndRemovePendingConnection (const Address &address)
 Finds a connection by address from the pending list and removes it.

void addConnection (NetConnection *connection)
 Adds a connection to the internal connection list.

void removeConnection (NetConnection *connection)
 Remove a connection from the list.

void startConnection (NetConnection *conn)
 Begins the connection handshaking process for a connection. Called from NetConnection::connect().

void sendConnectChallengeRequest (NetConnection *conn)
 Sends a connect challenge request on behalf of the connection to the remote host.

void handleConnectChallengeRequest (const Address &addr, BitStream *stream)
 Handles a connect challenge request by replying to the requestor of a connection with a unique token for that connection, as well as (possibly) a client puzzle (for DoS prevention), or this NetInterface's public key.

void sendConnectChallengeResponse (const Address &addr, Nonce &clientNonce, bool wantsKeyExchange, bool wantsCertificate)
 Sends a connect challenge request to the specified address.

void handleConnectChallengeResponse (const Address &address, BitStream *stream)
 Processes a ConnectChallengeResponse, by issueing a connect request if it was for a connection this NetInterface has pending.

void continuePuzzleSolution (NetConnection *conn)
 Continues computation of the solution of a client puzzle, and issues a connect request when the solution is found.

void sendConnectRequest (NetConnection *conn)
 Sends a connect request on behalf of a pending connection.

void handleConnectRequest (const Address &address, BitStream *stream)
 Handles a connection request from a remote host.

void sendConnectAccept (NetConnection *conn)
 Sends a connect accept packet to acknowledge the successful acceptance of a connect request.

void handleConnectAccept (const Address &address, BitStream *stream)
 Handles a connect accept packet, putting the connection associated with the remote host (if there is one) into an active state.

void sendConnectReject (ConnectionParameters *theParams, const Address &theAddress, const char *reason)
 Sends a connect rejection to a valid connect request in response to possible error conditions (server full, wrong password, etc).

void handleConnectReject (const Address &address, BitStream *stream)
 Handles a connect rejection packet by notifying the connection object that the connection was rejected.

void startArrangedConnection (NetConnection *conn)
 Begins the connection handshaking process for an arranged connection.

void sendPunchPackets (NetConnection *conn)
 Sends Punch packets to each address in the possible connection address list.

void handlePunch (const Address &theAddress, BitStream *stream)
 Handles an incoming Punch packet from a remote host.

void sendArrangedConnectRequest (NetConnection *conn)
 Sends an arranged connect request.

void handleArrangedConnectRequest (const Address &theAddress, BitStream *stream)
 Handles an incoming connect request from an arranged connection.

void handleDisconnect (const Address &address, BitStream *stream)
 Dispatches a disconnect packet for a specified connection.

void handleConnectionError (NetConnection *theConnection, const char *errorString)
 Handles an error reported while reading a packet from this remote connection.

void disconnect (NetConnection *conn, NetConnection::TerminationReason reason, const char *reasonString)
 Disconnects the given connection and removes it from the NetInterface.


Protected Attributes

Vector< NetConnection * > mConnectionList
 List of all the connections that are in a connected state on this NetInterface.

Vector< NetConnection * > mConnectionHashTable
 A resizable hash table for all connected connections. This is a flat hash table (no buckets).

Vector< NetConnection * > mPendingConnections
 List of connections that are in the startup state, where the remote host has not fully validated the connection.

RefPtr< AsymmetricKeymPrivateKey
 The private key used by this NetInterface for secure key exchange.

RefPtr< CertificatemCertificate
 A certificate, signed by some Certificate Authority, to authenticate this host.

ClientPuzzleManager mPuzzleManager
 The object that tracks the current client puzzle difficulty, current puzzle and solutions for this NetInterface.

U32 mCurrentTime
 Current time tracked by this NetInterface.

bool mRequiresKeyExchange
 True if all connections outgoing and incoming require key exchange.

U32 mLastTimeoutCheckTime
 Last time all the active connections were checked for timeouts.

U8 mRandomHashData [12]
 Data that gets hashed with connect challenge requests to prevent connection spoofing.

bool mAllowConnections
 Set if this NetInterface allows connections from remote instances.

DelaySendPacketmSendPacketList
 List of delayed packets pending to send.

NetInterfaceSocket Socket
State regarding the socket this NetInterface controls.

Socket mSocket
 Network socket this NetInterface communicates over.


Friends

class NetConnection


Member Enumeration Documentation

enum TNL::NetInterface::PacketType
 

PacketType is encoded as the first byte of each packet.

Subclasses of NetInterface can add custom, non-connected data packet types starting at FirstValidInfoPacketId, and overriding handleInfoPacket to process them.

Packets that arrive with the high bit of the first byte set (i.e. the first unsigned byte is greater than 127), are assumed to be connected protocol packets, and are dispatched to the appropriate connection for further processing.

Enumeration values:
ConnectChallengeRequest  Initial packet of the two-phase connect process.
ConnectChallengeResponse  Response packet to the ChallengeRequest containing client identity, a client puzzle, and possibly the server's public key.
ConnectRequest  A connect request packet, including all puzzle solution data and connection initiation data.
ConnectReject  A packet sent to notify a host that a ConnectRequest was rejected.
ConnectAccept  A packet sent to notify a host that a connection was accepted.
Disconnect  A packet sent to notify a host that the specified connection has terminated.
Punch  A packet sent in order to create a hole in a firewall or NAT so packets from the remote host can be received.
ArrangedConnectRequest  A connection request for an "arranged" connection.
FirstValidInfoPacketId  The first valid ID for a NetInterface subclass's info packets.

Reimplemented in Zap::GameNetInterface.

enum TNL::NetInterface::NetInterfaceConstants [protected]
 

Enumeration values:
ChallengeRetryCount  Number of times to send connect challenge requests before giving up.
ChallengeRetryTime  Timeout interval in milliseconds before retrying connect challenge.
ConnectRetryCount  Number of times to send connect requests before giving up.
ConnectRetryTime  Timeout interval in milliseconds before retrying connect request.
PunchRetryCount  Number of times to send groups of firewall punch packets before giving up.
PunchRetryTime  Timeout interval in milliseconds before retrying punch sends.
TimeoutCheckInterval  Interval in milliseconds between checking for connection timeouts.
PuzzleSolutionTimeout  If the server gives us a puzzle that takes more than 30 seconds, time out.


Constructor & Destructor Documentation

TNL::NetInterface::NetInterface const Address bindAddress  ) 
 

bindAddress Local network address to bind this interface to.

TNL::NetInterface::~NetInterface  ) 
 


Member Function Documentation

U32 TNL::NetInterface::computeClientIdentityToken const Address theAddress,
const Nonce theNonce
[protected]
 

Computes an identity token for the connecting client based on the address of the client and the client's unique nonce value.

NetConnection* TNL::NetInterface::findPendingConnection const Address address  )  [protected]
 

Finds a connection instance that this NetInterface has initiated.

void TNL::NetInterface::addPendingConnection NetConnection conn  )  [protected]
 

Adds a connection the list of pending connections.

void TNL::NetInterface::removePendingConnection NetConnection conn  )  [protected]
 

Removes a connection from the list of pending connections.

void TNL::NetInterface::findAndRemovePendingConnection const Address address  )  [protected]
 

Finds a connection by address from the pending list and removes it.

void TNL::NetInterface::addConnection NetConnection connection  )  [protected]
 

Adds a connection to the internal connection list.

void TNL::NetInterface::removeConnection NetConnection connection  )  [protected]
 

Remove a connection from the list.

void TNL::NetInterface::startConnection NetConnection conn  )  [protected]
 

Begins the connection handshaking process for a connection. Called from NetConnection::connect().

void TNL::NetInterface::sendConnectChallengeRequest NetConnection conn  )  [protected]
 

Sends a connect challenge request on behalf of the connection to the remote host.

void TNL::NetInterface::handleConnectChallengeRequest const Address addr,
BitStream stream
[protected]
 

Handles a connect challenge request by replying to the requestor of a connection with a unique token for that connection, as well as (possibly) a client puzzle (for DoS prevention), or this NetInterface's public key.

void TNL::NetInterface::sendConnectChallengeResponse const Address addr,
Nonce clientNonce,
bool  wantsKeyExchange,
bool  wantsCertificate
[protected]
 

Sends a connect challenge request to the specified address.

This can happen as a result of receiving a connect challenge request, or during an "arranged" connection for the non-initiator of the connection.

void TNL::NetInterface::handleConnectChallengeResponse const Address address,
BitStream stream
[protected]
 

Processes a ConnectChallengeResponse, by issueing a connect request if it was for a connection this NetInterface has pending.

void TNL::NetInterface::continuePuzzleSolution NetConnection conn  )  [protected]
 

Continues computation of the solution of a client puzzle, and issues a connect request when the solution is found.

void TNL::NetInterface::sendConnectRequest NetConnection conn  )  [protected]
 

Sends a connect request on behalf of a pending connection.

void TNL::NetInterface::handleConnectRequest const Address address,
BitStream stream
[protected]
 

Handles a connection request from a remote host.

This will verify the validity of the connection token, as well as any solution to a client puzzle this NetInterface sent to the remote host. If those tests pass, it will construct a local connection instance to handle the rest of the connection negotiation.

void TNL::NetInterface::sendConnectAccept NetConnection conn  )  [protected]
 

Sends a connect accept packet to acknowledge the successful acceptance of a connect request.

void TNL::NetInterface::handleConnectAccept const Address address,
BitStream stream
[protected]
 

Handles a connect accept packet, putting the connection associated with the remote host (if there is one) into an active state.

void TNL::NetInterface::sendConnectReject ConnectionParameters theParams,
const Address theAddress,
const char *  reason
[protected]
 

Sends a connect rejection to a valid connect request in response to possible error conditions (server full, wrong password, etc).

void TNL::NetInterface::handleConnectReject const Address address,
BitStream stream
[protected]
 

Handles a connect rejection packet by notifying the connection object that the connection was rejected.

void TNL::NetInterface::startArrangedConnection NetConnection conn  )  [protected]
 

Begins the connection handshaking process for an arranged connection.

void TNL::NetInterface::sendPunchPackets NetConnection conn  )  [protected]
 

Sends Punch packets to each address in the possible connection address list.

void TNL::NetInterface::handlePunch const Address theAddress,
BitStream stream
[protected]
 

Handles an incoming Punch packet from a remote host.

void TNL::NetInterface::sendArrangedConnectRequest NetConnection conn  )  [protected]
 

Sends an arranged connect request.

void TNL::NetInterface::handleArrangedConnectRequest const Address theAddress,
BitStream stream
[protected]
 

Handles an incoming connect request from an arranged connection.

void TNL::NetInterface::handleDisconnect const Address address,
BitStream stream
[protected]
 

Dispatches a disconnect packet for a specified connection.

void TNL::NetInterface::handleConnectionError NetConnection theConnection,
const char *  errorString
[protected]
 

Handles an error reported while reading a packet from this remote connection.

void TNL::NetInterface::disconnect NetConnection conn,
NetConnection::TerminationReason  reason,
const char *  reasonString
[protected]
 

Disconnects the given connection and removes it from the NetInterface.

Address TNL::NetInterface::getFirstBoundInterfaceAddress  ) 
 

Returns the address of the first network interface in the list that the socket on this NetInterface is bound to.

void TNL::NetInterface::setPrivateKey AsymmetricKey theKey  ) 
 

Sets the private key this NetInterface will use for authentication and key exchange.

void TNL::NetInterface::setRequiresKeyExchange bool  requires  )  [inline]
 

Requires that all connections use encryption and key exchange.

void TNL::NetInterface::setCertificate Certificate theCertificate  ) 
 

Sets the public certificate that validates the private key and stores information about this host.

If no certificate is set, this interface can still initiate and accept encrypted connections, but they will be vulnerable to man in the middle attacks, unless the remote host can validate the public key in another way.

bool TNL::NetInterface::doesAllowConnections  )  [inline]
 

Returns whether or not this NetInterface allows connections from remote hosts.

void TNL::NetInterface::setAllowsConnections bool  conn  )  [inline]
 

Sets whether or not this NetInterface allows connections from remote hosts.

Socket& TNL::NetInterface::getSocket  )  [inline]
 

Returns the Socket associated with this NetInterface.

NetError TNL::NetInterface::sendto const Address address,
BitStream stream
 

Sends a packet to the remote address over this interface's socket.

void TNL::NetInterface::sendtoDelayed const Address address,
BitStream stream,
U32  millisecondDelay
 

Sends a packet to the remote address after millisecondDelay time has elapsed.

This is used to simulate network latency on a LAN or single computer.

void TNL::NetInterface::checkIncomingPackets  ) 
 

Dispatch function for processing all network packets through this NetInterface.

virtual void TNL::NetInterface::processPacket const Address address,
BitStream packetStream
[virtual]
 

Processes a single packet, and dispatches either to handleInfoPacket or to the NetConnection associated with the remote address.

Reimplemented in Zap::GameNetInterface.

virtual void TNL::NetInterface::handleInfoPacket const Address address,
U8  packetType,
BitStream stream
[virtual]
 

Handles all packets that don't fall into the category of connection handshake or game data.

Reimplemented in Zap::GameNetInterface.

void TNL::NetInterface::processConnections  ) 
 

Checks all connections on this interface for packet sends, and for timeouts and all valid and pending connections.

Vector<NetConnection *>& TNL::NetInterface::getConnectionList  )  [inline]
 

Returns the list of connections on this NetInterface.

NetConnection* TNL::NetInterface::findConnection const Address remoteAddress  ) 
 

looks up a connected connection on this NetInterface

U32 TNL::NetInterface::getCurrentTime  )  [inline]
 

returns the current process time for this NetInterface


Friends And Related Function Documentation

friend class NetConnection [friend]
 


Field Documentation

Vector<NetConnection *> TNL::NetInterface::mConnectionList [protected]
 

List of all the connections that are in a connected state on this NetInterface.

Vector<NetConnection *> TNL::NetInterface::mConnectionHashTable [protected]
 

A resizable hash table for all connected connections. This is a flat hash table (no buckets).

Vector<NetConnection *> TNL::NetInterface::mPendingConnections [protected]
 

List of connections that are in the startup state, where the remote host has not fully validated the connection.

RefPtr<AsymmetricKey> TNL::NetInterface::mPrivateKey [protected]
 

The private key used by this NetInterface for secure key exchange.

RefPtr<Certificate> TNL::NetInterface::mCertificate [protected]
 

A certificate, signed by some Certificate Authority, to authenticate this host.

ClientPuzzleManager TNL::NetInterface::mPuzzleManager [protected]
 

The object that tracks the current client puzzle difficulty, current puzzle and solutions for this NetInterface.

Socket TNL::NetInterface::mSocket [protected]
 

Network socket this NetInterface communicates over.

U32 TNL::NetInterface::mCurrentTime [protected]
 

Current time tracked by this NetInterface.

bool TNL::NetInterface::mRequiresKeyExchange [protected]
 

True if all connections outgoing and incoming require key exchange.

U32 TNL::NetInterface::mLastTimeoutCheckTime [protected]
 

Last time all the active connections were checked for timeouts.

U8 TNL::NetInterface::mRandomHashData[12] [protected]
 

Data that gets hashed with connect challenge requests to prevent connection spoofing.

bool TNL::NetInterface::mAllowConnections [protected]
 

Set if this NetInterface allows connections from remote instances.

DelaySendPacket* TNL::NetInterface::mSendPacketList [protected]
 

List of delayed packets pending to send.