transport v0.1.0 Transport behaviour View Source

Encapsulates a common API which describes a transport strategy.

By using this API you can use TCP and TLS interchangeably, by specifying strategy modules in your server and client configurations. This API also seeks to iron out common missteps in setting up TLS connections and enforce some best practices for securing your WAN transmissions.

Currently the available transport strategies are:

  • Transport.Tcp: unencrypted, unauthenticated communication. Only appropriate in :dev and :test environments. Allows you to simplify early stage and test deployments.
  • Transport.Tls: two-way authenticated, encrypted communication, using X509 TLS encryption. This is the general use case for point-to-point API services including over untrusted networks.

You may use this API to implement your own transport layers, or use it to mock responses in tests.

Link to this section Summary

Callbacks

(for servers) blocks on a socket opened with b:listen/1,2 and waits for a connection request.

(for clients) initiates an unencrypted connection from the client to the server.

(for servers) upgrades an associated TCP connection to an authenticated, encrypted connection, if the transport module implements encryption.

(for servers) opens an unencrypted TCP port to listen for incoming connection requests.

(for clients and servers) blocks until data of a requested length comes over the transport channel.

(for clients and servers). Like b:recv/2 but with a timeout so the server doesn't block indefinitely.

(for clients and servers) sends iodata down the appropriate transport channel.

returns an atom which is intended for matching on active packet messages.

(for clients) upgrades a TCP connection to an authenticated, encrypted connection, if the transport module implements encryption.

Link to this section Types

Link to this section Callbacks

Link to this callback

accept(socket, timeout)

View Source
accept(socket(), timeout()) :: {:ok, socket()} | {:error, any()}

(for servers) blocks on a socket opened with b:listen/1,2 and waits for a connection request.

The resulting opened socket will be unencrypted, and must be upgraded with b:handshake/2 to initiate secure communications.

Link to this callback

connect(identifier, port, keyword)

View Source
connect(
  identifier :: :inet.ip_address(),
  port :: :inet.port_number(),
  keyword()
) :: {:ok, socket()} | {:error, any()}

(for clients) initiates an unencrypted connection from the client to the server.

This unencrypted connection can be upgraded to an encrypted connection later, using the b:upgrade/2 function. Implementation modules guarantee an active: false connection to ensure timing correctness when establishing the upgraded encryption.

If you need to set active: true or other connection options that the upgrade process is sensitive to, you can set them in the options argument of b:upgrade/2.

Link to this callback

handshake(socket, keyword)

View Source
handshake(socket :: :inet.socket(), keyword()) ::
  {:ok, socket()} | {:error, any()}

(for servers) upgrades an associated TCP connection to an authenticated, encrypted connection, if the transport module implements encryption.

connection options that are incompatible with the handshake (such as active: true) should be passed into the options argument here.

Link to this callback

listen(port)

View Source
listen(port :: :inet.port_number()) :: {:ok, socket()} | {:error, any()}
Link to this callback

listen(port, keyword)

View Source
listen(port :: :inet.port_number(), keyword()) ::
  {:ok, socket()} | {:error, any()}

(for servers) opens an unencrypted TCP port to listen for incoming connection requests.

Implementation modules guarantee an active: false connection to ensure correct synchronization of handshake/2 events.

Link to this callback

recv(socket, length)

View Source
recv(socket(), length :: non_neg_integer()) :: {:ok, binary()} | {:error, any()}

(for clients and servers) blocks until data of a requested length comes over the transport channel.

See :gen_tcp.recv/2 for more information.

Link to this callback

recv(socket, length, timeout)

View Source
recv(socket(), length :: non_neg_integer(), timeout()) ::
  {:ok, binary()} | {:error, any()}

(for clients and servers). Like b:recv/2 but with a timeout so the server doesn't block indefinitely.

See :gen_tcp.recv/3 for more information.

Link to this callback

send(socket, iodata)

View Source
send(socket(), iodata()) :: :ok | {:error, any()}

(for clients and servers) sends iodata down the appropriate transport channel.

If the data are bigger than the MTU, it may be broken into multiple packets over the line.

returns an atom which is intended for matching on active packet messages.

When the connection is active: :true, the owning process will recieve messages of the form: {:tcp, <socket>, <data>} or {:ssl, <socket>, <data>}, this function helps you generically match the identifier on the front of this message tuple.

Link to this callback

upgrade(socket, options)

View Source
upgrade(socket(), options :: keyword()) :: {:ok, socket()} | {:error, any()}

(for clients) upgrades a TCP connection to an authenticated, encrypted connection, if the transport module implements encryption.

connection options that are incompatible with encryption upgrading (such as active: true) should be passed into the options argument.