• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  * conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific prior written
16  * permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <semaphore.h>
33 #include <sys/socket.h>
34 #include <poll.h>
35 #include "It_container_test.h"
36 
37 static const char *SERVER_IP = "127.0.0.1";
38 static const int SERV_PORT = 8002;
39 static const char *SERVER_MSG = "Hi, I'm Tcp Server!";
40 static const char *PEER_MSG = "Hi, I'm Tcp Client!";
41 static const int DATA_LEN = 128;
42 
TcpClient(void * arg)43 static int TcpClient(void *arg)
44 {
45     int ret;
46     int client;
47     char buffer[DATA_LEN];
48     struct sockaddr_in server_addr;
49 
50     client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
51     if (client < 0) {
52         return EXIT_CODE_ERRNO_1;
53     }
54 
55     server_addr.sin_family = AF_INET;
56     server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
57     server_addr.sin_port = htons(SERV_PORT);
58     (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
59 
60     ret = connect(client, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
61                   sizeof(server_addr));
62     if (ret < 0) {
63         return EXIT_CODE_ERRNO_2;
64     }
65 
66     ret = send(client, PEER_MSG, strlen(PEER_MSG) + 1, 0);
67     if (ret < 0) {
68         return EXIT_CODE_ERRNO_3;
69     }
70 
71     ret = recv(client, buffer, sizeof(buffer), 0);
72     if (ret < 0) {
73         return EXIT_CODE_ERRNO_4;
74     }
75 
76     ret = strcmp(buffer, SERVER_MSG);
77     if (ret != 0) {
78         return EXIT_CODE_ERRNO_5;
79     }
80 
81     (void)close(client);
82 
83     return 0;
84 }
85 
ChildFunc(void *)86 static int ChildFunc(void *)
87 {
88     int ret;
89     int server;
90     int status;
91     char *stack = nullptr;
92     char *stackTop = nullptr;
93     char buffer[DATA_LEN];
94     struct sockaddr_in server_addr;
95 
96     server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
97     if (server < 0) {
98         return EXIT_CODE_ERRNO_1;
99     }
100 
101     server_addr.sin_family = AF_INET;
102     server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
103     server_addr.sin_port = htons(SERV_PORT);
104     (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
105 
106     ret = bind(server, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
107                sizeof(server_addr));
108     if (ret < 0) {
109         return EXIT_CODE_ERRNO_2;
110     }
111 
112     ret = listen(server, 1);
113     if (ret < 0) {
114         return EXIT_CODE_ERRNO_3;
115     }
116 
117     stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
118     EXPECT_STRNE(stack, nullptr);
119     stackTop = stack + STACK_SIZE;
120 
121     int arg = CHILD_FUNC_ARG;
122     int pid = clone(TcpClient, stackTop, SIGCHLD, &arg);
123     if (pid == -1) {
124         return EXIT_CODE_ERRNO_4;
125     }
126 
127     int client = accept(server, nullptr, nullptr);
128     if (ret < 0) {
129         return EXIT_CODE_ERRNO_5;
130     }
131 
132     ret = recv(client, buffer, sizeof(buffer), 0);
133     if (ret < 0) {
134         return EXIT_CODE_ERRNO_6;
135     }
136 
137     ret = strcmp(buffer, PEER_MSG);
138     if (ret != 0) {
139         return EXIT_CODE_ERRNO_7;
140     }
141 
142     ret = send(client, SERVER_MSG, strlen(SERVER_MSG) + 1, 0);
143     if (ret < 0) {
144         return EXIT_CODE_ERRNO_8;
145     }
146 
147     (void)close(client);
148     (void)close(server);
149 
150     ret = waitpid(pid, &status, 0);
151     if (ret != pid) {
152         return EXIT_CODE_ERRNO_9;
153     }
154 
155     int exitCode = WEXITSTATUS(status);
156     if (exitCode != 0) {
157         return EXIT_CODE_ERRNO_10;
158     }
159 
160     return 0;
161 }
162 
ItNetContainer006(void)163 void ItNetContainer006(void)
164 {
165     int ret = 0;
166     int status;
167 
168     char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
169     EXPECT_STRNE(stack, nullptr);
170     char *stackTop = stack + STACK_SIZE;
171 
172     int arg = CHILD_FUNC_ARG;
173     int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
174     ASSERT_NE(pid, -1);
175 
176     ret = waitpid(pid, &status, 0);
177     ASSERT_EQ(ret, pid);
178 
179     int exitCode = WEXITSTATUS(status);
180     ASSERT_EQ(exitCode, 0);
181 }
182