trivial v0.1.0 Trivial.Conn View Source

The struct for holding stateful TFTP connection information.

From rfc1350 Section 2:

A transfer is established by sending a request (WRQ to write onto a foreign file system, or RRQ to read from it), and receiving a positive reply, an acknowledgment packet for write, or the first data packet for read. In general an acknowledgment packet will contain the block number of the data packet being acknowledged. Each data packet has associated with it a block number; block numbers are consecutive and begin with one. Since the positive response to a write request is an acknowledgment packet, in this special case the block number will be zero. (Normally, since an acknowledgment packet is acknowledging a data packet, the acknowledgment packet will contain the block number of the data packet being acknowledged.) If the reply is an error packet, then the request has been denied.

In order to create a connection, each end of the connection chooses a TID for itself, to be used for the duration of that connection. The TID's chosen for a connection should be randomly chosen, so that the probability that the same number is chosen twice in immediate succession is very low. Every packet has associated with it the two TID's of the ends of the connection, the source TID and the destination TID. These TID's are handed to the supporting UDP (or other datagram protocol) as the source and destination ports. A requesting host chooses its source TID as described above, and sends its initial request to the known TID 69 decimal (105 octal) on the serving host. The response to the request, under normal operation, uses a TID chosen by the server as its source TID and the TID chosen for the previous message by the requestor as its destination TID. The two chosen TID's are then used for the remainder of the transfer.

Link to this section Summary

Types

t()

A struct which contains all relevant settings for a TFTP transaction.

Functions

converts an erlang UDP packet tuple to a request struct.

Used to populate the t/0 struct from a list of strings. In the tftp packet, this was a zero-delimited data structure.

Link to this section Types

Link to this type

t() View Source
t() :: %Trivial.Conn{
  blksize: non_neg_integer() | nil,
  client_ip: :inet.ip_address(),
  client_port: :inet.port_number(),
  daemon: pid(),
  data: term(),
  filename: String.t(),
  mode: :read | :write,
  module: module(),
  ref: reference(),
  socket: port() | nil,
  srv_pid: pid(),
  srv_port: :inet.port_number(),
  timeout: non_neg_integer() | nil,
  tsize: true | non_neg_integer() | nil
}

A struct which contains all relevant settings for a TFTP transaction.

Connection information (server):

  • daemon: erlang pid for the daemon which accepted the initial request.
  • srv_pid: erlang pid for the server handling downstream requests.
  • srv_port: serverside udp port. also known as the TID in rfc docs.
  • socket: erlang udp socket for the server

Connection information (client):

  • client_ip: ip address of the client.
  • client_port: clientside udp port

Library values:

  • filename: the request file name being served by this conn.
  • module: the module implementing Trivial.Server callbacks.
  • data: stateful data presented to the Trivial.Server behaviour module

TFTP options:

  • blksize: size to be transferred in each udp block.
  • tsize: true between initial request and when the client module populates the tsize value, after which it should be an integer.
  • timeout: currently unimplemented.

Link to this section Functions

Link to this function

from_request(arg1, arg2) View Source
from_request(packet :: tuple(), initializer :: {module(), term()}) ::
  {:ok, t()} | {:error, :eacces}

converts an erlang UDP packet tuple to a request struct.

From rfc1350 (p 8):

          2 bytes    string   1 byte     string   1 byte
        -----------------------------------------------
 RRQ/  | 01/02 |  Filename  |   0  |    Mode    |   0  |
 WRQ    -----------------------------------------------

This library will only accept read requests. A write request will emit an access error.

Link to this function

parse_options(conn, list) View Source
parse_options(t(), [String.t()]) :: t()

Used to populate the t/0 struct from a list of strings. In the tftp packet, this was a zero-delimited data structure.

Note that from rfc 2347 (p 2):

Options are appended to a TFTP Read Request or Write Request packet as follows:

+-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+-->
|  opc  |filename| 0 |  mode  | 0 |  opt1  | 0 | value1 | 0 | <
+-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+-->

 >-------+---+---~~---+---+
<  optN  | 0 | valueN | 0 |
 >-------+---+---~~---+---+