bricks v0.1.0 Bricks.Connector.Tcp View Source
A Connector for TCP sockets, using :gen_tcp
Belongs to application :bricks
Create Options
All
Ordering: Required first, then alphabetical
| Option | Type(s) | Default | Raw gen_tcp option |
|---|---|---|---|
:host | binary | (REQUIRED) | (POSITIONAL) |
:port | pos_integer | (REQUIRED) | (POSITIONAL) |
:connect_timeout | timeout | 5000 | (POSITIONAL) |
:bam_window | Socket.window | 10 | (NONE) |
:active | Socket.active | true | :active |
:bind_to_device | binary | (NONE) | :bind_to_device |
:buffer | non_neg_integer | (UNKNOWN) | :buffer |
:delay_send? | boolean | false | :delay_send |
:deliver | :port, :term | (UNKNOWN) | :deliver |
:dont_route? | boolean | (false?) | :dontroute |
:exit_on_close? | boolean | true | :exit_on_close |
:header_size | non_neg_integer | (NONE) | :header |
:high_msgq_watermark | pos_integer | (UNKNOWN) | :high_msgq_watermark |
:high_watermark | non_neg_integer | (UNKNOWN) | :high_watermark |
:ipv4? | boolean | true | :inet, :ipv6_v6only |
:ipv6? | boolean | false | :inet6, :ipv6_v6only |
:keepalive? | boolean | false | :keepalive |
:line_delimiter | char | ?\n | :line_delimiter |
:linger? | linger | (NONE) | :linger |
:local_port | Socket.port_num | 0 (random) | :port |
:low_msgq_watermark | pos_integer | (UNKNOWN) | :low_msgq_watermark |
:low_watermark | non_neg_integer | (UNKNOWN) | :low_watermark |
:network_interface | Socket.host | (NONE | :ip, :ifaddr |
:network_namespace | binary | (NONE) | :netns |
:nodelay? | boolean | false | :nodelay |
:packet_type | packet_type | :raw | :packet |
:packet_size | pos_integer | 0 (no limit) | :packet_size |
:priority | non_neg_integer | (NONE) | :priority |
:raw_fd | non_neg_integer | (NONE) | :fd |
:receive_buffer | non_neg_integer | (NONE) | :recbuf |
:receive_tclass? | boolean | false? | :recvtclass |
:receive_tos? | boolean | false? | :recvtos |
:receive_ttl? | boolean | false? | :recvttl |
:receive_timeout | timeout | 5000 | (POSITIONAL) |
:send_timeout | timeout | 5000 | :send_timeout |
:reuse_addr? | boolean | false | :reuseaddr |
:send_timeout_close? | boolean | true | :send_timeout_close |
:show_econnreset? | boolean | false | :show_econnreset |
:send_buffer | non_neg_integer | (NONE) | :sndbuf |
:tos | non_neg_integer | (NONE) | :tos |
:tclass | non_neg_integer | (NONE) | :tclass |
:tcp_module | atom | (SEE DOCS) | :tcp_module |
Destination Selection
| Option | Type | Default | Raw gen_tcp option |
|---|---|---|---|
:host | binary | (REQUIRED) | (POSITIONAL) |
:port | pos_integer | (REQUIRED) | (POSITIONAL) |
IP Version Selection
| Option | Type | Default | Raw gen_tcp option |
|---|---|---|---|
:ipv4? | boolean | true | :inet, :ipv6_v6only |
:ipv6? | boolean | false | :inet6, :ipv6_v6only |
These options toggle which IP versions may be used. At least one
must be true or you will get an error.
Timeouts
| Option | Type | Default | Raw gen_tcp option |
|---|---|---|---|
:connect_timeout | timeout | 5000 | (POSITIONAL) |
:receive_timeout | timeout | 5000 | (POSITIONAL) |
:send_timeout | timeout | 5000 | :send_timeout |
These toggle how long you are prepared to wait for an operation to
complete before a timeout error is returned. They are standard
erlang timeout values: non-negative integers or :infinity.
Activity Control
| Option | Type | Default | Raw gen_tcp option |
|---|---|---|---|
:active | Socket.active | true | :active |
:bam_window | Socket.window | 10 | (NONE) |
See discussion on socket activity modes in the Bricks.Socket
module documentation for more information.
Erlang Options
| Option | Type | Default | Raw gen_tcp option |
|---|---|---|---|
:buffer | non_neg_integer | (UNKNOWN) | :buffer |
:delay_send? | boolean | false | :delay_send |
:exit_on_close? | boolean | true | :exit_on_close |
:header_size | non_neg_integer | (NONE) | :header |
:high_msgq_watermark | pos_integer | (UNKNOWN) | :high_msgq_watermark |
:high_watermark | non_neg_integer | (UNKNOWN) | :high_watermark |
:line_delimiter | char | ?\n | :line_delimiter |
:low_msgq_watermark | pos_integer | (UNKNOWN) | :low_msgq_watermark |
:low_watermark | non_neg_integer | (UNKNOWN) | :low_watermark |
:packet_type | packet_type | :raw | :packet |
:send_timeout_close? | boolean | true | :send_timeout_close |
:show_econnreset? | boolean | false | :show_econnreset |
:tcp_module | atom | (SEE DOCS) | :tcp_module |
:tcp_opts | proplist | [] | (ANY) |
:buffer
The size of the user-level buffer used by the driver. Not to be
confused with options :send_buffer and :receive_buffer, which
correspond to the Kernel socket buffers. For TCP it is recommended
to have val(buffer) >= val(recbuf) to avoid performance issues
because of unnecessary copying. However, as the size set for recbuf
usually become larger, you are encouraged to use getopts/2 to
analyze the behavior of your operating system.
Note that this is also the maximum amount of data that can be
received from a single recv call. If you are using higher than
normal MTU consider setting buffer higher.
:delay_send?
Normally, when an Erlang process sends to a socket, the driver tries
to send the data immediately. If that fails, the driver uses any
means available to queue up the message to be sent whenever the
operating system says it can handle it. Setting delay_send: true
makes all messages queue up. The messages sent to the network are
then larger but fewer. The option affects the scheduling of send
requests versus Erlang processes instead of changing any real
property of the socket. The option is implementation-specific.
:exit_on_close?
The only reason to set it to false is if you want to continue
sending data to the socket after a close is detected, for example,
if the peer uses :gen_tcp.shutdown/2 to shut down the write side.
:header_size
This option is only meaningful if option binary was specified when
the socket was created. If option header is specified, the first
Size number bytes of data received from the socket are elements of a
list, and the remaining data is a binary specified as the tail of
the same list. For example, if set to 2, the data received matches
[byte1,byte2|binary]
:high_msgq_watermark
The socket message queue is set to a busy state when the amount of
data on the message queue reaches this limit. Notice that this limit
only concerns data that has not yet reached the ERTS internal socket
implementation. Defaults to 8 kB.
Senders of data to the socket are suspended if either the socket message queue is busy or the socket itself is busy.
For more information, see options :low_msgq_watermark,
:high_watermark, and :low_watermark.
Notice that distribution sockets disable the use of
:high_msgq_watermark and :low_msgq_watermark. Instead use the
distribution buffer busy limit, which is a similar feature.
:high_watermark
The socket is set to a busy state when the amount of data queued
internally by the ERTS socket implementation reaches this
limit. Defaults to 8 kB.
Senders of data to the socket are suspended if either the socket message queue is busy or the socket itself is busy.
For more information, see options low_watermark, high_msgq_watermark, and low_msqg_watermark.
:line_delimiter
Sets the line delimiting character for line-oriented protocols
(:line). Defaults to ?.
:low_msgq_watermark
If the socket message queue is in a busy state, the socket message
queue is set in a not busy state when the amount of data queued in
the message queue falls below this limit. Notice that this limit
only concerns data that has not yet reached the ERTS internal socket
implementation. Defaults to 4 kB.
Senders that are suspended because of either a busy message queue or a busy socket are resumed when the socket message queue and the socket are not busy.
For more information, see options :high_msgq_watermark,
:high_watermark, and :low_watermark.
Notice that distribution sockets disable the use of
:high_msgq_watermark and :low_msgq_watermark. Instead they use
the distribution buffer busy limit, which is a similar feature.
:low_watermark
If the socket is in a busy state, the socket is set in a not busy
state when the amount of data queued internally by the ERTS socket
implementation falls below this limit. Defaults to 4 kB.
Senders that are suspended because of a busy message queue or a busy socket are resumed when the socket message queue and the socket are not busy.
For more information, see options :high_watermark,
:high_msgq_watermark, and :low_msgq_watermark.
:packet_type
Defines the type of packets to use for a socket. Possible values:
:raw | 0
: No packaging is done.
1 | 2 | 4
: Packets consist of a header specifying the number of bytes in the
packet, followed by that number of bytes. The header length can be
one, two, or four bytes, and containing an unsigned integer in
big-endian byte order. Each send operation generates the header,
and the header is stripped off on each receive operation. The
4-byte header is limited to 2Gb.
:asn1 | :cdr | :sunrm | :fcgi | :tpkt | :line
: These packet types only have effect on receiving. When sending a
packet, it is the responsibility of the application to supply a
correct header. On receiving, however, one message is sent to the
controlling process for each complete packet received, and,
similarly, each call to :gen_tcp.recv/2,3 returns one complete
packet. The header is not stripped off.
The meanings of the packet types are as follows:
:asn1- ASN.1 BER:sunrm- Sun’s RPC encoding:cdr- CORBA (GIOP 1.1):fcgi- Fast CGI:tpkt- TPKT format [RFC1006]:line- Line mode, a packet is a line-terminated with newline, lines longer than the receive buffer are truncated
:http | :http_bin
The Hypertext Transfer Protocol. The packets are returned with the
format according to HttpPacket described in
:erlang.decode_packet/3 in ERTS. A socket in passive mode returns
{:ok, packet} from :gen_tcp.recv while an active socket sends
messages like {http, socket_handle, packet}.
:httph | :httph_bin
These two types are often not needed, as the socket automatically
switches from :http/:http_bin to :httph/:httph_bin
internally after the first line is read. However, there can be
occasions when they are useful, such as parsing trailers from
chunked encoding.
:send_timeout_close?
Used together with :send_timeout to specify whether the socket is to
be automatically closed when the send operation returns
{:error,:timeout}. The recommended setting is true, which
automatically closes the socket.
:show_econnreset?
When this option is set to false, which is default, an RST
received from the TCP peer is treated as a normal close (as though
an FIN was sent). A caller to :gen_tcp.recv/2 gets {:error,
:closed}. In active mode, the controlling process receives a
{:tcp_closed, socket_handle} message, indicating that the peer has
closed the connection.
Setting this option to true allows you to distinguish between a
connection that was closed normally, and one that was aborted
(intentionally or unintentionally) by the TCP peer. A call to
:gen_tcp.recv/2 returns {:error, :econnreset}. In active mode,
the controlling process receives a {:tcp_error, socket_handle,
:econnreset} message before the usual {:tcp_closed,
socket_handle}, as is the case for any other socket error. Calls to
:gen_tcp.send/2 also returns {:error, :econnreset} when it is
detected that a TCP peer has sent an RST.
A connected socket returned from :gen_tcp.accept/1 inherits the
:show_econnreset? setting from the listening socket.
:tcp_module
Overrides which callback module is used. Defaults to :inet_tcp for
IPv4 and :inet6_tcp for IPv6.
:tcp_opts
Raw gen_tcp/inet options proplist. Appended to options.
OS options
| Option | Type | Default | Raw gen_tcp option |
|---|---|---|---|
:bind_to_device | binary | (NONE) | :bind_to_device |
:deliver | :port, :term | (UNKNOWN) | :deliver |
:dont_route? | boolean | (false?) | :dontroute |
:keepalive? | boolean | false | :keepalive |
:linger | linger | (NONE) | :linger |
:local_port | Socket.port_num | 0 (random) | :port |
:network_interface | Socket.host | (NONE | :ip, :ifaddr |
:network_namespace | binary | (NONE) | :netns |
:nodelay? | boolean | false | :nodelay |
:packet_size | pos_integer | 0 (no limit) | :packet_size |
:priority | non_neg_integer | (NONE) | :priority |
:raw_fd | non_neg_integer | (NONE) | :fd |
:receive_buffer | non_neg_integer | (NONE) | :recbuf |
:receive_tclass? | boolean | false? | :recvtclass |
:receive_tos? | boolean | false? | :recvtos |
:receive_ttl? | boolean | false? | :recvttl |
:reuse_addr? | boolean | false | :reuseaddr |
:send_buffer | non_neg_integer | (NONE) | :sndbuf |
:tos | non_neg_integer | (NONE) | :tos |
:tclass | non_neg_integer | (NONE) | :tclass |
:bind_to_device
Binds a socket to a specific network interface. This option must be
used in a function call that creates a socket, that is,
:gen_tcp.connect/3,4, :gen_tcp.listen/2, :gen_udp.open/1,2, or
:gen_sctp.open/0,1,2.
Unlike getifaddrs/0, Ifname is encoded a binary. In the unlikely
case that a system is using non-7-bit-ASCII characters in network
device names, special care has to be taken when encoding this
argument.
This option uses the Linux-specific socket option SO_BINDTODEVICE,
such as in Linux kernel 2.0.30 or later, and therefore only exists
when the runtime system is compiled for such an operating system.
Before Linux 3.8, this socket option could be set, but could not retrieved with getopts/2. Since Linux 3.8, it is readable.
The virtual machine also needs elevated privileges, either running
as superuser or (for Linux) having capability CAP_NET_RAW.
The primary use case for this option is to bind sockets into Linux VRF instances.
:deliver
When active: true, data is delivered on the form port :
{socket_handle, {:data, [h1,..hsz | data]}} or term : {:tcp,
socket_handle, [h1..hsz | data]}
:dont_route?
Enables/disables routing bypass for outgoing messages.
:keepalive?
Enables/disables periodic transmission on a connected socket when no other data is exchanged. If the other end does not respond, the connection is considered broken and an error message is sent to the controlling process. Defaults to disabled.
:linger
Determines the time-out, in seconds, for flushing unsent data in the
:gen_tcp.close/1 socket call. If the first component of the value
tuple is false, the second is ignored. This means that
:gen_tcp.close/1 returns immediately, not waiting for data to be
flushed. Otherwise, the second component is the flushing time-out,
in seconds.
:local_port
Local port number to use for the outgoing socket.
:network_interface
If the host has many network interfaces, this option specifies which one to use.
:network_namespace
Sets a network namespace for the socket. Parameter s a filename
defining the namespace, for example, “/var/run/netns/example”,
typically created by command ip netns add example. This option
must be used in a function call that creates a socket, that is,
:gen_tcp.connect/3,4, :gen_tcp.listen/2, :gen_udp.open/1,2, or
:gen_sctp.open/0,1,2.
This option uses the Linux-specific syscall setns(), such as in
Linux kernel 3.0 or later, and therefore only exists when the
runtime system is compiled for such an operating system.
The virtual machine also needs elevated privileges, either running
as superuser or (for Linux) having capability CAP_SYS_ADMIN
according to the documentation for setns(2). However, during
testing also CAP_SYS_PTRACE and CAP_DAC_READ_SEARCH have proven
to be necessary.
Example:
setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search+epi beam.smp
Notice that the filesystem containing the virtual machine executable
(beam.smp in the example) must be local, mounted without flag
nosetuid, support extended attributes, and the kernel must support
file capabilities. All this runs out of the box on at least Ubuntu
12.04 LTS, except that SCTP sockets appear to not support network
namespaces.
Namespace is a filename and is encoded and decoded as discussed in module file, with the following exceptions:
Emulator flag +fnu is ignored.
:inet.getopts/2for this option returns a binary for the filename if the stored filename cannot be decoded. This is only to occur if you set the option using a binary that cannot be decoded with the emulator’s filename encoding::file.native_name_encoding/0.
:nodelay?
If true, option TCP_NODELAY is turned on for the socket, which
means that also small amounts of data are sent immediately.
:packet_size
Sets the maximum allowed length of the packet body. If the packet header indicates that the length of the packet is longer than the maximum allowed length, the packet is considered invalid. The same occurs if the packet header is too large for the socket receive buffer.
For line-oriented protocols (line, http*), option packet_size
also guarantees that lines up to the indicated length are accepted
and not considered invalid because of internal buffer limitations.
:priority
Sets the SO_PRIORITY socket level option on platforms where this is
implemented. The behavior and allowed range varies between different
systems. The option is ignored on platforms where it is not
implemented. Use with caution.
:raw_fd
If a socket has somehow been connected without using gen_tcp, use
this option to pass the file descriptor for it. If
:network_interface and/or :port options are combined with this
option, the fd is bound to the specified interface and port before
connecting. If these options are not specified, it is assumed that
the fd is already bound appropriately.
:receive_buffer
The minimum size of the receive buffer to use for the socket. You
are encouraged to use :inet.getopts/2 to retrieve the size set by
your operating system.
:receive_tclass?
If set to true activates returning the received TCLASS value on
platforms that implements the protocol IPPROTO_IPV6 option
IPV6_RECVTCLASS or IPV6_2292RECVTCLASS for the socket. The value
is returned as a {:tclass,tclass} tuple regardless of if the
platform returns an IPV6_TCLASS or an IPV6_RECVTCLASS CMSG
value.
For packet oriented sockets that supports receiving ancillary data
with the payload data (gen_udp and gen_sctp), the TCLASS value is
returned in an extended return tuple contained in an ancillary data
list. For stream oriented sockets (gen_tcp) the only way to get the
TCLASS value is if the platform supports the pktoptions option.
:receive_tos?
If set to true activates returning the received TOS value on
platforms that implements the protocol IPPROTO_IP option
IP_RECVTOS for the socket. The value is returned as a {:tos,tos}
tuple regardless of if the platform returns an IP_TOS or an
IP_RECVTOS CMSG value.
For packet oriented sockets that supports receiving ancillary data
with the payload data (:gen_udp and :gen_sctp), the TOS value
is returned in an extended return tuple contained in an ancillary
data list. For stream oriented sockets (:gen_tcp) the only way to
get the TOS value is if the platform supports the pktoptions option.
:receive_ttl?
If set to true activates returning the received TTL value on
platforms that implements the protocol IPPROTO_IP option
IP_RECVTTL for the socket. The value is returned as a {:ttl,ttl}
tuple regardless of if the platform returns an IP_TTL or an
IP_RECVTTL CMSG value.
For packet oriented sockets that supports receiving ancillary data
with the payload data (:gen_udp and :gen_sctp), the TTL value
is returned in an extended return tuple contained in an ancillary
data list. For stream oriented sockets (;gen_tcp) the only way to
get the TTL value is if the platform supports the pktoptions
option.
:reuse_addr?
Allows or disallows local reuse of port numbers. By default, reuse is disallowed.
:send_buffer
The minimum size of the send buffer to use for the socket. You are
encouraged to use getopts/2, to retrieve the size set by your
operating system.
:tos
Sets IP_TOS IP level options on platforms where this is
implemented. The behavior and allowed range varies between different
systems. The option is ignored on platforms where it is not
implemented. Use with caution.
:tclass
Sets IPV6_TCLASS IP level options on platforms where this is
implemented. The behavior and allowed range varies between different
systems. The option is ignored on platforms where it is not
implemented. Use with caution.
Link to this section Summary
Types
Options for create/1
Valid linger value. See docs for info
The errors that create/1 may return
Packet type for inbuilt message parsing facilities
TCP Connector State
Functions
Creates a Bricks.Connector which uses this module as a callback
and the provided options to open and configure the socket
Link to this section Types
create_opts() :: %{
:host => binary(),
:port => pos_integer(),
optional(:connect_timeout) => timeout(),
optional(:receive_timeout) => timeout(),
optional(:bam_window) => Bricks.Socket.window(),
optional(:active) => Bricks.Socket.active(),
optional(:bind_to_device) => binary(),
optional(:buffer) => non_neg_integer(),
optional(:delay_send?) => boolean(),
optional(:deliver) => :port | :term,
optional(:dont_route?) => boolean(),
optional(:exit_on_close?) => boolean(),
optional(:header_size) => non_neg_integer(),
optional(:high_msgq_watermark) => pos_integer(),
optional(:high_watermark) => non_neg_integer(),
optional(:ipv4?) => boolean(),
optional(:ipv6?) => boolean(),
optional(:keepalive?) => boolean(),
optional(:line_delimiter) => char(),
optional(:linger) => {boolean(), pos_integer()},
optional(:local_port) => Bricks.Socket.port_num(),
optional(:low_msgq_watermark) => pos_integer(),
optional(:low_watermark) => non_neg_integer(),
optional(:network_interface) => binary() | :inet.socket_address(),
optional(:network_namespace) => binary(),
optional(:nodelay?) => boolean(),
optional(:packet_type) => :raw | 1 | 2 | 4,
optional(:packet_size) => pos_integer(),
optional(:priority) => non_neg_integer(),
optional(:raw_fd) => non_neg_integer(),
optional(:receive_buffer) => non_neg_integer(),
optional(:receive_tclass?) => boolean(),
optional(:receive_tos?) => boolean(),
optional(:receive_ttl?) => boolean(),
optional(:reuse_addr?) => boolean(),
optional(:send_timeout) => timeout(),
optional(:send_timeout_close?) => boolean(),
optional(:show_econnreset?) => boolean(),
optional(:send_buffer) => non_neg_integer(),
optional(:tcp_module) => atom(),
optional(:tcp_opts) => [term()],
optional(:tos) => non_neg_integer(),
optional(:tclass) => non_neg_integer()
}
Options for create/1
Valid linger value. See docs for info
option_error() :: Bricks.Error.BadOption.t() | Bricks.Error.BadCombo.t()
The errors that create/1 may return
packet_type() :: :raw | 0 | 1 | 2 | 4 | :asn1 | :cdr | :sunrm | :fcgi | :tpkt | :line | :http | :http_bin | :httph | :httph_bin
Packet type for inbuilt message parsing facilities
t() :: %Bricks.Connector.Tcp{
active: Bricks.Socket.active(),
bam_window: Bricks.Socket.window(),
connect_timeout: timeout(),
host: Bricks.Socket.host(),
port: Bricks.Socket.port_num(),
receive_timeout: timeout(),
tcp_opts: [term()]
}
TCP Connector State
Link to this section Functions
create(create_opts()) :: {:ok, Bricks.Connector.t()} | {:error, option_error()}
Creates a Bricks.Connector which uses this module as a callback
and the provided options to open and configure the socket.
See module documentation for more information about the options