.TH gen_udp 3erl "kernel 8.5.4.3" "Ericsson AB" "Erlang Module Definition" .SH NAME gen_udp \- Interface to UDP sockets. .SH DESCRIPTION .LP This module provides functions for communicating with sockets using the UDP protocol\&. .LP .RS -4 .B Note: .RE Functions that create sockets can take an optional option; \fI{inet_backend, Backend}\fR\& that, if specified, has to be the first option\&. This selects the implementation backend towards the platform\&'s socket API\&. .LP This is a \fItemporary\fR\& option that will be ignored in a future release\&. .LP The default is \fIBackend = inet\fR\& that selects the traditional \fIinet_drv\&.c\fR\& driver\&. The other choice is \fIBackend = socket\fR\& that selects the new \fIsocket\fR\& module and its NIF implementation\&. .LP The system default can be changed when the node is started with the application \fIkernel\fR\&\&'s configuration variable \fIinet_backend\fR\&\&. .LP For \fIgen_udp\fR\& with \fIinet_backend = socket\fR\& we have tried to be as "compatible" as possible which has sometimes been impossible\&. Here is a list of cases when the behaviour of inet-backend \fIinet\fR\& (default) and \fIsocket\fR\& are different: .RS 2 .TP 2 * The option read_packets is currently \fIignored\fR\&\&. .LP .RE .SH DATA TYPES .nf \fBoption()\fR\& = .br {active, true | false | once | -32768\&.\&.32767} | .br {add_membership, membership()} | .br {broadcast, boolean()} | .br {buffer, integer() >= 0} | .br {debug, boolean()} | .br {deliver, port | term} | .br {dontroute, boolean()} | .br {drop_membership, membership()} | .br {header, integer() >= 0} | .br {high_msgq_watermark, integer() >= 1} | .br {low_msgq_watermark, integer() >= 1} | .br {mode, list | binary} | .br list | binary | .br {multicast_if, multicast_if()} | .br {multicast_loop, boolean()} | .br {multicast_ttl, integer() >= 0} | .br {priority, integer() >= 0} | .br {raw, .br Protocol :: integer() >= 0, .br OptionNum :: integer() >= 0, .br ValueBin :: binary()} | .br {read_packets, integer() >= 0} | .br {recbuf, integer() >= 0} | .br {reuseaddr, boolean()} | .br {sndbuf, integer() >= 0} | .br {tos, integer() >= 0} | .br {tclass, integer() >= 0} | .br {ttl, integer() >= 0} | .br {recvtos, boolean()} | .br {recvtclass, boolean()} | .br {recvttl, boolean()} | .br {ipv6_v6only, boolean()} .br .fi .nf \fBoption_name()\fR\& = .br active | broadcast | buffer | debug | deliver | dontroute | .br header | high_msgq_watermark | low_msgq_watermark | mode | .br multicast_if | multicast_loop | multicast_ttl | priority | .br {raw, .br Protocol :: integer() >= 0, .br OptionNum :: integer() >= 0, .br ValueSpec :: .br (ValueSize :: integer() >= 0) | (ValueBin :: binary())} | .br read_packets | recbuf | reuseaddr | sndbuf | tos | tclass | .br ttl | recvtos | recvtclass | recvttl | pktoptions | .br ipv6_v6only .br .fi .nf \fBopen_option()\fR\& = .br {ip, inet:socket_address()} | .br {fd, integer() >= 0} | .br {ifaddr, .br socket:sockaddr_in() | .br socket:sockaddr_in6() | .br inet:socket_address()} | .br inet:address_family() | .br {port, inet:port_number()} | .br {netns, file:filename_all()} | .br {bind_to_device, binary()} | .br option() .br .fi .nf .B socket() .br .fi .RS .LP As returned by \fIopen/1,2\fR\&\&. .RE .nf \fBmulticast_if()\fR\& = ip_multicast_if() | ip6_multicast_if() .br .fi .nf \fBip_multicast_if()\fR\& = inet:ip4_address() .br .fi .nf \fBip6_multicast_if()\fR\& = integer() .br .fi .RS .LP For IPv6 this is an interface index (an integer)\&. .RE .nf \fBmembership()\fR\& = ip_membership() | ip6_membership() .br .fi .nf \fBip_membership()\fR\& = .br {MultiAddress :: inet:ip4_address(), .br Interface :: inet:ip4_address()} | .br {MultiAddress :: inet:ip4_address(), .br Address :: inet:ip4_address(), .br IfIndex :: integer()} .br .fi .RS .LP The tuple with size 3 is *not* supported on all platforms\&. \&'ifindex\&' defaults to zero (0) on platforms that supports the 3-tuple variant\&. .RE .nf \fBip6_membership()\fR\& = .br {MultiAddress :: inet:ip6_address(), IfIndex :: integer()} .br .fi .SH EXPORTS .LP .nf .B close(Socket) -> ok .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br .RE .RE .RS .LP Closes a UDP socket\&. .RE .LP .nf .B controlling_process(Socket, Pid) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Pid = pid() .br Reason = closed | not_owner | badarg | inet:posix() .br .RE .RE .RS .LP Assigns a new controlling process \fIPid\fR\& to \fISocket\fR\&\&. The controlling process is the process that receives messages from the socket\&. If called by any other process than the current controlling process, \fI{error, not_owner}\fR\& is returned\&. If the process identified by \fIPid\fR\& is not an existing local pid, \fI{error, badarg}\fR\& is returned\&. \fI{error, badarg}\fR\& may also be returned in some cases when \fISocket\fR\& is closed during the execution of this function\&. .RE .LP .nf .B connect(Socket, SockAddr) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br SockAddr = socket:sockaddr_in() | socket:sockaddr_in6() .br Reason = inet:posix() .br .RE .RE .RS .LP Connecting a UDP socket only means storing the specified (destination) socket address, as specified by \fISockAddr\fR\&, so that the system knows where to send data\&. .LP This means that it is not necessary to specify the destination address when sending a datagram\&. That is, we can use \fIsend/2\fR\&\&. .LP It also means that the socket will only received data from this address\&. .RE .LP .nf .B connect(Socket, Address, Port) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Address = inet:socket_address() | inet:hostname() .br Port = inet:port_number() .br Reason = inet:posix() .br .RE .RE .RS .LP Connecting a UDP socket only means storing the specified (destination) socket address, as specified by \fIAddress\fR\& and \fIPort\fR\&, so that the system knows where to send data\&. .LP This means that it is not necessary to specify the destination address when sending a datagram\&. That is, we can use \fIsend/2\fR\&\&. .LP It also means that the socket will only received data from this address\&. .RE .LP .nf .B open(Port) -> {ok, Socket} | {error, Reason} .br .fi .br .nf .B open(Port, Opts) -> {ok, Socket} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Port = inet:port_number() .br Opts = [inet:inet_backend() | open_option()] .br Socket = socket() .br Reason = system_limit | inet:posix() .br .RE .RE .RS .LP Associates a UDP port number (\fIPort\fR\&) with the calling process\&. .LP The following options are available: .RS 2 .TP 2 .B \fIlist\fR\&: Received \fIPacket\fR\& is delivered as a list\&. .TP 2 .B \fIbinary\fR\&: Received \fIPacket\fR\& is delivered as a binary\&. .TP 2 .B \fI{ip, Address}\fR\&: If the host has many network interfaces, this option specifies which one to use\&. .TP 2 .B \fI{ifaddr, Address}\fR\&: Same as \fI{ip, Address}\fR\&\&. If the host has many network interfaces, this option specifies which one to use\&. .RS 2 .LP However, if this instead is an \fIsocket:sockaddr_in()\fR\& or \fIsocket:sockaddr_in6()\fR\& this takes precedence over any value previously set with the \fIip\fR\& options\&. If the \fIip\fR\& option comes \fIafter\fR\& the \fIifaddr\fR\& option, it may be used to \fIupdate\fR\& its corresponding field of the \fIifaddr\fR\& option (the \fIaddr\fR\& field)\&. .RE .TP 2 .B \fI{fd, integer() >= 0}\fR\&: If a socket has somehow been opened without using \fIgen_udp\fR\&, use this option to pass the file descriptor for it\&. If \fIPort\fR\& is not set to \fI0\fR\& and/or \fI{ip, ip_address()}\fR\& is combined with this option, the \fIfd\fR\& is bound to the specified interface and port after it is being opened\&. If these options are not specified, it is assumed that the \fIfd\fR\& is already bound appropriately\&. .TP 2 .B \fIinet6\fR\&: Sets up the socket for IPv6\&. .TP 2 .B \fIinet\fR\&: Sets up the socket for IPv4\&. .TP 2 .B \fIlocal\fR\&: Sets up a Unix Domain Socket\&. See \fIinet:local_address()\fR\& .TP 2 .B \fI{udp_module, module()}\fR\&: Overrides which callback module is used\&. Defaults to \fIinet_udp\fR\& for IPv4 and \fIinet6_udp\fR\& for IPv6\&. .TP 2 .B \fI{multicast_if, Address}\fR\&: Sets the local device for a multicast socket\&. .TP 2 .B \fI{multicast_loop, true | false}\fR\&: When \fItrue\fR\&, sent multicast packets are looped back to the local sockets\&. .TP 2 .B \fI{multicast_ttl, Integer}\fR\&: Option \fImulticast_ttl\fR\& changes the time-to-live (TTL) for outgoing multicast datagrams to control the scope of the multicasts\&. .RS 2 .LP Datagrams with a TTL of 1 are not forwarded beyond the local network\&. Defaults to \fI1\fR\&\&. .RE .TP 2 .B \fI{add_membership, {MultiAddress, InterfaceAddress}}\fR\&: Joins a multicast group\&. .TP 2 .B \fI{drop_membership, {MultiAddress, InterfaceAddress}}\fR\&: Leaves a multicast group\&. .TP 2 .B \fIOpt\fR\&: See \fIinet:setopts/2\fR\&\&. .RE .LP The returned socket \fISocket\fR\& is used to send packets from this port with \fIsend/4\fR\&\&. When UDP packets arrive at the opened port, if the socket is in an active mode, the packets are delivered as messages to the controlling process: .LP .nf {udp, Socket, IP, InPortNo, Packet} % Without ancillary data {udp, Socket, IP, InPortNo, AncData, Packet} % With ancillary data .fi .LP The message contains an \fIAncData\fR\& field if any of the socket options \fIrecvtos\fR\&, \fIrecvtclass\fR\& or \fIrecvttl\fR\& are active, otherwise it does not\&. .LP .LP If the socket is not in an active mode, data can be retrieved through the \fIrecv/2,3\fR\& calls\&. Notice that arriving UDP packets that are longer than the receive buffer option specifies can be truncated without warning\&. .LP When a socket in \fI{active, N}\fR\& mode (see \fIinet:setopts/2\fR\& for details), transitions to passive (\fI{active, false}\fR\&) mode, the controlling process is notified by a message of the following form: .LP .nf {udp_passive, Socket} .fi .LP \fIIP\fR\& and \fIInPortNo\fR\& define the address from which \fIPacket\fR\& comes\&. \fIPacket\fR\& is a list of bytes if option \fIlist\fR\& is specified\&. \fIPacket\fR\& is a binary if option \fIbinary\fR\& is specified\&. .LP Default value for the receive buffer option is \fI{recbuf, 8192}\fR\&\&. .LP If \fIPort == 0\fR\&, the underlying OS assigns a free UDP port, use \fIinet:port/1\fR\& to retrieve it\&. .RE .LP .nf .B recv(Socket, Length) -> {ok, RecvData} | {error, Reason} .br .fi .br .nf .B recv(Socket, Length, Timeout) -> {ok, RecvData} | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Length = integer() >= 0 .br Timeout = timeout() .br RecvData = .br {Address, Port, Packet} | {Address, Port, AncData, Packet} .br Address = inet:ip_address() | inet:returned_non_ip_address() .br Port = inet:port_number() .br AncData = inet:ancillary_data() .br Packet = string() | binary() .br Reason = not_owner | timeout | inet:posix() .br .RE .RE .RS .LP Receives a packet from a socket in passive mode\&. Optional parameter \fITimeout\fR\& specifies a time-out in milliseconds\&. Defaults to \fIinfinity\fR\&\&. .LP If any of the socket options \fIrecvtos\fR\&, \fIrecvtclass\fR\& or \fIrecvttl\fR\& are active, the \fIRecvData\fR\& tuple contains an \fIAncData\fR\& field, otherwise it does not\&. .RE .LP .nf .B send(Socket, Packet) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Packet = iodata() .br Reason = not_owner | inet:posix() .br .RE .RE .RS .LP Sends a packet on a connected socket (see \fIconnect/2\fR\& and \fIconnect/3\fR\&)\&. .RE .LP .nf .B send(Socket, Destination, Packet) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Destination = .br {inet:ip_address(), inet:port_number()} | .br inet:family_address() | .br socket:sockaddr_in() | .br socket:sockaddr_in6() .br Packet = iodata() .br Reason = not_owner | inet:posix() .br .RE .RE .RS .LP Sends a packet to the specified \fIDestination\fR\&\&. .LP This function is equivalent to \fIsend(Socket, Destination, [], Packet)\fR\&\&. .RE .LP .nf .B send(Socket, Host, Port, Packet) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Host = inet:hostname() | inet:ip_address() .br Port = inet:port_number() | atom() .br Packet = iodata() .br Reason = not_owner | inet:posix() .br .RE .RE .RS .LP Sends a packet to the specified \fIHost\fR\& and \fIPort\fR\&\&. .LP This clause is equivalent to \fIsend(Socket, Host, Port, [], Packet)\fR\&\&. .RE .LP .nf .B send(Socket, Destination, AncData, Packet) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Destination = .br {inet:ip_address(), inet:port_number()} | .br inet:family_address() | .br socket:sockaddr_in() | .br socket:sockaddr_in6() .br AncData = inet:ancillary_data() .br Packet = iodata() .br Reason = not_owner | inet:posix() .br .RE .RE .RS .LP Sends a packet to the specified \fIDestination\fR\& with ancillary data \fIAncData\fR\&\&. .LP .RS -4 .B Note: .RE The ancillary data \fIAncData\fR\& contains options that for this single message override the default options for the socket, an operation that may not be supported on all platforms, and if so return \fI{error, einval}\fR\&\&. Using more than one of an ancillary data item type may also not be supported\&. \fIAncData =:= []\fR\& is always supported\&. .RE .LP .nf .B send(Socket, Destination, PortZero, Packet) -> .B ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Destination = .br {inet:ip_address(), inet:port_number()} | .br inet:family_address() .br PortZero = inet:port_number() .br Packet = iodata() .br Reason = not_owner | inet:posix() .br .RE .RE .RS .LP Sends a packet to the specified \fIDestination\fR\&\&. Since \fIDestination\fR\& is complete, \fIPortZero\fR\& is redundant and has to be \fI0\fR\&\&. .LP This is a legacy clause mostly for \fIDestination = {local, Binary}\fR\& where \fIPortZero\fR\& is superfluous\&. It is equivalent to \fIsend(Socket, Destination, [], Packet)\fR\&, the clause right above here\&. .RE .LP .nf .B send(Socket, Host, Port, AncData, Packet) -> ok | {error, Reason} .br .fi .br .RS .LP Types: .RS 3 Socket = socket() .br Host = .br inet:hostname() | inet:ip_address() | inet:local_address() .br Port = inet:port_number() | atom() .br AncData = inet:ancillary_data() .br Packet = iodata() .br Reason = not_owner | inet:posix() .br .RE .RE .RS .LP Sends a packet to the specified \fIHost\fR\& and \fIPort\fR\&, with ancillary data \fIAncData\fR\&\&. .LP Argument \fIHost\fR\& can be a hostname or a socket address, and \fIPort\fR\& can be a port number or a service name atom\&. These are resolved into a \fIDestination\fR\& and after that this function is equivalent to \fIsend(Socket, Destination, AncData, Packet)\fR\&, read there about ancillary data\&. .RE