TURN protocol implementation.
Introduction to TURN
When a direct communication path cannot be found, it is necessary to use the services of an intermediate host that acts as a relay for the packets. This relay typically sits in the public Internet and relays packets between two hosts that both sit behind NATs.
TURN allows a host behind a NAT (called the TURN client) to request that another host (called the TURN server) act as a relay. The client can arrange for the server to relay packets to and from certain other hosts (called peers) and can control aspects of how the relaying is done. The client does this by obtaining an IP address and port on the server, called the relayed-transport-address. When a peer sends a packet to the relayed-transport-address, the server relays the packet to the client. When the client sends a data packet to the server, the server relays it to the appropriate peer using the relayed- transport-address as the source.
Overview of TURN operations
Discovering TURN server.
Client learns the IP address of the TURN server either through some privisioning or by querying DNS SRV records for TURN service for the specified domain. Client may use UDP or TCP (or TLS) to connect to the TURN server.
All TURN operations requires the use of authentication (it uses STUN long term autentication method), hence client must be configured with the correct credential to use the service.
Client creates one "relay port" (or called relayed-transport-address in TURN terminology) in the TURN server by sending TURN Allocate request, hence this process is called creating allocation. Once the allocation is successful, client will be given the IP address and port of the "relay
port" in the Allocate response.
Sending data through the relay.
Once allocation has been created, client may send data to any remote endpoints (called peers in TURN terminology) via the "relay port". It does so by sending Send Indication to the TURN server, giving the peer address in the indication message. But note that at this point peers are not allowed to send data towards the client (via the "relay port") before permission is installed for that peer.
Permission needs to be created in the TURN server so that a peer can send data to the client via the relay port (a peer in this case is identified by its IP address). Without this, when the TURN server receives data from the peer in the "relay port", it will drop this data.
Receiving data from peers.
Once permission has been installed for the peer, any data received by the TURN server (from that peer) in the "relay port" will be relayed back to client by using Data Indication.
TURN provides optimized framing to the data by using ChannelData packetization. The client activates this format by sending ChannelBind request to the TURN server, which provides (channel) binding which maps a particular peer address with a channel number. Data sent or received to/for this peer will then use ChannelData format instead of Send or Data Indications.
Refreshing the allocation, permissions, and channel bindings.
Allocations, permissions, and channel bindings need to be refreshed periodically by client, or otherwise they will expire.
Destroying the allocation.
Once the "relay port" is no longer needed, client destroys the allocation by sending Refresh request with LIFETIME attribute set to zero.
The TURN functionalities in PJNATH primarily consist of TURN client transport and TURN client session. Please see more below.
Using TURN transport
The TURN client transport is a ready to use object for relaying application data via a TURN server, by managing all the operations above.
Among other things it provides the following features:
- resolution of the TURN server with DNS SRV
- interface to create allocation, permissions, and channel bindings
- interface to send and receive packets through the relay
- provides callback to notify the application about incoming data
- managing the allocation, permissions, and channel bindings
Please see TURN client transport for more documentation about and on how to use this object.
Creating custom TURN transport
The TURN client session is a transport-independent object to manage a client TURN session. It contains the core logic for managing the TURN client session as listed in TURN operations above, but in transport-independent manner (i.e. it doesn't have a socket), so that developer can integrate TURN client functionality into existing framework that already has its own means to send and receive data, or to support new transport types to TURN, such as TLS.
You can create your own (custom) TURN transport by wrapping this into your own object, and provide it with the means to send and receive packets.
Please see TURN client session for more information.
The pjturn-client, a sample TURN client is a sample application to use the TURN client transport. Also there is a sample TURN server in the distribution as well.
Also see PJNATH Samples and screenshots for other samples.