1 /*
2 * Copyright (c) 2021-2022 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 "socket_exec.h"
17
18 #include <arpa/inet.h>
19 #include <cerrno>
20 #include <fcntl.h>
21 #include <memory>
22 #include <netinet/tcp.h>
23 #include <poll.h>
24 #include <sys/socket.h>
25 #include <thread>
26 #include <unistd.h>
27
28 #include "context_key.h"
29 #include "event_list.h"
30 #include "netstack_common_utils.h"
31 #include "netstack_log.h"
32 #include "napi_utils.h"
33 #include "securec.h"
34
35 static constexpr const int DEFAULT_BUFFER_SIZE = 8192;
36
37 static constexpr const int DEFAULT_POLL_TIMEOUT = 500; // 0.5 Seconds
38
39 static constexpr const int ADDRESS_INVALID = -1;
40
41 static constexpr const int NO_MEMORY = -2;
42
43 static constexpr const int MSEC_TO_USEC = 1000;
44
45 static constexpr const int MAX_SEC = 999999999;
46
47 namespace OHOS::NetStack::SocketExec {
48 struct MessageData {
49 MessageData() = delete;
MessageDataOHOS::NetStack::SocketExec::MessageData50 MessageData(void *d, size_t l, const SocketRemoteInfo &info) : data(d), len(l), remoteInfo(info) {}
~MessageDataOHOS::NetStack::SocketExec::MessageData51 ~MessageData()
52 {
53 if (data) {
54 free(data);
55 }
56 }
57
58 void *data;
59 size_t len;
60 SocketRemoteInfo remoteInfo;
61 };
62
63 static void
SetIsBound(sa_family_t family,GetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)64 SetIsBound(sa_family_t family, GetStateContext *context, const sockaddr_in *addr4, const sockaddr_in6 *addr6)
65 {
66 if (family == AF_INET) {
67 context->state_.SetIsBound(ntohs(addr4->sin_port) != 0);
68 } else if (family == AF_INET6) {
69 context->state_.SetIsBound(ntohs(addr6->sin6_port) != 0);
70 }
71 }
72
73 static void
SetIsConnected(sa_family_t family,GetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)74 SetIsConnected(sa_family_t family, GetStateContext *context, const sockaddr_in *addr4, const sockaddr_in6 *addr6)
75 {
76 if (family == AF_INET) {
77 context->state_.SetIsConnected(ntohs(addr4->sin_port) != 0);
78 } else if (family == AF_INET6) {
79 context->state_.SetIsConnected(ntohs(addr6->sin6_port) != 0);
80 }
81 }
82
CallbackTemplate(uv_work_t * work,int status)83 template <napi_value (*MakeJsValue)(napi_env, void *)> static void CallbackTemplate(uv_work_t *work, int status)
84 {
85 (void)status;
86
87 auto workWrapper = static_cast<UvWorkWrapper *>(work->data);
88 napi_env env = workWrapper->env;
89 auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
90 std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
91
92 napi_value obj = MakeJsValue(env, workWrapper->data);
93
94 std::pair<napi_value, napi_value> arg = {NapiUtils::GetUndefined(workWrapper->env), obj};
95 workWrapper->manager->Emit(workWrapper->type, arg);
96
97 delete workWrapper;
98 delete work;
99 }
100
MakeError(napi_env env,void * errCode)101 static napi_value MakeError(napi_env env, void *errCode)
102 {
103 auto code = reinterpret_cast<int32_t *>(errCode);
104 auto deleter = [](const int32_t *p) { delete p; };
105 std::unique_ptr<int32_t, decltype(deleter)> handler(code, deleter);
106
107 napi_value err = NapiUtils::CreateObject(env);
108 if (NapiUtils::GetValueType(env, err) != napi_object) {
109 return NapiUtils::GetUndefined(env);
110 }
111 NapiUtils::SetInt32Property(env, err, KEY_ERROR_CODE, *code);
112 return err;
113 }
114
MakeAddressString(sockaddr * addr)115 static std::string MakeAddressString(sockaddr *addr)
116 {
117 if (addr->sa_family == AF_INET) {
118 auto *addr4 = reinterpret_cast<sockaddr_in *>(addr);
119 const char *str = inet_ntoa(addr4->sin_addr);
120 if (str == nullptr || strlen(str) == 0) {
121 return {};
122 }
123 return str;
124 } else if (addr->sa_family == AF_INET6) {
125 auto *addr6 = reinterpret_cast<sockaddr_in6 *>(addr);
126 char str[INET6_ADDRSTRLEN] = {0};
127 if (inet_ntop(AF_INET6, &addr6->sin6_addr, str, INET6_ADDRSTRLEN) == nullptr || strlen(str) == 0) {
128 return {};
129 }
130 return str;
131 }
132 return {};
133 }
134
MakeJsMessageParam(napi_env env,napi_value msgBuffer,SocketRemoteInfo * remoteInfo)135 static napi_value MakeJsMessageParam(napi_env env, napi_value msgBuffer, SocketRemoteInfo *remoteInfo)
136 {
137 napi_value obj = NapiUtils::CreateObject(env);
138 if (NapiUtils::GetValueType(env, obj) != napi_object) {
139 return nullptr;
140 }
141 if (NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
142 NapiUtils::SetNamedProperty(env, obj, KEY_MESSAGE, msgBuffer);
143 }
144 napi_value jsRemoteInfo = NapiUtils::CreateObject(env);
145 if (NapiUtils::GetValueType(env, jsRemoteInfo) != napi_object) {
146 return nullptr;
147 }
148 NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_ADDRESS, remoteInfo->GetAddress());
149 NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_FAMILY, remoteInfo->GetFamily());
150 NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_PORT, remoteInfo->GetPort());
151 NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_SIZE, remoteInfo->GetSize());
152
153 NapiUtils::SetNamedProperty(env, obj, KEY_REMOTE_INFO, jsRemoteInfo);
154 return obj;
155 }
156
MakeMessage(napi_env env,void * para)157 static napi_value MakeMessage(napi_env env, void *para)
158 {
159 auto messageData = reinterpret_cast<MessageData *>(para);
160 auto deleter = [](const MessageData *p) { delete p; };
161 std::unique_ptr<MessageData, decltype(deleter)> handler(messageData, deleter);
162
163 if (messageData->data == nullptr || messageData->len == 0) {
164 return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &messageData->remoteInfo);
165 }
166
167 void *dataHandle = nullptr;
168 napi_value msgBuffer = NapiUtils::CreateArrayBuffer(env, messageData->len, &dataHandle);
169 if (dataHandle == nullptr || !NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
170 return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &messageData->remoteInfo);
171 }
172
173 int result = memcpy_s(dataHandle, messageData->len, messageData->data, messageData->len);
174 if (result != EOK) {
175 NETSTACK_LOGI("copy ret %{public}d", result);
176 return NapiUtils::GetUndefined(env);
177 }
178
179 return MakeJsMessageParam(env, msgBuffer, &messageData->remoteInfo);
180 }
181
OnRecvMessage(EventManager * manager,void * data,size_t len,sockaddr * addr)182 static void OnRecvMessage(EventManager *manager, void *data, size_t len, sockaddr *addr)
183 {
184 if (data == nullptr || len == 0) {
185 return;
186 }
187
188 SocketRemoteInfo remoteInfo;
189 std::string address = MakeAddressString(addr);
190 if (address.empty()) {
191 manager->EmitByUv(EVENT_ERROR, new int32_t(ADDRESS_INVALID), CallbackTemplate<MakeError>);
192 return;
193 }
194 remoteInfo.SetAddress(address);
195 remoteInfo.SetFamily(addr->sa_family);
196 if (addr->sa_family == AF_INET) {
197 auto *addr4 = reinterpret_cast<sockaddr_in *>(addr);
198 remoteInfo.SetPort(ntohs(addr4->sin_port));
199 } else if (addr->sa_family == AF_INET6) {
200 auto *addr6 = reinterpret_cast<sockaddr_in6 *>(addr);
201 remoteInfo.SetPort(ntohs(addr6->sin6_port));
202 }
203 remoteInfo.SetSize(len);
204
205 manager->EmitByUv(EVENT_MESSAGE, new MessageData(data, len, remoteInfo), CallbackTemplate<MakeMessage>);
206 }
207
208 class MessageCallback {
209 public:
210 MessageCallback() = delete;
211
212 virtual ~MessageCallback() = default;
213
MessageCallback(EventManager * manager)214 explicit MessageCallback(EventManager *manager) : manager_(manager) {}
215
216 virtual void OnError(int err) const = 0;
217
218 virtual void OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr) const = 0;
219
220 protected:
221 EventManager *manager_;
222 };
223
224 class TcpMessageCallback final : public MessageCallback {
225 public:
226 TcpMessageCallback() = delete;
227
228 ~TcpMessageCallback() override = default;
229
TcpMessageCallback(EventManager * manager)230 explicit TcpMessageCallback(EventManager *manager) : MessageCallback(manager) {}
231
OnError(int err) const232 void OnError(int err) const override
233 {
234 manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
235 }
236
OnMessage(int sock,void * data,size_t dataLen,sockaddr * addr) const237 void OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr) const override
238 {
239 (void)addr;
240
241 sockaddr sockAddr;
242 socklen_t len = sizeof(sockaddr);
243 int ret = getsockname(sock, &sockAddr, &len);
244 if (ret < 0) {
245 return;
246 }
247
248 if (sockAddr.sa_family == AF_INET) {
249 sockaddr_in addr4 = {0};
250 socklen_t len4 = sizeof(sockaddr_in);
251
252 ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr4), &len4);
253 if (ret < 0) {
254 return;
255 }
256 OnRecvMessage(manager_, data, dataLen, reinterpret_cast<sockaddr *>(&addr4));
257 return;
258 } else if (sockAddr.sa_family == AF_INET6) {
259 sockaddr_in6 addr6 = {0};
260 socklen_t len6 = sizeof(sockaddr_in6);
261
262 ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr6), &len6);
263 if (ret < 0) {
264 return;
265 }
266 OnRecvMessage(manager_, data, dataLen, reinterpret_cast<sockaddr *>(&addr6));
267 return;
268 }
269 }
270 };
271
272 class UdpMessageCallback final : public MessageCallback {
273 public:
274 UdpMessageCallback() = delete;
275
276 ~UdpMessageCallback() override = default;
277
UdpMessageCallback(EventManager * manager)278 explicit UdpMessageCallback(EventManager *manager) : MessageCallback(manager) {}
279
OnError(int err) const280 void OnError(int err) const override
281 {
282 manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
283 }
284
OnMessage(int sock,void * data,size_t dataLen,sockaddr * addr) const285 void OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr) const override
286 {
287 OnRecvMessage(manager_, data, dataLen, addr);
288 }
289 };
290
MakeNonBlock(int sock)291 static bool MakeNonBlock(int sock)
292 {
293 int flags = fcntl(sock, F_GETFL, 0);
294 while (flags == -1 && errno == EINTR) {
295 flags = fcntl(sock, F_GETFL, 0);
296 }
297 if (flags == -1) {
298 NETSTACK_LOGE("make non block failed %{public}s", strerror(errno));
299 return false;
300 }
301 int ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
302 while (ret == -1 && errno == EINTR) {
303 ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
304 }
305 if (ret == -1) {
306 NETSTACK_LOGE("make non block failed %{public}s", strerror(errno));
307 return false;
308 }
309 return true;
310 }
311
PollSendData(int sock,const char * data,size_t size,sockaddr * addr,socklen_t addrLen)312 static bool PollSendData(int sock, const char *data, size_t size, sockaddr *addr, socklen_t addrLen)
313 {
314 int bufferSize = DEFAULT_BUFFER_SIZE;
315 int opt = 0;
316 socklen_t optLen = sizeof(opt);
317 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
318 bufferSize = opt;
319 }
320 int sockType = 0;
321 optLen = sizeof(sockType);
322 if (getsockopt(sock, SOL_SOCKET, SO_TYPE, reinterpret_cast<void *>(&sockType), &optLen) < 0) {
323 NETSTACK_LOGI("get sock opt sock type failed = %{public}s", strerror(errno));
324 return false;
325 }
326
327 auto curPos = data;
328 auto leftSize = size;
329 nfds_t num = 1;
330 pollfd fds[1] = {{0}};
331 fds[0].fd = sock;
332 fds[0].events = 0;
333 fds[0].events |= POLLOUT;
334
335 while (leftSize > 0) {
336 int ret = poll(fds, num, DEFAULT_POLL_TIMEOUT);
337 if (ret == -1) {
338 NETSTACK_LOGE("poll to send failed %{public}s", strerror(errno));
339 return false;
340 }
341 if (ret == 0) {
342 NETSTACK_LOGE("poll to send timeout");
343 return false;
344 }
345
346 size_t sendSize = (sockType == SOCK_STREAM ? leftSize : std::min<size_t>(leftSize, bufferSize));
347 auto sendLen = sendto(sock, curPos, sendSize, 0, addr, addrLen);
348 if (sendLen < 0) {
349 if (errno == EAGAIN) {
350 continue;
351 }
352 NETSTACK_LOGE("send failed %{public}s", strerror(errno));
353 return false;
354 }
355 if (sendLen == 0) {
356 break;
357 }
358 curPos += sendLen;
359 leftSize -= sendLen;
360 }
361
362 if (leftSize != 0) {
363 NETSTACK_LOGE("send not complete");
364 return false;
365 }
366 return true;
367 }
368
ConfirmBufferSize(int sock)369 static int ConfirmBufferSize(int sock)
370 {
371 int bufferSize = DEFAULT_BUFFER_SIZE;
372 int opt = 0;
373 socklen_t optLen = sizeof(opt);
374 if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
375 bufferSize = opt;
376 }
377 return bufferSize;
378 }
379
PollRecvData(int sock,sockaddr * addr,socklen_t addrLen,const MessageCallback & callback)380 static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const MessageCallback &callback)
381 {
382 int bufferSize = ConfirmBufferSize(sock);
383
384 auto deleter = [](char *s) { free(reinterpret_cast<void *>(s)); };
385 std::unique_ptr<char, decltype(deleter)> buf(reinterpret_cast<char *>(malloc(bufferSize)), deleter);
386 if (buf == nullptr) {
387 callback.OnError(NO_MEMORY);
388 return;
389 }
390
391 auto addrDeleter = [](sockaddr *a) { free(reinterpret_cast<void *>(a)); };
392 std::unique_ptr<sockaddr, decltype(addrDeleter)> pAddr(addr, addrDeleter);
393
394 nfds_t num = 1;
395 pollfd fds[1] = {{0}};
396 fds[0].fd = sock;
397 fds[0].events = 0;
398 fds[0].events |= POLLIN;
399
400 while (true) {
401 int ret = poll(fds, num, DEFAULT_POLL_TIMEOUT);
402 if (ret < 0) {
403 NETSTACK_LOGE("poll to recv failed errno is: %{public}d %{public}s", errno, strerror(errno));
404 callback.OnError(errno);
405 return;
406 }
407 if (ret == 0) {
408 continue;
409 }
410 (void)memset_s(buf.get(), bufferSize, 0, bufferSize);
411 socklen_t tempAddrLen = addrLen;
412 auto recvLen = recvfrom(sock, buf.get(), bufferSize, 0, addr, &tempAddrLen);
413 if (recvLen < 0) {
414 if (errno == EAGAIN) {
415 continue;
416 }
417 NETSTACK_LOGE("recv failed errno is: %{public}d %{public}s", errno, strerror(errno));
418 callback.OnError(errno);
419 return;
420 }
421 if (recvLen == 0) {
422 continue;
423 }
424
425 void *data = malloc(recvLen);
426 if (data == nullptr) {
427 callback.OnError(NO_MEMORY);
428 return;
429 }
430 if (memcpy_s(data, recvLen, buf.get(), recvLen) != EOK) {
431 free(data);
432 }
433 callback.OnMessage(sock, data, recvLen, addr);
434 }
435 }
436
NonBlockConnect(int sock,sockaddr * addr,socklen_t addrLen,uint32_t timeoutMSec)437 static bool NonBlockConnect(int sock, sockaddr *addr, socklen_t addrLen, uint32_t timeoutMSec)
438 {
439 int ret = connect(sock, addr, addrLen);
440 if (ret >= 0) {
441 return true;
442 }
443 if (errno != EINPROGRESS) {
444 return false;
445 }
446
447 fd_set set = {0};
448 FD_ZERO(&set);
449 FD_SET(sock, &set);
450 if (timeoutMSec == 0) {
451 timeoutMSec = DEFAULT_CONNECT_TIMEOUT;
452 }
453
454 timeval timeout = {
455 .tv_sec = (timeoutMSec / MSEC_TO_USEC) % MAX_SEC,
456 .tv_usec = (timeoutMSec % MSEC_TO_USEC) * MSEC_TO_USEC,
457 };
458
459 ret = select(sock + 1, nullptr, &set, nullptr, &timeout);
460 if (ret < 0) {
461 NETSTACK_LOGE("select error: %{public}s\n", strerror(errno));
462 return false;
463 } else if (ret == 0) {
464 NETSTACK_LOGE("timeout!");
465 return false;
466 }
467
468 int err = 0;
469 socklen_t optLen = sizeof(err);
470 ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, reinterpret_cast<void *>(&err), &optLen);
471 if (ret < 0) {
472 return false;
473 }
474 if (err != 0) {
475 return false;
476 }
477 return true;
478 }
479
GetAddr(NetAddress * address,sockaddr_in * addr4,sockaddr_in6 * addr6,sockaddr ** addr,socklen_t * len)480 static void GetAddr(NetAddress *address, sockaddr_in *addr4, sockaddr_in6 *addr6, sockaddr **addr, socklen_t *len)
481 {
482 sa_family_t family = address->GetSaFamily();
483 if (family == AF_INET) {
484 addr4->sin_family = AF_INET;
485 addr4->sin_port = htons(address->GetPort());
486 addr4->sin_addr.s_addr = inet_addr(address->GetAddress().c_str());
487 *addr = reinterpret_cast<sockaddr *>(addr4);
488 *len = sizeof(sockaddr_in);
489 } else if (family == AF_INET6) {
490 addr6->sin6_family = AF_INET6;
491 addr6->sin6_port = htons(address->GetPort());
492 inet_pton(AF_INET6, address->GetAddress().c_str(), &addr6->sin6_addr);
493 *addr = reinterpret_cast<sockaddr *>(addr6);
494 *len = sizeof(sockaddr_in6);
495 }
496 }
497
SetBaseOptions(int sock,ExtraOptionsBase * option)498 static bool SetBaseOptions(int sock, ExtraOptionsBase *option)
499 {
500 if (option->GetReceiveBufferSize() != 0) {
501 int size = (int)option->GetReceiveBufferSize();
502 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
503 return false;
504 }
505 }
506
507 if (option->GetSendBufferSize() != 0) {
508 int size = (int)option->GetSendBufferSize();
509 if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
510 return false;
511 }
512 }
513
514 if (option->IsReuseAddress()) {
515 int reuse = 1;
516 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&reuse), sizeof(reuse)) < 0) {
517 return false;
518 }
519 }
520
521 if (option->GetSocketTimeout() != 0) {
522 timeval timeout = {(int)option->GetSocketTimeout(), 0};
523 if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
524 return false;
525 }
526 if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
527 return false;
528 }
529 }
530
531 return true;
532 }
533
MakeTcpSocket(sa_family_t family)534 int MakeTcpSocket(sa_family_t family)
535 {
536 if (family != AF_INET && family != AF_INET6) {
537 return -1;
538 }
539 int sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
540 NETSTACK_LOGD("new tcp socket is %{public}d", sock);
541 if (sock < 0) {
542 NETSTACK_LOGE("make tcp socket failed errno is %{public}d %{public}s", errno, strerror(errno));
543 return -1;
544 }
545 if (!MakeNonBlock(sock)) {
546 close(sock);
547 return -1;
548 }
549 return sock;
550 }
551
MakeUdpSocket(sa_family_t family)552 int MakeUdpSocket(sa_family_t family)
553 {
554 if (family != AF_INET && family != AF_INET6) {
555 return -1;
556 }
557 int sock = socket(family, SOCK_DGRAM, IPPROTO_UDP);
558 NETSTACK_LOGD("new udp socket is %{public}d", sock);
559 if (sock < 0) {
560 NETSTACK_LOGE("make udp socket failed errno is %{public}d %{public}s", errno, strerror(errno));
561 return -1;
562 }
563 if (!MakeNonBlock(sock)) {
564 close(sock);
565 return -1;
566 }
567 return sock;
568 }
569
ExecBind(BindContext * context)570 bool ExecBind(BindContext *context)
571 {
572 sockaddr_in addr4 = {0};
573 sockaddr_in6 addr6 = {0};
574 sockaddr *addr = nullptr;
575 socklen_t len;
576 GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
577 if (addr == nullptr) {
578 NETSTACK_LOGE("addr family error");
579 context->SetErrorCode(ADDRESS_INVALID);
580 return false;
581 }
582
583 if (bind(context->GetSocketFd(), addr, len) < 0) {
584 if (errno != EADDRINUSE) {
585 NETSTACK_LOGE("bind error is %{public}s %{public}d", strerror(errno), errno);
586 context->SetErrorCode(errno);
587 return false;
588 }
589 if (addr->sa_family == AF_INET) {
590 NETSTACK_LOGI("distribute a random port");
591 addr4.sin_port = 0; /* distribute a random port */
592 } else if (addr->sa_family == AF_INET6) {
593 NETSTACK_LOGI("distribute a random port");
594 addr6.sin6_port = 0; /* distribute a random port */
595 }
596 if (bind(context->GetSocketFd(), addr, len) < 0) {
597 NETSTACK_LOGE("rebind error is %{public}s %{public}d", strerror(errno), errno);
598 context->SetErrorCode(errno);
599 return false;
600 }
601 NETSTACK_LOGI("rebind success");
602 }
603 NETSTACK_LOGI("bind success");
604
605 return true;
606 }
607
ExecUdpBind(BindContext * context)608 bool ExecUdpBind(BindContext *context)
609 {
610 if (!ExecBind(context)) {
611 return false;
612 }
613
614 sockaddr_in addr4 = {0};
615 sockaddr_in6 addr6 = {0};
616 sockaddr *addr = nullptr;
617 socklen_t len;
618 GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
619 if (addr == nullptr) {
620 NETSTACK_LOGE("addr family error");
621 context->SetErrorCode(ADDRESS_INVALID);
622 return false;
623 }
624
625 if (addr->sa_family == AF_INET) {
626 auto pAddr4 = reinterpret_cast<sockaddr *>(malloc(sizeof(addr4)));
627 if (pAddr4 == nullptr) {
628 NETSTACK_LOGE("no memory!");
629 return false;
630 }
631 NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr4, sizeof(addr4), &addr4, sizeof(addr4)));
632 std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr4, sizeof(addr4),
633 UdpMessageCallback(context->GetManager()));
634 serviceThread.detach();
635 } else if (addr->sa_family == AF_INET6) {
636 auto pAddr6 = reinterpret_cast<sockaddr *>(malloc(sizeof(addr6)));
637 if (pAddr6 == nullptr) {
638 NETSTACK_LOGE("no memory!");
639 return false;
640 }
641 NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr6, sizeof(addr6), &addr6, sizeof(addr6)));
642 std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr6, sizeof(addr6),
643 UdpMessageCallback(context->GetManager()));
644 serviceThread.detach();
645 }
646
647 return true;
648 }
649
ExecUdpSend(UdpSendContext * context)650 bool ExecUdpSend(UdpSendContext *context)
651 {
652 if (!CommonUtils::HasInternetPermission()) {
653 context->SetPermissionDenied(true);
654 return false;
655 }
656
657 sockaddr_in addr4 = {0};
658 sockaddr_in6 addr6 = {0};
659 sockaddr *addr = nullptr;
660 socklen_t len;
661 GetAddr(&context->options.address, &addr4, &addr6, &addr, &len);
662 if (addr == nullptr) {
663 NETSTACK_LOGE("addr family error");
664 context->SetErrorCode(ADDRESS_INVALID);
665 return false;
666 }
667
668 if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(),
669 addr, len)) {
670 context->SetErrorCode(errno);
671 return false;
672 }
673 return true;
674 }
675
ExecTcpBind(BindContext * context)676 bool ExecTcpBind(BindContext *context)
677 {
678 return ExecBind(context);
679 }
680
ExecConnect(ConnectContext * context)681 bool ExecConnect(ConnectContext *context)
682 {
683 if (!CommonUtils::HasInternetPermission()) {
684 context->SetPermissionDenied(true);
685 return false;
686 }
687
688 sockaddr_in addr4 = {0};
689 sockaddr_in6 addr6 = {0};
690 sockaddr *addr = nullptr;
691 socklen_t len;
692 GetAddr(&context->options.address, &addr4, &addr6, &addr, &len);
693 if (addr == nullptr) {
694 NETSTACK_LOGE("addr family error");
695 context->SetErrorCode(ADDRESS_INVALID);
696 return false;
697 }
698
699 if (!NonBlockConnect(context->GetSocketFd(), addr, len, context->options.GetTimeout())) {
700 NETSTACK_LOGE("connect errno %{public}d %{public}s", errno, strerror(errno));
701 context->SetErrorCode(errno);
702 return false;
703 }
704
705 NETSTACK_LOGI("connect success");
706 std::thread serviceThread(PollRecvData, context->GetSocketFd(), nullptr, 0,
707 TcpMessageCallback(context->GetManager()));
708 serviceThread.detach();
709 return true;
710 }
711
ExecTcpSend(TcpSendContext * context)712 bool ExecTcpSend(TcpSendContext *context)
713 {
714 if (!CommonUtils::HasInternetPermission()) {
715 context->SetPermissionDenied(true);
716 return false;
717 }
718
719 std::string encoding = context->options.GetEncoding();
720 (void)encoding;
721 /* no use for now */
722
723 sockaddr sockAddr;
724 socklen_t len = sizeof(sockaddr);
725 if (getsockname(context->GetSocketFd(), &sockAddr, &len) < 0) {
726 NETSTACK_LOGE("get sock name failed");
727 context->SetErrorCode(ADDRESS_INVALID);
728 return false;
729 }
730 bool connected = false;
731 if (sockAddr.sa_family == AF_INET) {
732 sockaddr_in addr4 = {0};
733 socklen_t len4 = sizeof(addr4);
734 int ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr4), &len4);
735 if (ret >= 0 && addr4.sin_port != 0) {
736 connected = true;
737 }
738 } else if (sockAddr.sa_family == AF_INET6) {
739 sockaddr_in6 addr6 = {0};
740 socklen_t len6 = sizeof(addr6);
741 int ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr6), &len6);
742 if (ret >= 0 && addr6.sin6_port != 0) {
743 connected = true;
744 }
745 }
746
747 if (!connected) {
748 NETSTACK_LOGE("sock is not connect to remote %{public}s", strerror(errno));
749 context->SetErrorCode(errno);
750 return false;
751 }
752
753 if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(),
754 nullptr, 0)) {
755 NETSTACK_LOGE("send errno %{public}d %{public}s", errno, strerror(errno));
756 context->SetErrorCode(errno);
757 return false;
758 }
759 return true;
760 }
761
ExecClose(CloseContext * context)762 bool ExecClose(CloseContext *context)
763 {
764 if (!CommonUtils::HasInternetPermission()) {
765 context->SetPermissionDenied(true);
766 return false;
767 }
768
769 (void)context;
770
771 return true;
772 }
773
ExecGetState(GetStateContext * context)774 bool ExecGetState(GetStateContext *context)
775 {
776 if (!CommonUtils::HasInternetPermission()) {
777 context->SetPermissionDenied(true);
778 return false;
779 }
780
781 int opt;
782 socklen_t optLen = sizeof(int);
783 int r = getsockopt(context->GetSocketFd(), SOL_SOCKET, SO_TYPE, &opt, &optLen);
784 if (r < 0) {
785 context->state_.SetIsClose(true);
786 return true;
787 }
788
789 sockaddr sockAddr;
790 socklen_t len = sizeof(sockaddr);
791 int ret = getsockname(context->GetSocketFd(), &sockAddr, &len);
792 if (ret < 0) {
793 context->SetErrorCode(errno);
794 return false;
795 }
796
797 sockaddr_in addr4 = {0};
798 sockaddr_in6 addr6 = {0};
799 sockaddr *addr = nullptr;
800 socklen_t addrLen;
801 if (sockAddr.sa_family == AF_INET) {
802 addr = reinterpret_cast<sockaddr *>(&addr4);
803 addrLen = sizeof(addr4);
804 } else if (sockAddr.sa_family == AF_INET6) {
805 addr = reinterpret_cast<sockaddr *>(&addr6);
806 addrLen = sizeof(addr6);
807 }
808
809 if (addr == nullptr) {
810 context->SetErrorCode(ADDRESS_INVALID);
811 return false;
812 }
813
814 (void)memset_s(addr, addrLen, 0, addrLen);
815 len = addrLen;
816 ret = getsockname(context->GetSocketFd(), addr, &len);
817 if (ret < 0) {
818 context->SetErrorCode(errno);
819 return false;
820 }
821
822 SetIsBound(sockAddr.sa_family, context, &addr4, &addr6);
823
824 if (opt != SOCK_STREAM) {
825 return true;
826 }
827
828 (void)memset_s(addr, addrLen, 0, addrLen);
829 len = addrLen;
830 (void)getpeername(context->GetSocketFd(), addr, &len);
831 SetIsConnected(sockAddr.sa_family, context, &addr4, &addr6);
832 return true;
833 }
834
ExecGetRemoteAddress(GetRemoteAddressContext * context)835 bool ExecGetRemoteAddress(GetRemoteAddressContext *context)
836 {
837 if (!CommonUtils::HasInternetPermission()) {
838 context->SetPermissionDenied(true);
839 return false;
840 }
841
842 sockaddr sockAddr;
843 socklen_t len = sizeof(sockaddr);
844 int ret = getsockname(context->GetSocketFd(), &sockAddr, &len);
845 if (ret < 0) {
846 context->SetErrorCode(errno);
847 return false;
848 }
849
850 if (sockAddr.sa_family == AF_INET) {
851 sockaddr_in addr4 = {0};
852 socklen_t len4 = sizeof(sockaddr_in);
853
854 ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr4), &len4);
855 if (ret < 0) {
856 context->SetErrorCode(errno);
857 return false;
858 }
859
860 std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr4));
861 if (address.empty()) {
862 context->SetErrorCode(ADDRESS_INVALID);
863 return false;
864 }
865 context->address_.SetAddress(address);
866 context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
867 context->address_.SetPort(ntohs(addr4.sin_port));
868 return true;
869 } else if (sockAddr.sa_family == AF_INET6) {
870 sockaddr_in6 addr6 = {0};
871 socklen_t len6 = sizeof(sockaddr_in6);
872
873 ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr6), &len6);
874 if (ret < 0) {
875 context->SetErrorCode(errno);
876 return false;
877 }
878
879 std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr6));
880 if (address.empty()) {
881 context->SetErrorCode(ADDRESS_INVALID);
882 return false;
883 }
884 context->address_.SetAddress(address);
885 context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
886 context->address_.SetPort(ntohs(addr6.sin6_port));
887 return true;
888 }
889
890 return false;
891 }
892
ExecTcpSetExtraOptions(TcpSetExtraOptionsContext * context)893 bool ExecTcpSetExtraOptions(TcpSetExtraOptionsContext *context)
894 {
895 if (!CommonUtils::HasInternetPermission()) {
896 context->SetPermissionDenied(true);
897 return false;
898 }
899
900 if (!SetBaseOptions(context->GetSocketFd(), &context->options_)) {
901 context->SetErrorCode(errno);
902 return false;
903 }
904
905 if (context->options_.IsKeepAlive()) {
906 int keepalive = 1;
907 if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) {
908 context->SetErrorCode(errno);
909 return false;
910 }
911 }
912
913 if (context->options_.IsOOBInline()) {
914 int oobInline = 1;
915 if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_OOBINLINE, &oobInline, sizeof(oobInline)) < 0) {
916 context->SetErrorCode(errno);
917 return false;
918 }
919 }
920
921 if (context->options_.IsTCPNoDelay()) {
922 int tcpNoDelay = 1;
923 if (setsockopt(context->GetSocketFd(), IPPROTO_TCP, TCP_NODELAY, &tcpNoDelay, sizeof(tcpNoDelay)) < 0) {
924 context->SetErrorCode(errno);
925 return false;
926 }
927 }
928
929 linger soLinger = {0};
930 soLinger.l_onoff = context->options_.socketLinger.IsOn();
931 soLinger.l_linger = (int)context->options_.socketLinger.GetLinger();
932 if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger)) < 0) {
933 context->SetErrorCode(errno);
934 return false;
935 }
936
937 return true;
938 }
939
ExecUdpSetExtraOptions(UdpSetExtraOptionsContext * context)940 bool ExecUdpSetExtraOptions(UdpSetExtraOptionsContext *context)
941 {
942 if (!CommonUtils::HasInternetPermission()) {
943 context->SetPermissionDenied(true);
944 return false;
945 }
946
947 if (!SetBaseOptions(context->GetSocketFd(), &context->options)) {
948 context->SetErrorCode(errno);
949 return false;
950 }
951
952 if (context->options.IsBroadcast()) {
953 int broadcast = 1;
954 if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
955 context->SetErrorCode(errno);
956 return false;
957 }
958 }
959
960 return true;
961 }
962
BindCallback(BindContext * context)963 napi_value BindCallback(BindContext *context)
964 {
965 context->Emit(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
966 NapiUtils::GetUndefined(context->GetEnv())));
967 return NapiUtils::GetUndefined(context->GetEnv());
968 }
969
UdpSendCallback(UdpSendContext * context)970 napi_value UdpSendCallback(UdpSendContext *context)
971 {
972 return NapiUtils::GetUndefined(context->GetEnv());
973 }
974
ConnectCallback(ConnectContext * context)975 napi_value ConnectCallback(ConnectContext *context)
976 {
977 context->Emit(EVENT_CONNECT, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
978 NapiUtils::GetUndefined(context->GetEnv())));
979 return NapiUtils::GetUndefined(context->GetEnv());
980 }
981
TcpSendCallback(TcpSendContext * context)982 napi_value TcpSendCallback(TcpSendContext *context)
983 {
984 return NapiUtils::GetUndefined(context->GetEnv());
985 }
986
CloseCallback(CloseContext * context)987 napi_value CloseCallback(CloseContext *context)
988 {
989 int ret = close(context->GetSocketFd());
990 if (ret < 0) {
991 NETSTACK_LOGE("sock closed error %{public}s sock = %{public}d, ret = %{public}d", strerror(errno),
992 context->GetSocketFd(), ret);
993 } else {
994 NETSTACK_LOGI("sock %{public}d closed success", context->GetSocketFd());
995 }
996 context->SetSocketFd(0);
997 context->Emit(EVENT_CLOSE, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
998 NapiUtils::GetUndefined(context->GetEnv())));
999 return NapiUtils::GetUndefined(context->GetEnv());
1000 }
1001
GetStateCallback(GetStateContext * context)1002 napi_value GetStateCallback(GetStateContext *context)
1003 {
1004 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1005 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1006 return NapiUtils::GetUndefined(context->GetEnv());
1007 }
1008
1009 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
1010 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
1011 NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
1012
1013 return obj;
1014 }
1015
GetRemoteAddressCallback(GetRemoteAddressContext * context)1016 napi_value GetRemoteAddressCallback(GetRemoteAddressContext *context)
1017 {
1018 napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1019 if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1020 return NapiUtils::GetUndefined(context->GetEnv());
1021 }
1022
1023 NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
1024 NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
1025 NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
1026
1027 return obj;
1028 }
1029
TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext * context)1030 napi_value TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext *context)
1031 {
1032 return NapiUtils::GetUndefined(context->GetEnv());
1033 }
1034
UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext * context)1035 napi_value UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext *context)
1036 {
1037 return NapiUtils::GetUndefined(context->GetEnv());
1038 }
1039 } // namespace OHOS::NetStack::SocketExec
1040