From f429adba7e7a862b9949821b40aa3cba12455b3e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 8 Jun 2016 09:56:04 +0200 Subject: Remove internal state BOUND from inet_drv --- lib/kernel/src/inet.erl | 17 +++++++++++------ lib/kernel/src/inet_int.hrl | 1 + lib/kernel/src/local_tcp.erl | 10 ++++++++-- lib/kernel/src/local_udp.erl | 9 ++++++++- 4 files changed, 28 insertions(+), 9 deletions(-) (limited to 'lib/kernel') diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index de43ea792b..a7b3c1cef4 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -1296,7 +1296,7 @@ gethostbyaddr_tm_native(Addr, Timer, Opts) -> end. -spec open(Fd_or_OpenOpts :: integer() | list(), - Addr :: socket_address(), + Addr :: socket_address() | undefined, Port :: port_number(), Opts :: [socket_setopt()], Protocol :: socket_protocol(), @@ -1316,11 +1316,16 @@ open(FdO, Addr, Port, Opts, Protocol, Family, Type, Module) {ok,S} -> case prim_inet:setopts(S, Opts) of ok -> - case if is_list(Addr) -> - bindx(S, Addr, Port); - true -> - prim_inet:bind(S, Addr, Port) - end of + case + case Addr of + undefined -> + {ok, undefined}; + _ when is_list(Addr) -> + bindx(S, Addr, Port); + _ -> + prim_inet:bind(S, Addr, Port) + end + of {ok, _} -> inet_db:register_socket(S, Module), {ok,S}; diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index 32d09fb63c..c8a8962e78 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -25,6 +25,7 @@ %% %% family codes to open +-define(INET_AF_UNSPEC, 0). -define(INET_AF_INET, 1). -define(INET_AF_INET6, 2). -define(INET_AF_ANY, 3). % Fake for ANY in any address family diff --git a/lib/kernel/src/local_tcp.erl b/lib/kernel/src/local_tcp.erl index 64085ec42e..e3c67dfbb7 100644 --- a/lib/kernel/src/local_tcp.erl +++ b/lib/kernel/src/local_tcp.erl @@ -107,8 +107,14 @@ do_connect(Addr = {?FAMILY, _}, 0, Opts, Time) -> when tuple_size(BAddr) =:= 2, element(1, BAddr) =:= ?FAMILY; BAddr =:= any -> case inet:open( - Fd, BAddr, 0, SockOpts, - ?PROTO, ?FAMILY, ?TYPE, ?MODULE) of + Fd, + case BAddr of + any -> + undefined; + _ -> + BAddr + end, + 0, SockOpts, ?PROTO, ?FAMILY, ?TYPE, ?MODULE) of {ok, S} -> case prim_inet:connect(S, Addr, 0, Time) of ok -> {ok,S}; diff --git a/lib/kernel/src/local_udp.erl b/lib/kernel/src/local_udp.erl index ebb4d2b33f..481a8c4910 100644 --- a/lib/kernel/src/local_udp.erl +++ b/lib/kernel/src/local_udp.erl @@ -59,7 +59,14 @@ open(0, Opts) -> when tuple_size(BAddr) =:= 2, element(1, BAddr) =:= ?FAMILY; BAddr =:= any -> inet:open( - Fd, BAddr, 0, SockOpts, ?PROTO, ?FAMILY, ?TYPE, ?MODULE); + Fd, + case BAddr of + any -> + undefined; + _ -> + BAddr + end, + 0, SockOpts, ?PROTO, ?FAMILY, ?TYPE, ?MODULE); {ok, _} -> exit(badarg) end. -- cgit v1.2.3 From 16e895198a541ccbbbe6c970bd9572cf347a9c77 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 8 Jun 2016 14:46:44 +0200 Subject: Document the local (unix) address family --- lib/kernel/doc/src/gen_tcp.xml | 21 ++++++------ lib/kernel/doc/src/gen_udp.xml | 19 ++++++----- lib/kernel/doc/src/inet.xml | 53 +++++++++++++++++++++++++++++ lib/kernel/src/gen_tcp.erl | 12 +++---- lib/kernel/src/gen_udp.erl | 10 +++--- lib/kernel/src/inet.erl | 76 +++++++++++++++++++++++++++++------------- 6 files changed, 139 insertions(+), 52 deletions(-) (limited to 'lib/kernel') diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml index b75d42d198..88135ea43d 100644 --- a/lib/kernel/doc/src/gen_tcp.xml +++ b/lib/kernel/doc/src/gen_tcp.xml @@ -153,17 +153,17 @@ do_recv(Sock, Bs) -> Address can be a hostname or an IP address.

The following options are available:

- {ip, ip_address()} + {ip, Address}

If the host has many network interfaces, this option specifies which one to use.

- {ifaddr, ip_address()} -

Same as {ip, ip_address()}. If the host has many + {ifaddr, Address} +

Same as {ip, Address}. If the host has many network interfaces, this option specifies which one to use.

{fd, integer() >= 0}

If a socket has somehow been connected without using gen_tcp, use this option to pass the file descriptor - for it. If {ip, ip_address()} and/or + for it. If {ip, Address} and/or {port, port_number()} is 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 @@ -175,9 +175,10 @@ do_recv(Sock, Bs) -> local

- Sets up the socket for local address family. This option is only - valid together with {fd, integer()} when the file descriptor - is of local address family (e.g. a Unix Domain Socket) + Sets up a Unix Domain Socket. See + + inet:local_address() +

{port, Port} @@ -254,7 +255,7 @@ do_recv(Sock, Bs) ->

B is an integer >= 0. The backlog value defines the maximum length that the queue of pending connections can grow to. Defaults to 5.

- {ip, ip_address()} + {ip, Address}

If the host has many network interfaces, this option specifies which one to listen on.

{port, Port} @@ -263,8 +264,8 @@ do_recv(Sock, Bs) ->

If a socket has somehow been connected without using gen_tcp, use this option to pass the file descriptor for it.

- {ifaddr, ip_address()} -

Same as {ip, ip_address()}. If the host has many + {ifaddr, Address} +

Same as {ip, Address}. If the host has many network interfaces, this option specifies which one to use.

inet6 diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml index ca9d9c978c..3f88a0272d 100644 --- a/lib/kernel/doc/src/gen_udp.xml +++ b/lib/kernel/doc/src/gen_udp.xml @@ -85,11 +85,11 @@

Received Packet is delivered as a list.

binary

Received Packet is delivered as a binary.

- {ip, ip_address()} + {ip, Address}

If the host has many network interfaces, this option specifies which one to use.

- {ifaddr, ip_address()} -

Same as {ip, ip_address()}. If the host has many + {ifaddr, Address} +

Same as {ip, Address}. If the host has many network interfaces, this option specifies which one to use.

{fd, integer() >= 0} @@ -107,9 +107,10 @@ local

- Sets up the socket for local address family. This option is only - valid together with {fd, integer()} when the file descriptor - is of local address family (e.g. a Unix Domain Socket) + Sets up a Unix Domain Socket. See + + inet:local_address() +

{udp_module, module()} @@ -184,8 +185,10 @@ Send a packet. -

Sends a packet to the specified address and port. Argument - Address can be a hostname or an IP address.

+

+ Sends a packet to the specified address and port. Argument + Address can be a hostname or a socket address. +

diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 5ff167bcb3..c0dce2f50c 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -117,6 +117,59 @@ fe80::204:acff:fe17:bf38 + + + +

+ This address family only works on Unix-like systems. +

+

+ File is normally a file pathname + in a local filesystem. It is limited in length by the + operating system, traditionally to 108 bytes. +

+

+ A binary() is passed as is to the operating system, + but a string() is encoded according to the + + system filename encoding mode. + +

+

+ Other addresses are possible, for example Linux implements + "Abstract Addresses". See the documentation for + Unix Domain Sockets on your system, + normally unix in manual section 7. +

+

+ In most API functions where you can use + this address family the port number must be 0. +

+
+
+ + + + + + +

+ Addresses besides + + ip_address() + + ones that are returned from socket API functions. + See in particular + + local_address(). + + The unspec family corresponds to AF_UNSPEC and can + occur if the other side has no socket address. + The undefined family can only occur in the unlikely + event of an address family that the VM does not recognize. +

+
+
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index 2b3afcd44c..1a21541b7c 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -96,17 +96,17 @@ tos | ipv6_v6only. -type connect_option() :: - {ip, inet:ip_address()} | + {ip, inet:socket_address()} | {fd, Fd :: non_neg_integer()} | - {ifaddr, inet:ip_address()} | + {ifaddr, inet:socket_address()} | inet:address_family() | {port, inet:port_number()} | {tcp_module, module()} | option(). -type listen_option() :: - {ip, inet:ip_address()} | + {ip, inet:socket_address()} | {fd, Fd :: non_neg_integer()} | - {ifaddr, inet:ip_address()} | + {ifaddr, inet:socket_address()} | inet:address_family() | {port, inet:port_number()} | {backlog, B :: non_neg_integer()} | @@ -122,7 +122,7 @@ %% -spec connect(Address, Port, Options) -> {ok, Socket} | {error, Reason} when - Address :: inet:ip_address() | inet:hostname(), + Address :: inet:socket_address() | inet:hostname(), Port :: inet:port_number(), Options :: [connect_option()], Socket :: socket(), @@ -133,7 +133,7 @@ connect(Address, Port, Opts) -> -spec connect(Address, Port, Options, Timeout) -> {ok, Socket} | {error, Reason} when - Address :: inet:ip_address() | inet:hostname(), + Address :: inet:socket_address() | inet:hostname(), Port :: inet:port_number(), Options :: [connect_option()], Timeout :: timeout(), diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 2227bb3562..98d2f0bcfb 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -92,9 +92,9 @@ open(Port) -> -spec open(Port, Opts) -> {ok, Socket} | {error, Reason} when Port :: inet:port_number(), Opts :: [Option], - Option :: {ip, inet:ip_address()} + Option :: {ip, inet:socket_address()} | {fd, non_neg_integer()} - | {ifaddr, inet:ip_address()} + | {ifaddr, inet:socket_address()} | inet:address_family() | {port, inet:port_number()} | option(), @@ -114,7 +114,7 @@ close(S) -> -spec send(Socket, Address, Port, Packet) -> ok | {error, Reason} when Socket :: socket(), - Address :: inet:ip_address() | inet:hostname(), + Address :: inet:socket_address() | inet:hostname(), Port :: inet:port_number(), Packet :: iodata(), Reason :: not_owner | inet:posix(). @@ -148,7 +148,7 @@ send(S, Packet) when is_port(S) -> {ok, {Address, Port, Packet}} | {error, Reason} when Socket :: socket(), Length :: non_neg_integer(), - Address :: inet:ip_address(), + Address :: inet:ip_address() | inet:returned_non_ip_address(), Port :: inet:port_number(), Packet :: string() | binary(), Reason :: not_owner | inet:posix(). @@ -166,7 +166,7 @@ recv(S,Len) when is_port(S), is_integer(Len) -> Socket :: socket(), Length :: non_neg_integer(), Timeout :: timeout(), - Address :: inet:ip_address(), + Address :: inet:ip_address() | inet:returned_non_ip_address(), Port :: inet:port_number(), Packet :: string() | binary(), Reason :: not_owner | inet:posix(). diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index a7b3c1cef4..20c64a39ca 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -73,8 +73,9 @@ -export([start_timer/1, timeout/1, timeout/2, stop_timer/1]). -export_type([address_family/0, hostent/0, hostname/0, ip4_address/0, - ip6_address/0, ip_address/0, posix/0, socket/0, - port_number/0]). + ip6_address/0, ip_address/0, port_number/0, + local_address/0, socket_address/0, returned_non_ip_address/0, + posix/0, socket/0]). %% imports -import(lists, [append/1, duplicate/2, filter/2, foldl/3]). @@ -98,6 +99,11 @@ 0..65535,0..65535,0..65535,0..65535}. -type ip_address() :: ip4_address() | ip6_address(). -type port_number() :: 0..65535. +-type local_address() :: {local, File :: binary() | string()}. +-type returned_non_ip_address() :: + {local, binary()} | + {unspec, <<>>} | + {undefined, any()}. -type posix() :: exbadport | exbadseq | file:posix(). -type socket() :: port(). @@ -138,7 +144,7 @@ -type socket_protocol() :: 'tcp' | 'udp' | 'sctp'. -type socket_type() :: 'stream' | 'dgram' | 'seqpacket'. -type socket_address() :: - ip_address() | {address_family(), any()} | 'any' | 'loopback'. + ip_address() | 'any' | 'loopback' | local_address(). -type stat_option() :: 'recv_cnt' | 'recv_max' | 'recv_avg' | 'recv_oct' | 'recv_dvi' | 'send_cnt' | 'send_max' | 'send_avg' | 'send_oct' | 'send_pend'. @@ -163,26 +169,33 @@ close(Socket) -> end. --spec peername(Socket) -> {ok, {Address, Port}} | {error, posix()} when - Socket :: socket(), - Address :: ip_address(), - Port :: non_neg_integer(). +-spec peername(Socket :: socket()) -> + {ok, + {ip_address(), port_number()} | + returned_non_ip_address()} | + {error, posix()}. peername(Socket) -> prim_inet:peername(Socket). --spec setpeername(Socket :: socket(), Address :: {ip_address(), port_number()}) -> - 'ok' | {'error', any()}. +-spec setpeername( + Socket :: socket(), + Address :: + {ip_address() | 'any' | 'loopback', + port_number()} | + socket_address()) -> + 'ok' | {'error', any()}. setpeername(Socket, {IP,Port}) -> prim_inet:setpeername(Socket, {IP,Port}); setpeername(Socket, undefined) -> prim_inet:setpeername(Socket, undefined). --spec peernames(Socket) -> {ok, [{Address, Port}]} | {error, posix()} when - Socket :: socket(), - Address :: ip_address(), - Port :: non_neg_integer(). +-spec peernames(Socket :: socket()) -> + {ok, + [{ip_address(), port_number()} | + returned_non_ip_address()]} | + {error, posix()}. peernames(Socket) -> prim_inet:peernames(Socket). @@ -198,15 +211,21 @@ peernames(Socket, Assoc) -> prim_inet:peernames(Socket, Assoc). --spec sockname(Socket) -> {ok, {Address, Port}} | {error, posix()} when - Socket :: socket(), - Address :: ip_address(), - Port :: non_neg_integer(). +-spec sockname(Socket :: socket()) -> + {ok, + {ip_address(), port_number()} | + returned_non_ip_address()} | + {error, posix()}. sockname(Socket) -> prim_inet:sockname(Socket). --spec setsockname(Socket :: socket(), Address :: {ip_address(), port_number()}) -> +-spec setsockname( + Socket :: socket(), + Address :: + {ip_address() | 'any' | 'loopback', + port_number()} | + socket_address()) -> 'ok' | {'error', any()}. setsockname(Socket, {IP,Port}) -> @@ -214,10 +233,11 @@ setsockname(Socket, {IP,Port}) -> setsockname(Socket, undefined) -> prim_inet:setsockname(Socket, undefined). --spec socknames(Socket) -> {ok, [{Address, Port}]} | {error, posix()} when - Socket :: socket(), - Address :: ip_address(), - Port :: non_neg_integer(). +-spec socknames(Socket :: socket()) -> + {ok, + [{ip_address(), port_number()} | + returned_non_ip_address()]} | + {error, posix()}. socknames(Socket) -> prim_inet:socknames(Socket). @@ -1296,7 +1316,17 @@ gethostbyaddr_tm_native(Addr, Timer, Opts) -> end. -spec open(Fd_or_OpenOpts :: integer() | list(), - Addr :: socket_address() | undefined, + Addr :: + socket_address() | + {ip_address() | 'any' | 'loopback', % Unofficial + port_number()} | + {inet, % Unofficial + {ip4_address() | 'any' | 'loopback', + port_number()}} | + {inet6, % Unofficial + {ip6_address() | 'any' | 'loopback', + port_number()}} | + undefined, % Internal - no bind() Port :: port_number(), Opts :: [socket_setopt()], Protocol :: socket_protocol(), -- cgit v1.2.3