aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2019-05-29 13:50:12 +0200
committerMicael Karlberg <[email protected]>2019-05-29 13:50:12 +0200
commit5ef7039261b8af01d97ba22ea05d5a466423c256 (patch)
tree0fc34371f5143f0c340b2268d5dad7ec06855564 /erts
parent00f497b18202d4b1b97fbdd0dcf211a6066227a9 (diff)
parent0bb7928c5985b057efbf8846ffbfc55edc7f31d4 (diff)
downloadotp-5ef7039261b8af01d97ba22ea05d5a466423c256.tar.gz
otp-5ef7039261b8af01d97ba22ea05d5a466423c256.tar.bz2
otp-5ef7039261b8af01d97ba22ea05d5a466423c256.zip
Merge branch 'maint'
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/socket.xml21
-rw-r--r--erts/doc/src/socket_usage.xml2
-rw-r--r--erts/emulator/nifs/common/socket_int.h1
-rw-r--r--erts/emulator/nifs/common/socket_nif.c126
-rw-r--r--erts/emulator/nifs/common/socket_util.c20
-rwxr-xr-xerts/emulator/test/esock_ttest/esock-ttest106
-rwxr-xr-xerts/emulator/test/esock_ttest/esock-ttest-client63
-rw-r--r--erts/emulator/test/socket_SUITE.erl2967
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_client.erl96
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_client_gen.erl18
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_client_socket.erl85
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_gen.erl21
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_server.erl79
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_server_gen.erl16
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_server_socket.erl19
-rw-r--r--erts/emulator/test/socket_test_ttest_tcp_socket.erl131
-rw-r--r--erts/preloaded/ebin/socket.beambin70248 -> 70456 bytes
-rw-r--r--erts/preloaded/src/socket.erl81
18 files changed, 3143 insertions, 709 deletions
diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml
index 343b61d4aa..9b34bf1df1 100644
--- a/erts/doc/src/socket.xml
+++ b/erts/doc/src/socket.xml
@@ -373,19 +373,24 @@
<name name="open" arity="4" since="OTP 22.0"/>
<fsummary>Create an endpoint for communication.</fsummary>
<desc>
- <p>Creates an endpoint (socket) for communication.</p>
- <p>For some <c>types</c> there is a default protocol, which will
- be used if no protocol is specified: </p>
+ <p>Creates an endpoint (socket) for communication.</p>
- <list>
- <item><p><c>stream</c>: <c>tcp</c></p></item>
- <item><p><c>dgram</c>: <c>udp</c></p></item>
- <item><p><c>seqpacket</c>: <c>sctp</c></p></item>
- </list>
+ <p>For some <c>types</c> there is a default protocol,
+ indicated by <c>default</c>, which it <em>may</em> be
+ possible to specify.
+ And for <c>Domain = local</c>, if a protocol <em>is</em> pecified,
+ it <em>must</em> be <c>default</c>. </p>
<p>The <c>Extra</c> argument is intended for "obscure" options.
Currently the only supported option is <c>netns</c>, which
is only supported on the linux platform.</p>
+
+ <note>
+ <p>It may not be possible to specify the default protocol (except
+ when <c>Domain = local</c>). We need to be able to retreive
+ the resulting protocol, which is <em>not</em> possble on all
+ platforms. </p>
+ </note>
</desc>
</func>
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index e0f006e618..4b3872d7e3 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -205,7 +205,7 @@
<cell>protocol()</cell>
<cell>no</cell>
<cell>yes</cell>
- <cell>none</cell>
+ <cell><em>Not</em> on (some) Darwin (for instance)</cell>
</row>
<row>
<cell>rcvbuf</cell>
diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h
index 38c28a6de5..d6977be5aa 100644
--- a/erts/emulator/nifs/common/socket_int.h
+++ b/erts/emulator/nifs/common/socket_int.h
@@ -139,6 +139,7 @@ typedef unsigned int BOOLEAN_T;
GLOBAL_ATOM_DEF(ctrunc); \
GLOBAL_ATOM_DEF(data); \
GLOBAL_ATOM_DEF(debug); \
+ GLOBAL_ATOM_DEF(default); \
GLOBAL_ATOM_DEF(default_send_params); \
GLOBAL_ATOM_DEF(delayed_ack_time); \
GLOBAL_ATOM_DEF(dgram); \
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index e71c786d3e..25bc712949 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -528,6 +528,7 @@ typedef union {
#define SOCKET_TYPE_SEQPACKET 5
/* protocol */
+#define SOCKET_PROTOCOL_DEFAULT 0
#define SOCKET_PROTOCOL_IP 1
#define SOCKET_PROTOCOL_TCP 2
#define SOCKET_PROTOCOL_UDP 3
@@ -658,6 +659,10 @@ typedef union {
#define SOCKET_SUPPORTS_OPTIONS 0x0001
#define SOCKET_SUPPORTS_SCTP 0x0002
#define SOCKET_SUPPORTS_IPV6 0x0003
+#define SOCKET_SUPPORTS_LOCAL 0x0004
+
+#define ESOCK_WHICH_PROTO_ERROR -1
+#define ESOCK_WHICH_PROTO_UNSUP -2
@@ -994,12 +999,15 @@ static ERL_NIF_TERM nsupports_options_udp(ErlNifEnv* env);
static ERL_NIF_TERM nsupports_options_sctp(ErlNifEnv* env);
static ERL_NIF_TERM nsupports_sctp(ErlNifEnv* env);
static ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env);
+static ERL_NIF_TERM nsupports_local(ErlNifEnv* env);
static ERL_NIF_TERM nopen(ErlNifEnv* env,
int domain,
int type,
int protocol,
char* netns);
+static BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto);
+
static ERL_NIF_TERM nbind(ErlNifEnv* env,
ESockDescriptor* descP,
ESockAddress* sockAddrP,
@@ -2644,6 +2652,7 @@ static char str_exsend[] = "exsend"; // failed send
GLOBAL_ATOM_DECL(ctrunc); \
GLOBAL_ATOM_DECL(data); \
GLOBAL_ATOM_DECL(debug); \
+ GLOBAL_ATOM_DECL(default); \
GLOBAL_ATOM_DECL(default_send_params); \
GLOBAL_ATOM_DECL(delayed_ack_time); \
GLOBAL_ATOM_DECL(dgram); \
@@ -3046,6 +3055,9 @@ ERL_NIF_TERM nif_info(ErlNifEnv* env,
* {tcp, [{Opt, boolean()}]},
* {udp, [{Opt, boolean()}]},
* {sctp, [{Opt, boolean()}]}]
+ * sctp boolean()
+ * ipv6 boolean()
+ * local boolean()
*/
static
@@ -3073,13 +3085,10 @@ ERL_NIF_TERM nif_supports(ErlNifEnv* env,
-/* nopen - create an endpoint for communication
- *
- * Assumes the input has been validated.
+/* nsupports - what features do we support
*
- * Normally we want debugging on (individual) sockets to be controlled
- * by the sockets own debug flag. But since we don't even have a socket
- * yet, we must use the global debug flag.
+ * This is to prove information about what features actually
+ * work on the current platform.
*/
#if !defined(__WIN32__)
static
@@ -3102,6 +3111,10 @@ ERL_NIF_TERM nsupports(ErlNifEnv* env, int key)
result = nsupports_ipv6(env);
break;
+ case SOCKET_SUPPORTS_LOCAL:
+ result = nsupports_local(env);
+ break;
+
default:
result = esock_atom_false;
break;
@@ -4324,6 +4337,24 @@ ERL_NIF_TERM nsupports_ipv6(ErlNifEnv* env)
+#if !defined(__WIN32__)
+static
+ERL_NIF_TERM nsupports_local(ErlNifEnv* env)
+{
+ ERL_NIF_TERM supports;
+
+#if defined(AF_LOCAL)
+ supports = esock_atom_true;
+#else
+ supports = esock_atom_false;
+#endif
+
+ return supports;
+}
+#endif
+
+
+
/* ----------------------------------------------------------------------
* nif_open
*
@@ -4421,6 +4452,7 @@ ERL_NIF_TERM nif_open(ErlNifEnv* env,
* yet, we must use the global debug flag.
*/
#if !defined(__WIN32__)
+
static
ERL_NIF_TERM nopen(ErlNifEnv* env,
int domain, int type, int protocol,
@@ -4428,7 +4460,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
{
ESockDescriptor* descP;
ERL_NIF_TERM res;
- int save_errno = 0;
+ int proto = protocol, save_errno = 0;
SOCKET sock;
HANDLE event;
#ifdef HAVE_SETNS
@@ -4448,11 +4480,35 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
return esock_make_error_errno(env, save_errno);
#endif
- if ((sock = sock_open(domain, type, protocol)) == INVALID_SOCKET)
+ if ((sock = sock_open(domain, type, proto)) == INVALID_SOCKET)
return esock_make_error_errno(env, sock_errno());
SGDBG( ("SOCKET", "nopen -> open success: %d\r\n", sock) );
+
+ /* NOTE that if the protocol = 0 (default) and the domain is not
+ * local (AF_LOCAL) we need to explicitly get the protocol here!
+ */
+
+ if ((proto == 0)
+#if defined(AF_LOCAL)
+ && (domain != AF_LOCAL)
+#endif
+ )
+ if (!nopen_which_protocol(sock, &proto)) {
+ if (proto == ESOCK_WHICH_PROTO_ERROR) {
+ save_errno = sock_errno();
+ while ((sock_close(sock) == INVALID_SOCKET) &&
+ (sock_errno() == EINTR));
+ return esock_make_error_errno(env, save_errno);
+ } else {
+ while ((sock_close(sock) == INVALID_SOCKET) &&
+ (sock_errno() == EINTR));
+ return esock_make_error(env, esock_atom_eafnosupport);
+ }
+ }
+
+
#ifdef HAVE_SETNS
if ((netns != NULL) &&
!restore_network_namespace(current_ns, sock, &save_errno))
@@ -4484,7 +4540,7 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
descP->state = SOCKET_STATE_OPEN;
descP->domain = domain;
descP->type = type;
- descP->protocol = protocol;
+ descP->protocol = proto;
/* Does this apply to other types? Such as RAW?
* Also, is this really correct? Should we not wait for bind?
@@ -4521,6 +4577,32 @@ ERL_NIF_TERM nopen(ErlNifEnv* env,
return esock_make_ok2(env, res);
}
+
+
+static
+BOOLEAN_T nopen_which_protocol(SOCKET sock, int* proto)
+{
+#if defined(SO_PROTOCOL)
+ int val;
+ SOCKOPTLEN_T valSz = sizeof(val);
+ int res;
+
+ res = sock_getopt(sock, SOL_SOCKET, SO_PROTOCOL, &val, &valSz);
+
+ if (res != 0) {
+ *proto = ESOCK_WHICH_PROTO_ERROR;
+ return FALSE;
+ } else {
+ *proto = val;
+ return TRUE;
+ }
+#else
+ *proto = ESOCK_WHICH_PROTO_UNSUP;
+ return FALSE;
+#endif
+}
+
+
#endif // if !defined(__WIN32__)
@@ -10895,7 +10977,15 @@ ERL_NIF_TERM ngetopt_otp_protocol(ErlNifEnv* env,
switch (val) {
case IPPROTO_IP:
+#if defined(AF_LOCAL)
+ if (descP->domain == AF_LOCAL) {
+ result = esock_make_ok2(env, esock_atom_default);
+ } else {
+ result = esock_make_ok2(env, esock_atom_ip);
+ }
+#else
result = esock_make_ok2(env, esock_atom_ip);
+#endif
break;
case IPPROTO_TCP:
@@ -11467,7 +11557,14 @@ ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env,
} else {
switch (val) {
case IPPROTO_IP:
+#if defined(AF_LOCAL)
+ if (descP->domain == AF_LOCAL)
+ result = esock_make_ok2(env, esock_atom_default);
+ else
+ result = esock_make_ok2(env, esock_atom_ip);
+#else
result = esock_make_ok2(env, esock_atom_ip);
+#endif
break;
case IPPROTO_TCP:
@@ -15135,8 +15232,8 @@ char* encode_msghdr(ErlNifEnv* env,
"\r\n read: %d"
"\r\n", read) );
- /* The address is not used if we are connected,
- * so check (length = 0) before we try to encodel
+ /* The address is not used if we are connected (unless, maybe,
+ * family is 'local'), so check (length = 0) before we try to encodel
*/
if (msgHdrP->msg_namelen != 0) {
if ((xres = esock_encode_sockaddr(env,
@@ -16258,8 +16355,6 @@ char* encode_cmsghdr_data_ipv6(ErlNifEnv* env,
size_t dataLen,
ERL_NIF_TERM* eCMsgHdrData)
{
- char* xres;
-
switch (type) {
#if defined(IPV6_PKTINFO)
case IPV6_PKTINFO:
@@ -16267,6 +16362,7 @@ char* encode_cmsghdr_data_ipv6(ErlNifEnv* env,
struct in6_pktinfo* pktInfoP = (struct in6_pktinfo*) dataP;
ERL_NIF_TERM ifIndex = MKI(env, pktInfoP->ipi6_ifindex);
ERL_NIF_TERM addr;
+ char* xres;
if ((xres = esock_encode_ip6_address(env,
&pktInfoP->ipi6_addr,
@@ -17039,6 +17135,10 @@ BOOLEAN_T eproto2proto(ErlNifEnv* env,
}
switch (ep) {
+ case SOCKET_PROTOCOL_DEFAULT:
+ *proto = 0; // default - note that _IP also has the value 0...
+ break;
+
case SOCKET_PROTOCOL_IP:
*proto = IPPROTO_IP;
break;
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index a61cfc75ef..2740cb51ef 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -986,9 +986,27 @@ char* esock_decode_timeval(ErlNifEnv* env,
if (!GET_LONG(env, eSec, &timeP->tv_sec))
return ESOCK_STR_EINVAL;
+#if (SIZEOF_INT == 4)
+ {
+ int usec;
+ if (!GET_INT(env, eUSec, &usec))
+ return ESOCK_STR_EINVAL;
+ timeP->tv_usec = (typeof(timeP->tv_usec)) usec;
+ }
+#elif (SIZEOF_LONG == 4)
+ {
+ long usec;
+ if (!GET_LONG(env, eUSec, &usec))
+ return ESOCK_STR_EINVAL;
+ timeP->tv_usec = (typeof(timeP->tv_usec)) usec;
+ }
+#else
+ /* Ok, we give up... */
if (!GET_LONG(env, eUSec, &timeP->tv_usec))
return ESOCK_STR_EINVAL;
+#endif
+
return NULL;
}
@@ -1656,7 +1674,7 @@ char* make_sockaddr_un(ErlNifEnv* env,
ERL_NIF_TERM* sa)
{
ERL_NIF_TERM keys[] = {esock_atom_family, esock_atom_path};
- ERL_NIF_TERM vals[] = {esock_atom_inet, path};
+ ERL_NIF_TERM vals[] = {esock_atom_local, path};
unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM);
unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM);
diff --git a/erts/emulator/test/esock_ttest/esock-ttest b/erts/emulator/test/esock_ttest/esock-ttest
index f0d363ab30..cf1d9cd9ab 100755
--- a/erts/emulator/test/esock_ttest/esock-ttest
+++ b/erts/emulator/test/esock_ttest/esock-ttest
@@ -50,43 +50,47 @@ usage() ->
"~n units (server or client)."
"~n"
"~n options: "
- "~n --help Display this info and exit. "
- "~n --server [server-options] Start a server. "
- "~n There are no mandatory server options."
- "~n --client client-options Start a client"
- "~n Some client options are mandatory and"
- "~n others optional."
- "~n --active <active> boolean() | once."
- "~n Valid for both client and server."
- "~n Defaults to: false"
- "~n --transport <transport> Which transport to use: gen|sock[:plain|msg]"
- "~n gen: gen_tcp"
- "~n sock: socket"
- "~n plain: recv/send (default)"
- "~n msg: recvmsg/sendmsg"
- "~n Defaults to: sock:plain"
- "~n --scon <addr>:<port> Address and port of the server."
- "~n The address part is in the standard form:"
- "~n \"a.b.c.d\"."
- "~n Only valid for client."
- "~n Mandatory."
- "~n --msg-id <1|2|3> Choose which message to use during the test."
- "~n Basically: "
- "~n 1: small"
- "~n 2: medium"
- "~n 3: large"
- "~n Defaults to: 1"
- "~n --max-outstanding <Num> How many messages to send before waiting for"
- "~n a reply."
- "~n Valid only for client."
- "~n Defaults to: "
- "~n MsgID 1: 100"
- "~n MsgID 2: 10"
- "~n MsgID 3: 1"
- "~n --runtime <Time> Time of the test in seconds."
- "~n Only valid for client."
- "~n Mandatory."
- "~n Defaults to: 60 (seconds)"
+ "~n --help Display this info and exit. "
+ "~n --server [server-options] Start a server. "
+ "~n There are no mandatory server options."
+ "~n --client client-options Start a client"
+ "~n Some client options are mandatory and"
+ "~n others optional."
+ "~n --domain <domain> local | inet | inet6"
+ "~n Which domain to use."
+ "~n Only valid for server."
+ "~n Defaults to: inet"
+ "~n --active <active> boolean() | once."
+ "~n Valid for both client and server."
+ "~n Defaults to: false"
+ "~n --transport <transport> Which transport to use: gen|sock[:plain|msg]"
+ "~n gen: gen_tcp"
+ "~n sock: socket"
+ "~n plain: recv/send (default)"
+ "~n msg: recvmsg/sendmsg"
+ "~n Defaults to: sock:plain"
+ "~n --scon <addr>:<port>|<path> Server info."
+ "~n The address part is in the standard form:"
+ "~n \"a.b.c.d\"."
+ "~n <path> is used for Unix Domain sockets (local)."
+ "~n Only valid, and mandatory, for client."
+ "~n --msg-id <1|2|3> Choose which message to use during the test."
+ "~n Basically: "
+ "~n 1: small"
+ "~n 2: medium"
+ "~n 3: large"
+ "~n Defaults to: 1"
+ "~n --max-outstanding <Num> How many messages to send before waiting for"
+ "~n a reply."
+ "~n Valid only for client."
+ "~n Defaults to: "
+ "~n MsgID 1: 100"
+ "~n MsgID 2: 10"
+ "~n MsgID 3: 1"
+ "~n --runtime <Time> Time of the test in seconds."
+ "~n Only valid for client."
+ "~n Mandatory."
+ "~n Defaults to: 60 (seconds)"
"~n"
"~n"
"~n",
@@ -106,6 +110,7 @@ process_args(Args) ->
process_server_args(Args) ->
Defaults = #{role => server,
+ domain => inet,
active => false,
transport => {sock, plain}},
process_server_args(Args, Defaults).
@@ -113,6 +118,12 @@ process_server_args(Args) ->
process_server_args([], State) ->
State;
+process_server_args(["--domain", Domain|Args], State)
+ when ((Domain =:= "local") orelse
+ (Domain =:= "inet") orelse
+ (Domain =:= "inet6")) ->
+ process_server_args(Args, State#{domain => list_to_atom(Domain)});
+
process_server_args(["--active", Active|Args], State)
when ((Active =:= "false") orelse
(Active =:= "once") orelse
@@ -137,7 +148,7 @@ process_client_args(Args) ->
active => false,
transport => {sock, plain},
%% Will cause error if not provided
- %% Should be "addr:port"
+ %% Should be "addr:port or string()
server => undefined,
msg_id => 1,
%% Will be filled in based on msg_id if not provided
@@ -199,6 +210,8 @@ process_client_args(["--scon", Server|Args], State) ->
usage(f("Invalid Server Port: ~s", [PortStr]))
end,
process_client_args(Args, State#{server => {Addr, Port}});
+ [Path] ->
+ process_client_args(Args, State#{server => Path});
_ ->
usage(f("Invalid Server: ~s", [Server]))
end;
@@ -249,9 +262,11 @@ process_client_args_ensure_max_outstanding(
%% ==========================================================================
exec(#{role := server,
+ domain := Domain,
active := Active,
- transport := gen}) ->
- case socket_test_ttest_tcp_server_gen:start(Active) of
+ transport := gen})
+ when (Domain =:= inet) orelse (Domain =:= inet6) ->
+ case socket_test_ttest_tcp_server_gen:start(Domain, Active) of
{ok, {Pid, _}} ->
MRef = erlang:monitor(process, Pid),
receive
@@ -264,9 +279,10 @@ exec(#{role := server,
error
end;
exec(#{role := server,
+ domain := Domain,
active := Active,
transport := {sock, Method}}) ->
- case socket_test_ttest_tcp_server_socket:start(Method, Active) of
+ case socket_test_ttest_tcp_server_socket:start(Method, Domain, Active) of
{ok, {Pid, _}} ->
MRef = erlang:monitor(process, Pid),
receive
@@ -283,15 +299,15 @@ exec(#{role := client,
server := undefined}) ->
usage("Mandatory option 'server' not provided");
exec(#{role := client,
- server := {Addr, Port},
+ server := {_Addr, _Port} = ServerInfo,
active := Active,
transport := gen,
msg_id := MsgID,
max_outstanding := MaxOutstanding,
runtime := RunTime}) ->
case socket_test_ttest_tcp_client_gen:start(true,
+ ServerInfo,
Active,
- Addr, Port,
MsgID, MaxOutstanding,
RunTime) of
{ok, Pid} ->
@@ -306,7 +322,7 @@ exec(#{role := client,
error
end;
exec(#{role := client,
- server := {Addr, Port},
+ server := ServerInfo,
active := Active,
transport := {sock, Method},
msg_id := MsgID,
@@ -314,8 +330,8 @@ exec(#{role := client,
runtime := RunTime}) ->
case socket_test_ttest_tcp_client_socket:start(true,
Method,
+ ServerInfo,
Active,
- Addr, Port,
MsgID, MaxOutstanding,
RunTime) of
{ok, Pid} ->
diff --git a/erts/emulator/test/esock_ttest/esock-ttest-client b/erts/emulator/test/esock_ttest/esock-ttest-client
index 1ab56f2d44..7c90ae6391 100755
--- a/erts/emulator/test/esock_ttest/esock-ttest-client
+++ b/erts/emulator/test/esock_ttest/esock-ttest-client
@@ -26,33 +26,46 @@ ESOCK_TTEST=$EMU_TEST/esock_ttest
RUNTIME=30
-MSGID=$1
-SERVER_ADDR=$2
-SERVER_PORT=$3
+if [ $# = 3 ]; then
+ MSGID=$1
+ SERVER_INFO=$2:$3
+
+ ITERATIONS="\
+ gen false $MSGID
+ gen true $MSGID
+ gen once $MSGID
+ sock false $MSGID
+ sock true $MSGID
+ sock once $MSGID"
+
+else
+ if [ $# = 2 ]; then
+ MSGID=$1
+ SERVER_INFO=$2
+
+ ITERATIONS="\
+ sock false $MSGID
+ sock true $MSGID
+ sock once $MSGID"
+
+ else
+ echo "Invalid number of args"
+ exit 1;
+ fi
+fi
+
# ---------------------------------------------------------------------------
-ITERATIONS="\
- gen false $MSGID
- gen true $MSGID
- gen once $MSGID
- sock false $MSGID
- sock true $MSGID
- sock once $MSGID"
-
-# gen false 2
-# gen true 2
-# gen once 2
-# sock false 2
-# sock true 2
-# sock once 2
-# gen false 3
-# gen true 3
-# gen once 3
-# sock false 3
-# sock true 3
-# sock once 3
-#
+# For when we have figured out how to configure local for gen_tcp...
+
+#ITERATIONS="\
+# gen false $MSGID
+# gen true $MSGID
+# gen once $MSGID
+# sock false $MSGID
+# sock true $MSGID
+# sock once $MSGID"
# ---------------------------------------------------------------------------
@@ -64,7 +77,7 @@ echo "$ITERATIONS" |
# The /dev/null at the end is necessary because erlang "does things" with stdin
# and this case would cause the 'while read' to "fail" so that we only would
# loop one time
- $ESOCK_TTEST/esock-ttest --client --transport $TRANSPORT --active $ACTIVE --msg-id $MSG_ID --scon $SERVER_ADDR:$SERVER_PORT --runtime $RUNTIME </dev/null
+ $ESOCK_TTEST/esock-ttest --client --transport $TRANSPORT --active $ACTIVE --msg-id $MSG_ID --scon $SERVER_INFO --runtime $RUNTIME </dev/null
echo ""
done
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl
index e3545ccbf9..49b0fcccc2 100644
--- a/erts/emulator/test/socket_SUITE.erl
+++ b/erts/emulator/test/socket_SUITE.erl
@@ -70,10 +70,16 @@
%% *** API Basic ***
api_b_open_and_close_udp4/1,
api_b_open_and_close_tcp4/1,
+ api_b_open_and_close_udpL/1,
+ api_b_open_and_close_tcpL/1,
api_b_sendto_and_recvfrom_udp4/1,
+ api_b_sendto_and_recvfrom_udpL/1,
api_b_sendmsg_and_recvmsg_udp4/1,
+ api_b_sendmsg_and_recvmsg_udpL/1,
api_b_send_and_recv_tcp4/1,
+ api_b_send_and_recv_tcpL/1,
api_b_sendmsg_and_recvmsg_tcp4/1,
+ api_b_sendmsg_and_recvmsg_tcpL/1,
%% *** API Options ***
api_opt_simple_otp_options/1,
@@ -107,57 +113,79 @@
%% *** Socket Closure ***
sc_cpe_socket_cleanup_tcp4/1,
sc_cpe_socket_cleanup_tcp6/1,
+ sc_cpe_socket_cleanup_tcpL/1,
sc_cpe_socket_cleanup_udp4/1,
sc_cpe_socket_cleanup_udp6/1,
+ sc_cpe_socket_cleanup_udpL/1,
sc_lc_recv_response_tcp4/1,
sc_lc_recv_response_tcp6/1,
+ sc_lc_recv_response_tcpL/1,
sc_lc_recvfrom_response_udp4/1,
sc_lc_recvfrom_response_udp6/1,
+ sc_lc_recvfrom_response_udpL/1,
sc_lc_recvmsg_response_tcp4/1,
sc_lc_recvmsg_response_tcp6/1,
+ sc_lc_recvmsg_response_tcpL/1,
sc_lc_recvmsg_response_udp4/1,
sc_lc_recvmsg_response_udp6/1,
+ sc_lc_recvmsg_response_udpL/1,
sc_lc_acceptor_response_tcp4/1,
sc_lc_acceptor_response_tcp6/1,
+ sc_lc_acceptor_response_tcpL/1,
sc_rc_recv_response_tcp4/1,
sc_rc_recv_response_tcp6/1,
+ sc_rc_recv_response_tcpL/1,
sc_rc_recvmsg_response_tcp4/1,
sc_rc_recvmsg_response_tcp6/1,
+ sc_rc_recvmsg_response_tcpL/1,
sc_rs_recv_send_shutdown_receive_tcp4/1,
sc_rs_recv_send_shutdown_receive_tcp6/1,
+ sc_rs_recv_send_shutdown_receive_tcpL/1,
sc_rs_recvmsg_send_shutdown_receive_tcp4/1,
sc_rs_recvmsg_send_shutdown_receive_tcp6/1,
+ sc_rs_recvmsg_send_shutdown_receive_tcpL/1,
%% *** Traffic ***
traffic_send_and_recv_chunks_tcp4/1,
traffic_send_and_recv_chunks_tcp6/1,
+ traffic_send_and_recv_chunks_tcpL/1,
traffic_ping_pong_small_send_and_recv_tcp4/1,
traffic_ping_pong_small_send_and_recv_tcp6/1,
+ traffic_ping_pong_small_send_and_recv_tcpL/1,
traffic_ping_pong_medium_send_and_recv_tcp4/1,
traffic_ping_pong_medium_send_and_recv_tcp6/1,
+ traffic_ping_pong_medium_send_and_recv_tcpL/1,
traffic_ping_pong_large_send_and_recv_tcp4/1,
traffic_ping_pong_large_send_and_recv_tcp6/1,
+ traffic_ping_pong_large_send_and_recv_tcpL/1,
traffic_ping_pong_small_sendto_and_recvfrom_udp4/1,
traffic_ping_pong_small_sendto_and_recvfrom_udp6/1,
+ traffic_ping_pong_small_sendto_and_recvfrom_udpL/1,
traffic_ping_pong_medium_sendto_and_recvfrom_udp4/1,
traffic_ping_pong_medium_sendto_and_recvfrom_udp6/1,
+ traffic_ping_pong_medium_sendto_and_recvfrom_udpL/1,
traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4/1,
traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6/1,
+ traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL/1,
traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4/1,
traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6/1,
+ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL/1,
traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4/1,
traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6/1,
+ traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL/1,
traffic_ping_pong_small_sendmsg_and_recvmsg_udp4/1,
traffic_ping_pong_small_sendmsg_and_recvmsg_udp6/1,
+ traffic_ping_pong_small_sendmsg_and_recvmsg_udpL/1,
traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4/1,
traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6/1,
+ traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL/1,
%% *** Time Test ***
%% Server: transport = gen_tcp, active = false
@@ -325,24 +353,33 @@
%% Client: transport = socket(tcp)
ttest_ssockf_csockf_small_tcp4/1,
ttest_ssockf_csockf_small_tcp6/1,
+ ttest_ssockf_csockf_small_tcpL/1,
ttest_ssockf_csockf_medium_tcp4/1,
ttest_ssockf_csockf_medium_tcp6/1,
+ ttest_ssockf_csockf_medium_tcpL/1,
ttest_ssockf_csockf_large_tcp4/1,
ttest_ssockf_csockf_large_tcp6/1,
+ ttest_ssockf_csockf_large_tcpL/1,
ttest_ssockf_csocko_small_tcp4/1,
ttest_ssockf_csocko_small_tcp6/1,
+ ttest_ssockf_csocko_small_tcpL/1,
ttest_ssockf_csocko_medium_tcp4/1,
ttest_ssockf_csocko_medium_tcp6/1,
+ ttest_ssockf_csocko_medium_tcpL/1,
ttest_ssockf_csocko_large_tcp4/1,
ttest_ssockf_csocko_large_tcp6/1,
+ ttest_ssockf_csocko_large_tcpL/1,
ttest_ssockf_csockt_small_tcp4/1,
ttest_ssockf_csockt_small_tcp6/1,
+ ttest_ssockf_csockt_small_tcpL/1,
ttest_ssockf_csockt_medium_tcp4/1,
ttest_ssockf_csockt_medium_tcp6/1,
+ ttest_ssockf_csockt_medium_tcpL/1,
ttest_ssockf_csockt_large_tcp4/1,
ttest_ssockf_csockt_large_tcp6/1,
+ ttest_ssockf_csockt_large_tcpL/1,
%% Server: transport = socket(tcp), active = once
%% Client: transport = gen_tcp
@@ -371,24 +408,33 @@
%% Client: transport = socket(tcp)
ttest_ssocko_csockf_small_tcp4/1,
ttest_ssocko_csockf_small_tcp6/1,
+ ttest_ssocko_csockf_small_tcpL/1,
ttest_ssocko_csockf_medium_tcp4/1,
+ ttest_ssocko_csockf_medium_tcpL/1,
ttest_ssocko_csockf_medium_tcp6/1,
ttest_ssocko_csockf_large_tcp4/1,
ttest_ssocko_csockf_large_tcp6/1,
+ ttest_ssocko_csockf_large_tcpL/1,
ttest_ssocko_csocko_small_tcp4/1,
ttest_ssocko_csocko_small_tcp6/1,
+ ttest_ssocko_csocko_small_tcpL/1,
ttest_ssocko_csocko_medium_tcp4/1,
ttest_ssocko_csocko_medium_tcp6/1,
+ ttest_ssocko_csocko_medium_tcpL/1,
ttest_ssocko_csocko_large_tcp4/1,
ttest_ssocko_csocko_large_tcp6/1,
+ ttest_ssocko_csocko_large_tcpL/1,
ttest_ssocko_csockt_small_tcp4/1,
ttest_ssocko_csockt_small_tcp6/1,
+ ttest_ssocko_csockt_small_tcpL/1,
ttest_ssocko_csockt_medium_tcp4/1,
ttest_ssocko_csockt_medium_tcp6/1,
+ ttest_ssocko_csockt_medium_tcpL/1,
ttest_ssocko_csockt_large_tcp4/1,
ttest_ssocko_csockt_large_tcp6/1,
+ ttest_ssocko_csockt_large_tcpL/1,
%% Server: transport = socket(tcp), active = true
%% Client: transport = gen_tcp
@@ -417,24 +463,33 @@
%% Client: transport = socket(tcp)
ttest_ssockt_csockf_small_tcp4/1,
ttest_ssockt_csockf_small_tcp6/1,
+ ttest_ssockt_csockf_small_tcpL/1,
ttest_ssockt_csockf_medium_tcp4/1,
ttest_ssockt_csockf_medium_tcp6/1,
+ ttest_ssockt_csockf_medium_tcpL/1,
ttest_ssockt_csockf_large_tcp4/1,
ttest_ssockt_csockf_large_tcp6/1,
+ ttest_ssockt_csockf_large_tcpL/1,
ttest_ssockt_csocko_small_tcp4/1,
ttest_ssockt_csocko_small_tcp6/1,
+ ttest_ssockt_csocko_small_tcpL/1,
ttest_ssockt_csocko_medium_tcp4/1,
ttest_ssockt_csocko_medium_tcp6/1,
+ ttest_ssockt_csocko_medium_tcpL/1,
ttest_ssockt_csocko_large_tcp4/1,
ttest_ssockt_csocko_large_tcp6/1,
+ ttest_ssockt_csocko_large_tcpL/1,
ttest_ssockt_csockt_small_tcp4/1,
ttest_ssockt_csockt_small_tcp6/1,
+ ttest_ssockt_csockt_small_tcpL/1,
ttest_ssockt_csockt_medium_tcp4/1,
ttest_ssockt_csockt_medium_tcp6/1,
+ ttest_ssockt_csockt_medium_tcpL/1,
ttest_ssockt_csockt_large_tcp4/1,
- ttest_ssockt_csockt_large_tcp6/1
+ ttest_ssockt_csockt_large_tcp6/1,
+ ttest_ssockt_csockt_large_tcpL/1
%% Tickets
]).
@@ -508,71 +563,75 @@ use_group(Group, Env, Default) ->
groups() ->
- [{api, [], api_cases()},
- {api_basic, [], api_basic_cases()},
- {api_options, [], api_options_cases()},
- {api_op_with_timeout, [], api_op_with_timeout_cases()},
- {socket_closure, [], socket_closure_cases()},
- {sc_ctrl_proc_exit, [], sc_cp_exit_cases()},
- {sc_local_close, [], sc_lc_cases()},
- {sc_remote_close, [], sc_rc_cases()},
- {sc_remote_shutdown, [], sc_rs_cases()},
- {traffic, [], traffic_cases()},
- {ttest, [], ttest_cases()},
- {ttest_sgenf, [], ttest_sgenf_cases()},
- {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()},
- {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()},
- {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()},
- {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()},
- {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()},
- {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()},
- {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()},
- {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()},
- {ttest_sgeno, [], ttest_sgeno_cases()},
- {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()},
- {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()},
- {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()},
- {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()},
- {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()},
- {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()},
- {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()},
- {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()},
- {ttest_sgent, [], ttest_sgent_cases()},
- {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()},
- {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()},
- {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()},
- {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()},
- {ttest_sgent_csock, [], ttest_sgent_csock_cases()},
- {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()},
- {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()},
- {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()},
- {ttest_ssockf, [], ttest_ssockf_cases()},
- {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()},
- {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()},
- {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()},
- {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()},
- {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()},
- {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()},
- {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()},
- {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()},
- {ttest_ssocko, [], ttest_ssocko_cases()},
- {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()},
- {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()},
- {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()},
- {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()},
- {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()},
- {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()},
- {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()},
- {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()},
- {ttest_ssockt, [], ttest_ssockt_cases()},
- {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()},
- {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()},
- {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()},
- {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()},
- {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()},
- {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()},
- {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()},
- {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()}
+ [{api, [], api_cases()},
+ {api_basic, [], api_basic_cases()},
+ {api_options, [], api_options_cases()},
+ {api_op_with_timeout, [], api_op_with_timeout_cases()},
+ {socket_closure, [], socket_closure_cases()},
+ {sc_ctrl_proc_exit, [], sc_cp_exit_cases()},
+ {sc_local_close, [], sc_lc_cases()},
+ {sc_remote_close, [], sc_rc_cases()},
+ {sc_remote_shutdown, [], sc_rs_cases()},
+ {traffic, [], traffic_cases()},
+ {traffic_chunks, [], traffic_chunks_cases()},
+ {traffic_pp_send_recv, [], traffic_pp_send_recv_cases()},
+ {traffic_pp_sendto_recvfrom, [], traffic_pp_sendto_recvfrom_cases()},
+ {traffic_pp_sendmsg_recvmsg, [], traffic_pp_sendmsg_recvmsg_cases()},
+ {ttest, [], ttest_cases()},
+ {ttest_sgenf, [], ttest_sgenf_cases()},
+ {ttest_sgenf_cgen, [], ttest_sgenf_cgen_cases()},
+ {ttest_sgenf_cgenf, [], ttest_sgenf_cgenf_cases()},
+ {ttest_sgenf_cgeno, [], ttest_sgenf_cgeno_cases()},
+ {ttest_sgenf_cgent, [], ttest_sgenf_cgent_cases()},
+ {ttest_sgenf_csock, [], ttest_sgenf_csock_cases()},
+ {ttest_sgenf_csockf, [], ttest_sgenf_csockf_cases()},
+ {ttest_sgenf_csocko, [], ttest_sgenf_csocko_cases()},
+ {ttest_sgenf_csockt, [], ttest_sgenf_csockt_cases()},
+ {ttest_sgeno, [], ttest_sgeno_cases()},
+ {ttest_sgeno_cgen, [], ttest_sgeno_cgen_cases()},
+ {ttest_sgeno_cgenf, [], ttest_sgeno_cgenf_cases()},
+ {ttest_sgeno_cgeno, [], ttest_sgeno_cgeno_cases()},
+ {ttest_sgeno_cgent, [], ttest_sgeno_cgent_cases()},
+ {ttest_sgeno_csock, [], ttest_sgeno_csock_cases()},
+ {ttest_sgeno_csockf, [], ttest_sgeno_csockf_cases()},
+ {ttest_sgeno_csocko, [], ttest_sgeno_csocko_cases()},
+ {ttest_sgeno_csockt, [], ttest_sgeno_csockt_cases()},
+ {ttest_sgent, [], ttest_sgent_cases()},
+ {ttest_sgent_cgen, [], ttest_sgent_cgen_cases()},
+ {ttest_sgent_cgenf, [], ttest_sgent_cgenf_cases()},
+ {ttest_sgent_cgeno, [], ttest_sgent_cgeno_cases()},
+ {ttest_sgent_cgent, [], ttest_sgent_cgent_cases()},
+ {ttest_sgent_csock, [], ttest_sgent_csock_cases()},
+ {ttest_sgent_csockf, [], ttest_sgent_csockf_cases()},
+ {ttest_sgent_csocko, [], ttest_sgent_csocko_cases()},
+ {ttest_sgent_csockt, [], ttest_sgent_csockt_cases()},
+ {ttest_ssockf, [], ttest_ssockf_cases()},
+ {ttest_ssockf_cgen, [], ttest_ssockf_cgen_cases()},
+ {ttest_ssockf_cgenf, [], ttest_ssockf_cgenf_cases()},
+ {ttest_ssockf_cgeno, [], ttest_ssockf_cgeno_cases()},
+ {ttest_ssockf_cgent, [], ttest_ssockf_cgent_cases()},
+ {ttest_ssockf_csock, [], ttest_ssockf_csock_cases()},
+ {ttest_ssockf_csockf, [], ttest_ssockf_csockf_cases()},
+ {ttest_ssockf_csocko, [], ttest_ssockf_csocko_cases()},
+ {ttest_ssockf_csockt, [], ttest_ssockf_csockt_cases()},
+ {ttest_ssocko, [], ttest_ssocko_cases()},
+ {ttest_ssocko_cgen, [], ttest_ssocko_cgen_cases()},
+ {ttest_ssocko_cgenf, [], ttest_ssocko_cgenf_cases()},
+ {ttest_ssocko_cgeno, [], ttest_ssocko_cgeno_cases()},
+ {ttest_ssocko_cgent, [], ttest_ssocko_cgent_cases()},
+ {ttest_ssocko_csock, [], ttest_ssocko_csock_cases()},
+ {ttest_ssocko_csockf, [], ttest_ssocko_csockf_cases()},
+ {ttest_ssocko_csocko, [], ttest_ssocko_csocko_cases()},
+ {ttest_ssocko_csockt, [], ttest_ssocko_csockt_cases()},
+ {ttest_ssockt, [], ttest_ssockt_cases()},
+ {ttest_ssockt_cgen, [], ttest_ssockt_cgen_cases()},
+ {ttest_ssockt_cgenf, [], ttest_ssockt_cgenf_cases()},
+ {ttest_ssockt_cgeno, [], ttest_ssockt_cgeno_cases()},
+ {ttest_ssockt_cgent, [], ttest_ssockt_cgent_cases()},
+ {ttest_ssockt_csock, [], ttest_ssockt_csock_cases()},
+ {ttest_ssockt_csockf, [], ttest_ssockt_csockf_cases()},
+ {ttest_ssockt_csocko, [], ttest_ssockt_csocko_cases()},
+ {ttest_ssockt_csockt, [], ttest_ssockt_csockt_cases()}
%% {tickets, [], ticket_cases()}
].
@@ -588,10 +647,16 @@ api_basic_cases() ->
[
api_b_open_and_close_udp4,
api_b_open_and_close_tcp4,
+ api_b_open_and_close_udpL,
+ api_b_open_and_close_tcpL,
api_b_sendto_and_recvfrom_udp4,
+ api_b_sendto_and_recvfrom_udpL,
api_b_sendmsg_and_recvmsg_udp4,
+ api_b_sendmsg_and_recvmsg_udpL,
api_b_send_and_recv_tcp4,
- api_b_sendmsg_and_recvmsg_tcp4
+ api_b_send_and_recv_tcpL,
+ api_b_sendmsg_and_recvmsg_tcp4,
+ api_b_sendmsg_and_recvmsg_tcpL
].
api_options_cases() ->
@@ -638,13 +703,15 @@ socket_closure_cases() ->
].
%% These cases are all about socket cleanup after the controlling process
-%% exits *without* calling socket:close/1.
+%% exits *without* explicitly calling socket:close/1.
sc_cp_exit_cases() ->
[
sc_cpe_socket_cleanup_tcp4,
sc_cpe_socket_cleanup_tcp6,
+ sc_cpe_socket_cleanup_tcpL,
sc_cpe_socket_cleanup_udp4,
- sc_cpe_socket_cleanup_udp6
+ sc_cpe_socket_cleanup_udp6,
+ sc_cpe_socket_cleanup_udpL
].
%% These cases tests what happens when the socket is closed locally.
@@ -652,17 +719,22 @@ sc_lc_cases() ->
[
sc_lc_recv_response_tcp4,
sc_lc_recv_response_tcp6,
+ sc_lc_recv_response_tcpL,
sc_lc_recvfrom_response_udp4,
sc_lc_recvfrom_response_udp6,
+ sc_lc_recvfrom_response_udpL,
sc_lc_recvmsg_response_tcp4,
sc_lc_recvmsg_response_tcp6,
+ sc_lc_recvmsg_response_tcpL,
sc_lc_recvmsg_response_udp4,
sc_lc_recvmsg_response_udp6,
+ sc_lc_recvmsg_response_udpL,
sc_lc_acceptor_response_tcp4,
- sc_lc_acceptor_response_tcp6
+ sc_lc_acceptor_response_tcp6,
+ sc_lc_acceptor_response_tcpL
].
%% These cases tests what happens when the socket is closed remotely.
@@ -670,9 +742,11 @@ sc_rc_cases() ->
[
sc_rc_recv_response_tcp4,
sc_rc_recv_response_tcp6,
+ sc_rc_recv_response_tcpL,
sc_rc_recvmsg_response_tcp4,
- sc_rc_recvmsg_response_tcp6
+ sc_rc_recvmsg_response_tcp6,
+ sc_rc_recvmsg_response_tcpL
].
%% These cases tests what happens when the socket is shutdown/closed remotely
@@ -681,43 +755,72 @@ sc_rs_cases() ->
[
sc_rs_recv_send_shutdown_receive_tcp4,
sc_rs_recv_send_shutdown_receive_tcp6,
+ sc_rs_recv_send_shutdown_receive_tcpL,
sc_rs_recvmsg_send_shutdown_receive_tcp4,
- sc_rs_recvmsg_send_shutdown_receive_tcp6
+ sc_rs_recvmsg_send_shutdown_receive_tcp6,
+ sc_rs_recvmsg_send_shutdown_receive_tcpL
].
traffic_cases() ->
[
+ {group, traffic_chunks},
+ {group, traffic_pp_send_recv},
+ {group, traffic_pp_sendto_recvfrom},
+ {group, traffic_pp_sendmsg_recvmsg}
+ ].
+
+traffic_chunks_cases() ->
+ [
traffic_send_and_recv_chunks_tcp4,
traffic_send_and_recv_chunks_tcp6,
+ traffic_send_and_recv_chunks_tcpL
+ ].
+traffic_pp_send_recv_cases() ->
+ [
traffic_ping_pong_small_send_and_recv_tcp4,
traffic_ping_pong_small_send_and_recv_tcp6,
+ traffic_ping_pong_small_send_and_recv_tcpL,
traffic_ping_pong_medium_send_and_recv_tcp4,
traffic_ping_pong_medium_send_and_recv_tcp6,
+ traffic_ping_pong_medium_send_and_recv_tcpL,
traffic_ping_pong_large_send_and_recv_tcp4,
traffic_ping_pong_large_send_and_recv_tcp6,
+ traffic_ping_pong_large_send_and_recv_tcpL
+ ].
+traffic_pp_sendto_recvfrom_cases() ->
+ [
traffic_ping_pong_small_sendto_and_recvfrom_udp4,
traffic_ping_pong_small_sendto_and_recvfrom_udp6,
+ traffic_ping_pong_small_sendto_and_recvfrom_udpL,
traffic_ping_pong_medium_sendto_and_recvfrom_udp4,
traffic_ping_pong_medium_sendto_and_recvfrom_udp6,
+ traffic_ping_pong_medium_sendto_and_recvfrom_udpL
+ ].
+traffic_pp_sendmsg_recvmsg_cases() ->
+ [
traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4,
traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6,
+ traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL,
traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4,
traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6,
+ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL,
traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4,
traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6,
+ traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL,
traffic_ping_pong_small_sendmsg_and_recvmsg_udp4,
traffic_ping_pong_small_sendmsg_and_recvmsg_udp6,
+ traffic_ping_pong_small_sendmsg_and_recvmsg_udpL,
traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4,
- traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6
+ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6,
+ traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL
].
-
-
+
ttest_cases() ->
[
%% Server: transport = gen_tcp, active = false
@@ -1123,12 +1226,15 @@ ttest_ssockf_csockf_cases() ->
[
ttest_ssockf_csockf_small_tcp4,
ttest_ssockf_csockf_small_tcp6,
+ ttest_ssockf_csockf_small_tcpL,
ttest_ssockf_csockf_medium_tcp4,
ttest_ssockf_csockf_medium_tcp6,
+ ttest_ssockf_csockf_medium_tcpL,
ttest_ssockf_csockf_large_tcp4,
- ttest_ssockf_csockf_large_tcp6
+ ttest_ssockf_csockf_large_tcp6,
+ ttest_ssockf_csockf_large_tcpL
].
%% Server: transport = socket(tcp), active = false
@@ -1137,12 +1243,15 @@ ttest_ssockf_csocko_cases() ->
[
ttest_ssockf_csocko_small_tcp4,
ttest_ssockf_csocko_small_tcp6,
+ ttest_ssockf_csocko_small_tcpL,
ttest_ssockf_csocko_medium_tcp4,
ttest_ssockf_csocko_medium_tcp6,
+ ttest_ssockf_csocko_medium_tcpL,
ttest_ssockf_csocko_large_tcp4,
- ttest_ssockf_csocko_large_tcp6
+ ttest_ssockf_csocko_large_tcp6,
+ ttest_ssockf_csocko_large_tcpL
].
%% Server: transport = socket(tcp), active = false
@@ -1151,12 +1260,15 @@ ttest_ssockf_csockt_cases() ->
[
ttest_ssockf_csockt_small_tcp4,
ttest_ssockf_csockt_small_tcp6,
+ ttest_ssockf_csockt_small_tcpL,
ttest_ssockf_csockt_medium_tcp4,
ttest_ssockf_csockt_medium_tcp6,
+ ttest_ssockf_csockt_medium_tcpL,
ttest_ssockf_csockt_large_tcp4,
- ttest_ssockf_csockt_large_tcp6
+ ttest_ssockf_csockt_large_tcp6,
+ ttest_ssockf_csockt_large_tcpL
].
%% Server: transport = socket(tcp), active = once
@@ -1232,12 +1344,15 @@ ttest_ssocko_csockf_cases() ->
[
ttest_ssocko_csockf_small_tcp4,
ttest_ssocko_csockf_small_tcp6,
+ ttest_ssocko_csockf_small_tcpL,
ttest_ssocko_csockf_medium_tcp4,
ttest_ssocko_csockf_medium_tcp6,
+ ttest_ssocko_csockf_medium_tcpL,
ttest_ssocko_csockf_large_tcp4,
- ttest_ssocko_csockf_large_tcp6
+ ttest_ssocko_csockf_large_tcp6,
+ ttest_ssocko_csockf_large_tcpL
].
%% Server: transport = socket(tcp), active = once
@@ -1246,12 +1361,15 @@ ttest_ssocko_csocko_cases() ->
[
ttest_ssocko_csocko_small_tcp4,
ttest_ssocko_csocko_small_tcp6,
+ ttest_ssocko_csocko_small_tcpL,
ttest_ssocko_csocko_medium_tcp4,
ttest_ssocko_csocko_medium_tcp6,
+ ttest_ssocko_csocko_medium_tcpL,
ttest_ssocko_csocko_large_tcp4,
- ttest_ssocko_csocko_large_tcp6
+ ttest_ssocko_csocko_large_tcp6,
+ ttest_ssocko_csocko_large_tcpL
].
%% Server: transport = socket(tcp), active = once
@@ -1260,12 +1378,15 @@ ttest_ssocko_csockt_cases() ->
[
ttest_ssocko_csockt_small_tcp4,
ttest_ssocko_csockt_small_tcp6,
+ ttest_ssocko_csockt_small_tcpL,
ttest_ssocko_csockt_medium_tcp4,
ttest_ssocko_csockt_medium_tcp6,
+ ttest_ssocko_csockt_medium_tcpL,
ttest_ssocko_csockt_large_tcp4,
- ttest_ssocko_csockt_large_tcp6
+ ttest_ssocko_csockt_large_tcp6,
+ ttest_ssocko_csockt_large_tcpL
].
%% Server: transport = socket(tcp), active = true
@@ -1341,12 +1462,15 @@ ttest_ssockt_csockf_cases() ->
[
ttest_ssockt_csockf_small_tcp4,
ttest_ssockt_csockf_small_tcp6,
+ ttest_ssockt_csockf_small_tcpL,
ttest_ssockt_csockf_medium_tcp4,
ttest_ssockt_csockf_medium_tcp6,
+ ttest_ssockt_csockf_medium_tcpL,
ttest_ssockt_csockf_large_tcp4,
- ttest_ssockt_csockf_large_tcp6
+ ttest_ssockt_csockf_large_tcp6,
+ ttest_ssockt_csockf_large_tcpL
].
%% Server: transport = socket(tcp), active = true
@@ -1355,12 +1479,15 @@ ttest_ssockt_csocko_cases() ->
[
ttest_ssockt_csocko_small_tcp4,
ttest_ssockt_csocko_small_tcp6,
+ ttest_ssockt_csocko_small_tcpL,
ttest_ssockt_csocko_medium_tcp4,
ttest_ssockt_csocko_medium_tcp6,
+ ttest_ssockt_csocko_medium_tcpL,
ttest_ssockt_csocko_large_tcp4,
- ttest_ssockt_csocko_large_tcp6
+ ttest_ssockt_csocko_large_tcp6,
+ ttest_ssockt_csocko_large_tcpL
].
%% Server: transport = socket(tcp), active = true
@@ -1369,12 +1496,15 @@ ttest_ssockt_csockt_cases() ->
[
ttest_ssockt_csockt_small_tcp4,
ttest_ssockt_csockt_small_tcp6,
+ ttest_ssockt_csockt_small_tcpL,
ttest_ssockt_csockt_medium_tcp4,
ttest_ssockt_csockt_medium_tcp6,
+ ttest_ssockt_csockt_medium_tcpL,
ttest_ssockt_csockt_large_tcp4,
- ttest_ssockt_csockt_large_tcp6
+ ttest_ssockt_csockt_large_tcp6,
+ ttest_ssockt_csockt_large_tcpL
].
%% ticket_cases() ->
@@ -1510,6 +1640,46 @@ api_b_open_and_close_tcp4(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Basically open (create) and close an Unix Domain dgram (UDP) socket.
+%% With some extra checks...
+api_b_open_and_close_udpL(suite) ->
+ [];
+api_b_open_and_close_udpL(doc) ->
+ [];
+api_b_open_and_close_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_b_open_and_close_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ type => dgram,
+ protocol => default},
+ ok = api_b_open_and_close(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically open (create) and close an Unix Domain stream (TCP) socket.
+%% With some extra checks...
+api_b_open_and_close_tcpL(suite) ->
+ [];
+api_b_open_and_close_tcpL(doc) ->
+ [];
+api_b_open_and_close_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_b_open_and_close_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ type => stream,
+ protocol => default},
+ ok = api_b_open_and_close(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
api_b_open_and_close(InitState) ->
Seq =
[
@@ -1633,6 +1803,37 @@ api_b_sendto_and_recvfrom_udp4(_Config) when is_list(_Config) ->
socket:recvfrom(Sock)
end,
InitState = #{domain => inet,
+ proto => udp,
+ send => Send,
+ recv => Recv},
+ ok = api_b_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically send and receive on an IPv4 UDP (dgram) socket using
+%% sendto and recvfrom.
+api_b_sendto_and_recvfrom_udpL(suite) ->
+ [];
+api_b_sendto_and_recvfrom_udpL(doc) ->
+ [];
+api_b_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_b_sendto_and_recvfrom_udpL,
+ fun() ->
+ has_support_unix_domain_socket(),
+ unix_domain_socket_host_cond()
+ end,
+ fun() ->
+ Send = fun(Sock, Data, Dest) ->
+ socket:sendto(Sock, Data, Dest)
+ end,
+ Recv = fun(Sock) ->
+ socket:recvfrom(Sock)
+ end,
+ InitState = #{domain => local,
+ proto => default,
send => Send,
recv => Recv},
ok = api_b_send_and_recv_udp(InitState)
@@ -1665,17 +1866,66 @@ api_b_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) ->
end,
Recv = fun(Sock) ->
%% We have some issues on old darwing...
- socket:setopt(Sock, otp, debug, true),
+ %% socket:setopt(Sock, otp, debug, true),
case socket:recvmsg(Sock) of
{ok, #{addr := Source,
iov := [Data]}} ->
- socket:setopt(Sock, otp, debug, false),
+ %% socket:setopt(Sock, otp, debug, false),
{ok, {Source, Data}};
{error, _} = ERROR ->
ERROR
end
end,
InitState = #{domain => inet,
+ proto => udp,
+ send => Send,
+ recv => Recv},
+ ok = api_b_send_and_recv_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically send and receive on an IPv4 UDP (dgram) socket
+%% using sendmsg and recvmsg.
+api_b_sendmsg_and_recvmsg_udpL(suite) ->
+ [];
+api_b_sendmsg_and_recvmsg_udpL(doc) ->
+ [];
+api_b_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(api_b_sendmsg_and_recvmsg_udpL,
+ fun() ->
+ has_support_unix_domain_socket(),
+ unix_domain_socket_host_cond()
+ end,
+ fun() ->
+ Send = fun(Sock, Data, Dest) ->
+ %% We need tests for this,
+ %% but this is not the place it.
+ %% CMsgHdr = #{level => ip,
+ %% type => tos,
+ %% data => reliability},
+ %% CMsgHdrs = [CMsgHdr],
+ MsgHdr = #{addr => Dest,
+ %% ctrl => CMsgHdrs,
+ iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr)
+ end,
+ Recv = fun(Sock) ->
+ %% We have some issues on old darwing...
+ %% socket:setopt(Sock, otp, debug, true),
+ case socket:recvmsg(Sock) of
+ {ok, #{addr := Source,
+ iov := [Data]}} ->
+ %% socket:setopt(Sock, otp, debug, false),
+ {ok, {Source, Data}};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ InitState = #{domain => local,
+ proto => default,
send => Send,
recv => Recv},
ok = api_b_send_and_recv_udp(InitState)
@@ -1688,42 +1938,64 @@ api_b_send_and_recv_udp(InitState) ->
Seq =
[
#{desc => "local address",
- cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
- {ok, State#{lsa => LSA}}
+ cmd => fun(#{domain := local = Domain} = State) ->
+ LSASrc = which_local_socket_addr(Domain),
+ LSADst = which_local_socket_addr(Domain),
+ {ok, State#{lsa_src => LSASrc,
+ lsa_dst => LSADst}};
+ (#{domain := Domain} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ {ok, State#{lsa_src => LSA,
+ lsa_dst => LSA}}
end},
+
#{desc => "open src socket",
- cmd => fun(#{domain := Domain} = State) ->
- Sock = sock_open(Domain, dgram, udp),
- SASrc = sock_sockname(Sock),
- {ok, State#{sock_src => Sock, sa_src => SASrc}}
+ cmd => fun(#{domain := Domain,
+ proto := Proto} = State) ->
+ Sock = sock_open(Domain, dgram, Proto),
+ {ok, State#{sock_src => Sock}}
end},
#{desc => "bind src",
- cmd => fun(#{sock_src := Sock, lsa := LSA}) ->
- sock_bind(Sock, LSA),
- ok
+ cmd => fun(#{sock_src := Sock, lsa_src := LSA}) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ?SEV_IPRINT("src bound"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("src bind failed: ~p", [Reason]),
+ ERROR
+ end
end},
#{desc => "sockname src socket",
cmd => fun(#{sock_src := Sock} = State) ->
SASrc = sock_sockname(Sock),
- %% ei("src sockaddr: ~p", [SASrc]),
+ ?SEV_IPRINT("src sockaddr: "
+ "~n ~p", [SASrc]),
{ok, State#{sa_src => SASrc}}
end},
+
#{desc => "open dst socket",
- cmd => fun(#{domain := Domain} = State) ->
- Sock = sock_open(Domain, dgram, udp),
+ cmd => fun(#{domain := Domain,
+ proto := Proto} = State) ->
+ Sock = sock_open(Domain, dgram, Proto),
{ok, State#{sock_dst => Sock}}
end},
#{desc => "bind dst",
- cmd => fun(#{sock_dst := Sock, lsa := LSA}) ->
- sock_bind(Sock, LSA),
- ok
+ cmd => fun(#{sock_dst := Sock, lsa_dst := LSA}) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ?SEV_IPRINT("src bound"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("src bind failed: ~p", [Reason]),
+ ERROR
+ end
end},
#{desc => "sockname dst socket",
cmd => fun(#{sock_dst := Sock} = State) ->
SADst = sock_sockname(Sock),
- %% ei("dst sockaddr: ~p", [SADst]),
+ ?SEV_IPRINT("dst sockaddr: "
+ "~n ~p", [SADst]),
{ok, State#{sa_dst => SADst}}
end},
#{desc => "send req (to dst)",
@@ -1761,12 +2033,32 @@ api_b_send_and_recv_udp(InitState) ->
end
end},
#{desc => "close src socket",
- cmd => fun(#{sock_src := Sock}) ->
- ok = socket:close(Sock)
+ cmd => fun(#{domain := local,
+ sock_src := Sock,
+ lsa_src := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() -> maps:remove(lsa_src, State) end,
+ fun() -> State end),
+ {ok, maps:remove(sock_src, State1)};
+ (#{sock_src := Sock} = State) ->
+ ok = socket:close(Sock),
+ {ok, maps:remove(sock_src, State)}
end},
#{desc => "close dst socket",
- cmd => fun(#{sock_dst := Sock}) ->
- ok = socket:close(Sock)
+ cmd => fun(#{domain := local,
+ sock_dst := Sock,
+ lsa_dst := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() -> maps:remove(lsa_dst, State) end,
+ fun() -> State end),
+ {ok, maps:remove(sock_dst, State1)};
+ (#{sock_dst := Sock} = State) ->
+ ok = socket:close(Sock),
+ {ok, maps:remove(sock_dst, State)}
end},
%% *** We are done ***
@@ -1796,6 +2088,34 @@ api_b_send_and_recv_tcp4(_Config) when is_list(_Config) ->
socket:recv(Sock)
end,
InitState = #{domain => inet,
+ proto => tcp,
+ send => Send,
+ recv => Recv},
+ ok = api_b_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically send and receive using the "common" functions (send and recv)
+%% on an Unix Domain (stream) socket (TCP).
+api_b_send_and_recv_tcpL(suite) ->
+ [];
+api_b_send_and_recv_tcpL(doc) ->
+ [];
+api_b_send_and_recv_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_b_send_and_recv_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Send = fun(Sock, Data) ->
+ socket:send(Sock, Data)
+ end,
+ Recv = fun(Sock) ->
+ socket:recv(Sock)
+ end,
+ InitState = #{domain => local,
+ proto => default,
send => Send,
recv => Recv},
ok = api_b_send_and_recv_tcp(InitState)
@@ -1828,6 +2148,56 @@ api_b_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) ->
end
end,
InitState = #{domain => inet,
+ proto => tcp,
+ send => Send,
+ recv => Recv},
+ ok = api_b_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Basically send and receive using the msg functions (sendmsg and recvmsg)
+%% on an Unix Domain (stream) socket (TCP).
+api_b_sendmsg_and_recvmsg_tcpL(suite) ->
+ [];
+api_b_sendmsg_and_recvmsg_tcpL(doc) ->
+ [];
+api_b_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(api_b_sendmsg_and_recvmsg_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Send = fun(Sock, Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr)
+ end,
+ Recv = fun(Sock) ->
+ case socket:recvmsg(Sock) of
+ %% On some platforms, the address
+ %% is *not* provided (e.g. FreeBSD)
+ {ok, #{addr := undefined,
+ iov := [Data]}} ->
+ {ok, Data};
+ %% On some platforms, the address
+ %% *is* provided (e.g. linux)
+ {ok, #{addr := #{family := local},
+ iov := [Data]}} ->
+ socket:setopt(Sock,
+ otp,
+ debug,
+ false),
+ {ok, Data};
+ {error, _} = ERROR ->
+ socket:setopt(Sock,
+ otp,
+ debug,
+ false),
+ ERROR
+ end
+ end,
+ InitState = #{domain => local,
+ proto => default,
send => Send,
recv => Recv},
ok = api_b_send_and_recv_tcp(InitState)
@@ -1855,13 +2225,13 @@ api_b_send_and_recv_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{lsa => LSA}}
end},
#{desc => "create listen socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, stream, tcp) of
+ cmd => fun(#{domain := Domain,
+ proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{lsock => Sock}};
{error, _} = ERROR ->
@@ -1869,9 +2239,19 @@ api_b_send_and_recv_tcp(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{lsock := LSock, lsa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ lsa := LSA} = _State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock, lsa := LSA} = State) ->
case socket:bind(LSock, LSA) of
{ok, Port} ->
+ ?SEV_IPRINT("bound to port: ~w", [Port]),
{ok, State#{lport => Port}};
{error, _} = ERROR ->
ERROR
@@ -1882,7 +2262,12 @@ api_b_send_and_recv_tcp(InitState) ->
socket:listen(LSock)
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, lport := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester, lsa := #{path := Path}}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Path),
+ ok;
+ (#{tester := Tester, lport := Port}) ->
+ %% This is actually not used for unix domain socket
?SEV_ANNOUNCE_READY(Tester, init, Port),
ok
end},
@@ -1946,12 +2331,29 @@ api_b_send_and_recv_tcp(InitState) ->
end
end},
#{desc => "close connection socket",
- cmd => fun(#{csock := Sock}) ->
- socket:close(Sock)
+ cmd => fun(#{csock := Sock} = State) ->
+ ok = socket:close(Sock),
+ {ok, maps:remove(csock, State)}
end},
#{desc => "close listen socket",
- cmd => fun(#{lsock := Sock}) ->
- socket:close(Sock)
+ cmd => fun(#{domain := local,
+ lsock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(lsock, State1)};
+ (#{lsock := LSock} = State) ->
+ case socket:close(LSock) of
+ ok ->
+ {ok, maps:remove(lsock, State)};
+ {error, _} = ERROR ->
+ ERROR
+ end
end},
%% *** We are done ***
@@ -1962,7 +2364,10 @@ api_b_send_and_recv_tcp(InitState) ->
[
%% *** Wait for start order ***
#{desc => "await start (from tester)",
- cmd => fun(State) ->
+ cmd => fun(#{domain := local} = State) ->
+ {Tester, Path} = ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester, server_path => Path}};
+ (State) ->
{Tester, Port} = ?SEV_AWAIT_START(),
{ok, State#{tester => Tester, server_port => Port}}
end},
@@ -1974,16 +2379,20 @@ api_b_send_and_recv_tcp(InitState) ->
%% *** The init part ***
#{desc => "which server (local) address",
- cmd => fun(#{domain := Domain, server_port := Port} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
- SSA = LSA#{port => Port},
+ cmd => fun(#{domain := local = Domain,
+ server_path := Path} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ SSA = #{family => Domain, path => Path},
+ {ok, State#{local_sa => LSA, server_sa => SSA}};
+ (#{domain := Domain, server_port := Port} = State) ->
+ LSA = which_local_socket_addr(Domain),
+ SSA = LSA#{port => Port},
{ok, State#{local_sa => LSA, server_sa => SSA}}
end},
#{desc => "create socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, stream, tcp) of
+ cmd => fun(#{domain := Domain,
+ proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{sock => Sock}};
{error, _} = ERROR ->
@@ -2054,8 +2463,20 @@ api_b_send_and_recv_tcp(InitState) ->
end
end},
#{desc => "close socket",
- cmd => fun(#{sock := Sock}) ->
- socket:close(Sock)
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(sock, State1)};
+ (#{sock := Sock} = State) ->
+ ok = socket:close(Sock),
+ {ok, maps:remove(sock, State)}
end},
%% *** We are done ***
@@ -2530,8 +2951,7 @@ api_opt_simple_otp_rcvbuf_option() ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
@@ -2776,8 +3196,7 @@ api_opt_simple_otp_rcvbuf_option() ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create socket",
@@ -3434,11 +3853,11 @@ api_to_connect_tcp4(suite) ->
api_to_connect_tcp4(doc) ->
[];
api_to_connect_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
Cond = fun() -> api_to_connect_cond() end,
tc_try(api_to_connect_tcp4,
Cond,
fun() ->
- ?TT(?SECS(10)),
InitState = #{domain => inet,
backlog => 1,
timeout => 5000,
@@ -3454,7 +3873,9 @@ api_to_connect_cond() ->
%% So, just to simplify, we require atleast 4.15
api_to_connect_cond({unix, linux}, {Maj, Min, _Rev}) ->
if
- ((Maj >= 4) andalso (Min >= 15)) ->
+ (Maj > 4) ->
+ ok;
+ ((Maj =:= 4) andalso (Min >= 15)) ->
ok;
true ->
skip("TC does not work")
@@ -3491,10 +3912,10 @@ api_to_connect_tcp6(suite) ->
api_to_connect_tcp6(doc) ->
[];
api_to_connect_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_connect_tcp6,
fun() -> has_support_ipv6(), api_to_connect_cond() end,
fun() ->
- ?TT(?SECS(10)),
InitState = #{domain => inet6,
backlog => 1,
timeout => 5000,
@@ -3531,8 +3952,7 @@ api_to_connect_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
@@ -3603,8 +4023,7 @@ api_to_connect_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create node",
@@ -3754,8 +4173,7 @@ api_to_connect_tcp(InitState) ->
end},
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "order server start",
@@ -3906,9 +4324,7 @@ api_toc_tcp_client_await_terminate(Parent) ->
end.
api_to_connect_tcp_await_timeout(To, ServerSA, Domain, ConLimit) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
NewSock = fun() ->
S = case socket:open(Domain, stream, tcp) of
{ok, Sock} ->
@@ -3986,9 +4402,9 @@ api_to_accept_tcp4(suite) ->
api_to_accept_tcp4(doc) ->
[];
api_to_accept_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_accept_tcp4,
fun() ->
- ?TT(?SECS(10)),
InitState = #{domain => inet, timeout => 5000},
ok = api_to_accept_tcp(InitState)
end).
@@ -4003,10 +4419,10 @@ api_to_accept_tcp6(suite) ->
api_to_accept_tcp6(doc) ->
[];
api_to_accept_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_accept_tcp4,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
InitState = #{domain => inet6, timeout => 5000},
ok = api_to_accept_tcp(InitState)
end).
@@ -4020,8 +4436,7 @@ api_to_accept_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{lsa => LSA}}
end},
#{desc => "create (listen) socket",
@@ -4145,8 +4560,7 @@ api_to_maccept_tcp(InitState) ->
end},
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{lsa => LSA}}
end},
#{desc => "create (listen) socket",
@@ -4602,9 +5016,9 @@ api_to_recv_tcp4(suite) ->
api_to_recv_tcp4(doc) ->
[];
api_to_recv_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recv_tcp4,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recv(Sock, 0, To) end,
InitState = #{domain => inet,
recv => Recv,
@@ -4622,12 +5036,12 @@ api_to_recv_tcp6(suite) ->
api_to_recv_tcp6(doc) ->
[];
api_to_recv_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recv_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
case socket:supports(ipv6) of
true ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) ->
socket:recv(Sock, 0, To)
end,
@@ -4663,8 +5077,7 @@ api_to_receive_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
@@ -4782,10 +5195,8 @@ api_to_receive_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain, server_port := Port} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
- SSA = LSA#{port => Port},
+ LSA = which_local_socket_addr(Domain),
+ SSA = LSA#{port => Port},
{ok, State#{local_sa => LSA, server_sa => SSA}}
end},
#{desc => "create socket",
@@ -4961,9 +5372,9 @@ api_to_recvfrom_udp4(suite) ->
api_to_recvfrom_udp4(doc) ->
[];
api_to_recvfrom_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recvfrom_udp4,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvfrom(Sock, 0, To) end,
InitState = #{domain => inet,
recv => Recv,
@@ -4981,10 +5392,10 @@ api_to_recvfrom_udp6(suite) ->
api_to_recvfrom_udp6(doc) ->
[];
api_to_recvfrom_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recvfrom_udp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvfrom(Sock, 0, To) end,
InitState = #{domain => inet6,
recv => Recv,
@@ -5001,8 +5412,7 @@ api_to_receive_udp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{lsa => LSA}}
end},
#{desc => "create socket",
@@ -5078,9 +5488,9 @@ api_to_recvmsg_udp4(suite) ->
api_to_recvmsg_udp4(doc) ->
[];
api_to_recvmsg_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recvmsg_udp4,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet,
recv => Recv,
@@ -5098,10 +5508,10 @@ api_to_recvmsg_udp6(suite) ->
api_to_recvmsg_udp6(doc) ->
[];
api_to_recvmsg_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recvmsg_udp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet6,
recv => Recv,
@@ -5119,9 +5529,9 @@ api_to_recvmsg_tcp4(suite) ->
api_to_recvmsg_tcp4(doc) ->
[];
api_to_recvmsg_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recvmsg_tcp4,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet,
recv => Recv,
@@ -5139,10 +5549,10 @@ api_to_recvmsg_tcp6(suite) ->
api_to_recvmsg_tcp6(doc) ->
[];
api_to_recvmsg_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(api_to_recvmsg_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
InitState = #{domain => inet6,
recv => Recv,
@@ -5170,9 +5580,9 @@ sc_cpe_socket_cleanup_tcp4(suite) ->
sc_cpe_socket_cleanup_tcp4(doc) ->
[];
sc_cpe_socket_cleanup_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
tc_try(sc_cpe_socket_cleanup_tcp4,
fun() ->
- ?TT(?SECS(5)),
InitState = #{domain => inet,
type => stream,
protocol => tcp},
@@ -5190,10 +5600,10 @@ sc_cpe_socket_cleanup_tcp6(suite) ->
sc_cpe_socket_cleanup_tcp6(doc) ->
[];
sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
tc_try(sc_cpe_socket_cleanup_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(5)),
InitState = #{domain => inet6,
type => stream,
protocol => tcp},
@@ -5204,6 +5614,27 @@ sc_cpe_socket_cleanup_tcp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test that the sockets are cleaned up
%% ("removed") when the controlling process terminates (without explicitly
+%% calling the close function). For a Unix Domain (stream) socket (TCP).
+
+sc_cpe_socket_cleanup_tcpL(suite) ->
+ [];
+sc_cpe_socket_cleanup_tcpL(doc) ->
+ [];
+sc_cpe_socket_cleanup_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(sc_cpe_socket_cleanup_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ type => stream,
+ protocol => default},
+ ok = sc_cpe_socket_cleanup(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sockets are cleaned up
+%% ("removed") when the controlling process terminates (without explicitly
%% calling the close function). For a IPv4 UDP (dgram) socket.
sc_cpe_socket_cleanup_udp4(suite) ->
@@ -5211,9 +5642,9 @@ sc_cpe_socket_cleanup_udp4(suite) ->
sc_cpe_socket_cleanup_udp4(doc) ->
[];
sc_cpe_socket_cleanup_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
tc_try(sc_cpe_socket_cleanup_udp4,
fun() ->
- ?TT(?SECS(5)),
InitState = #{domain => inet,
type => dgram,
protocol => udp},
@@ -5232,10 +5663,10 @@ sc_cpe_socket_cleanup_udp6(suite) ->
sc_cpe_socket_cleanup_udp6(doc) ->
[];
sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
tc_try(sc_cpe_socket_cleanup_udp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(5)),
InitState = #{domain => inet6,
type => dgram,
protocol => udp},
@@ -5244,6 +5675,28 @@ sc_cpe_socket_cleanup_udp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sockets are cleaned up
+%% ("removed") when the controlling process terminates (without explicitly
+%% calling the close function). For a Unix Domain (dgram) socket (UDP).
+
+sc_cpe_socket_cleanup_udpL(suite) ->
+ [];
+sc_cpe_socket_cleanup_udpL(doc) ->
+ [];
+sc_cpe_socket_cleanup_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(5)),
+ tc_try(sc_cpe_socket_cleanup_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ type => dgram,
+ protocol => default},
+ ok = sc_cpe_socket_cleanup(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sc_cpe_socket_cleanup(InitState) ->
OwnerSeq =
@@ -5386,12 +5839,11 @@ sc_lc_recv_response_tcp4(suite) ->
sc_lc_recv_response_tcp4(doc) ->
[];
sc_lc_recv_response_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(sc_lc_recv_response_tcp4,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recv(Sock) end,
InitState = #{domain => inet,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_lc_receive_response_tcp(InitState)
@@ -5408,13 +5860,12 @@ sc_lc_recv_response_tcp6(suite) ->
sc_lc_recv_response_tcp6(doc) ->
[];
sc_lc_recv_response_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(sc_lc_recv_response_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recv(Sock) end,
InitState = #{domain => inet6,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_lc_receive_response_tcp(InitState)
@@ -5422,6 +5873,28 @@ sc_lc_recv_response_tcp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recv function.
+%% Socket is Unix Domain (stream) socket.
+
+sc_lc_recv_response_tcpL(suite) ->
+ [];
+sc_lc_recv_response_tcpL(doc) ->
+ [];
+sc_lc_recv_response_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(sc_lc_recv_response_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Recv = fun(Sock) -> socket:recv(Sock) end,
+ InitState = #{domain => local,
+ protocol => default,
+ recv => Recv},
+ ok = sc_lc_receive_response_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sc_lc_receive_response_tcp(InitState) ->
%% This (acceptor) is the server that accepts connections.
@@ -5444,15 +5917,13 @@ sc_lc_receive_response_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
- {ok, State#{local_sa => LSA}}
+ LSA = which_local_socket_addr(Domain),
+ {ok, State#{lsa => LSA}}
end},
#{desc => "create (listen) socket",
cmd => fun(#{domain := Domain,
- type := Type,
protocol := Proto} = State) ->
- case socket:open(Domain, Type, Proto) of
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{lsock => Sock}};
{error, _} = ERROR ->
@@ -5460,9 +5931,22 @@ sc_lc_receive_response_tcp(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{lsock := LSock, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ lsa := LSA} = _State) ->
+ ?SEV_IPRINT("bind to LSA: "
+ "~n ~p", [LSA]),
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock,
+ lsa := LSA} = State) ->
case socket:bind(LSock, LSA) of
{ok, Port} ->
+ ?SEV_IPRINT("bound to port: ~w", [Port]),
{ok, State#{lport => Port}};
{error, _} = ERROR ->
ERROR
@@ -5473,7 +5957,12 @@ sc_lc_receive_response_tcp(InitState) ->
socket:listen(LSock)
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, lport := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester,
+ lsa := #{path := Path}}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Path),
+ ok;
+ (#{tester := Tester, lport := Port}) ->
?SEV_ANNOUNCE_READY(Tester, init, Port),
ok
end},
@@ -5494,7 +5983,8 @@ sc_lc_receive_response_tcp(InitState) ->
cmd => fun(#{lsock := LSock} = State) ->
case socket:accept(LSock) of
{ok, Sock} ->
- ?SEV_IPRINT("connection accepted"),
+ ?SEV_IPRINT("connection accepted: "
+ "~n ~p", [socket:sockname(Sock)]),
{ok, State#{csock => Sock}};
{error, _} = ERROR ->
ERROR
@@ -5525,9 +6015,8 @@ sc_lc_receive_response_tcp(InitState) ->
?SEV_AWAIT_CONTINUE(Tester, tester, close),
ok
end},
- #{desc => "close the connection socket",
+ #{desc => "close connection socket",
cmd => fun(#{csock := Sock} = State) ->
- %% ok = socket:setopt(Sock, otp, debug, true),
case socket:close(Sock) of
ok ->
{ok, maps:remove(csock, State)};
@@ -5551,8 +6040,19 @@ sc_lc_receive_response_tcp(InitState) ->
ERROR
end
end},
- #{desc => "close socket",
- cmd => fun(#{lsock := Sock} = State) ->
+ #{desc => "close listen socket",
+ cmd => fun(#{domain := local,
+ lsock := Sock,
+ lsa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->maps:remove(lsa, State) end,
+ fun() -> State end),
+ State2 = maps:remove(lsock, State1),
+ State3 = maps:remove(lport, State2),
+ {ok, State3};
+ (#{lsock := Sock} = State) ->
case socket:close(Sock) of
ok ->
State1 = maps:remove(lsock, State),
@@ -5667,15 +6167,13 @@ sc_lc_receive_response_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create socket",
cmd => fun(#{domain := Domain,
- type := Type,
protocol := Proto} = State) ->
- case socket:open(Domain, Type, Proto) of
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{sock => Sock}};
{error, _} = ERROR ->
@@ -5684,6 +6182,8 @@ sc_lc_receive_response_tcp(InitState) ->
end},
#{desc => "bind socket to local address",
cmd => fun(#{sock := Sock, local_sa := LSA} = _State) ->
+ ?SEV_IPRINT("bind to LSA: "
+ "~n ~p", [LSA]),
case socket:bind(Sock, LSA) of
{ok, _} ->
ok;
@@ -5699,7 +6199,19 @@ sc_lc_receive_response_tcp(InitState) ->
%% The actual test
#{desc => "await continue (connect)",
- cmd => fun(#{tester := Tester, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local = Domain,
+ tester := Tester} = State) ->
+ case ?SEV_AWAIT_CONTINUE(Tester, tester, connect) of
+ {ok, ServerPath} ->
+ ?SEV_IPRINT("Server Path: "
+ "~n ~s", [ServerPath]),
+ ServerSA = #{family => Domain,
+ path => ServerPath},
+ {ok, State#{server_sa => ServerSA}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{tester := Tester, local_sa := LSA} = State) ->
case ?SEV_AWAIT_CONTINUE(Tester, tester, connect) of
{ok, Port} ->
ServerSA = LSA#{port => Port},
@@ -5729,7 +6241,18 @@ sc_lc_receive_response_tcp(InitState) ->
end
end},
#{desc => "close socket",
- cmd => fun(#{sock := Sock} = State) ->
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ sock_close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(sock, State1)};
+ (#{sock := Sock} = State) ->
sock_close(Sock),
{ok, maps:remove(sock, State)}
end},
@@ -5776,8 +6299,8 @@ sc_lc_receive_response_tcp(InitState) ->
#{desc => "await acceptor ready (init)",
cmd => fun(#{acceptor := Pid} = State) ->
case ?SEV_AWAIT_READY(Pid, acceptor, init) of
- {ok, Port} ->
- {ok, State#{lport => Port}};
+ {ok, PortOrPath} ->
+ {ok, State#{server_info => PortOrPath}};
{error, _} = ERROR ->
ERROR
end
@@ -5834,8 +6357,8 @@ sc_lc_receive_response_tcp(InitState) ->
end},
?SEV_SLEEP(?SECS(1)),
#{desc => "order client to continue (connect)",
- cmd => fun(#{client := Pid, lport := Port} = _State) ->
- ?SEV_ANNOUNCE_CONTINUE(Pid, connect, Port),
+ cmd => fun(#{client := Pid, server_info := Info} = _State) ->
+ ?SEV_ANNOUNCE_CONTINUE(Pid, connect, Info),
ok
end},
#{desc => "await acceptor ready (accept)",
@@ -6002,12 +6525,11 @@ sc_lc_recvfrom_response_udp4(suite) ->
sc_lc_recvfrom_response_udp4(doc) ->
[];
sc_lc_recvfrom_response_udp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_lc_recvfrom_response_udp4,
fun() ->
- ?TT(?SECS(30)),
Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
InitState = #{domain => inet,
- type => dgram,
protocol => udp,
recv => Recv},
ok = sc_lc_receive_response_udp(InitState)
@@ -6024,13 +6546,36 @@ sc_lc_recvfrom_response_udp6(suite) ->
sc_lc_recvfrom_response_udp6(doc) ->
[];
sc_lc_recvfrom_response_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_lc_recvfrom_response_udp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(30)),
Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
- InitState = #{domain => inet6,
- recv => Recv},
+ InitState = #{domain => inet6,
+ protocol => udp,
+ recv => Recv},
+ ok = sc_lc_receive_response_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recv function.
+%% Socket is Unix Domainm (dgram) socket.
+
+sc_lc_recvfrom_response_udpL(suite) ->
+ [];
+sc_lc_recvfrom_response_udpL(doc) ->
+ [];
+sc_lc_recvfrom_response_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(sc_lc_recvfrom_response_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Recv = fun(Sock, To) -> socket:recvfrom(Sock, [], To) end,
+ InitState = #{domain => local,
+ protocol => default,
+ recv => Recv},
ok = sc_lc_receive_response_udp(InitState)
end).
@@ -6055,20 +6600,25 @@ sc_lc_receive_response_udp(InitState) ->
%% *** Init part ***
#{desc => "local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "open socket",
- cmd => fun(#{domain := Domain} = State) ->
- Sock = sock_open(Domain, dgram, udp),
+ cmd => fun(#{domain := Domain, protocol := Proto} = State) ->
+ Sock = sock_open(Domain, dgram, Proto),
SA = sock_sockname(Sock),
{ok, State#{sock => Sock, sa => SA}}
end},
#{desc => "bind socket",
cmd => fun(#{sock := Sock, local_sa := LSA}) ->
- sock_bind(Sock, LSA),
- ok
+ case socket:bind(Sock, LSA) of
+ {ok, _Port} ->
+ ?SEV_IPRINT("src bound"),
+ ok;
+ {error, Reason} = ERROR ->
+ ?SEV_EPRINT("src bind failed: ~p", [Reason]),
+ ERROR
+ end
end},
#{desc => "announce ready (init)",
cmd => fun(#{tester := Tester, sock := Sock}) ->
@@ -6107,7 +6657,18 @@ sc_lc_receive_response_udp(InitState) ->
ok = ?SEV_AWAIT_CONTINUE(Tester, tester, close)
end},
#{desc => "close socket",
- cmd => fun(#{sock := Sock} = State) ->
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(sock, State1)};
+ (#{sock := Sock} = State) ->
case socket:close(Sock) of
ok ->
{ok, maps:remove(sock, State)};
@@ -6400,9 +6961,9 @@ sc_lc_receive_response_udp(InitState) ->
i("start 'tester' evaluator"),
TesterInitState = #{prim_server => PrimServer#ev.pid,
- sec_server1 => SecServer1#ev.pid,
- sec_server2 => SecServer2#ev.pid,
- sec_server3 => SecServer3#ev.pid},
+ sec_server1 => SecServer1#ev.pid,
+ sec_server2 => SecServer2#ev.pid,
+ sec_server3 => SecServer3#ev.pid},
Tester = ?SEV_START("tester", TesterSeq, TesterInitState),
i("await evaluator"),
@@ -6422,12 +6983,11 @@ sc_lc_recvmsg_response_tcp4(suite) ->
sc_lc_recvmsg_response_tcp4(doc) ->
[];
sc_lc_recvmsg_response_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(sc_lc_recvmsg_response_tcp4,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_lc_receive_response_tcp(InitState)
@@ -6444,13 +7004,12 @@ sc_lc_recvmsg_response_tcp6(suite) ->
sc_lc_recvmsg_response_tcp6(doc) ->
[];
sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(sc_recvmsg_response_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet6,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_lc_receive_response_tcp(InitState)
@@ -6460,6 +7019,28 @@ sc_lc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test what happens when a socket is
%% locally closed while the process is calling the recvmsg function.
+%% Socket is Unix Domain (stream) socket.
+
+sc_lc_recvmsg_response_tcpL(suite) ->
+ [];
+sc_lc_recvmsg_response_tcpL(doc) ->
+ [];
+sc_lc_recvmsg_response_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(sc_recvmsg_response_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Recv = fun(Sock) -> socket:recvmsg(Sock) end,
+ InitState = #{domain => local,
+ protocol => default,
+ recv => Recv},
+ ok = sc_lc_receive_response_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recvmsg function.
%% Socket is IPv4.
sc_lc_recvmsg_response_udp4(suite) ->
@@ -6471,8 +7052,9 @@ sc_lc_recvmsg_response_udp4(_Config) when is_list(_Config) ->
fun() ->
?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
- InitState = #{domain => inet,
- recv => Recv},
+ InitState = #{domain => inet,
+ protocol => udp,
+ recv => Recv},
ok = sc_lc_receive_response_udp(InitState)
end).
@@ -6492,8 +7074,32 @@ sc_lc_recvmsg_response_udp6(_Config) when is_list(_Config) ->
fun() ->
?TT(?SECS(10)),
Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
- InitState = #{domain => inet6,
- recv => Recv},
+ InitState = #{domain => inet6,
+ protocol => udp,
+ recv => Recv},
+ ok = sc_lc_receive_response_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the recvmsg function.
+%% Socket is Unix Domain (dgram) socket.
+
+sc_lc_recvmsg_response_udpL(suite) ->
+ [];
+sc_lc_recvmsg_response_udpL(doc) ->
+ [];
+sc_lc_recvmsg_response_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(sc_recvmsg_response_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Recv = fun(Sock, To) -> socket:recvmsg(Sock, To) end,
+ InitState = #{domain => local,
+ protocol => default,
+ recv => Recv},
ok = sc_lc_receive_response_udp(InitState)
end).
@@ -6511,11 +7117,10 @@ sc_lc_acceptor_response_tcp4(suite) ->
sc_lc_acceptor_response_tcp4(doc) ->
[];
sc_lc_acceptor_response_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(sc_lc_acceptor_response_tcp4,
fun() ->
- ?TT(?SECS(10)),
InitState = #{domain => inet,
- type => stream,
protocol => tcp},
ok = sc_lc_acceptor_response_tcp(InitState)
end).
@@ -6533,18 +7138,39 @@ sc_lc_acceptor_response_tcp6(suite) ->
sc_lc_acceptor_response_tcp6(doc) ->
[];
sc_lc_acceptor_response_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
tc_try(sc_lc_acceptor_response_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
- InitState = #{domain => inet,
- type => stream,
+ InitState = #{domain => inet6,
protocol => tcp},
ok = sc_lc_acceptor_response_tcp(InitState)
end).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% locally closed while the process is calling the accept function.
+%% We test what happens with a non-controlling_process also, since we
+%% git the setup anyway.
+%% Socket is Unix Domain (stream) socket.
+
+sc_lc_acceptor_response_tcpL(suite) ->
+ [];
+sc_lc_acceptor_response_tcpL(doc) ->
+ [];
+sc_lc_acceptor_response_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(sc_lc_acceptor_response_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ protocol => default},
+ ok = sc_lc_acceptor_response_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sc_lc_acceptor_response_tcp(InitState) ->
PrimAcceptorSeq =
@@ -6564,15 +7190,13 @@ sc_lc_acceptor_response_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{lsa => LSA}}
end},
#{desc => "create (listen) socket",
cmd => fun(#{domain := Domain,
- type := Type,
protocol := Proto} = State) ->
- case socket:open(Domain, Type, Proto) of
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{sock => Sock}};
{error, _} = ERROR ->
@@ -6609,8 +7233,8 @@ sc_lc_acceptor_response_tcp(InitState) ->
end
end},
#{desc => "await connection",
- cmd => fun(#{sock := Sock, timeout := Timeout} = _State) ->
- case socket:accept(Sock, Timeout) of
+ cmd => fun(#{sock := LSock, timeout := Timeout} = _State) ->
+ case socket:accept(LSock, Timeout) of
{error, timeout} ->
ok;
{ok, Sock} ->
@@ -6631,7 +7255,25 @@ sc_lc_acceptor_response_tcp(InitState) ->
ok = ?SEV_AWAIT_CONTINUE(Tester, tester, close)
end},
#{desc => "close socket",
- cmd => fun(#{sock := Sock} = State) ->
+ cmd => fun(#{domain := local,
+ sock := Sock,
+ lsa := #{path := Path}} = State) ->
+ case socket:close(Sock) of
+ ok ->
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(lsa, State)
+ end,
+ fun() ->
+ State
+ end),
+ {ok, maps:remove(sock, State1)};
+ {error, _} = ERROR ->
+ unlink_path(Path),
+ ERROR
+ end;
+ (#{sock := Sock} = State) ->
case socket:close(Sock) of
ok ->
{ok, maps:remove(sock, State)};
@@ -6946,12 +7588,11 @@ sc_rc_recv_response_tcp4(suite) ->
sc_rc_recv_response_tcp4(doc) ->
[];
sc_rc_recv_response_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_rc_recv_response_tcp4,
fun() ->
- ?TT(?SECS(30)),
Recv = fun(Sock) -> socket:recv(Sock) end,
InitState = #{domain => inet,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_rc_receive_response_tcp(InitState)
@@ -6968,13 +7609,12 @@ sc_rc_recv_response_tcp6(suite) ->
sc_rc_recv_response_tcp6(doc) ->
[];
sc_rc_recv_response_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_rc_recv_response_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recv(Sock) end,
InitState = #{domain => inet6,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_rc_receive_response_tcp(InitState)
@@ -6982,6 +7622,28 @@ sc_rc_recv_response_tcp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% remotely closed while the process is calling the recv function.
+%% Socket is Unix Domain (stream) socket.
+
+sc_rc_recv_response_tcpL(suite) ->
+ [];
+sc_rc_recv_response_tcpL(doc) ->
+ [];
+sc_rc_recv_response_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(sc_rc_recv_response_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Recv = fun(Sock) -> socket:recv(Sock) end,
+ InitState = #{domain => local,
+ protocol => default,
+ recv => Recv},
+ ok = sc_rc_receive_response_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sc_rc_receive_response_tcp(InitState) ->
%% Each connection are handled by handler processes.
@@ -7004,13 +7666,12 @@ sc_rc_receive_response_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, stream, tcp) of
+ cmd => fun(#{domain := Domain, protocol := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{lsock => Sock}};
{error, _} = ERROR ->
@@ -7018,7 +7679,17 @@ sc_rc_receive_response_tcp(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{lsock := LSock, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ lsa := LSA} = _State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock,
+ local_sa := LSA} = State) ->
case socket:bind(LSock, LSA) of
{ok, Port} ->
{ok, State#{lport => Port}};
@@ -7031,7 +7702,15 @@ sc_rc_receive_response_tcp(InitState) ->
socket:listen(LSock)
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester,
+ local_sa := LSA}) ->
+ %% Actually we only need to send the path,
+ %% but to keep it simple, we send the "same"
+ %% as for non-local.
+ ?SEV_ANNOUNCE_READY(Tester, init, LSA),
+ ok;
+ (#{tester := Tester, local_sa := LSA, lport := Port}) ->
ServerSA = LSA#{port => Port},
?SEV_ANNOUNCE_READY(Tester, init, ServerSA),
ok
@@ -7213,7 +7892,25 @@ sc_rc_receive_response_tcp(InitState) ->
{ok, State2}
end},
#{desc => "close listen socket",
- cmd => fun(#{lsock := LSock} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ lsa := #{path := Path}} = State) ->
+ case socket:close(LSock) of
+ ok ->
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(lsa, State)
+ end,
+ fun() ->
+ State
+ end),
+ {ok, maps:remove(lsock, State1)};
+ {error, _} = ERROR ->
+ unlink_path(Path),
+ ERROR
+ end;
+ (#{lsock := LSock} = State) ->
case socket:close(LSock) of
ok ->
{ok, maps:remove(lsock, State)};
@@ -7270,8 +7967,10 @@ sc_rc_receive_response_tcp(InitState) ->
ok
end},
#{desc => "order remote client to start",
- cmd => fun(#{rclient := Client, server_sa := ServerSA}) ->
- ?SEV_ANNOUNCE_START(Client, ServerSA),
+ cmd => fun(#{rclient := Client,
+ server_sa := ServerSA,
+ protocol := Proto}) ->
+ ?SEV_ANNOUNCE_START(Client, {ServerSA, Proto}),
ok
end},
#{desc => "await remote client ready",
@@ -7672,16 +8371,16 @@ sc_rc_tcp_client_start(Node) ->
sc_rc_tcp_client(Parent) ->
sc_rc_tcp_client_init(Parent),
- ServerSA = sc_rc_tcp_client_await_start(Parent),
+ {ServerSA, Proto} = sc_rc_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
- Sock = sc_rc_tcp_client_create(Domain),
- sc_rc_tcp_client_bind(Sock, Domain),
+ Sock = sc_rc_tcp_client_create(Domain, Proto),
+ Path = sc_rc_tcp_client_bind(Sock, Domain),
sc_rc_tcp_client_announce_ready(Parent, init),
sc_rc_tcp_client_await_continue(Parent, connect),
sc_rc_tcp_client_connect(Sock, ServerSA),
sc_rc_tcp_client_announce_ready(Parent, connect),
sc_rc_tcp_client_await_continue(Parent, close),
- sc_rc_tcp_client_close(Sock),
+ sc_rc_tcp_client_close(Sock, Path),
sc_rc_tcp_client_announce_ready(Parent, close),
Reason = sc_rc_tcp_client_await_terminate(Parent),
?SEV_IPRINT("terminate"),
@@ -7697,9 +8396,9 @@ sc_rc_tcp_client_await_start(Parent) ->
i("sc_rc_tcp_client_await_start -> entry"),
?SEV_AWAIT_START(Parent).
-sc_rc_tcp_client_create(Domain) ->
+sc_rc_tcp_client_create(Domain, Proto) ->
i("sc_rc_tcp_client_create -> entry"),
- case socket:open(Domain, stream, tcp) of
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
case socket:getopt(Sock, otp, fd) of
{ok, FD} ->
@@ -7714,12 +8413,17 @@ sc_rc_tcp_client_create(Domain) ->
sc_rc_tcp_client_bind(Sock, Domain) ->
i("sc_rc_tcp_client_bind -> entry"),
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
case socket:bind(Sock, LSA) of
{ok, _} ->
- ok;
+ case socket:sockname(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ Path;
+ {ok, _} ->
+ undefined;
+ {error, Reason1} ->
+ exit({sockname, Reason1})
+ end;
{error, Reason} ->
exit({bind, Reason})
end.
@@ -7741,13 +8445,17 @@ sc_rc_tcp_client_connect(Sock, ServerSA) ->
exit({connect, Reason})
end.
-sc_rc_tcp_client_close(Sock) ->
+sc_rc_tcp_client_close(Sock, Path) ->
i("sc_rc_tcp_client_close -> entry"),
case socket:close(Sock) of
ok ->
+ unlink_path(Path),
ok;
{error, Reason} ->
- exit({close, Reason})
+ ?SEV_EPRINT("failed closing: "
+ "~n Reason: ~p", [Reason]),
+ unlink_path(Path),
+ {error, {close, Reason}}
end.
sc_rc_tcp_client_await_terminate(Parent) ->
@@ -7827,12 +8535,11 @@ sc_rc_recvmsg_response_tcp4(suite) ->
sc_rc_recvmsg_response_tcp4(doc) ->
[];
sc_rc_recvmsg_response_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_rc_recvmsg_response_tcp4,
fun() ->
- ?TT(?SECS(30)),
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_rc_receive_response_tcp(InitState)
@@ -7849,13 +8556,12 @@ sc_rc_recvmsg_response_tcp6(suite) ->
sc_rc_recvmsg_response_tcp6(doc) ->
[];
sc_rc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_rc_recvmsg_response_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(10)),
Recv = fun(Sock) -> socket:recvmsg(Sock) end,
InitState = #{domain => inet6,
- type => stream,
protocol => tcp,
recv => Recv},
ok = sc_rc_receive_response_tcp(InitState)
@@ -7863,6 +8569,28 @@ sc_rc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% remotely closed while the process is calling the recvmsg function.
+%% Socket is Unix Domain (stream) socket.
+
+sc_rc_recvmsg_response_tcpL(suite) ->
+ [];
+sc_rc_recvmsg_response_tcpL(doc) ->
+ [];
+sc_rc_recvmsg_response_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(sc_rc_recvmsg_response_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ Recv = fun(Sock) -> socket:recvmsg(Sock) end,
+ InitState = #{domain => local,
+ protocol => default,
+ recv => Recv},
+ ok = sc_rc_receive_response_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test what happens when a socket is
%% remotely closed while the process is calling the recv function.
%% The remote client sends data, then shutdown(write) and then the
@@ -7872,6 +8600,7 @@ sc_rc_recvmsg_response_tcp6(_Config) when is_list(_Config) ->
%% To minimize the chance of "weirdness", we should really have test cases
%% where the two sides of the connection is on different machines. But for
%% now, we will make do with different VMs on the same host.
+%% This would of course not work for Unix Domain sockets.
%%
sc_rs_recv_send_shutdown_receive_tcp4(suite) ->
@@ -7879,9 +8608,9 @@ sc_rs_recv_send_shutdown_receive_tcp4(suite) ->
sc_rs_recv_send_shutdown_receive_tcp4(doc) ->
[];
sc_rs_recv_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(sc_rs_recv_send_shutdown_receive_tcp4,
fun() ->
- ?TT(?SECS(30)),
MsgData = ?DATA,
Recv = fun(Sock) ->
socket:recv(Sock)
@@ -7890,6 +8619,7 @@ sc_rs_recv_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
socket:send(Sock, Data)
end,
InitState = #{domain => inet,
+ proto => tcp,
recv => Recv,
send => Send,
data => MsgData},
@@ -7921,6 +8651,39 @@ sc_rs_recv_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
socket:send(Sock, Data)
end,
InitState = #{domain => inet6,
+ proto => tcp,
+ recv => Recv,
+ send => Send,
+ data => MsgData},
+ ok = sc_rs_send_shutdown_receive_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% remotely closed while the process is calling the recv function.
+%% The remote client sends data, then shutdown(write) and then the
+%% reader attempts a recv.
+%% Socket is Unix Domain (stream) socket.
+
+sc_rs_recv_send_shutdown_receive_tcpL(suite) ->
+ [];
+sc_rs_recv_send_shutdown_receive_tcpL(doc) ->
+ [];
+sc_rs_recv_send_shutdown_receive_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(sc_rs_recv_send_shutdown_receive_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ MsgData = ?DATA,
+ Recv = fun(Sock) ->
+ socket:recv(Sock)
+ end,
+ Send = fun(Sock, Data) ->
+ socket:send(Sock, Data)
+ end,
+ InitState = #{domain => local,
+ proto => default,
recv => Recv,
send => Send,
data => MsgData},
@@ -7952,13 +8715,12 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
i("get local address for ~p", [Domain]),
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, stream, tcp) of
+ cmd => fun(#{domain := Domain, proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{lsock => Sock}};
{error, _} = ERROR ->
@@ -7966,9 +8728,19 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{lsock := LSock, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ local_sa := LSA} = _State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock, local_sa := LSA} = State) ->
case socket:bind(LSock, LSA) of
{ok, Port} ->
+ ?SEV_IPRINT("bound to port: ~w", [Port]),
{ok, State#{lport => Port}};
{error, _} = ERROR ->
ERROR
@@ -7979,7 +8751,11 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
socket:listen(LSock)
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester, local_sa := LSA}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, LSA),
+ ok;
+ (#{tester := Tester, local_sa := LSA, lport := Port}) ->
ServerSA = LSA#{port => Port},
?SEV_ANNOUNCE_READY(Tester, init, ServerSA),
ok
@@ -8090,7 +8866,18 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
{ok, State2}
end},
#{desc => "close listen socket",
- cmd => fun(#{lsock := LSock} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(lsock, State1)};
+ (#{lsock := LSock} = State) ->
case socket:close(LSock) of
ok ->
{ok, maps:remove(lsock, State)};
@@ -8148,8 +8935,10 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
ok
end},
#{desc => "order remote client to start",
- cmd => fun(#{rclient := Client, server_sa := ServerSA}) ->
- ?SEV_ANNOUNCE_START(Client, ServerSA),
+ cmd => fun(#{rclient := Client,
+ proto := Proto,
+ server_sa := ServerSA}) ->
+ ?SEV_ANNOUNCE_START(Client, {ServerSA, Proto}),
ok
end},
#{desc => "await remote client ready",
@@ -8479,12 +9268,14 @@ sc_rs_send_shutdown_receive_tcp(InitState) ->
i("start server evaluator"),
ServerInitState = #{domain => maps:get(domain, InitState),
+ proto => maps:get(proto, InitState),
recv => maps:get(recv, InitState)},
Server = ?SEV_START("server", ServerSeq, ServerInitState),
i("start client evaluator"),
ClientInitState = #{host => local_host(),
domain => maps:get(domain, InitState),
+ proto => maps:get(proto, InitState),
send => maps:get(send, InitState)},
Client = ?SEV_START("client", ClientSeq, ClientInitState),
@@ -8506,10 +9297,10 @@ sc_rs_tcp_client_start(Node, Send) ->
sc_rs_tcp_client(Parent, Send) ->
sc_rs_tcp_client_init(Parent),
- ServerSA = sc_rs_tcp_client_await_start(Parent),
+ {ServerSA, Proto} = sc_rs_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
- Sock = sc_rs_tcp_client_create(Domain),
- sc_rs_tcp_client_bind(Sock, Domain),
+ Sock = sc_rs_tcp_client_create(Domain, Proto),
+ Path = sc_rs_tcp_client_bind(Sock, Domain),
sc_rs_tcp_client_announce_ready(Parent, init),
sc_rs_tcp_client_await_continue(Parent, connect),
sc_rs_tcp_client_connect(Sock, ServerSA),
@@ -8521,7 +9312,7 @@ sc_rs_tcp_client(Parent, Send) ->
sc_rs_tcp_client_shutdown(Sock),
sc_rs_tcp_client_announce_ready(Parent, shutdown),
sc_rs_tcp_client_await_continue(Parent, close),
- sc_rs_tcp_client_close(Sock),
+ sc_rs_tcp_client_close(Sock, Path),
sc_rs_tcp_client_announce_ready(Parent, close),
Reason = sc_rs_tcp_client_await_terminate(Parent),
?SEV_IPRINT("terminate"),
@@ -8537,9 +9328,9 @@ sc_rs_tcp_client_await_start(Parent) ->
i("sc_rs_tcp_client_await_start -> entry"),
?SEV_AWAIT_START(Parent).
-sc_rs_tcp_client_create(Domain) ->
+sc_rs_tcp_client_create(Domain, Proto) ->
i("sc_rs_tcp_client_create -> entry"),
- case socket:open(Domain, stream, tcp) of
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
Sock;
{error, Reason} ->
@@ -8548,12 +9339,17 @@ sc_rs_tcp_client_create(Domain) ->
sc_rs_tcp_client_bind(Sock, Domain) ->
i("sc_rs_tcp_client_bind -> entry"),
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
case socket:bind(Sock, LSA) of
{ok, _} ->
- ok;
+ case socket:sockname(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ Path;
+ {ok, _} ->
+ undefined;
+ {error, Reason1} ->
+ exit({sockname, Reason1})
+ end;
{error, Reason} ->
exit({bind, Reason})
end.
@@ -8600,13 +9396,17 @@ sc_rs_tcp_client_shutdown(Sock) ->
exit({shutdown, Reason})
end.
-sc_rs_tcp_client_close(Sock) ->
+sc_rs_tcp_client_close(Sock, Path) ->
i("sc_rs_tcp_client_close -> entry"),
case socket:close(Sock) of
ok ->
+ unlink_path(Path),
ok;
{error, Reason} ->
- exit({close, Reason})
+ ?SEV_EPRINT("failed closing: "
+ "~n Reason: ~p", [Reason]),
+ unlink_path(Path),
+ {error, {close, Reason}}
end.
sc_rs_tcp_client_await_terminate(Parent) ->
@@ -8711,12 +9511,11 @@ sc_rs_recvmsg_send_shutdown_receive_tcp4(_Config) when is_list(_Config) ->
MsgHdr = #{iov => [Data]},
socket:sendmsg(Sock, MsgHdr)
end,
- InitState = #{domain => inet,
- type => stream,
- protocol => tcp,
- recv => Recv,
- send => Send,
- data => MsgData},
+ InitState = #{domain => inet,
+ proto => tcp,
+ recv => Recv,
+ send => Send,
+ data => MsgData},
ok = sc_rs_send_shutdown_receive_tcp(InitState)
end).
@@ -8748,15 +9547,62 @@ sc_rs_recvmsg_send_shutdown_receive_tcp6(_Config) when is_list(_Config) ->
end
end,
Send = fun(Sock, Data) when is_binary(Data) ->
- MsgHdr = #{iov => [Data]},
- socket:sendmsg(Sock, MsgHdr)
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr)
end,
- InitState = #{domain => inet6,
- type => stream,
- protocol => tcp,
- recv => Recv,
- send => Send,
- data => MsgData},
+ InitState = #{domain => inet6,
+ proto => tcp,
+ recv => Recv,
+ send => Send,
+ data => MsgData},
+ ok = sc_rs_send_shutdown_receive_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test what happens when a socket is
+%% remotely closed while the process is calling the recvmsg function.
+%% The remote client sends data, then shutdown(write) and then the
+%% reader attempts a recv.
+%% Socket is UNix Domain (stream) socket.
+
+sc_rs_recvmsg_send_shutdown_receive_tcpL(suite) ->
+ [];
+sc_rs_recvmsg_send_shutdown_receive_tcpL(doc) ->
+ [];
+sc_rs_recvmsg_send_shutdown_receive_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(10)),
+ tc_try(sc_rs_recvmsg_send_shutdown_receive_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ {ok, CWD} = file:get_cwd(),
+ ?SEV_IPRINT("CWD: ~s", [CWD]),
+ MsgData = ?DATA,
+ Recv = fun(Sock) ->
+ case socket:recvmsg(Sock) of
+ %% On some platforms, the address
+ %% is *not* provided (e.g. FreeBSD)
+ {ok, #{addr := undefined,
+ iov := [Data]}} ->
+ {ok, Data};
+ %% On some platforms, the address
+ %% *is* provided (e.g. linux)
+ {ok, #{addr := #{family := local},
+ iov := [Data]}} ->
+ {ok, Data};
+ {error, _} = ERROR ->
+ ERROR
+ end
+ end,
+ Send = fun(Sock, Data) when is_binary(Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr)
+ end,
+ InitState = #{domain => local,
+ proto => default,
+ recv => Recv,
+ send => Send,
+ data => MsgData},
ok = sc_rs_send_shutdown_receive_tcp(InitState)
end).
@@ -8773,10 +9619,11 @@ traffic_send_and_recv_chunks_tcp4(suite) ->
traffic_send_and_recv_chunks_tcp4(doc) ->
[];
traffic_send_and_recv_chunks_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(traffic_send_and_recv_chunks_tcp4,
fun() ->
- ?TT(?SECS(30)),
- InitState = #{domain => inet},
+ InitState = #{domain => inet,
+ proto => tcp},
ok = traffic_send_and_recv_chunks_tcp(InitState)
end).
@@ -8794,11 +9641,34 @@ traffic_send_and_recv_chunks_tcp6(suite) ->
traffic_send_and_recv_chunks_tcp6(doc) ->
[];
traffic_send_and_recv_chunks_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
tc_try(traffic_send_and_recv_chunks_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(30)),
- InitState = #{domain => inet6},
+ InitState = #{domain => inet6,
+ proto => tcp},
+ ok = traffic_send_and_recv_chunks_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the send and recv functions
+%% behave as expected when sending and/or reading chunks.
+%% First send data in one "big" chunk, and read it in "small" chunks.
+%% Second, send in a bunch of "small" chunks, and read in one "big" chunk.
+%% Socket is UNix Domain (Stream) socket.
+
+traffic_send_and_recv_chunks_tcpL(suite) ->
+ [];
+traffic_send_and_recv_chunks_tcpL(doc) ->
+ [];
+traffic_send_and_recv_chunks_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ tc_try(traffic_send_and_recv_chunks_tcp6,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default},
ok = traffic_send_and_recv_chunks_tcp(InitState)
end).
@@ -8823,13 +9693,12 @@ traffic_send_and_recv_chunks_tcp(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, stream, tcp) of
+ cmd => fun(#{domain := Domain, proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{lsock => Sock}};
{error, _} = ERROR ->
@@ -8837,7 +9706,17 @@ traffic_send_and_recv_chunks_tcp(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{lsock := LSock, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ local_sa := LSA} = _State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock,
+ local_sa := LSA} = State) ->
case socket:bind(LSock, LSA) of
{ok, Port} ->
{ok, State#{lport => Port}};
@@ -8850,7 +9729,14 @@ traffic_send_and_recv_chunks_tcp(InitState) ->
socket:listen(LSock)
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester,
+ local_sa := LSA}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, LSA),
+ ok;
+ (#{tester := Tester,
+ local_sa := LSA,
+ lport := Port}) ->
ServerSA = LSA#{port => Port},
?SEV_ANNOUNCE_READY(Tester, init, ServerSA),
ok
@@ -9045,9 +9931,20 @@ traffic_send_and_recv_chunks_tcp(InitState) ->
{ok, maps:remove(csock, State)}
end},
#{desc => "close listen socket",
- cmd => fun(#{lsock := Sock} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ ok = socket:close(Sock),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(lsock, State1)};
+ (#{lsock := Sock} = State) ->
(catch socket:close(Sock)),
- {ok, maps:remove(lsock, State)}
+ {ok, maps:remove(lsock, State)}
end},
%% *** We are done ***
@@ -9098,8 +9995,10 @@ traffic_send_and_recv_chunks_tcp(InitState) ->
ok
end},
#{desc => "order remote client to start",
- cmd => fun(#{rclient := Client, server_sa := ServerSA}) ->
- ?SEV_ANNOUNCE_START(Client, ServerSA),
+ cmd => fun(#{rclient := Client,
+ server_sa := ServerSA,
+ proto := Proto}) ->
+ ?SEV_ANNOUNCE_START(Client, {ServerSA, Proto}),
ok
end},
#{desc => "await remote client ready",
@@ -9654,14 +10553,14 @@ traffic_snr_tcp_client_start(Node) ->
erlang:spawn(Node, Fun).
traffic_snr_tcp_client(Parent) ->
- {Sock, ServerSA} = traffic_snr_tcp_client_init(Parent),
+ {Sock, ServerSA, Path} = traffic_snr_tcp_client_init(Parent),
traffic_snr_tcp_client_announce_ready(Parent, init),
traffic_snr_tcp_client_await_continue(Parent, connect),
traffic_snr_tcp_client_connect(Sock, ServerSA),
traffic_snr_tcp_client_announce_ready(Parent, connect),
traffic_snr_tcp_client_send_loop(Parent, Sock),
Reason = traffic_snr_tcp_client_await_terminate(Parent),
- traffic_snr_tcp_client_close(Sock),
+ traffic_snr_tcp_client_close(Sock, Path),
exit(Reason).
@@ -9687,19 +10586,19 @@ traffic_snr_tcp_client_init(Parent) ->
put(sname, "rclient"),
?SEV_IPRINT("init"),
_MRef = erlang:monitor(process, Parent),
- ServerSA = traffic_snr_tcp_client_await_start(Parent),
+ {ServerSA, Proto} = traffic_snr_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
- Sock = traffic_snr_tcp_client_create(Domain),
- traffic_snr_tcp_client_bind(Sock, Domain),
- {Sock, ServerSA}.
+ Sock = traffic_snr_tcp_client_create(Domain, Proto),
+ Path = traffic_snr_tcp_client_bind(Sock, Domain),
+ {Sock, ServerSA, Path}.
traffic_snr_tcp_client_await_start(Parent) ->
i("traffic_snr_tcp_client_await_start -> entry"),
?SEV_AWAIT_START(Parent).
-traffic_snr_tcp_client_create(Domain) ->
+traffic_snr_tcp_client_create(Domain, Proto) ->
i("traffic_snr_tcp_client_create -> entry"),
- case socket:open(Domain, stream, tcp) of
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
Sock;
{error, Reason} ->
@@ -9708,12 +10607,17 @@ traffic_snr_tcp_client_create(Domain) ->
traffic_snr_tcp_client_bind(Sock, Domain) ->
i("traffic_snr_tcp_client_bind -> entry"),
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
case socket:bind(Sock, LSA) of
{ok, _} ->
- ok;
+ case socket:sockname(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ Path;
+ {ok, _} ->
+ undefined;
+ {error, Reason1} ->
+ exit({sockname, Reason1})
+ end;
{error, Reason} ->
exit({bind, Reason})
end.
@@ -9734,13 +10638,17 @@ traffic_snr_tcp_client_connect(Sock, ServerSA) ->
exit({connect, Reason})
end.
-traffic_snr_tcp_client_close(Sock) ->
+traffic_snr_tcp_client_close(Sock, Path) ->
i("traffic_snr_tcp_client_close -> entry"),
case socket:close(Sock) of
ok ->
+ unlink_path(Path),
ok;
{error, Reason} ->
- exit({close, Reason})
+ ?SEV_EPRINT("failed closing: "
+ "~n Reason: ~p", [Reason]),
+ unlink_path(Path),
+ {error, {close, Reason}}
end.
traffic_snr_tcp_client_await_terminate(Parent) ->
@@ -9768,12 +10676,13 @@ traffic_ping_pong_small_send_and_recv_tcp4(suite) ->
traffic_ping_pong_small_send_and_recv_tcp4(doc) ->
[];
traffic_ping_pong_small_send_and_recv_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_send_and_recv_tcp4,
fun() ->
- ?TT(?SECS(15)),
InitState = #{domain => inet,
+ proto => tcp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_send_and_recv_tcp(InitState)
@@ -9795,13 +10704,42 @@ traffic_ping_pong_small_send_and_recv_tcp6(suite) ->
traffic_ping_pong_small_send_and_recv_tcp6(doc) ->
[];
traffic_ping_pong_small_send_and_recv_tcp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_send_and_recv_tcp6,
fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(15)),
InitState = #{domain => inet6,
+ proto => tcp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_send_and_recv_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the send and recv functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes), medium (8K) and large (8M).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'small' message test case, for Unix Domain (stream) socket.
+
+traffic_ping_pong_small_send_and_recv_tcpL(suite) ->
+ [];
+traffic_ping_pong_small_send_and_recv_tcpL(doc) ->
+ [];
+traffic_ping_pong_small_send_and_recv_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(15)),
+ Msg = l2b(?TPP_SMALL),
+ Num = ?TPP_SMALL_NUM,
+ tc_try(traffic_ping_pong_small_send_and_recv_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_send_and_recv_tcp(InitState)
@@ -9828,6 +10766,7 @@ traffic_ping_pong_medium_send_and_recv_tcp4(_Config) when is_list(_Config) ->
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet,
+ proto => tcp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_send_and_recv_tcp(InitState)
@@ -9855,6 +10794,36 @@ traffic_ping_pong_medium_send_and_recv_tcp6(_Config) when is_list(_Config) ->
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet6,
+ proto => tcp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_send_and_recv_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the send and recv functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes), medium (8K) and large (8M).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'medium' message test case, for Unix Domain (stream) socket.
+
+traffic_ping_pong_medium_send_and_recv_tcpL(suite) ->
+ [];
+traffic_ping_pong_medium_send_and_recv_tcpL(doc) ->
+ [];
+traffic_ping_pong_medium_send_and_recv_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(30)),
+ Msg = l2b(?TPP_MEDIUM),
+ Num = ?TPP_MEDIUM_NUM,
+ tc_try(traffic_ping_pong_medium_send_and_recv_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_send_and_recv_tcp(InitState)
@@ -9876,12 +10845,13 @@ traffic_ping_pong_large_send_and_recv_tcp4(suite) ->
traffic_ping_pong_large_send_and_recv_tcp4(doc) ->
[];
traffic_ping_pong_large_send_and_recv_tcp4(_Config) when is_list(_Config) ->
+ ?TT(?SECS(45)),
Msg = l2b(?TPP_LARGE),
Num = ?TPP_LARGE_NUM,
tc_try(traffic_ping_pong_large_send_and_recv_tcp4,
fun() ->
- ?TT(?SECS(45)),
InitState = #{domain => inet,
+ proto => tcp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_send_and_recv_tcp(InitState)
@@ -9909,11 +10879,53 @@ traffic_ping_pong_large_send_and_recv_tcp6(_Config) when is_list(_Config) ->
fun() ->
?TT(?SECS(45)),
InitState = #{domain => inet6,
+ proto => tcp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_send_and_recv_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the send and recv functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes), medium (8K) and large (8M).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'large' message test case, for UNix Domain (stream) socket.
+
+traffic_ping_pong_large_send_and_recv_tcpL(suite) ->
+ [];
+traffic_ping_pong_large_send_and_recv_tcpL(doc) ->
+ [];
+traffic_ping_pong_large_send_and_recv_tcpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(45)),
+ Msg = l2b(?TPP_LARGE),
+ Num = ?TPP_LARGE_NUM,
+ tc_try(traffic_ping_pong_large_send_and_recv_tcpL,
+ fun() ->
+ has_support_unix_domain_socket(),
+ traffic_ping_pong_large_host_cond()
+ end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_send_and_recv_tcp(InitState)
end).
+%% This test case is a bit extreme and fails on some hosts
+%% (e.g. OpenIndiana Hipster), so exclude them.
+traffic_ping_pong_large_host_cond() ->
+ traffic_ping_pong_large_host_cond(os:type(), os:version()).
+
+traffic_ping_pong_large_host_cond({unix, sunos}, _) ->
+ skip("TC does not work on platform");
+traffic_ping_pong_large_host_cond(_, _) ->
+ ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -9936,6 +10948,7 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp4(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(45)),
InitState = #{domain => inet,
+ proto => udp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
@@ -9956,12 +10969,43 @@ traffic_ping_pong_small_sendto_and_recvfrom_udp6(suite) ->
traffic_ping_pong_small_sendto_and_recvfrom_udp6(doc) ->
[];
traffic_ping_pong_small_sendto_and_recvfrom_udp6(_Config) when is_list(_Config) ->
+ ?TT(?SECS(45)),
Msg = l2b(?TPP_SMALL),
Num = ?TPP_SMALL_NUM,
tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udp6,
+ fun() -> has_support_ipv6() end,
fun() ->
- ?TT(?SECS(45)),
- InitState = #{domain => inet,
+ InitState = #{domain => inet6,
+ proto => udp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendto and recvfrom
+%% functions by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for two different message sizes;
+%% small (8 bytes) and medium (8K).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'small' message test case, for Unix Domain (dgram) socket.
+
+traffic_ping_pong_small_sendto_and_recvfrom_udpL(suite) ->
+ [];
+traffic_ping_pong_small_sendto_and_recvfrom_udpL(doc) ->
+ [];
+traffic_ping_pong_small_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) ->
+ ?TT(?SECS(45)),
+ Msg = l2b(?TPP_SMALL),
+ Num = ?TPP_SMALL_NUM,
+ tc_try(traffic_ping_pong_small_sendto_and_recvfrom_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
@@ -9989,6 +11033,7 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp4(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(45)),
InitState = #{domain => inet,
+ proto => udp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
@@ -10016,6 +11061,36 @@ traffic_ping_pong_medium_sendto_and_recvfrom_udp6(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(45)),
InitState = #{domain => inet6,
+ proto => udp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendto and recvfrom
+%% functions by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for two different message sizes;
+%% small (8 bytes) and medium (8K).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'medium' message test case, for Unix Domain (dgram) socket.
+
+traffic_ping_pong_medium_sendto_and_recvfrom_udpL(suite) ->
+ [];
+traffic_ping_pong_medium_sendto_and_recvfrom_udpL(doc) ->
+ [];
+traffic_ping_pong_medium_sendto_and_recvfrom_udpL(_Config) when is_list(_Config) ->
+ Msg = l2b(?TPP_MEDIUM),
+ Num = ?TPP_MEDIUM_NUM,
+ tc_try(traffic_ping_pong_medium_sendto_and_recvfrom_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ ?TT(?SECS(45)),
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendto_and_recvfrom_udp(InitState)
@@ -10043,6 +11118,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(20)),
InitState = #{domain => inet,
+ proto => tcp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
@@ -10070,6 +11146,35 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(20)),
InitState = #{domain => inet6,
+ proto => tcp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendmsg and recvmsg functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes), medium (8K) and large (8M).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'small' message test case, for Unix Domain (stream) socket.
+
+traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL(suite) ->
+ [];
+traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL(doc) ->
+ [];
+traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) ->
+ Msg = l2b(?TPP_SMALL),
+ Num = ?TPP_SMALL_NUM,
+ tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ ?TT(?SECS(20)),
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
@@ -10096,6 +11201,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet,
+ proto => tcp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
@@ -10122,7 +11228,36 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
fun() -> has_support_ipv6() end,
fun() ->
?TT(?SECS(20)),
- InitState = #{domain => ine6,
+ InitState = #{domain => inet6,
+ proto => tcp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendmsg and recvmsg functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes), medium (8K) and large (8M).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'medium' message test case, for Unix Domain (stream) socket.
+
+traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(suite) ->
+ [];
+traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(doc) ->
+ [];
+traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) ->
+ Msg = l2b(?TPP_MEDIUM),
+ Num = ?TPP_MEDIUM_NUM,
+ tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ ?TT(?SECS(20)),
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
@@ -10146,15 +11281,27 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config)
Msg = l2b(?TPP_LARGE),
Num = ?TPP_LARGE_NUM,
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp4,
+ fun() -> traffic_ping_pong_large_sendmsg_and_recvmsg_cond() end,
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet,
+ proto => tcp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
end).
+traffic_ping_pong_large_sendmsg_and_recvmsg_cond() ->
+ traffic_ping_pong_large_sendmsg_and_recvmsg_cond(os:type(), os:version()).
+
+traffic_ping_pong_large_sendmsg_and_recvmsg_cond({unix, linux}, {M, _, _})
+ when (M < 3) ->
+ skip("TC may not work on this version");
+traffic_ping_pong_large_sendmsg_and_recvmsg_cond(_, _) ->
+ ok.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case is intended to test that the sendmsg and recvmsg functions
%% by repeatedly sending a meassage between two entities.
@@ -10172,10 +11319,43 @@ traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6(_Config) when is_list(_Config)
Msg = l2b(?TPP_LARGE),
Num = ?TPP_LARGE_NUM,
tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcp6,
- fun() -> has_support_ipv6() end,
+ fun() ->
+ has_support_ipv6(),
+ traffic_ping_pong_large_sendmsg_and_recvmsg_cond()
+ end,
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet6,
+ proto => tcp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendmsg and recvmsg functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes), medium (8K) and large (8M).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'large' message test case, for Unix Domain (stream) socket.
+
+traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(suite) ->
+ [];
+traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(doc) ->
+ [];
+traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL(_Config) when is_list(_Config) ->
+ Msg = l2b(?TPP_LARGE),
+ Num = ?TPP_LARGE_NUM,
+ tc_try(traffic_ping_pong_large_sendmsg_and_recvmsg_tcpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ ?TT(?SECS(30)),
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState)
@@ -10203,6 +11383,7 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(60)),
InitState = #{domain => inet,
+ proto => udp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState)
@@ -10229,7 +11410,36 @@ traffic_ping_pong_small_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config)
fun() -> has_support_ipv6() end,
fun() ->
?TT(?SECS(30)),
- InitState = #{domain => inet,
+ InitState = #{domain => inet6,
+ proto => udp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState)
+ end).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendmsg and recvmsg functions
+%% by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes) and medium (8K).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'small' message test case, for Unix Domain (dgram) socket.
+
+traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(suite) ->
+ [];
+traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(doc) ->
+ [];
+traffic_ping_pong_small_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) ->
+ Msg = l2b(?TPP_SMALL),
+ Num = ?TPP_SMALL_NUM,
+ tc_try(traffic_ping_pong_small_sendmsg_and_recvmsg_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ ?TT(?SECS(30)),
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState)
@@ -10256,6 +11466,7 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config)
fun() ->
?TT(?SECS(30)),
InitState = #{domain => inet,
+ proto => udp,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState)
@@ -10282,7 +11493,37 @@ traffic_ping_pong_medium_sendmsg_and_recvmsg_udp6(_Config) when is_list(_Config)
fun() -> has_support_ipv6() end,
fun() ->
?TT(?SECS(20)),
- InitState = #{domain => ine6,
+ InitState = #{domain => inet6,
+ proto => udp,
+ msg => Msg,
+ num => Num},
+ ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState)
+ end).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case is intended to test that the sendmsg and recvmsg
+%% functions by repeatedly sending a meassage between two entities.
+%% The same basic test case is used for three different message sizes;
+%% small (8 bytes) and medium (8K).
+%% The message is sent from A to B and then back again. This is
+%% repeated a set number of times (more times the small the message).
+%% This is the 'medium' message test case, for Unix Domain (dgram) socket.
+
+traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(suite) ->
+ [];
+traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(doc) ->
+ [];
+traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL(_Config) when is_list(_Config) ->
+ Msg = l2b(?TPP_MEDIUM),
+ Num = ?TPP_MEDIUM_NUM,
+ tc_try(traffic_ping_pong_medium_sendmsg_and_recvmsg_udpL,
+ fun() -> has_support_unix_domain_socket() end,
+ fun() ->
+ ?TT(?SECS(20)),
+ InitState = #{domain => local,
+ proto => default,
msg => Msg,
num => Num},
ok = traffic_ping_pong_sendmsg_and_recvmsg_udp(InitState)
@@ -10302,14 +11543,26 @@ traffic_ping_pong_send_and_recv_tcp(InitState) ->
},
traffic_ping_pong_send_and_receive_tcp(InitState2).
-traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) ->
- Send = fun(Sock, Data) when is_binary(Data) ->
- MsgHdr = #{iov => [Data]},
- socket:sendmsg(Sock, MsgHdr);
- (Sock, Data) when is_list(Data) -> %% We assume iovec...
- MsgHdr = #{iov => Data},
- socket:sendmsg(Sock, MsgHdr)
+traffic_ping_pong_sendmsg_and_recvmsg_tcp(#{domain := local} = InitState) ->
+ Recv = fun(Sock, Sz) ->
+ case socket:recvmsg(Sock, Sz, 0) of
+ %% On some platforms, the address
+ %% is *not* provided (e.g. FreeBSD)
+ {ok, #{addr := undefined,
+ iov := [Data]}} ->
+ {ok, Data};
+ %% On some platforms, the address
+ %% *is* provided (e.g. linux)
+ {ok, #{addr := #{family := local},
+ iov := [Data]}} ->
+ {ok, Data};
+ {error, _} = ERROR ->
+ ERROR
+ end
end,
+ InitState2 = InitState#{recv => Recv}, % Receive function
+ traffic_ping_pong_sendmsg_and_recvmsg_tcp2(InitState2);
+traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) ->
Recv = fun(Sock, Sz) ->
case socket:recvmsg(Sock, Sz, 0) of
{ok, #{addr := undefined,
@@ -10319,9 +11572,18 @@ traffic_ping_pong_sendmsg_and_recvmsg_tcp(InitState) ->
ERROR
end
end,
- InitState2 = InitState#{send => Send, % Send function
- recv => Recv % Receive function
- },
+ InitState2 = InitState#{recv => Recv}, % Receive function
+ traffic_ping_pong_sendmsg_and_recvmsg_tcp2(InitState2).
+
+traffic_ping_pong_sendmsg_and_recvmsg_tcp2(InitState) ->
+ Send = fun(Sock, Data) when is_binary(Data) ->
+ MsgHdr = #{iov => [Data]},
+ socket:sendmsg(Sock, MsgHdr);
+ (Sock, Data) when is_list(Data) -> %% We assume iovec...
+ MsgHdr = #{iov => Data},
+ socket:sendmsg(Sock, MsgHdr)
+ end,
+ InitState2 = InitState#{send => Send}, % Send function
traffic_ping_pong_send_and_receive_tcp(InitState2).
@@ -10381,13 +11643,12 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, stream, tcp) of
+ cmd => fun(#{domain := Domain, proto := Proto} = State) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
{ok, State#{lsock => Sock}};
{error, _} = ERROR ->
@@ -10395,9 +11656,19 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{lsock := LSock, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := LSock,
+ lsa := LSA} = _State) ->
+ case socket:bind(LSock, LSA) of
+ {ok, _Port} ->
+ ok; % We do not care about the port for local
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{lsock := LSock, local_sa := LSA} = State) ->
case socket:bind(LSock, LSA) of
{ok, Port} ->
+ ?SEV_IPRINT("bound to port: ~w", [Port]),
{ok, State#{lport => Port}};
{error, _} = ERROR ->
ERROR
@@ -10412,7 +11683,11 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
socket:listen(LSock)
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, local_sa := LSA, lport := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester, local_sa := LSA}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, LSA),
+ ok;
+ (#{tester := Tester, local_sa := LSA, lport := Port}) ->
ServerSA = LSA#{port => Port},
?SEV_ANNOUNCE_READY(Tester, init, ServerSA),
ok
@@ -10523,9 +11798,20 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
{ok, State1}
end},
#{desc => "close listen socket",
- cmd => fun(#{lsock := Sock} = State) ->
+ cmd => fun(#{domain := local,
+ lsock := Sock,
+ local_sa := #{path := Path}} = State) ->
+ (catch socket:close(Sock)),
+ State1 =
+ unlink_path(Path,
+ fun() ->
+ maps:remove(local_sa, State)
+ end,
+ fun() -> State end),
+ {ok, maps:remove(lsock, State1)};
+ (#{lsock := Sock} = State) ->
(catch socket:close(Sock)),
- {ok, maps:remove(lsock, State)}
+ {ok, maps:remove(lsock, State)}
end},
%% *** We are done ***
@@ -10577,12 +11863,14 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
end},
#{desc => "order remote client to start",
cmd => fun(#{rclient := RClient,
+ proto := Proto,
server_sa := ServerSA,
buf_init := BufInit,
send := Send,
recv := Recv}) ->
?SEV_ANNOUNCE_START(RClient,
- {ServerSA, BufInit, Send, Recv}),
+ {ServerSA, Proto, BufInit,
+ Send, Recv}),
ok
end},
#{desc => "await remote client ready",
@@ -10883,6 +12171,7 @@ traffic_ping_pong_send_and_receive_tcp2(InitState) ->
i("start server evaluator"),
ServerInitState = #{domain => maps:get(domain, InitState),
+ proto => maps:get(proto, InitState),
recv => maps:get(recv, InitState),
send => maps:get(send, InitState),
buf_init => maps:get(buf_init, InitState)},
@@ -10976,14 +12265,6 @@ tpp_tcp_handler_msg_exchange_loop(Sock, Send, Recv, N, Sent, Received, Start) ->
?SEV_EPRINT("send (~w): ~p", [N, SReason]),
exit({send, SReason, N})
end;
- %% {error, timeout} ->
- %% ?SEV_IPRINT("timeout(~w) - try again", [N]),
- %% case Send(Sock, list_to_binary("ping")) of
- %% ok ->
- %% exit({'ping-send', ok, N});
- %% {error, Reason} ->
- %% exit({'ping-send', Reason, N})
- %% end;
{error, closed} ->
?SEV_IPRINT("closed - we are done: ~w, ~w, ~w", [N, Sent, Received]),
Stop = ?LIB:timestamp(),
@@ -11002,10 +12283,10 @@ tpp_tcp_client_create(Node) ->
tpp_tcp_client(Parent) ->
tpp_tcp_client_init(Parent),
- {ServerSA, BufInit, Send, Recv} = tpp_tcp_client_await_start(Parent),
+ {ServerSA, Proto, BufInit, Send, Recv} = tpp_tcp_client_await_start(Parent),
Domain = maps:get(family, ServerSA),
- Sock = tpp_tcp_client_sock_open(Domain, BufInit),
- tpp_tcp_client_sock_bind(Sock, Domain),
+ Sock = tpp_tcp_client_sock_open(Domain, Proto, BufInit),
+ Path = tpp_tcp_client_sock_bind(Sock, Domain),
tpp_tcp_client_announce_ready(Parent, init),
tpp_tcp_client_await_continue(Parent, connect),
tpp_tcp_client_sock_connect(Sock, ServerSA),
@@ -11014,7 +12295,7 @@ tpp_tcp_client(Parent) ->
Result = tpp_tcp_client_msg_exchange(Sock, Send, Recv, InitMsg, Num),
tpp_tcp_client_announce_ready(Parent, send, Result),
Reason = tpp_tcp_client_await_terminate(Parent),
- tpp_tcp_client_sock_close(Sock),
+ tpp_tcp_client_sock_close(Sock, Path),
?SEV_IPRINT("terminating"),
exit(Reason).
@@ -11054,8 +12335,10 @@ tpp_tcp_client_await_terminate(Parent) ->
?SEV_IPRINT("await terminate"),
case ?SEV_AWAIT_TERMINATE(Parent, parent) of
ok ->
- ok;
+ ?SEV_IPRINT("termination received: normal"),
+ normal;
{error, Reason} ->
+ ?SEV_IPRINT("termination received: ~w", [Reason]),
Reason
end.
@@ -11099,8 +12382,8 @@ tpp_tcp_client_msg_exchange_loop(Sock, Send, Recv, Data,
exit({send, SReason, N})
end.
-tpp_tcp_client_sock_open(Domain, BufInit) ->
- case socket:open(Domain, stream, tcp) of
+tpp_tcp_client_sock_open(Domain, Proto, BufInit) ->
+ case socket:open(Domain, stream, Proto) of
{ok, Sock} ->
ok = BufInit(Sock),
Sock;
@@ -11109,14 +12392,19 @@ tpp_tcp_client_sock_open(Domain, BufInit) ->
end.
tpp_tcp_client_sock_bind(Sock, Domain) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
case socket:bind(Sock, LSA) of
{ok, _} ->
- ok;
- {error, Reason} ->
- exit({bind, Reason})
+ case socket:sockname(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ Path;
+ {ok, _} ->
+ undefined;
+ {error, Reason1} ->
+ exit({sockname, Reason1})
+ end;
+ {error, Reason2} ->
+ exit({bind, Reason2})
end.
tpp_tcp_client_sock_connect(Sock, ServerSA) ->
@@ -11127,14 +12415,20 @@ tpp_tcp_client_sock_connect(Sock, ServerSA) ->
exit({connect, Reason})
end.
-tpp_tcp_client_sock_close(Sock) ->
+tpp_tcp_client_sock_close(Sock, Path) ->
case socket:close(Sock) of
ok ->
+ unlink_path(Path),
ok;
{error, Reason} ->
- exit({close, Reason})
+ ?SEV_EPRINT("failed closing: "
+ "~n Reason: ~p", [Reason]),
+ unlink_path(Path),
+ {error, {close, Reason}}
end.
+
+
-define(TPP_REQUEST, 1).
-define(TPP_REPLY, 2).
@@ -11300,13 +12594,12 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
%% *** Init part ***
#{desc => "which local address",
cmd => fun(#{domain := Domain} = State) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain, addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
{ok, State#{local_sa => LSA}}
end},
#{desc => "create listen socket",
- cmd => fun(#{domain := Domain} = State) ->
- case socket:open(Domain, dgram, udp) of
+ cmd => fun(#{domain := Domain, proto := Proto} = State) ->
+ case socket:open(Domain, dgram, Proto) of
{ok, Sock} ->
{ok, State#{sock => Sock}};
{error, _} = ERROR ->
@@ -11314,7 +12607,15 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
end
end},
#{desc => "bind to local address",
- cmd => fun(#{sock := Sock, local_sa := LSA} = State) ->
+ cmd => fun(#{domain := local,
+ sock := Sock, local_sa := LSA} = _State) ->
+ case socket:bind(Sock, LSA) of
+ {ok, _} ->
+ ok;
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{sock := Sock, local_sa := LSA} = State) ->
case socket:bind(Sock, LSA) of
{ok, Port} ->
{ok, State#{port => Port}};
@@ -11357,7 +12658,11 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
end
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester, local_sa := LSA, port := Port}) ->
+ cmd => fun(#{domain := local,
+ tester := Tester, local_sa := LSA}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, LSA),
+ ok;
+ (#{tester := Tester, local_sa := LSA, port := Port}) ->
ServerSA = LSA#{port => Port},
?SEV_ANNOUNCE_READY(Tester, init, ServerSA),
ok
@@ -11396,6 +12701,19 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
ERROR
end
end},
+ #{desc => "(maybe) unlink socket",
+ cmd => fun(#{domain := local,
+ local_sa := #{path := Path}} = State) ->
+ unlink_path(Path,
+ fun() ->
+ {ok, maps:remove(local_sa, State)}
+ end,
+ fun() ->
+ ok
+ end);
+ (_) ->
+ ok
+ end},
#{desc => "announce ready (close)",
cmd => fun(#{tester := Tester} = _State) ->
?SEV_ANNOUNCE_READY(Tester, close),
@@ -11492,11 +12810,13 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
#{desc => "order remote handler to start",
cmd => fun(#{handler := Handler,
server_sa := ServerSA,
+ proto := Proto,
buf_init := BufInit,
send := Send,
recv := Recv}) ->
?SEV_ANNOUNCE_START(Handler,
- {ServerSA, BufInit, Send, Recv}),
+ {ServerSA, Proto, BufInit,
+ Send, Recv}),
ok
end},
#{desc => "await (remote) handler ready",
@@ -11741,6 +13061,7 @@ traffic_ping_pong_send_and_receive_udp2(InitState) ->
i("start server evaluator"),
ServerInitState = #{domain => maps:get(domain, InitState),
+ proto => maps:get(proto, InitState),
recv => maps:get(recv, InitState),
send => maps:get(send, InitState),
buf_init => maps:get(buf_init, InitState)},
@@ -11841,12 +13162,12 @@ tpp_udp_client_handler_create(Node) ->
tpp_udp_client_handler(Parent) ->
tpp_udp_client_handler_init(Parent),
?SEV_IPRINT("await start command"),
- {ServerSA, BufInit, Send, Recv} = tpp_udp_handler_await_start(Parent),
+ {ServerSA, Proto, BufInit, Send, Recv} = tpp_udp_handler_await_start(Parent),
?SEV_IPRINT("start command with"
"~n ServerSA: ~p", [ServerSA]),
Domain = maps:get(family, ServerSA),
- Sock = tpp_udp_sock_open(Domain, BufInit),
- tpp_udp_sock_bind(Sock, Domain),
+ Sock = tpp_udp_sock_open(Domain, Proto, BufInit),
+ Path = tpp_udp_sock_bind(Sock, Domain),
?SEV_IPRINT("announce ready", []),
tpp_udp_handler_announce_ready(Parent, init),
{InitMsg, Num} = tpp_udp_handler_await_continue(Parent, send),
@@ -11859,7 +13180,7 @@ tpp_udp_client_handler(Parent) ->
?SEV_IPRINT("await terminate"),
Reason = tpp_udp_handler_await_terminate(Parent),
?SEV_IPRINT("terminate with ~p", [Reason]),
- tpp_udp_sock_close(Sock),
+ tpp_udp_sock_close(Sock, Path),
?SEV_IPRINT("terminating"),
exit(Reason).
@@ -11997,8 +13318,8 @@ tpp_udp_handler_await_terminate(Parent) ->
end.
-tpp_udp_sock_open(Domain, BufInit) ->
- case socket:open(Domain, dgram, udp) of
+tpp_udp_sock_open(Domain, Proto, BufInit) ->
+ case socket:open(Domain, dgram, Proto) of
{ok, Sock} ->
ok = BufInit(Sock),
Sock;
@@ -12007,9 +13328,7 @@ tpp_udp_sock_open(Domain, BufInit) ->
end.
tpp_udp_sock_bind(Sock, Domain) ->
- LAddr = which_local_addr(Domain),
- LSA = #{family => Domain,
- addr => LAddr},
+ LSA = which_local_socket_addr(Domain),
case socket:bind(Sock, LSA) of
{ok, _} ->
ok;
@@ -12017,12 +13336,16 @@ tpp_udp_sock_bind(Sock, Domain) ->
exit({bind, Reason})
end.
-tpp_udp_sock_close(Sock) ->
+tpp_udp_sock_close(Sock, Path) ->
case socket:close(Sock) of
ok ->
+ unlink_path(Path),
ok;
{error, Reason} ->
- exit({close, Reason})
+ ?SEV_EPRINT("Failed closing socket: "
+ "~n ~p", [Reason]),
+ unlink_path(Path),
+ {error, {close, Reason}}
end.
@@ -15104,6 +16427,30 @@ ttest_ssockf_csockf_small_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = false
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssockf_csockf_small_tcpL(suite) ->
+ [];
+ttest_ssockf_csockf_small_tcpL(doc) ->
+ [];
+ttest_ssockf_csockf_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csockf_small_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, false,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -15152,6 +16499,30 @@ ttest_ssockf_csockf_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = false
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssockf_csockf_medium_tcpL(suite) ->
+ [];
+ttest_ssockf_csockf_medium_tcpL(doc) ->
+ [];
+ttest_ssockf_csockf_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csockf_medium_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, false,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -15199,6 +16570,30 @@ ttest_ssockf_csockf_large_tcp6(Config) when is_list(Config) ->
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = false
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssockf_csockf_large_tcpL(suite) ->
+ [];
+ttest_ssockf_csockf_large_tcpL(doc) ->
+ [];
+ttest_ssockf_csockf_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csockf_large_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, false,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = once
%% Message Size: small (=1)
%% Domain: inet
@@ -15248,6 +16643,30 @@ ttest_ssockf_csocko_small_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = once
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssockf_csocko_small_tcpL(suite) ->
+ [];
+ttest_ssockf_csocko_small_tcpL(doc) ->
+ [];
+ttest_ssockf_csocko_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csocko_small_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, once,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = once
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -15296,6 +16715,30 @@ ttest_ssockf_csocko_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = once
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssockf_csocko_medium_tcpL(suite) ->
+ [];
+ttest_ssockf_csocko_medium_tcpL(doc) ->
+ [];
+ttest_ssockf_csocko_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csocko_medium_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, once,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = once
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -15343,6 +16786,30 @@ ttest_ssockf_csocko_large_tcp6(Config) when is_list(Config) ->
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = once
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssockf_csocko_large_tcpL(suite) ->
+ [];
+ttest_ssockf_csocko_large_tcpL(doc) ->
+ [];
+ttest_ssockf_csocko_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csocko_large_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, once,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = true
%% Message Size: small (=1)
%% Domain: inet
@@ -15390,6 +16857,30 @@ ttest_ssockf_csockt_small_tcp6(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = true
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssockf_csockt_small_tcpL(suite) ->
+ [];
+ttest_ssockf_csockt_small_tcpL(doc) ->
+ [];
+ttest_ssockf_csockt_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csocko_small_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, true,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = true
%% Message Size: medium (=2)
@@ -15440,6 +16931,30 @@ ttest_ssockf_csockt_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = false
%% Client: Transport = socket(tcp), Active = true
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssockf_csockt_medium_tcpL(suite) ->
+ [];
+ttest_ssockf_csockt_medium_tcpL(doc) ->
+ [];
+ttest_ssockf_csockt_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csockt_medium_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, true,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = true
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -15486,6 +17001,30 @@ ttest_ssockf_csockt_large_tcp6(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = false
+%% Client: Transport = socket(tcp), Active = true
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssockf_csockt_large_tcpL(suite) ->
+ [];
+ttest_ssockf_csockt_large_tcpL(doc) ->
+ [];
+ttest_ssockf_csockt_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockf_csockt_large_tcpL,
+ Runtime,
+ local,
+ sock, false,
+ sock, true,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = gen_tcp, Active = false
%% Message Size: small (=1)
@@ -15968,6 +17507,30 @@ ttest_ssocko_csockf_small_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = false
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssocko_csockf_small_tcpL(suite) ->
+ [];
+ttest_ssocko_csockf_small_tcpL(doc) ->
+ [];
+ttest_ssocko_csockf_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csockf_small_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, false,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -16016,6 +17579,30 @@ ttest_ssocko_csockf_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = false
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssocko_csockf_medium_tcpL(suite) ->
+ [];
+ttest_ssocko_csockf_medium_tcpL(doc) ->
+ [];
+ttest_ssocko_csockf_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csockf_medium_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, false,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -16063,6 +17650,30 @@ ttest_ssocko_csockf_large_tcp6(Config) when is_list(Config) ->
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = false
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssocko_csockf_large_tcpL(suite) ->
+ [];
+ttest_ssocko_csockf_large_tcpL(doc) ->
+ [];
+ttest_ssocko_csockf_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csockf_large_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, false,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = once
%% Message Size: small (=1)
%% Domain: inet
@@ -16112,6 +17723,30 @@ ttest_ssocko_csocko_small_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = once
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssocko_csocko_small_tcpL(suite) ->
+ [];
+ttest_ssocko_csocko_small_tcpL(doc) ->
+ [];
+ttest_ssocko_csocko_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csocko_small_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, once,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = once
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -16160,6 +17795,30 @@ ttest_ssocko_csocko_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = once
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssocko_csocko_medium_tcpL(suite) ->
+ [];
+ttest_ssocko_csocko_medium_tcpL(doc) ->
+ [];
+ttest_ssocko_csocko_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csocko_medium_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, once,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = once
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -16207,6 +17866,30 @@ ttest_ssocko_csocko_large_tcp6(Config) when is_list(Config) ->
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = once
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssocko_csocko_large_tcpL(suite) ->
+ [];
+ttest_ssocko_csocko_large_tcpL(doc) ->
+ [];
+ttest_ssocko_csocko_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csocko_large_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, once,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = true
%% Message Size: small (=1)
%% Domain: inet
@@ -16254,6 +17937,30 @@ ttest_ssocko_csockt_small_tcp6(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = true
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssocko_csockt_small_tcpL(suite) ->
+ [];
+ttest_ssocko_csockt_small_tcpL(doc) ->
+ [];
+ttest_ssocko_csockt_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csocko_small_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, true,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = true
%% Message Size: medium (=2)
@@ -16304,6 +18011,30 @@ ttest_ssocko_csockt_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = once
%% Client: Transport = socket(tcp), Active = true
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssocko_csockt_medium_tcpL(suite) ->
+ [];
+ttest_ssocko_csockt_medium_tcpL(doc) ->
+ [];
+ttest_ssocko_csockt_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csockt_medium_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, true,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = true
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -16350,6 +18081,30 @@ ttest_ssocko_csockt_large_tcp6(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = once
+%% Client: Transport = socket(tcp), Active = true
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssocko_csockt_large_tcpL(suite) ->
+ [];
+ttest_ssocko_csockt_large_tcpL(doc) ->
+ [];
+ttest_ssocko_csockt_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssocko_csockt_large_tcpL,
+ Runtime,
+ local,
+ sock, once,
+ sock, true,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = gen_tcp, Active = false
%% Message Size: small (=1)
@@ -16832,6 +18587,30 @@ ttest_ssockt_csockf_small_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = false
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssockt_csockf_small_tcpL(suite) ->
+ [];
+ttest_ssockt_csockf_small_tcpL(doc) ->
+ [];
+ttest_ssockt_csockf_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csockf_small_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, false,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -16880,6 +18659,30 @@ ttest_ssockt_csockf_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = false
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssockt_csockf_medium_tcpL(suite) ->
+ [];
+ttest_ssockt_csockf_medium_tcpL(doc) ->
+ [];
+ttest_ssockt_csockf_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csockf_medium_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, false,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = false
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -16927,6 +18730,30 @@ ttest_ssockt_csockf_large_tcp6(Config) when is_list(Config) ->
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = false
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssockt_csockf_large_tcpL(suite) ->
+ [];
+ttest_ssockt_csockf_large_tcpL(doc) ->
+ [];
+ttest_ssockt_csockf_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csockf_large_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, false,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = once
%% Message Size: small (=1)
%% Domain: inet
@@ -16976,6 +18803,30 @@ ttest_ssockt_csocko_small_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = once
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssockt_csocko_small_tcpL(suite) ->
+ [];
+ttest_ssockt_csocko_small_tcpL(doc) ->
+ [];
+ttest_ssockt_csocko_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csocko_small_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, once,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = once
%% Message Size: medium (=2)
%% Domain: inet
%%
@@ -17024,6 +18875,30 @@ ttest_ssockt_csocko_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = once
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssockt_csocko_medium_tcpL(suite) ->
+ [];
+ttest_ssockt_csocko_medium_tcpL(doc) ->
+ [];
+ttest_ssockt_csocko_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csocko_medium_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, once,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = once
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -17071,6 +18946,30 @@ ttest_ssockt_csocko_large_tcp6(Config) when is_list(Config) ->
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = once
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssockt_csocko_large_tcpL(suite) ->
+ [];
+ttest_ssockt_csocko_large_tcpL(doc) ->
+ [];
+ttest_ssockt_csocko_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csocko_large_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, once,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = true
%% Message Size: small (=1)
%% Domain: inet
@@ -17118,6 +19017,30 @@ ttest_ssockt_csockt_small_tcp6(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This test case uses the time test (ttest) utility to implement a
%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = true
+%% Message Size: small (=1)
+%% Domain: local
+%%
+
+ttest_ssockt_csockt_small_tcpL(suite) ->
+ [];
+ttest_ssockt_csockt_small_tcpL(doc) ->
+ [];
+ttest_ssockt_csockt_small_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csocko_small_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, true,
+ 1, 200).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = true
%% Message Size: medium (=2)
@@ -17168,6 +19091,30 @@ ttest_ssockt_csockt_medium_tcp6(Config) when is_list(Config) ->
%% ping-pong like test case.
%% Server: Transport = socket(tcp), Active = true
%% Client: Transport = socket(tcp), Active = true
+%% Message Size: medium (=2)
+%% Domain: local
+%%
+
+ttest_ssockt_csockt_medium_tcpL(suite) ->
+ [];
+ttest_ssockt_csockt_medium_tcpL(doc) ->
+ [];
+ttest_ssockt_csockt_medium_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csockt_medium_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, true,
+ 2, 20).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = true
%% Message Size: large (=3)
%% Domain: inet
%%
@@ -17212,6 +19159,30 @@ ttest_ssockt_csockt_large_tcp6(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% This test case uses the time test (ttest) utility to implement a
+%% ping-pong like test case.
+%% Server: Transport = socket(tcp), Active = true
+%% Client: Transport = socket(tcp), Active = true
+%% Message Size: large (=3)
+%% Domain: local
+%%
+
+ttest_ssockt_csockt_large_tcpL(suite) ->
+ [];
+ttest_ssockt_csockt_large_tcpL(doc) ->
+ [];
+ttest_ssockt_csockt_large_tcpL(Config) when is_list(Config) ->
+ Runtime = which_ttest_runtime(Config),
+ ttest_tcp(ttest_ssockt_csockt_large_tcpL,
+ Runtime,
+ local,
+ sock, true,
+ sock, true,
+ 3, 2).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
which_ttest_runtime(Config) when is_list(Config) ->
case lists:keysearch(esock_test_ttest_runtime, 1, Config) of
@@ -17272,7 +19243,8 @@ ttest_tcp(TC,
tc_try(TC,
fun() ->
if
- (Domain =/= inet) -> has_support_ipv6();
+ (Domain =:= local) -> has_support_unix_domain_socket();
+ (Domain =:= inet6) -> has_support_ipv6();
true -> ok
end
end,
@@ -17326,11 +19298,25 @@ ttest_tcp(InitState) ->
ok
end},
#{desc => "start ttest (remote) server",
- cmd => fun(#{mod := Mod,
+ cmd => fun(#{domain := local = Domain,
+ mod := Mod,
active := Active,
node := Node} = State) ->
- case ttest_tcp_server_start(Node, Mod, Active) of
- {ok, {{Pid, _MRef}, {Addr, Port}}} ->
+ case ttest_tcp_server_start(Node,
+ Domain, Mod, Active) of
+ {ok, {{Pid, _}, Path}} ->
+ {ok, State#{rserver => Pid,
+ path => Path}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{domain := Domain,
+ mod := Mod,
+ active := Active,
+ node := Node} = State) ->
+ case ttest_tcp_server_start(Node,
+ Domain, Mod, Active) of
+ {ok, {{Pid, _}, {Addr, Port}}} ->
{ok, State#{rserver => Pid,
addr => Addr,
port => Port}};
@@ -17339,7 +19325,12 @@ ttest_tcp(InitState) ->
end
end},
#{desc => "announce ready (init)",
- cmd => fun(#{tester := Tester,
+ cmd => fun(#{domain := local,
+ tester := Tester,
+ path := Path}) ->
+ ?SEV_ANNOUNCE_READY(Tester, init, Path),
+ ok;
+ (#{tester := Tester,
addr := Addr,
port := Port}) ->
?SEV_ANNOUNCE_READY(Tester, init, {Addr, Port}),
@@ -17394,8 +19385,14 @@ ttest_tcp(InitState) ->
[
%% *** Wait for start order part ***
#{desc => "await start",
- cmd => fun(State) ->
- {Tester, {ServerAddr, ServerPort}} = ?SEV_AWAIT_START(),
+ cmd => fun(#{domain := local} = State) ->
+ {Tester, ServerPath} =
+ ?SEV_AWAIT_START(),
+ {ok, State#{tester => Tester,
+ server_path => ServerPath}};
+ (State) ->
+ {Tester, {ServerAddr, ServerPort}} =
+ ?SEV_AWAIT_START(),
{ok, State#{tester => Tester,
server_addr => ServerAddr,
server_port => ServerPort}}
@@ -17436,7 +19433,32 @@ ttest_tcp(InitState) ->
ok
end},
#{desc => "start ttest (remote) client",
- cmd => fun(#{node := Node,
+ cmd => fun(#{domain := local = Domain,
+ node := Node,
+ mod := Mod,
+ active := Active,
+ msg_id := MsgID,
+ max_outstanding := MaxOutstanding,
+ runtime := RunTime,
+ server_path := Path} = State) ->
+ Self = self(),
+ Notify =
+ fun(Result) ->
+ ?SEV_ANNOUNCE_READY(Self, ttest, Result)
+ end,
+ case ttest_tcp_client_start(Node, Notify,
+ Domain, Mod,
+ Path,
+ Active,
+ MsgID, MaxOutstanding,
+ RunTime) of
+ {ok, {Pid, _MRef}} ->
+ {ok, State#{rclient => Pid}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+ (#{domain := Domain,
+ node := Node,
mod := Mod,
active := Active,
msg_id := MsgID,
@@ -17450,8 +19472,9 @@ ttest_tcp(InitState) ->
?SEV_ANNOUNCE_READY(Self, ttest, Result)
end,
case ttest_tcp_client_start(Node, Notify,
- Mod, Active,
- Addr, Port,
+ Domain, Mod,
+ {Addr, Port},
+ Active,
MsgID, MaxOutstanding,
RunTime) of
{ok, {Pid, _MRef}} ->
@@ -17463,8 +19486,6 @@ ttest_tcp(InitState) ->
#{desc => "await ttest ready",
cmd => fun(#{tester := Tester,
rclient := RClient} = State) ->
- %% TTestResult = ?SEV_AWAIT_READY(RClient, rclient, ttest,
- %% [{tester, Tester}]),
case ?SEV_AWAIT_READY(RClient, rclient, ttest,
[{tester, Tester}]) of
{ok, Result} ->
@@ -17535,8 +19556,13 @@ ttest_tcp(InitState) ->
ok
end},
#{desc => "await server ready (init)",
- cmd => fun(#{server := Pid} = State) ->
- {ok, {Addr, Port}} = ?SEV_AWAIT_READY(Pid, server, init),
+ cmd => fun(#{domain := local,
+ server := Pid} = State) ->
+ {ok, Path} = ?SEV_AWAIT_READY(Pid, server, init),
+ {ok, State#{server_path => Path}};
+ (#{server := Pid} = State) ->
+ {ok, {Addr, Port}} =
+ ?SEV_AWAIT_READY(Pid, server, init),
{ok, State#{server_addr => Addr,
server_port => Port}}
end},
@@ -17544,7 +19570,12 @@ ttest_tcp(InitState) ->
%% Start the client
#{desc => "order client start",
- cmd => fun(#{client := Pid,
+ cmd => fun(#{domain := local,
+ client := Pid,
+ server_path := Path} = _State) ->
+ ?SEV_ANNOUNCE_START(Pid, Path),
+ ok;
+ (#{client := Pid,
server_addr := Addr,
server_port := Port} = _State) ->
?SEV_ANNOUNCE_START(Pid, {Addr, Port}),
@@ -17683,7 +19714,8 @@ ttest_tcp(InitState) ->
Client = ?SEV_START("client", ClientSeq, ClientInitState),
i("start 'tester' evaluator"),
- TesterInitState = #{server => Server#ev.pid,
+ TesterInitState = #{domain => maps:get(domain, InitState),
+ server => Server#ev.pid,
client => Client#ev.pid},
Tester = ?SEV_START("tester", TesterSeq, TesterInitState),
@@ -17692,12 +19724,12 @@ ttest_tcp(InitState) ->
-ttest_tcp_server_start(Node, gen, Active) ->
+ttest_tcp_server_start(Node, _Domain, gen, Active) ->
Transport = socket_test_ttest_tcp_gen,
socket_test_ttest_tcp_server:start_monitor(Node, Transport, Active);
-ttest_tcp_server_start(Node, sock, Active) ->
+ttest_tcp_server_start(Node, Domain, sock, Active) ->
TransportMod = socket_test_ttest_tcp_socket,
- Transport = {TransportMod, #{method => plain}},
+ Transport = {TransportMod, #{domain => Domain, method => plain}},
socket_test_ttest_tcp_server:start_monitor(Node, Transport, Active).
ttest_tcp_server_stop(Pid) ->
@@ -17705,26 +19737,26 @@ ttest_tcp_server_stop(Pid) ->
ttest_tcp_client_start(Node,
Notify,
- gen,
- Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+ _Domain, gen,
+ ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
Transport = socket_test_ttest_tcp_gen,
socket_test_ttest_tcp_client:start_monitor(Node,
Notify,
Transport,
+ ServerInfo,
Active,
- Addr, Port,
MsgID, MaxOutstanding, RunTime);
ttest_tcp_client_start(Node,
Notify,
- sock,
- Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+ Domain, sock,
+ ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
TransportMod = socket_test_ttest_tcp_socket,
- Transport = {TransportMod, #{method => plain}},
+ Transport = {TransportMod, #{domain => Domain, method => plain}},
socket_test_ttest_tcp_client:start_monitor(Node,
Notify,
Transport,
+ ServerInfo,
Active,
- Addr, Port,
MsgID, MaxOutstanding, RunTime).
@@ -17801,19 +19833,6 @@ sock_open(Domain, Type, Proto) ->
end.
-sock_bind(Sock, SockAddr) ->
- try socket:bind(Sock, SockAddr) of
- {ok, Port} ->
- Port;
- {error, Reason} ->
- i("sock_bind -> error: ~p", [Reason]),
- ?FAIL({bind, Reason})
- catch
- C:E:S ->
- i("sock_bind -> failed: ~p, ~p, ~p", [C, E, S]),
- ?FAIL({bind, C, E, S})
- end.
-
sock_connect(Sock, SockAddr) ->
try socket:connect(Sock, SockAddr) of
ok ->
@@ -17899,13 +19918,50 @@ local_host() ->
end.
+%% The point of this is to "ensure" that paths from different test runs
+%% don't clash.
+mk_unique_path() ->
+ [NodeName | _] = string:tokens(atom_to_list(node()), [$@]),
+ Path = ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]),
+ ensure_unique_path(Path).
+
+ensure_unique_path(Path) ->
+ case file:read_file_info(Path) of
+ {ok, _} -> % Ouch, append a unique ID and try again
+ ensure_unique_path(Path, 1);
+ {error, _} ->
+ %% We assume this means it does not exist yet...
+ %% If we have several process in paralell trying to create
+ %% (unique) path's, then we are in trouble. To *really* be
+ %% on the safe side we should have a (central) path registry...
+ Path
+ end.
+
+ensure_unique_path(Path, ID) when (ID < 100) -> % If this is not enough...
+ NewPath = ?LIB:f("~s_~w", [Path, ID]),
+ case file:read_file_info(NewPath) of
+ {ok, _} -> % Ouch, this also existed, increment and try again
+ ensure_unique_path(Path, ID + 1);
+ {error, _} -> % We assume this means it does not exist yet...
+ NewPath
+ end;
+ensure_unique_path(_, _) ->
+ skip("Could not create unique path").
+
+
+which_local_socket_addr(local = Domain) ->
+ #{family => Domain,
+ path => mk_unique_path()};
+
%% This gets the local address (not 127.0...)
%% We should really implement this using the (new) net module,
%% but until that gets the necessary functionality...
-which_local_addr(Domain) ->
+which_local_socket_addr(Domain) ->
case inet:getifaddrs() of
{ok, IFL} ->
- which_addr(Domain, IFL);
+ Addr = which_addr(Domain, IFL),
+ #{family => Domain,
+ addr => Addr};
{error, Reason} ->
?FAIL({inet, getifaddrs, Reason})
end.
@@ -17935,12 +19991,55 @@ which_addr2(Domain, [_|IFO]) ->
+unlink_path(Path) ->
+ unlink_path(Path, fun() -> ok end, fun() -> ok end).
+
+unlink_path(Path, Success, Failure) when is_list(Path) andalso
+ is_function(Success, 0) andalso
+ is_function(Failure, 0) ->
+ ?SEV_IPRINT("try unlink path: "
+ "~n ~s", [Path]),
+ case os:cmd("unlink " ++ Path) of
+ "" ->
+ ?SEV_IPRINT("path unlinked: "
+ "~n Path: ~s", [Path]),
+ Success();
+ Result ->
+ ?SEV_EPRINT("unlink maybe failed: "
+ "~n Path: ~s"
+ "~n Res: ~s", [Path, Result]),
+ Failure()
+ end;
+unlink_path(_, _, _) ->
+ ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Here are all the *general* test vase condition functions.
+unix_domain_socket_host_cond() ->
+ unix_domain_socket_host_cond(os:type(), os:version()).
+
+unix_domain_socket_host_cond({unix, linux}, {M, _, _}) when (M < 3) ->
+ skip("TC may not work on this version");
+unix_domain_socket_host_cond(_, _) ->
+ ok.
+
+has_support_unix_domain_socket() ->
+ case os:type() of
+ {win32, _} ->
+ skip("Not supported");
+ _ ->
+ case socket:supports(local) of
+ true ->
+ ok;
+ false ->
+ skip("Not supported")
+ end
+ end.
+
+
%% The idea is that this function shall test if the test host has
%% support for IPv6. If not, there is no point in running IPv6 tests.
%% Currently we just skip.
diff --git a/erts/emulator/test/socket_test_ttest_tcp_client.erl b/erts/emulator/test/socket_test_ttest_tcp_client.erl
index 5efa3fe491..b5c5300fd0 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_client.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_client.erl
@@ -42,16 +42,16 @@
-export([
%% These are for the test suite
- start_monitor/6, start_monitor/7, start_monitor/9,
+ start_monitor/5, start_monitor/6, start_monitor/8,
%% These are for starting in a shell when run "manually"
- start/4, start/5, start/7, start/8,
+ start/3, start/4, start/6, start/7,
stop/1
]).
%% Internal exports
-export([
- do_start/10
+ do_start/9
]).
-include_lib("kernel/include/inet.hrl").
@@ -80,25 +80,25 @@
%% ==========================================================================
-start_monitor(Node, Notify, Transport, Active, Addr, Port) ->
- start_monitor(Node, Notify, Transport, Active, Addr, Port, ?MSG_ID_DEFAULT).
+start_monitor(Node, Notify, Transport, ServerInfo, Active) ->
+ start_monitor(Node, Notify, Transport, ServerInfo, Active, ?MSG_ID_DEFAULT).
-start_monitor(Node, Notify, Transport, Active, Addr, Port, 1 = MsgID) ->
- start_monitor(Node, Notify, Transport, Active, Addr, Port, MsgID,
+start_monitor(Node, Notify, Transport, ServerInfo, Active, 1 = MsgID) ->
+ start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID,
?MAX_OUTSTANDING_DEFAULT_1, ?RUNTIME_DEFAULT);
-start_monitor(Node, Notify, Transport, Active, Addr, Port, 2 = MsgID) ->
- start_monitor(Node, Notify, Transport, Active, Addr, Port, MsgID,
+start_monitor(Node, Notify, Transport, ServerInfo, Active, 2 = MsgID) ->
+ start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID,
?MAX_OUTSTANDING_DEFAULT_2, ?RUNTIME_DEFAULT);
-start_monitor(Node, Notify, Transport, Active, Addr, Port, 3 = MsgID) ->
- start_monitor(Node, Notify, Transport, Active, Addr, Port, MsgID,
+start_monitor(Node, Notify, Transport, ServerInfo, Active, 3 = MsgID) ->
+ start_monitor(Node, Notify, Transport, ServerInfo, Active, MsgID,
?MAX_OUTSTANDING_DEFAULT_3, ?RUNTIME_DEFAULT).
-start_monitor(Node, Notify, Transport, Active, Addr, Port,
+start_monitor(Node, Notify, Transport, ServerInfo, Active,
MsgID, MaxOutstanding, RunTime)
when (Node =/= node()) ->
Args = [false,
self(), Notify,
- Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime],
+ Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime],
case rpc:call(Node, ?MODULE, do_start, Args) of
{badrpc, _} = Reason ->
{error, Reason};
@@ -108,11 +108,11 @@ start_monitor(Node, Notify, Transport, Active, Addr, Port,
{error, _} = ERROR ->
ERROR
end;
-start_monitor(_, Notify, Transport, Active, Addr, Port,
+start_monitor(_, Notify, Transport, ServerInfo, Active,
MsgID, MaxOutstanding, RunTime) ->
case do_start(false,
self(), Notify,
- Transport, Active, Addr, Port,
+ Transport, Active, ServerInfo,
MsgID, MaxOutstanding, RunTime) of
{ok, Pid} ->
MRef = erlang:monitor(process, Pid),
@@ -122,50 +122,48 @@ start_monitor(_, Notify, Transport, Active, Addr, Port,
end.
-start(Transport, Active, Addr, Port) ->
- start(Transport, Active, Addr, Port, ?MSG_ID_DEFAULT).
+start(Transport, ServerInfo, Active) ->
+ start(Transport, ServerInfo, Active, ?MSG_ID_DEFAULT).
-start(Transport, Active, Addr, Port, 1 = MsgID) ->
+start(Transport, ServerInfo, Active, 1 = MsgID) ->
start(false,
- Transport, Active, Addr, Port, MsgID,
+ Transport, ServerInfo, Active, MsgID,
?MAX_OUTSTANDING_DEFAULT_1, ?RUNTIME_DEFAULT);
-start(Transport, Active, Addr, Port, 2 = MsgID) ->
+start(Transport, ServerInfo, Active, 2 = MsgID) ->
start(false,
- Transport, Active, Addr, Port, MsgID,
+ Transport, ServerInfo, Active, MsgID,
?MAX_OUTSTANDING_DEFAULT_2, ?RUNTIME_DEFAULT);
-start(Transport, Active, Addr, Port, 3 = MsgID) ->
+start(Transport, ServerInfo, Active, 3 = MsgID) ->
start(false,
- Transport, Active, Addr, Port, MsgID,
+ Transport, ServerInfo, Active, MsgID,
?MAX_OUTSTANDING_DEFAULT_3, ?RUNTIME_DEFAULT).
-start(Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+start(Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
start(false,
- Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime).
+ Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime).
-start(Quiet, Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+start(Quiet, Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
Notify = fun(R) -> present_results(R) end,
do_start(Quiet,
self(), Notify,
- Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime).
+ Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime).
-spec do_start(Quiet,
Parent,
Notify,
Transport,
+ ServerInfo,
Active,
- Addr,
- Port,
MsgID,
MaxOutstanding,
RunTime) -> {ok, Pid} | {error, Reason} when
- Quiet :: pid(),
+ Quiet :: boolean(),
Parent :: pid(),
Notify :: function(),
Transport :: atom() | tuple(),
+ ServerInfo :: {inet:ip_address(), inet:port_number()} | string(),
Active :: active(),
- Addr :: inet:ip_address(),
- Port :: inet:port_number(),
MsgID :: msg_id(),
MaxOutstanding :: max_outstanding(),
RunTime :: runtime(),
@@ -174,14 +172,13 @@ start(Quiet, Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
do_start(Quiet,
Parent, Notify,
- Transport, Active, Addr, Port, MsgID, MaxOutstanding, RunTime)
+ Transport, ServerInfo, Active, MsgID, MaxOutstanding, RunTime)
when is_boolean(Quiet) andalso
is_pid(Parent) andalso
is_function(Notify) andalso
(is_atom(Transport) orelse is_tuple(Transport)) andalso
(is_boolean(Active) orelse (Active =:= once)) andalso
- is_tuple(Addr) andalso
- (is_integer(Port) andalso (Port > 0)) andalso
+ (is_tuple(ServerInfo) orelse is_list(ServerInfo)) andalso
(is_integer(MsgID) andalso (MsgID >= 1) andalso (MsgID =< 3)) andalso
(is_integer(MaxOutstanding) andalso (MaxOutstanding > 0)) andalso
(is_integer(RunTime) andalso (RunTime > 0)) ->
@@ -191,7 +188,7 @@ do_start(Quiet,
Starter,
Parent,
Notify,
- Transport, Active, Addr, Port,
+ Transport, Active, ServerInfo,
MsgID, MaxOutstanding, RunTime)
end,
{Pid, MRef} = spawn_monitor(Init),
@@ -217,25 +214,30 @@ stop(Pid) when is_pid(Pid) ->
init(Quiet,
Starter,
Parent, Notify,
- Transport, Active, Addr, Port,
+ Transport, Active, ServerInfo,
MsgID, MaxOutstanding, RunTime) ->
if
not Quiet ->
?I("init with"
"~n Transport: ~p"
"~n Active: ~p"
- "~n Addr: ~s"
- "~n Port: ~p"
+ "~n ServerInfo: ~s"
"~n Msg ID: ~p (=> 16 + ~w bytes)"
"~n Max Outstanding: ~p"
"~n (Suggested) Run Time: ~p ms",
- [Transport, Active, inet:ntoa(Addr), Port,
+ [Transport, Active,
+ case ServerInfo of
+ {Addr, Port} ->
+ ?F("Addr: ~s, Port: ~w", [inet:ntoa(Addr), Port]);
+ Path ->
+ Path
+ end,
MsgID, size(which_msg_data(MsgID)), MaxOutstanding, RunTime]);
true ->
ok
end,
{Mod, Connect} = process_transport(Transport),
- case Connect(Addr, Port) of
+ case Connect(ServerInfo) of
{ok, Sock} ->
if not Quiet -> ?I("connected");
true -> ok
@@ -269,9 +271,15 @@ init(Quiet,
end.
process_transport(Mod) when is_atom(Mod) ->
- {Mod, fun(A, P) -> Mod:connect(A, P) end};
-process_transport({Mod, Opts}) ->
- {Mod, fun(A, P) -> Mod:connect(A, P, Opts) end}.
+ %% In this case we assume it to be a plain tcp socket
+ {Mod, fun({A, P}) -> Mod:connect(A, P) end};
+process_transport({Mod, #{domain := Domain} = Opts}) ->
+ Connect =
+ case Domain of
+ local -> fun(Path) -> Mod:connect(Path, Opts) end;
+ _ -> fun({A, P}) -> Mod:connect(A, P, Opts) end
+ end,
+ {Mod, Connect}.
which_msg_data(1) -> ?MSG_DATA1;
diff --git a/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl
index 0ec2e908d7..65a3a94d38 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_client_gen.erl
@@ -21,28 +21,28 @@
-module(socket_test_ttest_tcp_client_gen).
-export([
- start/3, start/4, start/6, start/7,
+ start/2, start/3, start/5, start/6,
stop/1
]).
-define(TRANSPORT_MOD, socket_test_ttest_tcp_gen).
-start(Active, Addr, Port) ->
- socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, Active, Addr, Port).
+start(ServerInfo, Active) ->
+ socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, ServerInfo, Active).
-start(Active, Addr, Port, MsgID) ->
- socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, Active, Addr, Port, MsgID).
+start(ServerInfo, Active, MsgID) ->
+ socket_test_ttest_tcp_client:start(?TRANSPORT_MOD, ServerInfo, Active, MsgID).
-start(Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+start(ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
socket_test_ttest_tcp_client:start(false,
?TRANSPORT_MOD,
- Active, Addr, Port,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime).
-start(Quiet, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+start(Quiet, ServerInfo, Active, MsgID, MaxOutstanding, RunTime) ->
socket_test_ttest_tcp_client:start(Quiet,
?TRANSPORT_MOD,
- Active, Addr, Port,
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime).
stop(Pid) ->
diff --git a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl
index acf2556793..ccace2a560 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_client_socket.erl
@@ -21,30 +21,89 @@
-module(socket_test_ttest_tcp_client_socket).
-export([
- start/4, start/5, start/7, start/8,
+ start/3, start/4, start/6, start/7,
stop/1
]).
-define(TRANSPORT_MOD, socket_test_ttest_tcp_socket).
--define(MOD(M), {?TRANSPORT_MOD, #{method => Method}}).
+-define(MOD(D, M), {?TRANSPORT_MOD, #{domain => D, method => M}}).
-start(Method, Active, Addr, Port) ->
- socket_test_ttest_tcp_client:start_monitor(?MOD(Method), Active, Addr, Port).
+start(Method, ServerInfo, Active)
+ when is_list(ServerInfo) ->
+ Domain = local,
+ socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Method),
+ ServerInfo, Active);
+start(Method, ServerInfo = {Addr, _}, Active)
+ when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+ Domain = inet,
+ socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Method),
+ ServerInfo, Active);
+start(Method, ServerInfo = {Addr, _}, Active)
+ when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+ Domain = inet6,
+ socket_test_ttest_tcp_client:start_monitor(?MOD(Domain, Method),
+ ServerInfo, Active).
-start(Method, Active, Addr, Port, MsgID) ->
- socket_test_ttest_tcp_client:start(?MOD(Method),
- Active, Addr, Port, MsgID).
+start(Method, ServerInfo, Active, MsgID)
+ when is_list(ServerInfo) ->
+ %% This is just a simplification
+ Domain = local,
+ socket_test_ttest_tcp_client:start(?MOD(Domain, Method),
+ ServerInfo, Active, MsgID);
+start(Method, ServerInfo = {Addr, _}, Active, MsgID)
+ when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+ %% This is just a simplification
+ Domain = inet,
+ socket_test_ttest_tcp_client:start(?MOD(Domain, Method),
+ ServerInfo, Active, MsgID);
+start(Method, ServerInfo = {Addr, _}, Active, MsgID)
+ when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+ Domain = inet6,
+ socket_test_ttest_tcp_client:start(?MOD(Domain, Method),
+ ServerInfo, Active, MsgID).
-start(Method, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+start(Method, ServerInfo, Active, MsgID, MaxOutstanding, RunTime)
+ when is_list(ServerInfo) ->
+ Domain = local,
socket_test_ttest_tcp_client:start(false,
- ?MOD(Method),
- Active, Addr, Port,
+ ?MOD(Domain, Method),
+ ServerInfo, Active,
+ MsgID, MaxOutstanding, RunTime);
+start(Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime)
+ when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+ Domain = inet,
+ socket_test_ttest_tcp_client:start(false,
+ ?MOD(Domain, Method),
+ ServerInfo, Active,
+ MsgID, MaxOutstanding, RunTime);
+start(Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime)
+ when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+ Domain = inet6,
+ socket_test_ttest_tcp_client:start(false,
+ ?MOD(Domain, Method),
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime).
-start(Quiet, Method, Active, Addr, Port, MsgID, MaxOutstanding, RunTime) ->
+start(Quiet, Method, ServerInfo, Active, MsgID, MaxOutstanding, RunTime)
+ when is_list(ServerInfo) ->
+ Domain = local,
+ socket_test_ttest_tcp_client:start(Quiet,
+ ?MOD(Domain, Method),
+ ServerInfo, Active,
+ MsgID, MaxOutstanding, RunTime);
+start(Quiet, Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime)
+ when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+ Domain = inet,
+ socket_test_ttest_tcp_client:start(Quiet,
+ ?MOD(Domain, Method),
+ ServerInfo, Active,
+ MsgID, MaxOutstanding, RunTime);
+start(Quiet, Method, ServerInfo = {Addr, _}, Active, MsgID, MaxOutstanding, RunTime)
+ when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+ Domain = inet6,
socket_test_ttest_tcp_client:start(Quiet,
- ?MOD(Method),
- Active, Addr, Port,
+ ?MOD(Domain, Method),
+ ServerInfo, Active,
MsgID, MaxOutstanding, RunTime).
stop(Pid) ->
diff --git a/erts/emulator/test/socket_test_ttest_tcp_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_gen.erl
index 604408c489..05b250e3d9 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_gen.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_gen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,9 +24,9 @@
accept/1, accept/2,
active/2,
close/1,
- connect/2,
+ connect/2, connect/3,
controlling_process/2,
- listen/0, listen/1,
+ listen/0, listen/1, listen/2,
peername/1,
port/1,
recv/2, recv/3,
@@ -80,6 +80,13 @@ close(Sock) ->
connect(Addr, Port) ->
Opts = [binary, {packet, raw}, {active, false}, {buffer, 32*1024}],
+ do_connect(Addr, Port, Opts).
+
+connect(Addr, Port, #{domain := Domain}) ->
+ Opts = [Domain, binary, {packet, raw}, {active, false}, {buffer, 32*1024}],
+ do_connect(Addr, Port, Opts).
+
+do_connect(Addr, Port, Opts) ->
case gen_tcp:connect(Addr, Port, Opts) of
{ok, Sock} ->
{ok, Sock};
@@ -95,8 +102,12 @@ controlling_process(Sock, NewPid) ->
listen() ->
listen(0).
-listen(Port) when is_integer(Port) andalso (Port >= 0) ->
- Opts = [binary, {ip, {0,0,0,0}}, {packet, raw}, {active, false},
+listen(Port) ->
+ listen(Port, #{domain => inet}).
+
+listen(Port, #{domain := Domain}) when is_integer(Port) andalso (Port >= 0) ->
+ Opts = [Domain,
+ binary, {ip, {0,0,0,0}}, {packet, raw}, {active, false},
{buffer, 32*1024}],
case gen_tcp:listen(Port, Opts) of
{ok, Sock} ->
diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl
index e8d626e3d8..e916fcb93e 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_server.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -96,8 +96,9 @@ do_start(Parent, Transport, Active)
(is_atom(Transport) orelse is_tuple(Transport)) andalso
(is_boolean(Active) orelse (Active =:= once)) ->
Starter = self(),
- ServerInit = fun() -> put(sname, "server"),
- server_init(Starter, Parent, Transport, Active)
+ ServerInit = fun() ->
+ put(sname, "server"),
+ server_init(Starter, Parent, Transport, Active)
end,
{Pid, MRef} = spawn_monitor(ServerInit),
receive
@@ -126,17 +127,29 @@ server_init(Starter, Parent, Transport, Active) ->
case Listen(0) of
{ok, LSock} ->
case Mod:port(LSock) of
- {ok, Port} ->
- Addr = which_addr(), % This is just for convenience
- ?I("listening on:"
- "~n Addr: ~p (~s)"
- "~n Port: ~w"
- "~n", [Addr, inet:ntoa(Addr), Port]),
- Starter ! {?MODULE, self(), {ok, {Addr, Port}}},
+ {ok, PortOrPath} ->
+ Result =
+ if
+ is_integer(PortOrPath) ->
+ %% This is just for convenience
+ Addr = which_addr(),
+ ?I("listening on:"
+ "~n Addr: ~p (~s)"
+ "~n Port: ~w"
+ "~n", [Addr, inet:ntoa(Addr), PortOrPath]),
+ {Addr, PortOrPath};
+ is_list(PortOrPath) ->
+ ?I("listening on:"
+ "~n Path: ~s"
+ "~n", [PortOrPath]),
+ PortOrPath
+ end,
+ Starter ! {?MODULE, self(), {ok, Result}},
server_loop(#{parent => Parent,
mod => Mod,
active => Active,
lsock => LSock,
+ port_or_path => PortOrPath,
handlers => [],
stats_interval => StatsInterval,
%% Accumulation
@@ -208,7 +221,9 @@ format_peername({Addr, Port}) ->
?F("~s (~s:~w)", [N, inet:ntoa(Addr), Port]);
{error, _} ->
?F("~p, ~p", [Addr, Port])
- end.
+ end;
+format_peername(Path) when is_list(Path) ->
+ Path.
maybe_start_stats_timer(#{active := Active, stats_interval := Time}, Handler)
when (Active =/= false) andalso (is_integer(Time) andalso (Time > 0)) ->
@@ -219,7 +234,10 @@ maybe_start_stats_timer(_, _) ->
start_stats_timer(Time, ProcStr, Pid) ->
erlang:start_timer(Time, self(), {stats, Time, ProcStr, Pid}).
-server_handle_message(#{parent := Parent, handlers := H} = State) ->
+server_handle_message(#{mod := Mod,
+ lsock := LSock,
+ parent := Parent,
+ handlers := H} = State) ->
receive
{timeout, _TRef, {stats, Interval, ProcStr, Pid}} ->
case server_handle_stats(ProcStr, Pid) of
@@ -233,6 +251,7 @@ server_handle_message(#{parent := Parent, handlers := H} = State) ->
{?MODULE, Ref, Parent, stop} ->
reply(Parent, Ref, ok),
lists:foreach(fun(P) -> handler_stop(P) end, H),
+ (catch Mod:close(LSock)),
exit(normal);
{'DOWN', _MRef, process, Pid, Reason} ->
@@ -272,28 +291,26 @@ server_handle_handler_down(Pid,
AccMCnt2 = AccMCnt + MCnt,
AccBCnt2 = AccBCnt + BCnt,
AccHCnt2 = AccHCnt + 1,
- ?I("handler ~p (~w) done => accumulated results: "
- "~n Run Time: ~s ms"
+ MsgCount2Str =
+ fun(RT, ART, MC, AMC) when (RT > 0) ->
+ ?F("~w => ~w (~w) msgs / ms", [MC, MC div RT, AMC div ART]);
+ (_, _, MC, AMC) ->
+ ?F("~w (~w)", [MC, AMC])
+ end,
+ ByteCount2Str =
+ fun(RT, ART, BC, ABC) when (RT > 0) ->
+ ?F("~w => ~w (~w) bytes / ms", [BC, BC div RT, ABC div ART]);
+ (_, _, BC, ABC) ->
+ ?F("~w", [BC, ABC])
+ end,
+ ?I("handler ~p (~w) done: "
+ "~n Run Time: ~s"
"~n Message Count: ~s"
"~n Byte Count: ~s",
[Pid, AccHCnt2,
- ?FORMAT_TIME(AccRunTime2),
- if (AccRunTime2 > 0) ->
- ?F("~w => ~w (~w) msgs / ms",
- [AccMCnt2,
- AccMCnt2 div AccRunTime2,
- (AccMCnt2 div AccHCnt2) div AccRunTime2]);
- true ->
- ?F("~w", [AccMCnt2])
- end,
- if (AccRunTime2 > 0) ->
- ?F("~w => ~w (~w) bytes / ms",
- [AccBCnt2,
- AccBCnt2 div AccRunTime2,
- (AccBCnt2 div AccHCnt2) div AccRunTime2]);
- true ->
- ?F("~w", [AccBCnt2])
- end]),
+ ?FORMAT_TIME(RunTime),
+ MsgCount2Str(RunTime, AccRunTime2, MCnt, AccMCnt2),
+ ByteCount2Str(RunTime, AccRunTime2, BCnt, AccBCnt2)]),
State#{runtime => AccRunTime2,
mcnt => AccMCnt2,
bcnt => AccBCnt2,
diff --git a/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl b/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl
index b1b31f5158..fdf40f1369 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_server_gen.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,20 +21,18 @@
-module(socket_test_ttest_tcp_server_gen).
-export([
- start/1,
+ start/1, start/2,
stop/1
]).
-define(TRANSPORT_MOD, socket_test_ttest_tcp_gen).
+-define(MOD(D), {?TRANSPORT_MOD, #{domain => D}}).
start(Active) ->
- socket_test_ttest_tcp_server:start(?TRANSPORT_MOD, Active).
- %% {ok, {Pid, AddrPort}} ->
- %% MRef = erlang:monitor(process, Pid),
- %% {ok, {Pid, MRef, AddrPort}};
- %% {error, _} = ERROR ->
- %% ERROR
- %% end.
+ start(inet, Active).
+
+start(Domain, Active) ->
+ socket_test_ttest_tcp_server:start(?MOD(Domain), Active).
stop(Pid) ->
diff --git a/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl
index b7ea1e8e93..d1de230637 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_server_socket.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -21,23 +21,18 @@
-module(socket_test_ttest_tcp_server_socket).
-export([
- start/2,
+ start/3,
stop/1
]).
-define(TRANSPORT_MOD, socket_test_ttest_tcp_socket).
-%% -define(MOD(M), {?TRANSPORT_MOD, #{method => M,
+%% -define(MOD(D, M), {?TRANSPORT_MOD, #{domain => D,
+%% method => M,
%% stats_interval => 10000}}).
--define(MOD(M), {?TRANSPORT_MOD, #{method => M}}).
+-define(MOD(D, M), {?TRANSPORT_MOD, #{domain => D, method => M}}).
-start(Method, Active) ->
- socket_test_ttest_tcp_server:start(?MOD(Method), Active).
- %% {ok, {Pid, AddrPort}} ->
- %% MRef = erlang:monitor(process, Pid),
- %% {ok, {Pid, MRef, AddrPort}};
- %% {error, _} = ERROR ->
- %% ERROR
- %% end.
+start(Method, Domain, Active) ->
+ socket_test_ttest_tcp_server:start(?MOD(Domain, Method), Active).
stop(Pid) ->
socket_test_ttest_tcp_server:stop(Pid).
diff --git a/erts/emulator/test/socket_test_ttest_tcp_socket.erl b/erts/emulator/test/socket_test_ttest_tcp_socket.erl
index 0ae2412e4c..cf68bfe591 100644
--- a/erts/emulator/test/socket_test_ttest_tcp_socket.erl
+++ b/erts/emulator/test/socket_test_ttest_tcp_socket.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2019. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
accept/1, accept/2,
active/2,
close/1,
- connect/2, connect/3,
+ connect/1, connect/2, connect/3,
controlling_process/2,
listen/0, listen/1, listen/2,
port/1,
@@ -36,6 +36,8 @@
]).
+-define(LIB, socket_test_lib).
+
-define(READER_RECV_TIMEOUT, 1000).
-define(DATA_MSG(Sock, Method, Data),
@@ -97,37 +99,85 @@ active(#{reader := Pid}, NewActive)
close(#{sock := Sock, reader := Pid}) ->
Pid ! {?MODULE, stop},
- socket:close(Sock).
+ Unlink = case socket:sockname(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ fun() -> os:cmd("unlink " ++ Path), ok end;
+ _ ->
+ fun() -> ok end
+ end,
+ Res = socket:close(Sock),
+ Unlink(),
+ Res.
%% Create a socket and connect it to a peer
-connect(Addr, Port) ->
- connect(Addr, Port, #{method => plain}).
-
-connect(Addr, Port, #{method := Method} = Opts) ->
+connect(ServerPath) when is_list(ServerPath) ->
+ Domain = local,
+ ClientPath = mk_unique_path(),
+ LocalSA = #{family => Domain,
+ path => ClientPath},
+ ServerSA = #{family => Domain, path => ServerPath},
+ Opts = #{domain => Domain,
+ proto => default,
+ method => plain},
+ Cleanup = fun() -> os:cmd("unlink " ++ ClientPath), ok end,
+ do_connect(LocalSA, ServerSA, Cleanup, Opts).
+
+connect(Addr, Port) when is_tuple(Addr) andalso is_integer(Port) ->
+ Domain = inet,
+ LocalSA = any,
+ ServerSA = #{family => Domain,
+ addr => Addr,
+ port => Port},
+ Opts = #{domain => Domain,
+ proto => tcp,
+ method => plain},
+ Cleanup = fun() -> ok end,
+ do_connect(LocalSA, ServerSA, Cleanup, Opts);
+connect(ServerPath,
+ #{domain := local = Domain} = Opts)
+ when is_list(ServerPath) ->
+ ClientPath = mk_unique_path(),
+ LocalSA = #{family => Domain,
+ path => ClientPath},
+ ServerSA = #{family => Domain,
+ path => ServerPath},
+ Cleanup = fun() -> os:cmd("unlink " ++ ClientPath), ok end,
+ do_connect(LocalSA, ServerSA, Cleanup, Opts#{proto => default}).
+
+connect(Addr, Port, #{domain := Domain} = Opts) ->
+ LocalSA = any,
+ ServerSA = #{family => Domain,
+ addr => Addr,
+ port => Port},
+ Cleanup = fun() -> ok end,
+ do_connect(LocalSA, ServerSA, Cleanup, Opts#{proto => tcp}).
+
+do_connect(LocalSA, ServerSA, Cleanup, #{domain := Domain,
+ proto := Proto,
+ method := Method} = Opts) ->
try
begin
Sock =
- case socket:open(inet, stream, tcp) of
+ case socket:open(Domain, stream, Proto) of
{ok, S} ->
S;
{error, OReason} ->
throw({error, {open, OReason}})
end,
- case socket:bind(Sock, any) of
+ case socket:bind(Sock, LocalSA) of
{ok, _} ->
ok;
{error, BReason} ->
(catch socket:close(Sock)),
+ Cleanup(),
throw({error, {bind, BReason}})
end,
- SA = #{family => inet,
- addr => Addr,
- port => Port},
- case socket:connect(Sock, SA) of
+ case socket:connect(Sock, ServerSA) of
ok ->
ok;
{error, CReason} ->
(catch socket:close(Sock)),
+ Cleanup(),
throw({error, {connect, CReason}})
end,
Self = self(),
@@ -140,6 +190,9 @@ connect(Addr, Port, #{method := Method} = Opts) ->
ERROR
end.
+mk_unique_path() ->
+ [NodeName | _] = string:tokens(atom_to_list(node()), [$@]),
+ ?LIB:f("/tmp/esock_~s_~w", [NodeName, erlang:system_time(nanosecond)]).
maybe_start_stats_timer(#{stats_to := Pid,
stats_interval := T},
@@ -163,37 +216,57 @@ controlling_process(#{sock := Sock, reader := Pid}, NewPid) ->
%% Create a listen socket
listen() ->
- listen(0, #{method => plain}).
-
-listen(Port) ->
- listen(Port, #{method => plain}).
-listen(Port, #{method := Method} = Opts)
- when (is_integer(Port) andalso (Port >= 0)) andalso
- ((Method =:= plain) orelse (Method =:= msg)) ->
+ listen(0).
+
+listen(Port) when is_integer(Port) ->
+ listen(Port, #{domain => inet, method => plain});
+listen(Path) when is_list(Path) ->
+ listen(Path, #{domain => local, method => plain}).
+
+listen(0, #{domain := local} = Opts) ->
+ listen(mk_unique_path(), Opts);
+listen(Path, #{domain := local = Domain} = Opts)
+ when is_list(Path) andalso (Path =/= []) ->
+ SA = #{family => Domain,
+ path => Path},
+ Cleanup = fun() -> os:cmd("unlink " ++ Path), ok end,
+ do_listen(SA, Cleanup, Opts#{proto => default});
+listen(Port, #{domain := Domain} = Opts)
+ when is_integer(Port) andalso (Port >= 0) ->
+ %% Bind fills in the rest
+ SA = #{family => Domain,
+ port => Port},
+ Cleanup = fun() -> ok end,
+ do_listen(SA, Cleanup, Opts#{proto => tcp}).
+
+do_listen(SA,
+ Cleanup,
+ #{domain := Domain, proto := Proto, method := Method} = Opts)
+ when (Method =:= plain) orelse (Method =:= msg) ->
try
begin
- Sock = case socket:open(inet, stream, tcp) of
+ Sock = case socket:open(Domain, stream, Proto) of
{ok, S} ->
S;
{error, OReason} ->
throw({error, {open, OReason}})
end,
- SA = #{family => inet,
- port => Port},
case socket:bind(Sock, SA) of
{ok, _} ->
ok;
{error, BReason} ->
(catch socket:close(Sock)),
+ Cleanup(),
throw({error, {bind, BReason}})
end,
case socket:listen(Sock) of
ok ->
- ok;
- {error, LReason} ->
+ ok;
+ {error, LReason} ->
(catch socket:close(Sock)),
- throw({error, {listen, LReason}})
- end,
+ Cleanup(),
+ throw({error, {listen, LReason}})
+ end,
{ok, #{sock => Sock, opts => Opts}}
end
catch
@@ -204,6 +277,8 @@ listen(Port, #{method := Method} = Opts)
port(#{sock := Sock}) ->
case socket:sockname(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ {ok, Path};
{ok, #{port := Port}} ->
{ok, Port};
{error, _} = ERROR ->
@@ -213,6 +288,8 @@ port(#{sock := Sock}) ->
peername(#{sock := Sock}) ->
case socket:peername(Sock) of
+ {ok, #{family := local, path := Path}} ->
+ {ok, Path};
{ok, #{addr := Addr, port := Port}} ->
{ok, {Addr, Port}};
{error, _} = ERROR ->
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 27efe10f38..e37aa81b7c 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index 126db66cdd..0f0d8f7a02 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -602,12 +602,13 @@
%% -define(SOCKET_TYPE_RDM, 4).
-define(SOCKET_TYPE_SEQPACKET, 5).
--define(SOCKET_PROTOCOL_IP, 1).
--define(SOCKET_PROTOCOL_TCP, 2).
--define(SOCKET_PROTOCOL_UDP, 3).
--define(SOCKET_PROTOCOL_SCTP, 4).
--define(SOCKET_PROTOCOL_ICMP, 5).
--define(SOCKET_PROTOCOL_IGMP, 6).
+-define(SOCKET_PROTOCOL_DEFAULT, 0).
+-define(SOCKET_PROTOCOL_IP, 1).
+-define(SOCKET_PROTOCOL_TCP, 2).
+-define(SOCKET_PROTOCOL_UDP, 3).
+-define(SOCKET_PROTOCOL_SCTP, 4).
+-define(SOCKET_PROTOCOL_ICMP, 5).
+-define(SOCKET_PROTOCOL_IGMP, 6).
-define(SOCKET_LISTEN_BACKLOG_DEFAULT, 5).
@@ -820,6 +821,7 @@
-define(SOCKET_SUPPORTS_OPTIONS, 16#0001).
-define(SOCKET_SUPPORTS_SCTP, 16#0002).
-define(SOCKET_SUPPORTS_IPV6, 16#0003).
+-define(SOCKET_SUPPORTS_LOCAL, 16#0004).
%% ===========================================================================
@@ -875,18 +877,21 @@ info() ->
-spec supports() -> [{options, supports_options()} |
{sctp, boolean()} |
- {ipv6, boolean()}].
+ {ipv6, boolean()} |
+ {local, boolean()}].
supports() ->
[{options, supports(options)},
{sctp, supports(sctp)},
- {ipv6, supports(ipv6)}].
+ {ipv6, supports(ipv6)},
+ {local, supports(local)}].
-dialyzer({nowarn_function, supports/1}).
-spec supports(options) -> supports_options();
(sctp) -> boolean();
(ipv6) -> boolean();
+ (local) -> boolean();
(Key1) -> false when
Key1 :: term().
@@ -896,6 +901,8 @@ supports(sctp) ->
nif_supports(?SOCKET_SUPPORTS_SCTP);
supports(ipv6) ->
nif_supports(?SOCKET_SUPPORTS_IPV6);
+supports(local) ->
+ nif_supports(?SOCKET_SUPPORTS_LOCAL);
supports(_Key1) ->
false.
@@ -1006,12 +1013,12 @@ supports(_Key1, _Key2, _Key3) ->
Reason :: term().
open(Domain, Type) ->
- open(Domain, Type, null).
+ open(Domain, Type, default).
-spec open(Domain, Type, Protocol) -> {ok, Socket} | {error, Reason} when
Domain :: domain(),
Type :: type(),
- Protocol :: null | protocol(),
+ Protocol :: default | protocol(),
Socket :: socket(),
Reason :: term().
@@ -1021,15 +1028,14 @@ open(Domain, Type, Protocol) ->
-spec open(Domain, Type, Protocol, Extra) -> {ok, Socket} | {error, Reason} when
Domain :: domain(),
Type :: type(),
- Protocol :: null | protocol(),
+ Protocol :: default | protocol(),
Extra :: map(),
Socket :: socket(),
Reason :: term().
-open(Domain, Type, Protocol0, Extra) when is_map(Extra) ->
+open(Domain, Type, Protocol, Extra) when is_map(Extra) ->
try
begin
- Protocol = default_protocol(Protocol0, Type),
EDomain = enc_domain(Domain),
EType = enc_type(Domain, Type),
EProtocol = enc_protocol(Type, Protocol),
@@ -1052,15 +1058,6 @@ open(Domain, Type, Protocol0, Extra) when is_map(Extra) ->
{error, Reason}
end.
-%% Note that this is just a convenience function for when the protocol was
-%% not specified. If its actually specified, then that will be selected.
-%% Also, this only works for the some of the type's (stream, dgram and
-%% seqpacket).
-default_protocol(null, stream) -> tcp;
-default_protocol(null, dgram) -> udp;
-default_protocol(null, seqpacket) -> sctp;
-default_protocol(null, Type) -> throw({error, {no_default_protocol, Type}});
-default_protocol(Protocol, _) -> Protocol.
%% ===========================================================================
@@ -2355,7 +2352,7 @@ peername(#socket{ref = SockRef}) ->
enc_domain(local) -> ?SOCKET_DOMAIN_LOCAL;
enc_domain(inet) -> ?SOCKET_DOMAIN_INET;
enc_domain(inet6) -> ?SOCKET_DOMAIN_INET6;
-enc_domain(Domain) -> throw({error, {invalid_domain, Domain}}).
+enc_domain(Domain) -> invalid_domain(Domain).
-spec enc_type(Domain, Type) -> non_neg_integer() when
Domain :: domain(),
@@ -2366,22 +2363,23 @@ enc_type(_, stream) -> ?SOCKET_TYPE_STREAM;
enc_type(_, dgram) -> ?SOCKET_TYPE_DGRAM;
enc_type(_, raw) -> ?SOCKET_TYPE_RAW;
enc_type(_, seqpacket) -> ?SOCKET_TYPE_SEQPACKET;
-enc_type(_, Type) -> throw({error, {invalid_type, Type}}).
+enc_type(_, Type) -> invalid_type(Type).
-spec enc_protocol(Type, Protocol) -> non_neg_integer() |
{raw, non_neg_integer()} when
Type :: type(),
Protocol :: protocol().
-enc_protocol(dgram, ip) -> ?SOCKET_PROTOCOL_IP;
-enc_protocol(stream, tcp) -> ?SOCKET_PROTOCOL_TCP;
-enc_protocol(dgram, udp) -> ?SOCKET_PROTOCOL_UDP;
-enc_protocol(seqpacket, sctp) -> ?SOCKET_PROTOCOL_SCTP;
-enc_protocol(raw, icmp) -> ?SOCKET_PROTOCOL_ICMP;
-enc_protocol(raw, igmp) -> ?SOCKET_PROTOCOL_IGMP;
+enc_protocol(_, default) -> ?SOCKET_PROTOCOL_DEFAULT;
+enc_protocol(dgram, ip) -> ?SOCKET_PROTOCOL_IP;
+enc_protocol(stream, tcp) -> ?SOCKET_PROTOCOL_TCP;
+enc_protocol(dgram, udp) -> ?SOCKET_PROTOCOL_UDP;
+enc_protocol(seqpacket, sctp) -> ?SOCKET_PROTOCOL_SCTP;
+enc_protocol(raw, icmp) -> ?SOCKET_PROTOCOL_ICMP;
+enc_protocol(raw, igmp) -> ?SOCKET_PROTOCOL_IGMP;
enc_protocol(raw, {raw, P} = RAW) when is_integer(P) -> RAW;
enc_protocol(Type, Proto) ->
- throw({error, {invalid_protocol, {Type, Proto}}}).
+ invalid_protocol(Type, Proto).
-spec enc_send_flags(Flags) -> non_neg_integer() when
@@ -2532,7 +2530,7 @@ enc_setopt_value(otp, rcvbuf, V, _, _, _) when is_integer(V) andalso (V > 0) ->
V;
%% N: Number of reads (when specifying length = 0)
%% V: Size of the "read" buffer
-enc_setopt_value(otp, rcvbuf, {N, BufSz} = V, _, stream = _T, tcp = _P)
+enc_setopt_value(otp, rcvbuf, {N, BufSz} = V, _, stream = _T, _P)
when (is_integer(N) andalso (N > 0)) andalso
(is_integer(BufSz) andalso (BufSz > 0)) ->
V;
@@ -3510,6 +3508,25 @@ tdiff(T1, T2) ->
%%
%% ===========================================================================
+-spec invalid_domain(Domain) -> no_return() when
+ Domain :: term().
+
+invalid_domain(Domain) ->
+ error({invalid_domain, Domain}).
+
+-spec invalid_type(Type) -> no_return() when
+ Type :: term().
+
+invalid_type(Type) ->
+ error({invalid_type, Type}).
+
+-spec invalid_protocol(Type, Proto) -> no_return() when
+ Type :: term(),
+ Proto :: term().
+
+invalid_protocol(Type, Proto) ->
+ error({invalid_protocol, {Type, Proto}}).
+
-spec not_supported(What) -> no_return() when
What :: term().