Skip to content

Latest commit

 

History

History
136 lines (105 loc) · 6.66 KB

README_P2P.md

File metadata and controls

136 lines (105 loc) · 6.66 KB

About that P2P support....

SteamNetworkingSockets supports peer-to-peer connections. A "peer-to-peer" connection in this context means that the hosts do not (initially) know each other's IP address. Furthermore, they may be behind NAT, and so they may not know their own public IP address. They may not even have a public IP that other hosts can use to send them inbound traffic. Here is a good article about the problem of NAT traversal.

ICE is an internet standard protocol for discovering and sharing IP addresses, negotiating NAT, and establishing a direct connection or fallback to relaying the connection if necessary.

The opensource version of the code can compile with google webrtc's ICE implementation. We interface with the WebRTC code at a reletaively low level and only use it for datagram transport. We don't use DTLS or WebRTC data channels. (In the future, we may offer alternate NAT traversal implementations. In particular, we'd like to have an implementation that uses PCP, which is not used by the current google WebRTC code.)

Symmetric connect mode

SteamNetworkingSockets offers a unique feature known as symmetric connect mode, which really puts the "peer" in "peer-to-peer connection". This feature is useful in the following common use case:

  • Two hosts wish to establish a single connection between them.
  • Either host may initiate the connection.
  • The hosts may initiate the connection at the same time.

This situation involves race conditions that can be tricky to get right, especially when authentication, encryption, ICE roles, etc are involved. With symmetric connect mode, sorting out these race conditions and producing a single connection is handled by the API.

See the k_ESteamNetworkingConfig_SymmetricConnect connection flag in steamnetworkingtypes.h for more info.

Requirements

Peer-to-peer connections require more than just working code. In addition to the code in this library, there are several other prerequisites. (Note that the Steamworks API provides all of these services for Steam games.)

Signaling service

A side channel, capable of relaying small rendezvous messages from one host to another. This means hosts must have a constant connection to your service, once that enables you to push messages to them.

SteamNetworkingSockets supports a pluggable signaling service. The requirements placed on your signaling service are relatively minimal:

  • Individual rendezvous messages are small. (Perhaps bigger than IP MTU, but never more than a few KB.)
  • Only datagram "best-effort" delivery is required. We are tolerant protocol is tolerant of dropped, duplicated, or reordered messages. These anomolies may cause negotiation to take longer, but not fail. This means, for example that there doesn't need to be a mechanism to inform the system when your connection to the signaling service is disrupted.
  • The channel can be relatively low bandwidth and high latency. Usually there is a burst of a handful of exchanges when a connection is created, followed by silence, unless something changes with the connection.

STUN server(s)

A STUN server is used to help peers discover their own public IP address and open up firewalls. STUN servers are relatively low bandwidth, and there are publicly-available ones.

Relay fallback

Unfortunatley, for some pairs of hosts, NAT piercing is not successful. In this situation, the traffic must be relayed. In the ICE protocol, this is done using TURN servers. (NOTE: Any TURN server also doubles as a STUN server.) Because the TURN server is relaying every packet, is is a relatively costly service, so you probably will need to run your own, or just fail connections that cannot pierce NAT.

On Steam we use a custom relay service known as Steam Datgaram Relay -- SDR for short -- carrying packets through our network of relays and on our backbone. (You may see this mentioned in the opensource code here, but the SDR support code is not opensource.) Also, on Steam we always relay traffic and do not share IP addresses between untrusted peers, so that malicious players cannot DoS attack.

Naming hosts and matchmaking

The above requirements are just what is needed to make a connection between two hosts, once you know who to connect to. But before that, you need a way to assign an identity to a host, authenticate them, matchmaking them, etc. Those services are also included with Steam, but outside the scope of a transport library like this.

Using P2P

Assuming you have all of those requirements, you can use SteamNetworkingSockets to make P2P connections!

To compile with ICE support, set USE_STEAMWEBRTC when building the project files:

cmake -DUSE_STEAMWEBRTC=ON (etc...)

You'll also need to activate two git submodules to pull down the google WebRTC code. (Just run cmake and follow the instructions.)

Take a look at these files for more information:

  • steamnetworkingcustomsignaling.h contains the interfaces you'll need to implement for your signaling service.
  • An example of a really trivial signaling protocol:
  • A test case that puts everything together. It starts up an example trivial signaling protocol server and two peers, and has them connect to each other and exchange a few messages. We use the publicly-available google STUN servers. (No TURN servers for relay fallback in this example.)
    • test_p2p.py Executive test script that starts all the processes.
    • test_p2p.cpp Code for the process each peer runs.

Roadmap

Here are some things we have in mind to make P2P support better:

  • Get plugins written for standard, opensource protocols that could be used for signaling, such as XMPP. This would be a great project for somebody else to do! We would welcome contributions to this repository, or happily link to your own project. (See issue #136)
  • Allow setting the "default" signaling protocol. (See issue #137)
  • LAN beacon support, so that P2P connections can be made even when signaling is down or the hosts do not have Internet connectivity. (See issue #82)