NAT P2P Interface

Interface to send and receive data between users, and related networking functionality.

The P2P Interface enables games implementing the Epic Online Systems (EOS) SDK to set up and manage Peer-to-Peer (P2P) Connections between users. This enables them to send and receive data between one another directly, typically for the purpose of a multiplayer game. Connections made with the EOS P2P Interface are only established between authenticated users, and are secure-by-default using DTLS, which provides two distinct advantages. First, the speed of handling P2P connections is significantly increased, in that EOS's authentication greatly reduces the need for connections to be re-negotiated. Second, the process of securely handling connections is itself greatly simplified for the SDK user, abstracting out the need for detailed network socket management and condensing most functions to what data needs to be sent and to whom.

Accessing the P2P Interface

In order to use the functions within the EOS P2P Interface, you must first obtain a valid EOS_HP2P handle from the Platform Interface function EOS_Platform_GetP2PInterface, as this handle is used in all P2P Interface functions. For more information about the Platform Interface and this function, you may refer to the page on the EOS Platform Interface .

Managing P2P Connections

The P2P Interface uses the struct EOS_P2P_SocketId as a title-specified identifier for a connection between peers. Most P2P functions related to connections either require an EOS_P2P_SocketId to associate with a connection request, or to return one in order to specify what connection a received connection request is associated with. EOS_P2P_SocketId is comprised of the following parameters:

Parameter

Description

ApiVersion

A version field. This must be set to EOS_P2P_SOCKETID_API_LATEST.

SocketName

A value used to vet all incoming connections from unknown peers in multiplayer games. A SocketName must contain 1-32 alpha-numeric, null-terminated characters.

The SocketName field can be a single value for all connections, or it can be a secret value known only to specific players in a multiplayer session. As accepted P2P connections expose a user's IP address to the peer that they are connecting to, it is important to not blindly accept any connection request.

A valid EOS_ProductUserId is also usually required both for users to identify themselves when sending data, and to specify which user they wish to send data to.

All function parameters and their associated values in the P2P Interface are required unless explicitly marked as optional. This includes out-parameters, which the P2P Interface often uses to output data for asynchronous functions or event responses. If a function has a return type of EOS_EResult and the return value is not EOS_Success, then take note that any out-parameters that the function provides will be unset unless specified otherwise.

Requesting Connections

When a local user attempts to send information to a remote user, such as with the EOS_P2P_SendPacket function, the P2P Interface will automatically make a request to open a connection between those two users, with an EOS_P2P_SocketId acting as the identifier for that connection. The user sending the information automatically accepts their own request for that SocketId, while the user receiving the information must accept it, usually by listening for the incoming connection request and using the EOS_P2P_AcceptConnection function.

All operations requiring an open P2P connection can be used to both request and accept a P2P connection if one is not already open. For example, EOS_P2P_AcceptConnection can be used to request a P2P connection with a remote user, and EOS_P2P_SendPacket can be used to accept a remote user's P2P connection request if one has already been made for the Socket Id that the local user is trying to use to send information. This effectively means that it is possible to use EOS_P2P_AcceptConnection to pre-emptively accept the next connection request made with a given SocketId.

If multiple connections are open with a particular user, only the first connection must be negotiated. This greatly increases the speed at which data may be received with subsequent connection requests.

Receiving Connection Request Notifications

When a user receives a connection request, a notify event is fired to all bound Peer Connection Request Handlers.

To listen for connection requests with a new Peer Connection Request Handler, use EOS_P2P_AddNotifyPeerConnectionRequest to bind a function that you would like to use as a response to incoming connection requests. The EOS_P2P_AddNotifyPeerConnectionRequest function takes the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

A pointer to an EOS_P2P_AddNotifyPeerConnectionRequestOptions struct.

ClientData (Optional)

Pointer to data that will be returned to the caller when the event fires.

ConnectionRequestHandler

A function that will act as your Peer Connection Request Handler, responding to incoming connection requests. This function must take a pointer to an EOS_P2P_OnIncomingConnectionRequestInfo struct as a parameter.

The EOS_P2P_AddNotifyPeerConnectionRequestOptions struct is comprised of the following parameters:

Parameter

Description

ApiVersion

A version field. Set to EOS_P2P_ADDNOTIFYPEERCONNECTIONREQUEST_API_LATEST

LocalUserId

Set to the ID of the local user that is listening for incoming connection request.

SocketId (Optional)

Pointer to a valid EOS_P2P_SocketId struct that you would like to use to filter connection requests.

The EOS_P2P_AddNotifyPeerConnectionRequest function will return either a valid EOS_NotificationId on success, or the value EOS_INVALID_NOTIFICATIONID on failure.

You can remove a Peer Connection Request Handler with the EOS_P2P_RemoveNotifyPeerConnectionRequest function, which requires the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

NotificationId

A valid EOS_NotificationId returned from EOS_P2P_AddNotifyPeerConnectionRequest, used to identify the peer connection request handler you wish to remove.

Accepting Connections

The EOS_P2P_AcceptConnection function can be used to accept a connection that has been requested, or to start a new connection request. Both users must accept a connection for a given SocketId before the connection can be established and used to send data. The user attempting to open a connection automatically accepts the connection for the EOS_P2P_SocketId that their information is being sent on, but the user receiving the connection request must accept it either by opening their own connection request, or by using EOS_P2P_AcceptConnection.

To call the EOS_P2P_AcceptConnection function, you must provide the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

A pointer to an EOS_P2P_AcceptConnectionOptions struct.

The EOS_P2P_AcceptConnectionOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_ACCEPTCONNECTION_API_LATEST

LocalUserId

Set to the EOS_ProductUserId of the local user that is accepting the connection.

RemoteUserId

Set to the EOS_ProductUserId of the remote user that the local user wants to connect to.

SocketId

Pointer to a valid EOS_P2P_SocketId struct that you would like to accept a connection for.

The EOS_P2P_AcceptConnection function will return a value of EOS_InvalidParameters if any of the supplied input was invalid. It will return EOS_Success if the supplied information was valid, signifying that the connection was locally accepted and will be able to send data when the remote user accepts the connection as well. Calling EOS_P2P_AcceptConnection multiple times before a Connection Closed event fires will have no effect.

Closing Connections

The EOS_P2P_CloseConnection function can be used to reject a connection that has been requested, or to close a connection that was previously accepted with a specific user. If all connections with a specific user are closed, the backing socket connection will also be destroyed soon after. The EOS_P2P_CloseConnection function requires the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

A pointer to an EOS_P2P_CloseConnectionOptions struct.

The EOS_P2P_CloseConnectionOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_CLOSECONNECTION_API_LATEST.

LocalUserId

Set to the EOS_ProductUserId of the local user that is closing or rejecting the connection.

RemoteUserId

Set to the EOS_ProductUserId of the remote user whose connection is being closed or rejected.

SocketId

Pointer to a valid EOS_P2P_SocketId struct you would like to close or reject a connection on.

The EOS_P2P_CloseConnection function will return either a value of EOS_InvalidParameters, signifying that the supplied input for the function was invalid, or it will return a value of EOS_Success, in which case the supplied input was valid and the connection will be closed or the connection request will be silently rejected.

The EOS_P2P_CloseConnections function can be used to close or reject all connections on a specific SocketId, rather than a connection from a specific user. This could be used at the end of a session to drop all related connections for that session. The EOS_P2P_CloseConnections function requires the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

Pointer to an EOS_P2P_CloseConnectionsOptions struct.

The EOS_P2P_CloseConnectionsOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_CLOSECONNECTIONS_API_LATEST

LocalUserId

Set to the EOS_ProductUserId of the local user that is closing all connections with the requested SocketId.

SocketId

Pointer to a valid EOS_P2P_SocketId struct that you would like to close all connections on.

The function will return a result of EOS_InvalidParameters if any of the supplied input was invalid, or it will return EOS_Success if the supplied information was valid and all the connections with the specified SocketId were successfully closed.

Receiving Connection Closed Notifications

When an open or pending connection closes, a Connection Closed Event will fire, notifying the application and permitting it to respond. To create a handler for Connection Closed Events, use the EOS_P2P_AddNotifyPeerConnectionClosed function, which requires the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

Pointer to a EOS_P2P_AddNotifyPeerConnectionClosedOptions struct.

ClientData (Optional)

Pointer to data that will be returned to the caller when the event fires.

ConnectionClosedHandler

A function that will be called when the Connection Closed Event fires. This function must take a pointer to an EOS_P2P_OnRemoteConnectionClosedInfo struct passed as a parameter.

The EOS_P2P_AddNotifyPeerConnectionClosedOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_ADDNOTIFYPEERCONNECTIONCLOSED_API_LATEST.

LocalUserId

Set to the EOS_ProductUserId of the local user that is listening for connections to close.

SocketId (Optional)

Pointer to a valid EOS_P2P_SocketId struct that you would like to filter connection closed events on.

The EOS_P2P_AddNotifyPeerConnectionClosed function returns an EOS_NotificationId that can be used to identify the Connection Closed Event Handler.

You can remove a Connection Closed Event Handler by calling the function EOS_P2P_RemoveNotifyPeerConnectionClosed, which takes the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

NotificationId

A valid EOS_NotificationId returned from EOS_P2P_AddNotifyPeerConnectionClosed.

Sending and Receiving Data Through P2P Connections

Once a P2P Connection is successfully established, users may send and receive data through it.

Sending Data

The EOS_P2P_SendPacket function will securely send a packet to another user. If there is already an open connection to that peer, it will be sent immediately. If there is not an open connection, then a request for a new connection will be made. The EOS_P2P_SendPacket function takes the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

A pointer to a EOS_P2P_SendPacketOptions struct.

The EOS_P2P_SendPacketOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_SENDPACKET_API_LATEST.

LocalUserId

Set to the EOS_ProductUserId of the local user that is sending the packet.

RemoteUserId

Set to the EOS_ProductUserId of the remote user to send the packet to.

SocketId

Pointer to a valid EOS_P2P_SocketId.

Channel

Set to the channel to send this data on.

DataLengthBytes

Set to the amount of bytes to send from Data.

Data

Pointer to the start of the buffer of data to send DataLengthBytes from.

bAllowDelayedDelivery

If we do not have an established connection and this is false, the packet will be silently dropped. Otherwise the packet will be queued until the connection has been opened or until the connection is closed using EOS_P2P_CloseConnection or EOS_P2P_CloseConnections.

This function will return either EOS_InvalidParameters if any of the supplied input is invalid, or EOS_Success if the supplied information was valid and could be sent. Note that a return of Success only denotes that the packet can be successfully sent, not whether or not it is successfully delivered. Successful delivery is not guaranteed, as data is sent unreliably.

Receiving Data

The P2P Interface queues packets that a user receives internally, awaiting a call to the EOS_P2P_ReceivePacket function in order to remove it from the queue and store its data in a buffer. This function takes the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

A pointer to a valid EOS_P2P_ReceivePacketOptions struct.

OutPeerId

A pointer to an EOS_ProductUserId value to write out who sent this packet.

OutSocketId

A pointer to an EOS_P2P_SocketId struct to write the associated SocketId data into.

OutChannel

A pointer to a uint8_t to write the associated Channel for this packet.

OutData

A pointer to a buffer that will have the data from the received packet written to it. This buffer must be the size of MaxDataSizeBytes in the Options for this function.

OutBytesWritten

A pointer to a uint32_t, which will record the number of bytes written to OutData.

The EOS_P2P_ReceivePacketOptions struct contains the following parameters:

Parameter

Description

ApiVersion

A version field. Set to EOS_P2P_RECEIVEPACKET_API_LATEST

LocalUserId

Set to the EOS_ProductUserId of the local user that is requesting the received packet.

MaxDataSizeBytes

The maximum amount of bytes that can be written to the OutData buffer safely.

RequestedChannel (Optional)

If set, only packets belonging to this channel will be received.

The function will return EOS_InvalidParameters if any of the input parameters were invalid. It will return EOS_Success if the packet and its associated data is copied into all of the out-paramters successfully, and it will return EOS_NotFound if there are no packets available to fulfill the request. It is important to note that the out-parameters will only be written to if the function returns a value of EOS_Success.

EOS_P2P_ReceivePacketOptions requires you to specify the amount of data that can be safely written to the buffer with MaxDataSizeBytes, in addition to specifying the buffer itself with OutData. If the provided buffer is too small to fit the next packet, the data will be silently truncated to the provided buffer's length. It is possible to discard a packet's data entirely by providing a buffer of NULL in OutData, with a size of 0 in MaxDataSizeBytes. It is also possible to safely use a buffer of EOS_P2P_MAX_PACKET_SIZE to store the data from a packet, but it is recommended to call EOS_P2P_GetNextReceivedPacketSize to retrieve the exact size of the packet data before calling EOS_P2P_ReceivePacket.

It is recommended to call EOS_P2P_RecievePacket often to prevent the internal packet queue from filling up. If the internal packet queue is full, incoming packets will be lost rather than received.

Determining Packet Size

EOS_P2P_GetNextReceivedPacketSize retrieves size in bytes of the next packet in the internal queue without removing it from the queue, and it takes the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

Pointer to a EOS_P2P_GetNextReceivedPacketSizeOptions struct.

OutPacketSizeBytes

A pointer to a uint32_t that can store the size of the next packet for the user calling the function.

The EOS_P2P_GetNextReceivedPacketSizeOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_GETNEXTRECEIVEDPACKETSIZE_API_LATEST

LocalUserId

Set to the EOS_ProductUserId of the local user that is requesting the size of the next packet.

RequestedChannel (Optional)

If set, only the size of the next packet belonging to this channel will be returned.

This function will return a value of EOS_InvalidParameters if any of the input parameters are invalid, or a value of EOS_Success if the packet data size was copied to OutPacketSizeBytes successfully. If no data is available, the function will return a value of EOS_NotFound instead.

Determining NAT Type

While the P2P Interface will attempt NAT-traversal, it is not always possible to receive incoming connections when one or more peers has a restrictive NAT. In these cases a relay is required, which will be used automatically in case of NAT-traversal failure. To help determine if the user can easily connect to peers, the P2P Interface can query the local user's NAT Type in relation to the internet. This is represented by EOS_ENATType, which can take the following values:

Value

Description

EOS_NAT_Unknown

The NAT Type is either currently unknown or we are otherwise unable to accurately determine it.

EOS_NAT_Open

All types of peers should be able to directly connect to you.

EOS_NAT_Moderate

You can directly connect to other Moderate and Open peers without the use of relay servers.

EOS_NAT_Strict

You can directly connect only to Open peers without the use of relay servers.

The EOS_P2P_QueryNATType function can asynchronously determine the NAT Type of the current connection. It does this by sending multiple packets of data to remote servers, and those servers respond back with what IP and Ports the local application used. Note that additional calls to EOS_P2P_QueryNATType while a request is already in progress will be grouped into that first request, and will not start new requests. EOS_P2P_QueryNATType takes the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

A pointer to an EOS_P2P_QueryNATTypeOptions struct.

ClientData (Optional)

Pointer to data that will be returned to the caller when the query finishes.

NATTypeQueriedHandler

Pointer to a function to call when the query finishes.

The EOS_P2P_QueryNATTypeOptions struct contains the following parameters:

Parameter

Description

ApiVersion

A version field. Set to EOS_P2P_QUERYNATTYPE_API_LATEST.

Because the NAT Type query is asynchronous, this function does not return a value directly. Instead, it outputs the user's NAT Type through a NAT Type Queried Handler, a function that is registered to occur when the query finishes. In some cases this query will be unable to determine the user's NAT Type, and will instead return a value of EOS_NAT_Unknown.

When EOS_P2P_QueryNATType completes, the value of the user's NAT Type is cached, and you can instead call the function EOS_P2P_GetNATType to return that value immediately. This will only return successfully if EOS_P2P_QueryNATType has completed at least once. To call the EOS_P2P_GetNATType function, you must provide the following parameters:

Parameter

Description

Handle

A valid EOS_HP2P handle received from the Platform Interface.

Options

Pointer to an EOS_P2P_GetNATTypeOptions struct.

OutNATType

Pointer to an EOS_ENATType object to set to the cached value that was previously queried by EOS_P2P_QueryNATType.

The EOS_P2P_GetNATTypeOptions struct contains the following parameters:

Parameter

Description

ApiVersion

Set to EOS_P2P_GETNATTYPE_API_LATEST.

The EOS_P2P_GetNATType function will return EOS_Success if EOS_P2P_QueryNATType was successfully called in the past. It will return EOS_NotFound if EOS_P2P_QueryNATType has not been called before, or if it has not been completed.

Tags