///
import messages = require('./messages');
import net = require('../net/net.types');
/**
* A TURN server which delegates the creation and operation of relay sockets
* to a separate - possibly remote - backend. The separation is intended to
* facilitate transformation of intra-process traffic, viz. obfuscation. The
* intended use of this server is as a proxy for WebRTC traffic to provide,
* when paired with a NAT-punching and obfuscated network transport, for
* a hard-to-detect and hard-to-block peer-to-peer connection.
*
* Based on:
* http://www.ietf.org/rfc/rfc5766.txt
*
* While this server should behave as a regular TURN server, its normal
* (and most tested!) configuration is as a relay for a single WebRTC data
* channel, servicing just one client which is attempting to communicate
* with a single remote host.
*
* As such, please note:
* - no attempt is made to model permissions (permission requests always
* succeed)
* - no attempt is made to model lifetime (allocations live for the
* lifetime of the server)
* - there's no support for channels (just send and data indications)
* - while the server does sign its responses with a MESSAGE-INTEGRITY
* attribute, it does not verify the client's signature
* - only the long-term credential mechanism is supported
*/
export declare class Frontend {
/** Socket on which the server is listening. */
private socket_;
/**
* These are invoked when the remote side sends us a response
* to a relay socket creation request.
*/
private callbacks_;
/**
* These are fulfilled when the callback is invoked.
*/
private promises_;
/** Invoked when a message must be sent to the frontend. */
private ipcHandler_;
/**
* Returns a promise to create a socket, bind to the specified address, and
* start listening for datagrams. Specify port zero to have the system
* choose a free port.
*/
bind(address: string, port: number): Promise;
/**
* Called when data is received from a TURN client on our UDP socket.
* Sends a response to the client, if one is required (send and data
* indications are the exception). Note that the RFC states that any
* message which cannot be handled or understood by the server should be
* ignored.
*/
private onData_;
/**
* Resolves to the response which should be sent to the client, or undefined
* if none is required, e.g. for send indications. Rejects if the STUN
* method is unsupported or there is an error handling the message.
* Public for testing.
*/
handleStunMessage: (stunMessage: messages.StunMessage, clientEndpoint: net.Endpoint) => Promise;
/**
* Resolves to a success response. Since we don't actually track
* permissions, this is pretty straightforward.
*/
private handleCreatePermissionRequest_;
/**
* Resolves to a success response. REFRESH messages don't seem to be
* required by Chrome (at least for establishing data channels) but are
* required by turnutils_uclient.
*/
private handleRefreshRequest_;
/**
* Resolves to an ALLOCATE response, which will be a FAILURE_RESPONSE or
* SUCCESS_RESPONSE depending on whether the request includes a username
* attribute and whether a relay socket can be created on the remote side.
*
* Note that there are two classes of ALLOCATE requests:
* 1. The first is the very first request sent by the client to a TURN
* server to which the server should always respond with a *failure*
* response which *also* contains attributes (notably realm) which
* the client can include in subsequent ALLOCATE requests.
* 2. In the second case, the client includes REALM, USERNAME, and
* MESSAGE-INTEGRITY attributes and the server creates a relay socket
* before responding to the client.
*
* Right now, the server has no real notion of usernames and realms so we
* are just performing the dance that TURN clients expect, using the
* presence of a USERNAME attribute to distinguish the first case from the
* second.
*
* Section 10.2 outlines the precise behaviour required:
* http://tools.ietf.org/html/rfc5389#section-10.2
*/
private handleAllocateRequest_;
/**
* Makes a request to the remote side to send a datagram on the client's
* relay socket.
*/
private handleSendIndication_;
/**
* Handles a message from the backend.
*/
handleIpc: (stunMessage: messages.StunMessage, clientEndpoint: net.Endpoint) => Promise;
/** Sets the function to call to send a message to the frontend. */
setIpcHandler: (ipcHandler: (stunMessage: messages.StunMessage, clientEndpoint: net.Endpoint) => void) => void;
}