• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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