Jerboa v0.2.0 Jerboa.Client
STUN client process
Use start/1
function to spawn new client process:
iex> Jerboa.Client.start server: %{address: server_ip, port: server_port}
{:ok, #PID<...>}
(see start/1
for configuration options)
Basic usage
Requesting server reflexive address
The bind/1
issues a Binding request to a server and returns reflexive IP address and port.
If returned message is not a valid STUN message or it doesn’t include XOR Mapped Address
attribute, the client simply crashes.
iex> Jerboa.Client.bind client_pid
{:ok, {{192, 168, 1, 20}, 32780}}
persist/1
sends a Binding indication to a server, which is not meant to return
any response, but is an attempt to refresh NAT bindings in routers on the path to a server.
Note that this is only an attempt, there is no guarantee that some router on the path
won’t rebind client’s inside address and port.
Creating allocations
Allocation is a logical communication path between one client and multiple peers. In practice a socket is created on the server, which peers can send data to, and the server will forward this data to the client. Client can send data to the server which will forward it to one or more peers.
Refer to TURN RFC for a more detailed description.
allocate/1
is used to request an allocation on the server. On success it returns
an :ok
tuple, which contains allocated IP address and port number. Jerboa won’t
try to request an allocation if it knows that the client already has one.
Note that allocations have an expiration time (RFC recommends 10 minutes), To refresh
an existing allocation one can use refresh/1
.
Installing permissions
Once the allocation is created, you may install permissions for peers in order to exchange
data with them over relay. Permissions are created using create_permission/2
:
create_permission client, {192, 168, 22, 111}
create_permission client, [{192, 168, 22, 111}, {212, 168, 33, 222}]
Sending and receiving data
After permission is installed, you may send and receive data from peer. To send
data you must simply call send/3
, providing peer’s address and data to be sent (a binary):
send client, {{192, 168, 22, 111}, 1234}, "Hello, world!"
Receiving data is handled using subscriptions mechanism. Once you subscribe to the data
(using subscribe/3
) sent by some peer, it will be delivered to subscribing process
as a message in format:
{:peer_data, client :: pid, peer :: address, data :: binary}
Subscriptions imply that receiving data is asynchronous by default. There is a convenience
recv/2
function, which will block calling process until it receives data from the given
peer address. recv
accepts optional timeout in milliseconds (or atom :infinity
), which
defaults to 5000.
Note that permissions installed do not affect subscriptions - if you subscribe to data from peer which you’ve not installed permissions for, the data will never appear in subscribed process’ mailbox.
Logging
Client logs progress messages with :debug
level, so Elixir’s Logger needs to
be configured first to see them. It is recommended to allow Jerboa logging metadata,
i.e. :jerboa_client
and :jerboa_server
:
config :logger,
level: :debug,
metadata: [:jerboa_client, :jerboa_server]
Summary
Functions
Creates allocation on the server or returns relayed transport address if client already has an allocation
Sends Binding request to a server
Creates permissions on the allocation for the given peer addresses
Sends Binding indication to a server
Blocks the calling process until it receives the data from the given peer
Tries to refresh the allocation on the server
Sends data to a given peer
Starts STUN client process
Stops the client
Subscribes calling process to data received from the given peer
Subscribes PID to data received from the given peer
Cancels subscription of calling process
Cancels subscription of given PID
Types
allocate_opt :: {:even_port, boolean} | {:reserve, boolean} | {:reservation_token, <<_::64>>}
Functions
Creates allocation on the server or returns relayed transport address if client already has an allocation
Options
:even_port
- optional - if set totrue
, EVEN-PORT attribute will be included in the request, which prompts the server to allocate even port number:reserve
- optional - if set totrue
, prompts the server to allocate an even port, reserve next highest port number, and return a reservation token which can be later used to create an allocation on reserved port. If this option is present,:even_port
is ignored.:reservation_token
- optional - token returned by previous allocation request withreserve: true
. Passing the token should result in reserved port being assigned to the allocation, or an error if the token is invalid or the reservation has timed out. If this option is present,:reserve
is ignored.
Sends Binding request to a server
Returns reflexive address and port on successful response. Returns error tuple if response from the server is invalid.
Creates permissions on the allocation for the given peer addresses
If permission is already installed for the given address, the permission will be refreshed.
Examples
create_permission client, {192, 168, 22, 111}
create_permission client, [{192, 168, 22, 111}, {212, 168, 33, 222}]
Sends Binding indication to a server
recv(t, peer_addr :: Jerboa.Client.ip, timeout :: non_neg_integer | :infinity) :: {:ok, peer :: Jerboa.Client.address, data :: binary} | {:error, :timeout}
Blocks the calling process until it receives the data from the given peer
Calling process needs to be subscribed to this peer’s data before calling this function, otherwise it will always time out.
Accepts timeout in milliseconds as optional argument (defualt is 5000),
may be also atom :infinity
.
This function simply uses subscriptions mechanism. It implies lack of knowledge about permissions installed for the given peer, thus if there is no permission, the function will most likely time out.
Sends data to a given peer
Note that there are no guarantees that the data sent reaches the peer. TURN servers don’t acknowledge Send indications.
Returns {:error, :no_permission}
if there is no permission installed
for the given peer.
Starts STUN client process
iex> opts = [server: {{192, 168, 1, 20}, 3478}, username: "user", secret: "abcd"]
iex> Jerboa.Client.start(opts)
{:ok, #PID<...>}
Options
:server
- required - a tuple with server’s address and port:username
- required - username used for authentication:secret
- required - secret used for authentication
Stops the client
Subscribes calling process to data received from the given peer
Message format is
{:peer_data, client_pid :: pid, peer :: address, data :: binary}
Subscribes PID to data received from the given peer
Message format is
{:peer_data, client_pid :: pid, peer :: address, data :: binary}
Cancels subscription of calling process