• 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 = 8000;
41 static const char *PEER_IP = "192.168.100.5";
42 static const int PEER_PORT = 8001;
43 static const int DATA_LEN = 128;
44 static const char *SERVER_MSG = "===Hi, I'm Server.===";
45 static const char *PEER_MSG = "===Hi, I'm Peer.===";
46 static const int TRY_COUNT = 5;
47 
UdpClient(void)48 static int UdpClient(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     struct sockaddr_in peer_addr;
56 
57     peer = socket(AF_INET, SOCK_DGRAM, 0);
58     if (peer < 0) {
59         return EXIT_CODE_ERRNO_1;
60     }
61 
62     server_addr.sin_family = AF_INET;
63     server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
64     server_addr.sin_port = htons(SERVER_PORT);
65     (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
66 
67     peer_addr.sin_family = AF_INET;
68     peer_addr.sin_addr.s_addr = inet_addr(PEER_IP);
69     peer_addr.sin_port = htons(PEER_PORT);
70     (void)memset_s(&(peer_addr.sin_zero), sizeof(peer_addr.sin_zero), 0, sizeof(peer_addr.sin_zero));
71 
72     ret = bind(peer, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&peer_addr)),
73                sizeof(struct sockaddr));
74     if (ret != 0) {
75         return EXIT_CODE_ERRNO_2;
76     }
77 
78     timeval tv = {1, 0};
79     ret = setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO, const_cast<void *>(reinterpret_cast<void *>(&tv)), sizeof(timeval));
80 
81     /* loop try util server is ready */
82     while (try_count--) {
83         ret = sendto(peer, PEER_MSG, strlen(PEER_MSG) + 1, 0,
84                      const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
85                      (socklen_t)sizeof(server_addr));
86         if (ret == -1) {
87             continue;
88         }
89         ret = recvfrom(peer, recv_data, DATA_LEN, 0, nullptr, nullptr);
90         if (ret != -1) {
91             break;
92         }
93     }
94     if (ret < 0) {
95         return EXIT_CODE_ERRNO_3;
96     }
97 
98     (void)close(peer);
99 
100     ret = strcmp(recv_data, SERVER_MSG);
101     if (ret != 0) {
102         return EXIT_CODE_ERRNO_4;
103     }
104 
105     return 0;
106 }
107 
ChildFunc(void * arg)108 static int ChildFunc(void *arg)
109 {
110     int ret = NetContainerResetNetAddr(IFNAME, PEER_IP, NETMASK, GW);
111     if (ret != 0) {
112         return EXIT_CODE_ERRNO_1;
113     }
114 
115     return UdpClient();
116 }
117 
UdpServer(void)118 static int UdpServer(void)
119 {
120     int ret = 0;
121     int server;
122     int try_count = TRY_COUNT;
123     char recv_data[DATA_LEN];
124     struct sockaddr_in server_addr;
125     struct sockaddr_in peer_addr;
126     socklen_t peer_addr_len = sizeof(struct sockaddr);
127 
128     server = socket(AF_INET, SOCK_DGRAM, 0);
129     if (server < 0) {
130         return EXIT_CODE_ERRNO_1;
131     }
132 
133     server_addr.sin_family = AF_INET;
134     server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
135     server_addr.sin_port = htons(SERVER_PORT);
136     (void)memset_s(&(server_addr.sin_zero), sizeof(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
137 
138     ret = bind(server, const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&server_addr)),
139                sizeof(struct sockaddr));
140     if (ret != 0) {
141         return EXIT_CODE_ERRNO_2;
142     }
143 
144     ret = recvfrom(server, recv_data, DATA_LEN, 0, reinterpret_cast<struct sockaddr *>(&peer_addr), &peer_addr_len);
145     if (ret < 0) {
146         return EXIT_CODE_ERRNO_3;
147     }
148 
149     ret = sendto(server, SERVER_MSG, strlen(SERVER_MSG) + 1, 0,
150                  const_cast<struct sockaddr *>(reinterpret_cast<struct sockaddr *>(&peer_addr)), peer_addr_len);
151     if (ret < 0) {
152         return EXIT_CODE_ERRNO_4;
153     }
154 
155     (void)close(server);
156 
157     ret = strcmp(recv_data, PEER_MSG);
158     if (ret != 0) {
159         return EXIT_CODE_ERRNO_5;
160     }
161 
162     return ret;
163 }
164 
UdpServerThread(void * arg)165 static void *UdpServerThread(void *arg)
166 {
167     int ret = NetContainerResetNetAddr(IFNAME, SERVER_IP, NETMASK, GW);
168     if (ret != 0) {
169         return (void *)(intptr_t)ret;
170     }
171 
172     ret = UdpServer();
173 
174     return (void *)(intptr_t)ret;
175 }
176 
ItNetContainer005(void)177 void ItNetContainer005(void)
178 {
179     int ret = 0;
180     int status;
181     void *tret = nullptr;
182     pthread_t srv;
183     pthread_attr_t attr;
184 
185     ret = pthread_attr_init(&attr);
186     ASSERT_EQ(ret, 0);
187 
188     ret = pthread_create(&srv, &attr, UdpServerThread, nullptr);
189     ASSERT_EQ(ret, 0);
190 
191     char *stack = (char *)mmap(nullptr, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
192     EXPECT_STRNE(stack, nullptr);
193     char *stackTop = stack + STACK_SIZE;
194 
195     int arg = CHILD_FUNC_ARG;
196     auto pid = clone(ChildFunc, stackTop, SIGCHLD | CLONE_NEWNET, &arg);
197     ASSERT_NE(pid, -1);
198 
199     ret = waitpid(pid, &status, 0);
200     ASSERT_EQ(ret, pid);
201 
202     int exitCode = WEXITSTATUS(status);
203     ASSERT_EQ(exitCode, 0);
204 
205     ret = pthread_join(srv, &tret);
206     ASSERT_EQ(ret, 0);
207 
208     ret = pthread_attr_destroy(&attr);
209     ASSERT_EQ(ret, 0);
210 }
211