1 /*
2  * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "_main.h"
8 
happy_path(struct net_socketpair_fixture * fixture,const int family,const char * family_s,const int type,const char * type_s,const int proto,const char * proto_s)9 static void happy_path(
10 	struct net_socketpair_fixture *fixture,
11 	const int family, const char *family_s,
12 	const int type, const char *type_s,
13 	const int proto, const char *proto_s
14 )
15 {
16 	int res;
17 
18 	const char *expected_msg = "Hello, socketpair(2) world!";
19 	const unsigned int expected_msg_len = strlen(expected_msg);
20 	char actual_msg[32];
21 	size_t actual_msg_len;
22 	struct iovec iovec;
23 	struct msghdr msghdr;
24 	socklen_t len;
25 
26 	/* sockets are bidirectional. test functions from both ends */
27 	for (int i = 0; i < 2; ++i) {
28 
29 		/*
30 		 * Test with send() / recv()
31 		 */
32 
33 		res = zsock_send(fixture->sv[i], expected_msg, expected_msg_len, 0);
34 
35 		zassert_not_equal(res, -1, "send() failed: %d", errno);
36 		actual_msg_len = res;
37 		zassert_equal(actual_msg_len, expected_msg_len,
38 				  "did not send entire message");
39 
40 		memset(actual_msg, 0, sizeof(actual_msg));
41 
42 		res = zsock_recv(fixture->sv[(!i) & 1], actual_msg, sizeof(actual_msg), 0);
43 
44 		zassert_not_equal(res, -1, "recv() failed: %d", errno);
45 		actual_msg_len = res;
46 		zassert_equal(actual_msg_len, expected_msg_len,
47 			      "wrong return value");
48 
49 		zassert_true(strncmp(expected_msg, actual_msg,
50 			actual_msg_len) == 0,
51 			"the wrong message was passed through the socketpair");
52 
53 		/*
54 		 * Test with sendto(2) / recvfrom(2)
55 		 */
56 
57 		res = zsock_sendto(fixture->sv[i], expected_msg, expected_msg_len, 0, NULL, 0);
58 
59 		zassert_not_equal(res, -1, "sendto() failed: %d", errno);
60 		actual_msg_len = res;
61 		zassert_equal(actual_msg_len, expected_msg_len,
62 				  "did not sendto entire message");
63 
64 		memset(actual_msg, 0, sizeof(actual_msg));
65 
66 		len = 0;
67 		res = zsock_recvfrom(fixture->sv[(!i) & 1], actual_msg, sizeof(actual_msg), 0,
68 				     NULL, &len);
69 		zassert_true(res >= 0, "recvfrom() failed: %d", errno);
70 		actual_msg_len = res;
71 		zassert_equal(actual_msg_len, expected_msg_len,
72 			      "wrong return value");
73 
74 		zassert_true(strncmp(expected_msg, actual_msg,
75 			actual_msg_len) == 0,
76 			"the wrong message was passed through the socketpair");
77 
78 		/*
79 		 * Test with sendmsg(2) / recv(2) - Zephyr lacks recvmsg atm
80 		 */
81 
82 		memset(&msghdr, 0, sizeof(msghdr));
83 		msghdr.msg_iov = &iovec;
84 		msghdr.msg_iovlen = 1;
85 		iovec.iov_base = (void *)expected_msg;
86 		iovec.iov_len = expected_msg_len;
87 
88 		res = zsock_sendmsg(fixture->sv[i], &msghdr, 0);
89 
90 		zassert_not_equal(res, -1, "sendmsg() failed: %d", errno);
91 		actual_msg_len = res;
92 		zassert_equal(actual_msg_len, expected_msg_len,
93 				  "did not sendmsg entire message");
94 
95 		res = zsock_recv(fixture->sv[(!i) & 1], actual_msg, sizeof(actual_msg), 0);
96 
97 		zassert_not_equal(res, -1, "recv() failed: %d", errno);
98 		actual_msg_len = res;
99 		zassert_equal(actual_msg_len, expected_msg_len,
100 			      "wrong return value");
101 
102 		zassert_true(strncmp(expected_msg, actual_msg,
103 			actual_msg_len) == 0,
104 			"the wrong message was passed through the socketpair");
105 	}
106 }
107 
ZTEST_USER_F(net_socketpair,test_AF_LOCAL_SOCK_STREAM_0)108 ZTEST_USER_F(net_socketpair, test_AF_LOCAL_SOCK_STREAM_0)
109 {
110 	happy_path(
111 		fixture,
112 		AF_LOCAL, "AF_LOCAL",
113 		SOCK_STREAM, "SOCK_STREAM",
114 		0, "0"
115 	);
116 }
117 
ZTEST_USER_F(net_socketpair,test_AF_UNIX_SOCK_STREAM_0)118 ZTEST_USER_F(net_socketpair, test_AF_UNIX_SOCK_STREAM_0)
119 {
120 	happy_path(
121 		fixture,
122 		AF_UNIX, "AF_UNIX",
123 		SOCK_STREAM, "SOCK_STREAM",
124 		0, "0"
125 	);
126 }
127