1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi/native_api.h"
17 #include <arpa/inet.h>
18 #include <js_native_api_types.h>
19 #include <netinet/in.h>
20 #include <cstdlib>
21 #include <sys/socket.h>
22 #include <unistd.h>
23 #include <cstdio>
24 #include <cerrno>
25 #include <cstring>
26 
27 #define PARAM_5 5
28 #define PARAM_6000 6000
29 #define PARAM_6002 6002
30 #define PARAM_6004 6004
31 #define PARAM_8000 8000
32 
33 #define PARAM_0 0
34 #define PARAM_1 1
35 #define PARAM_2 2
36 #define PARAM_UNNORMAL (-1)
37 #define FAILD (-1)
38 #define SIZE_10 10
39 #define SIZE_100 100
40 
Socket(napi_env env, napi_callback_info info)41 static napi_value Socket(napi_env env, napi_callback_info info)
42 {
43     int result = socket(AF_INET, SOCK_STREAM, PARAM_0);
44     napi_value results = nullptr;
45     napi_create_int32(env, result, &results);
46     return results;
47 }
48 
Bind(napi_env env, napi_callback_info info)49 static napi_value Bind(napi_env env, napi_callback_info info)
50 {
51     napi_value result = nullptr;
52     int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
53     struct sockaddr_in server = {PARAM_0};
54     server.sin_family = AF_INET;
55     server.sin_port = htons(PARAM_8000);
56     server.sin_addr.s_addr = inet_addr("127.0.0.1");
57     int ret = bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)), sizeof(server));
58     close(sockfd);
59     napi_create_int32(env, ret, &result);
60     return result;
61 }
62 
Listen(napi_env env, napi_callback_info info)63 static napi_value Listen(napi_env env, napi_callback_info info)
64 {
65     napi_value result = nullptr;
66     int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
67     struct sockaddr_in local = {PARAM_0};
68     local.sin_family = AF_INET;
69     local.sin_port = htons(PARAM_6000);
70     local.sin_addr.s_addr = inet_addr("192.168.59.65");
71     bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
72     int ret = listen(sockfd, PARAM_5);
73     close(sockfd);
74     napi_create_int32(env, ret, &result);
75     return result;
76 }
77 
Connect(napi_env env, napi_callback_info info)78 static napi_value Connect(napi_env env, napi_callback_info info)
79 {
80     napi_value result = nullptr;
81     int ret = PARAM_1;
82     if (fork() == PARAM_0) {
83         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
84         if (sockfd >= PARAM_0) {
85             struct sockaddr_in local = {PARAM_0};
86             local.sin_family = AF_INET;
87             local.sin_port = htons(PARAM_6002);
88             local.sin_addr.s_addr = inet_addr("127.0.0.1");
89             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
90             listen(sockfd, PARAM_5);
91             struct sockaddr_in clnAddr = {PARAM_0};
92             socklen_t clnAddrLen = sizeof(clnAddr);
93             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
94         }
95         close(sockfd);
96         _exit(PARAM_0);
97     } else {
98         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
99         if (sock >= PARAM_0) {
100             struct sockaddr_in server = {PARAM_0};
101             server.sin_family = AF_INET;
102             server.sin_port = htons(PARAM_6002);
103             server.sin_addr.s_addr = inet_addr("127.0.0.1");
104             while (ret) {
105                 ret = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
106                               sizeof(server));
107             }
108         }
109         close(sock);
110     }
111     napi_create_int32(env, ret, &result);
112     return result;
113 }
114 
Send(napi_env env, napi_callback_info info)115 static napi_value Send(napi_env env, napi_callback_info info)
116 {
117     napi_value result = nullptr;
118     int ret = PARAM_1;
119     if (fork() == PARAM_0) {
120         int sockfd = socket(AF_INET, SOCK_STREAM, PARAM_0);
121         if (sockfd >= PARAM_0) {
122             struct sockaddr_in local = {PARAM_0};
123             local.sin_family = AF_INET;
124             local.sin_port = htons(PARAM_6004);
125             local.sin_addr.s_addr = inet_addr("127.0.0.1");
126             bind(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&local)), sizeof(local));
127             listen(sockfd, PARAM_5);
128             struct sockaddr_in clnAddr = {PARAM_0};
129             socklen_t clnAddrLen = sizeof(clnAddr);
130             accept(sockfd, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&clnAddr)), &clnAddrLen);
131         }
132         close(sockfd);
133         _exit(PARAM_0);
134     } else {
135         int sock = socket(AF_INET, SOCK_STREAM, PARAM_0);
136         if (sock >= PARAM_0) {
137             struct sockaddr_in server = {PARAM_0};
138             server.sin_family = AF_INET;
139             server.sin_port = htons(PARAM_6004);
140             server.sin_addr.s_addr = inet_addr("127.0.0.1");
141             int conn = PARAM_1;
142             while (conn) {
143                 conn = connect(sock, reinterpret_cast<sockaddr *>(static_cast<struct sockaddr_in *>(&server)),
144                                sizeof(server));
145             }
146             char sendBuf[] = "x";
147             ret = send(sock, sendBuf, sizeof(sendBuf), PARAM_0);
148         }
149         close(sock);
150     }
151     napi_create_int32(env, ret, &result);
152     return result;
153 }
154 
Recv(napi_env env, napi_callback_info info)155 static napi_value Recv(napi_env env, napi_callback_info info)
156 {
157     size_t argc = PARAM_1;
158     napi_value args[1] = {nullptr};
159     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
160     int param = PARAM_0;
161     napi_get_value_int32(env, args[0], &param);
162 
163     int resultValue = FAILD;
164     if (param == PARAM_UNNORMAL) {
165         size_t dataLen = atoi("11");
166         char buf[SIZE_10];
167         resultValue = recv(PARAM_0, buf, dataLen, PARAM_0);
168     } else {
169         char buf[SIZE_100];
170         int sockets[PARAM_2];
171         socketpair(AF_UNIX, SOCK_STREAM, PARAM_0, sockets);
172         send(sockets[PARAM_1], "x", PARAM_1, PARAM_0);
173         resultValue = recv(sockets[PARAM_0], buf, sizeof buf, PARAM_0);
174     }
175 
176     napi_value result = nullptr;
177 
178     napi_create_int32(env, resultValue, &result);
179     return result;
180 }
181 
182 EXTERN_C_START
Init(napi_env env, napi_value exports)183 static napi_value Init(napi_env env, napi_value exports)
184 {
185     napi_property_descriptor desc[] = {
186         {"Socket", nullptr, Socket, nullptr, nullptr, nullptr, napi_default, nullptr},
187         {"Listen", nullptr, Listen, nullptr, nullptr, nullptr, napi_default, nullptr},
188         {"Bind", nullptr, Bind, nullptr, nullptr, nullptr, napi_default, nullptr},
189         {"Connect", nullptr, Connect, nullptr, nullptr, nullptr, napi_default, nullptr},
190         {"Send", nullptr, Send, nullptr, nullptr, nullptr, napi_default, nullptr},
191         {"Recv", nullptr, Recv, nullptr, nullptr, nullptr, napi_default, nullptr},
192     };
193     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
194     return exports;
195 }
196 EXTERN_C_END
197 
198 static napi_module demoModule = {
199     .nm_version = 1,
200     .nm_flags = 0,
201     .nm_filename = nullptr,
202     .nm_register_func = Init,
203     .nm_modname = "pcsNetworkTest",
204     .nm_priv = ((void *)0),
205     .reserved = {0},
206 };
207 
RegisterEntryModule(void)208 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
209