• 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 <net/if.h>
33 #include <net/route.h>
34 #include "It_container_test.h"
35 
36 static const char *NETMASK = "255.255.255.0";
37 static const char *GW = "192.168.100.1";
38 static const char *IFNAME = "veth0";
39 static const char *SERVER_IP = "192.168.100.6";
40 static const int SERVER_PORT = 8005;
41 static const char *PEER_IP = "192.168.100.5";
42 static const char *SERVER_MSG = "===Hi, I'm Server.===";
43 static const char *PEER_MSG = "===Hi, I'm Peer.===";
44 static const int TRY_COUNT = 5;
45 static const int DATA_LEN = 128;
46 static const int IpLen = 16;
47 
TcpClient(void)48 static int TcpClient(void)
49 {
50     int ret = 0;
51     int peer;
52     int try_count = TRY_COUNT;
53     char recv_data[DATA_LEN];
54     struct sockaddr_in server_addr;
55 
56     peer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
57     if (peer < 0) {
58         return EXIT_CODE_ERRNO_1;
59     }
60 
61     server_addr.sin_family = AF_INET;
62     server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
63     server_addr.sin_port = htons(SERVER_PORT);
64     (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
65 
66     do {
67         sleep(1);
68         ret = connect(peer, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
69                       sizeof(struct sockaddr));
70     } while (ret !=0 && (try_count--));
71 
72     if (ret < 0) {
73         (void)close(peer);
74         printf("[ERR][%s:%d] connect failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
75         return EXIT_CODE_ERRNO_2;
76     }
77 
78     ret = send(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0);
79     if (ret < 0) {
80         (void)close(peer);
81         printf("[ERR][%s:%d] send failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
82         return EXIT_CODE_ERRNO_3;
83     }
84 
85     ret = recv(peer, recv_data, sizeof(recv_data), 0);
86     if (ret < 0) {
87         (void)close(peer);
88         printf("[ERR][%s:%d] recv failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
89         return EXIT_CODE_ERRNO_4;
90     }
91     (void)close(peer);
92 
93     ret = strcmp(recv_data, SERVER_MSG);
94     if (ret != 0) {
95         return EXIT_CODE_ERRNO_5;
96     }
97     return 0;
98 }
99 
TcpServer(void)100 static int TcpServer(void)
101 {
102     int ret = 0;
103     int server;
104     int peer;
105     char recv_data[DATA_LEN];
106     struct sockaddr_in server_addr;
107 
108     server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
109     if (server < 0) {
110         return EXIT_CODE_ERRNO_1;
111     }
112 
113     server_addr.sin_family = AF_INET;
114     server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
115     server_addr.sin_port = htons(SERVER_PORT);
116     (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
117 
118     ret = bind(server, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
119                sizeof(struct sockaddr));
120     if (ret != 0) {
121         printf("[ERR][%s:%d] bind failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
122         return EXIT_CODE_ERRNO_2;
123     }
124 
125     ret = listen(server, 1);
126     if (ret < 0) {
127         printf("[ERR][%s:%d] listen failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
128         return EXIT_CODE_ERRNO_3;
129     }
130 
131     peer = accept(server, nullptr, nullptr);
132     if (peer < 0) {
133         printf("[ERR][%s:%d] accept failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
134         return EXIT_CODE_ERRNO_4;
135     }
136 
137     (void)close(server);
138 
139     ret = recv(peer, recv_data, sizeof(recv_data), 0);
140     if (ret < 0) {
141         printf("[ERR][%s:%d] recv failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
142         return EXIT_CODE_ERRNO_5;
143     }
144 
145     ret = strcmp(recv_data, PEER_MSG);
146     if (ret != 0) {
147         return EXIT_CODE_ERRNO_6;
148     }
149 
150     ret = send(peer, SERVER_MSG, strlen(SERVER_MSG) + 1, 0);
151     if (ret < 0) {
152         printf("[ERR][%s:%d] send failed, %s!\n", __FUNCTION__, __LINE__, strerror(errno));
153         return EXIT_CODE_ERRNO_7;
154     }
155 
156     (void)close(peer);
157     return 0;
158 }
159 
TcpClientThread(void * arg)160 static void *TcpClientThread(void *arg)
161 {
162     char newIp[IpLen] = {NULL};
163     int ret = NetContainerResetNetAddr(IFNAME, PEER_IP, NETMASK, GW);
164     if (ret != 0) {
165         return (void *)(intptr_t)EXIT_CODE_ERRNO_1;
166     }
167 
168     ret = NetContainerGetLocalIP(IFNAME, newIp, IpLen);
169     if (ret != 0) {
170         return (void *)(intptr_t)EXIT_CODE_ERRNO_2;
171     }
172 
173     if (strncmp(PEER_IP, newIp, strlen(PEER_IP)) != 0) {
174         return (void *)(intptr_t)EXIT_CODE_ERRNO_3;
175     }
176     printf("######## [%s:%d] %s: %s ########\n", __FUNCTION__, __LINE__, IFNAME, newIp);
177 
178     ret = TcpClient();
179     return (void *)(intptr_t)ret;
180 }
181 
ChildFunc(void * arg)182 static int ChildFunc(void *arg)
183 {
184     char newIp[IpLen] = {NULL};
185     int ret = NetContainerResetNetAddr(IFNAME, SERVER_IP, NETMASK, GW);
186     if (ret != 0) {
187         return EXIT_CODE_ERRNO_8;
188     }
189 
190     ret = NetContainerGetLocalIP(IFNAME, newIp, IpLen);
191     if (ret != 0) {
192         return EXIT_CODE_ERRNO_9;
193     }
194 
195     if (strncmp(SERVER_IP, newIp, strlen(SERVER_IP)) != 0) {
196         return EXIT_CODE_ERRNO_10;
197     }
198 
199     printf("######## [%s:%d] %s: %s ########\n", __FUNCTION__, __LINE__, IFNAME, newIp);
200     return TcpServer();
201 }
202 
ItNetContainer009(void)203 VOID ItNetContainer009(void)
204 {
205     int ret = 0;
206     int status;
207     void *tret = nullptr;
208     pthread_t srv;
209     pthread_attr_t attr;
210 
211     char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
212     EXPECT_STRNE(stack, nullptr);
213     char *stackTop = stack + STACK_SIZE;
214 
215     int arg = CHILD_FUNC_ARG;
216     int pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
217     ASSERT_NE(pid, -1);
218 
219     ret = pthread_attr_init(&attr);
220     ASSERT_EQ(ret, 0);
221 
222     ret = pthread_create(&srv, &attr, TcpClientThread, nullptr);
223     ASSERT_EQ(ret, 0);
224 
225     ret = pthread_join(srv, &tret);
226     ASSERT_EQ(ret, 0);
227 
228     ret = (uintptr_t)tret;
229     ASSERT_EQ(ret, 0);
230 
231     ret = pthread_attr_destroy(&attr);
232     ASSERT_EQ(ret, 0);
233 
234     ret = waitpid(pid, &status, 0);
235     ASSERT_EQ(ret, pid);
236 
237     int exitCode = WEXITSTATUS(status);
238     ASSERT_EQ(exitCode, 0);
239 }
240