aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/doc/src/inet.xml127
-rw-r--r--lib/kernel/src/application_controller.erl2
-rw-r--r--lib/kernel/src/gen_tcp.erl4
-rw-r--r--lib/kernel/src/inet.erl56
-rw-r--r--lib/kernel/src/inet_int.hrl2
-rw-r--r--lib/kernel/src/inet_parse.erl13
-rw-r--r--lib/kernel/test/global_SUITE.erl2
-rw-r--r--lib/kernel/test/inet_SUITE.erl21
8 files changed, 194 insertions, 33 deletions
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index f498a88c5e..a1590c2dce 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -371,7 +371,51 @@ fe80::204:acff:fe17:bf38
</taglist>
</desc>
</func>
-
+ <func>
+ <name name="parse_ipv4_address" arity="1" />
+ <fsummary>Parse an IPv4 address</fsummary>
+ <desc>
+ <p>Parses an IPv4 address string and returns an <a href="#type-ip4_address">ip4_address()</a>.
+ Accepts a shortened IPv4 shortened address string.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="parse_ipv4strict_address" arity="1" />
+ <fsummary>Parse an IPv4 address strict.</fsummary>
+ <desc>
+ <p>Parses an IPv4 address string containing four fields, i.e <b>not</b> shortened, and returns an <a href="#type-ip4_adress">ip4_address()</a>.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="parse_ipv6_address" arity="1" />
+ <fsummary>Parse an IPv6 address</fsummary>
+ <desc>
+ <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
+ If an IPv4 address string is passed, an IPv4-mapped IPv6 address is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="parse_ipv6strict_address" arity="1" />
+ <fsummary>Parse an IPv6 address strict.</fsummary>
+ <desc>
+ <p>Parses an IPv6 address string and returns an <a href="#type-ip6_address">ip6_address()</a>.
+ Does <b>not</b> accept IPv4 adresses.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="parse_address" arity="1" />
+ <fsummary>Parse an IPv4 or IPv6 address.</fsummary>
+ <desc>
+ <p>Parses an IPv4 or IPv6 address string and returns an <a href="#type-ip4_address">ip4_address()</a> or <a href="#type-ip6_address">ip6_address()</a>. Accepts a shortened IPv4 address string.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="parse_strict_address" arity="1" />
+ <fsummary>Parse an IPv4 or IPv6 address strict.</fsummary>
+ <desc>
+ <p>Parses an IPv4 or IPv6 address string and returns an <a href="#type-ip4_address">ip4_address()</a> or <a href="#type-ip6_adress">ip6_address()</a>. Does <b>not</b> accept a shortened IPv4 address string.</p>
+ </desc>
+ </func>
<func>
<name name="peername" arity="1"/>
<fsummary>Return the address and port for the other end of a connection</fsummary>
@@ -512,13 +556,37 @@ fe80::204:acff:fe17:bf38
<c>[Byte1,Byte2|Binary]</c>.</p>
</item>
- <tag><c>{high_watermark, Size}</c></tag>
- <item> <p>
- Sender is forced busy if sent and enqueued data
- reaches the highwater mark.
- <br /> Default: 8192 kB.
- </p>
- </item>
+ <tag><c>{high_msgq_watermark, Size}</c> (TCP/IP sockets)</tag>
+ <item>
+ <p>The socket message queue will be set into a busy
+ state when the amount of data queued on the message
+ queue reaches this limit. Note that this limit only
+ concerns data that have not yet reached the ERTS internal
+ socket implementation. Default value used is 8 kB.</p>
+ <p>Senders of data to the socket will be suspended if
+ either the socket message queue is busy, or the socket
+ itself is busy.</p>
+ <p>For more information see the <c>low_msgq_watermark</c>,
+ <c>high_watermark</c>, and <c>low_watermark</c> options.</p>
+ <p>Note that distribution sockets will disable the use of
+ <c>high_msgq_watermark</c> and <c>low_msgq_watermark</c>,
+ and will instead use the
+ <seealso marker="erts:erlang#system_info_dist_buf_busy_limit">distribution
+ buffer busy limit</seealso> which is a similar feature.</p>
+ </item>
+
+ <tag><c>{high_watermark, Size}</c> (TCP/IP sockets)</tag>
+ <item>
+ <p>The socket will be set into a busy state when the amount
+ of data queued internally by the ERTS socket implementation
+ reaches this limit. Default value used is 8 kB.</p>
+ <p>Senders of data to the socket will be suspended if
+ either the socket message queue is busy, or the socket
+ itself is busy.</p>
+ <p>For more information see the <c>low_watermark</c>,
+ <c>high_msgq_watermark</c>, and <c>low_msqg_watermark</c>
+ options.</p>
+ </item>
<tag><c>{ipv6_v6only, Boolean}</c></tag>
<item>
@@ -603,14 +671,41 @@ fe80::204:acff:fe17:bf38
the flushing time-out in seconds.</p>
</item>
- <tag><c>{low_watermark, Size}</c></tag>
- <item> <p>
- If the port has reached its <c>high_watermark</c> it will
- force busy onto senders. When the port data queue reaches the
- <c>low_watermark</c> callers are no longer forced busy.
- <br /> Default: 4096 kB.
- </p>
- </item>
+ <tag><c>{low_msgq_watermark, Size}</c> (TCP/IP sockets)</tag>
+ <item>
+ <p>If the socket message queue is in a busy state, the
+ socket message queue will be set in a not busy state when
+ the amount of data queued in the message queue falls
+ below this limit. Note that this limit only concerns data
+ that have not yet reached the ERTS internal socket
+ implementation. Default value used is 4 kB.</p>
+ <p>Senders that have been suspended due to either a
+ busy message queue or a busy socket, will be resumed
+ when neither the socket message queue, nor the socket
+ are busy.</p>
+ <p>For more information see the <c>high_msgq_watermark</c>,
+ <c>high_watermark</c>, and <c>low_watermark</c> options.</p>
+ <p>Note that distribution sockets will disable the use of
+ <c>high_msgq_watermark</c> and <c>low_msgq_watermark</c>,
+ and will instead use the
+ <seealso marker="erts:erlang#system_info_dist_buf_busy_limit">distribution
+ buffer busy limit</seealso> which is a similar feature.</p>
+ </item>
+
+ <tag><c>{low_watermark, Size}</c> (TCP/IP sockets)</tag>
+ <item>
+ <p>If the socket is in a busy state, the socket will
+ be set in a not busy state when the amount of data
+ queued internally by the ERTS socket implementation
+ falls below this limit. Default value used is 4 kB.</p>
+ <p>Senders that have been suspended due to either a
+ busy message queue or a busy socket, will be resumed
+ when neither the socket message queue, nor the socket
+ are busy.</p>
+ <p>For more information see the <c>high_watermark</c>,
+ <c>high_msgq_watermark</c>, and <c>low_msgq_watermark</c>
+ options.</p>
+ </item>
<tag><c>{mode, Mode :: binary | list}</c></tag>
<item>
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 68cd26ec10..75ce852001 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -1960,5 +1960,5 @@ to_string(Term) ->
true ->
Term;
false ->
- lists:flatten(io_lib:write(Term))
+ lists:flatten(io_lib:format("~134217728p", [Term]))
end.
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index 22e6aa5bc8..ec13ab6d2e 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -37,9 +37,11 @@
{dontroute, boolean()} |
{exit_on_close, boolean()} |
{header, non_neg_integer()} |
+ {high_msgq_watermark, pos_integer()} |
{high_watermark, non_neg_integer()} |
{keepalive, boolean()} |
{linger, {boolean(), non_neg_integer()}} |
+ {low_msgq_watermark, pos_integer()} |
{low_watermark, non_neg_integer()} |
{mode, list | binary} | list | binary |
{nodelay, boolean()} |
@@ -67,9 +69,11 @@
dontroute |
exit_on_close |
header |
+ high_msgq_watermark |
high_watermark |
keepalive |
linger |
+ low_msgq_watermark |
low_watermark |
mode |
nodelay |
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 92c1802a86..9670271b2e 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -30,7 +30,9 @@
ifget/3, ifget/2, ifset/3, ifset/2,
getstat/1, getstat/2,
ip/1, stats/0, options/0,
- pushf/3, popf/1, close/1, gethostname/0, gethostname/1]).
+ pushf/3, popf/1, close/1, gethostname/0, gethostname/1,
+ parse_ipv4_address/1, parse_ipv6_address/1, parse_ipv4strict_address/1,
+ parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1]).
-export([connect_options/2, listen_options/2, udp_options/2, sctp_options/2]).
@@ -527,6 +529,48 @@ getservbyname(Name, Protocol) when is_atom(Name) ->
Error -> Error
end.
+-spec parse_ipv4_address(Address) ->
+ {ok, IPv4Address} | {error, einval} when
+ Address :: string(),
+ IPv4Address :: ip_address().
+parse_ipv4_address(Addr) ->
+ inet_parse:ipv4_address(Addr).
+
+-spec parse_ipv6_address(Address) ->
+ {ok, IPv6Address} | {error, einval} when
+ Address :: string(),
+ IPv6Address :: ip_address().
+parse_ipv6_address(Addr) ->
+ inet_parse:ipv6_address(Addr).
+
+-spec parse_ipv4strict_address(Address) ->
+ {ok, IPv4Address} | {error, einval} when
+ Address :: string(),
+ IPv4Address :: ip_address().
+parse_ipv4strict_address(Addr) ->
+ inet_parse:ipv4strict_address(Addr).
+
+-spec parse_ipv6strict_address(Address) ->
+ {ok, IPv6Address} | {error, einval} when
+ Address :: string(),
+ IPv6Address :: ip_address().
+parse_ipv6strict_address(Addr) ->
+ inet_parse:ipv6strict_address(Addr).
+
+-spec parse_address(Address) ->
+ {ok, IPAddress} | {error, einval} when
+ Address :: string(),
+ IPAddress :: ip_address().
+parse_address(Addr) ->
+ inet_parse:address(Addr).
+
+-spec parse_strict_address(Address) ->
+ {ok, IPAddress} | {error, einval} when
+ Address :: string(),
+ IPAddress :: ip_address().
+parse_strict_address(Addr) ->
+ inet_parse:strict_address(Addr).
+
%% Return a list of available options
options() ->
[
@@ -535,6 +579,7 @@ options() ->
buffer, header, active, packet, deliver, mode,
multicast_if, multicast_ttl, multicast_loop,
exit_on_close, high_watermark, low_watermark,
+ high_msgq_watermark, low_msgq_watermark,
send_timeout, send_timeout_close
].
@@ -552,8 +597,8 @@ stats() ->
connect_options() ->
[tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
header, active, packet, packet_size, buffer, mode, deliver,
- exit_on_close, high_watermark, low_watermark, send_timeout,
- send_timeout_close, delay_send,raw].
+ exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
+ low_msgq_watermark, send_timeout, send_timeout_close, delay_send, raw].
connect_options(Opts, Family) ->
BaseOpts =
@@ -608,8 +653,9 @@ con_add(Name, Val, R, Opts, AllOpts) ->
listen_options() ->
[tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay,
header, active, packet, buffer, mode, deliver, backlog, ipv6_v6only,
- exit_on_close, high_watermark, low_watermark, send_timeout,
- send_timeout_close, delay_send, packet_size,raw].
+ exit_on_close, high_watermark, low_watermark, high_msgq_watermark,
+ low_msgq_watermark, send_timeout, send_timeout_close, delay_send,
+ packet_size, raw].
listen_options(Opts, Family) ->
BaseOpts =
diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl
index 6d808b54cd..000119bc74 100644
--- a/lib/kernel/src/inet_int.hrl
+++ b/lib/kernel/src/inet_int.hrl
@@ -141,6 +141,8 @@
-define(INET_LOPT_READ_PACKETS, 33).
-define(INET_OPT_RAW, 34).
-define(INET_LOPT_TCP_SEND_TIMEOUT_CLOSE, 35).
+-define(INET_LOPT_TCP_MSGQ_HIWTRMRK, 36).
+-define(INET_LOPT_TCP_MSGQ_LOWTRMRK, 37).
% Specific SCTP options: separate range:
-define(SCTP_OPT_RTOINFO, 100).
-define(SCTP_OPT_ASSOCINFO, 101).
diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl
index ba62a59068..3551e701b6 100644
--- a/lib/kernel/src/inet_parse.erl
+++ b/lib/kernel/src/inet_parse.erl
@@ -36,7 +36,7 @@
-export([ipv4_address/1, ipv6_address/1]).
-export([ipv4strict_address/1, ipv6strict_address/1]).
--export([address/1]).
+-export([address/1, strict_address/1]).
-export([visible_string/1, domain/1]).
-export([ntoa/1, dots/1]).
-export([split_line/1]).
@@ -456,6 +456,17 @@ address(Cs) when is_list(Cs) ->
address(_) ->
{error, einval}.
+%%Parse ipv4 strict address or ipv6 strict address
+strict_address(Cs) when is_list(Cs) ->
+ case ipv4strict_address(Cs) of
+ {ok,IP} ->
+ {ok,IP};
+ _ ->
+ ipv6strict_address(Cs)
+ end;
+strict_address(Cs) ->
+ {error, einval}.
+
%%
%% Parse IPv4 address:
%% d1.d2.d3.d4
diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl
index 1cc3eb7c79..b40c50f79f 100644
--- a/lib/kernel/test/global_SUITE.erl
+++ b/lib/kernel/test/global_SUITE.erl
@@ -3821,7 +3821,7 @@ start_node_rel(Name0, Rel, Config) ->
Name = node_name(Name0, Config),
{Release, Compat} = case Rel of
this ->
- {[this], "+R8"};
+ {[this], ""};
Rel when is_atom(Rel) ->
{[{release, atom_to_list(Rel)}], ""};
RelList ->
diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl
index ce138b6804..e5e1794514 100644
--- a/lib/kernel/test/inet_SUITE.erl
+++ b/lib/kernel/test/inet_SUITE.erl
@@ -37,7 +37,8 @@
gethostnative_soft_restart/0, gethostnative_soft_restart/1,
gethostnative_debug_level/0, gethostnative_debug_level/1,
getif/1,
- getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1]).
+ getif_ifr_name_overflow/1,getservbyname_overflow/1, getifaddrs/1,
+ parse_strict_address/1]).
-export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1,
kill_gethost/0, parallell_gethost/0]).
@@ -52,7 +53,7 @@ all() ->
t_gethostnative, gethostnative_parallell, cname_loop,
gethostnative_debug_level, gethostnative_soft_restart,
getif, getif_ifr_name_overflow, getservbyname_overflow,
- getifaddrs].
+ getifaddrs, parse_strict_address].
groups() ->
[{parse, [], [parse_hosts, parse_address]}].
@@ -582,16 +583,16 @@ parse_address(Config) when is_list(Config) ->
"fe80::198.168.0.",
"fec0::fFfF:127.0.0.1."],
t_parse_address
- (ipv6_address,
+ (parse_ipv6_address,
V6Strict++V6Sloppy++V6Err++V4Err),
t_parse_address
- (ipv6strict_address,
+ (parse_ipv6strict_address,
V6Strict++V6Err++V4Err++[S || {_,S} <- V6Sloppy]),
t_parse_address
- (ipv4_address,
+ (parse_ipv4_address,
V4Strict++V4Sloppy++V4Err++V6Err++[S || {_,S} <- V6Strict]),
t_parse_address
- (ipv4strict_address,
+ (parse_ipv4strict_address,
V4Strict++V4Err++V6Err++[S || {_,S} <- V4Sloppy++V6Strict]).
t_parse_address(Func, []) ->
@@ -599,14 +600,16 @@ t_parse_address(Func, []) ->
ok;
t_parse_address(Func, [{Addr,String}|L]) ->
io:format("~p = ~p.~n", [Addr,String]),
- {ok,Addr} = inet_parse:Func(String),
+ {ok,Addr} = inet:Func(String),
t_parse_address(Func, L);
t_parse_address(Func, [String|L]) ->
io:format("~p.~n", [String]),
- {error,einval} = inet_parse:Func(String),
+ {error,einval} = inet:Func(String),
t_parse_address(Func, L).
-
+parse_strict_address(Config) when is_list(Config) ->
+ {ok, Ipv4} = inet:parse_strict_address("127.0.0.1"),
+ {ok, Ipv6} = inet:parse_strict_address("c11:0c22:5c33:c440:55c0:c66c:77:0088").
t_gethostnative(suite) ->[];
t_gethostnative(doc) ->[];