1 /*
2  * Copyright (c) 2021-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 "socket_exec.h"
17 
18 #include <arpa/inet.h>
19 #include <atomic>
20 #include <cerrno>
21 #include <condition_variable>
22 #include <fcntl.h>
23 #include <map>
24 #include <memory>
25 #include <mutex>
26 #include <netinet/tcp.h>
27 #include <poll.h>
28 #include <sys/socket.h>
29 #include <thread>
30 #include <unistd.h>
31 
32 #include "context_key.h"
33 #include "event_list.h"
34 #include "napi_utils.h"
35 #include "netstack_common_utils.h"
36 #include "netstack_log.h"
37 #include "securec.h"
38 #include "socket_async_work.h"
39 #include "socket_module.h"
40 #include "socket_exec_common.h"
41 
42 #ifdef IOS_PLATFORM
43 #define SO_PROTOCOL 38
44 #endif
45 
46 static constexpr const int DEFAULT_BUFFER_SIZE = 8192;
47 
48 static constexpr const int MAX_SOCKET_BUFFER_SIZE = 262144;
49 
50 static constexpr const int DEFAULT_TIMEOUT_MS = 20000;
51 
52 static constexpr const int DEFAULT_POLL_TIMEOUT = 500; // 0.5 Seconds
53 
54 static constexpr const int ADDRESS_INVALID = 99;
55 
56 static constexpr const int OTHER_ERROR = 100;
57 
58 static constexpr const int UNKNOW_ERROR = -1;
59 
60 static constexpr const int NO_MEMORY = -2;
61 
62 static constexpr const int USER_LIMIT = 511;
63 
64 static constexpr const int MAX_CLIENTS = 1024;
65 
66 static constexpr const int ERRNO_BAD_FD = 9;
67 
68 static constexpr const int UNIT_CONVERSION_1000 = 1000;
69 
70 static constexpr const char *TCP_SOCKET_CONNECTION = "TCPSocketConnection";
71 
72 static constexpr const char *TCP_SERVER_ACCEPT_RECV_DATA = "OS_NET_SockRD";
73 
74 static constexpr const char *TCP_SERVER_HANDLE_CLIENT = "OS_NET_SockAcc";
75 
76 static constexpr const char *SOCKET_EXEC_UDP_BIND = "OS_NET_SockUPRD";
77 
78 static constexpr const char *SOCKET_EXEC_CONNECT = "OS_NET_SockTPRD";
79 
80 static constexpr const char *SOCKET_RECV_FROM_MULTI_CAST = "OS_NET_SockMPRD";
81 
82 namespace OHOS::NetStack::Socket::SocketExec {
83 #define ERROR_RETURN(context, ...) \
84     do { \
85         NETSTACK_LOGE(__VA_ARGS__); \
86         context->SetErrorCode(errno); \
87         context->SetExecOK(false); \
88         return false; \
89     } while (0)
90 
91 std::map<int32_t, int32_t> g_clientFDs;
92 std::map<int32_t, EventManager *> g_clientEventManagers;
93 std::condition_variable g_cv;
94 std::mutex g_mutex;
95 std::atomic_int g_userCounter = 0;
96 
SetIsBound(sa_family_t family,GetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)97 static void SetIsBound(sa_family_t family, GetStateContext *context, const sockaddr_in *addr4,
98                        const sockaddr_in6 *addr6)
99 {
100     if (family == AF_INET) {
101         context->state_.SetIsBound(ntohs(addr4->sin_port) != 0);
102     } else if (family == AF_INET6) {
103         context->state_.SetIsBound(ntohs(addr6->sin6_port) != 0);
104     }
105 }
106 
SetIsConnected(sa_family_t family,GetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)107 static void SetIsConnected(sa_family_t family, GetStateContext *context, const sockaddr_in *addr4,
108                            const sockaddr_in6 *addr6)
109 {
110     if (family == AF_INET) {
111         context->state_.SetIsConnected(ntohs(addr4->sin_port) != 0);
112     } else if (family == AF_INET6) {
113         context->state_.SetIsConnected(ntohs(addr6->sin6_port) != 0);
114     }
115 }
116 
MakeError(napi_env env,void * errCode)117 static napi_value MakeError(napi_env env, void *errCode)
118 {
119     auto code = reinterpret_cast<int32_t *>(errCode);
120     auto deleter = [](const int32_t *p) { delete p; };
121     std::unique_ptr<int32_t, decltype(deleter)> handler(code, deleter);
122 
123     napi_value err = NapiUtils::CreateObject(env);
124     if (NapiUtils::GetValueType(env, err) != napi_object) {
125         return NapiUtils::GetUndefined(env);
126     }
127     NapiUtils::SetInt32Property(env, err, KEY_ERROR_CODE, *code);
128     return err;
129 }
130 
MakeClose(napi_env env,void * data)131 static napi_value MakeClose(napi_env env, void *data)
132 {
133     (void)data;
134     NETSTACK_LOGI("go to MakeClose");
135     napi_value obj = NapiUtils::CreateObject(env);
136     if (NapiUtils::GetValueType(env, obj) != napi_object) {
137         return NapiUtils::GetUndefined(env);
138     }
139 
140     return obj;
141 }
142 
TcpServerConnectionFinalize(napi_env,void * data,void *)143 void TcpServerConnectionFinalize(napi_env, void *data, void *)
144 {
145     NETSTACK_LOGI("socket handle is finalized");
146     auto manager = static_cast<EventManager *>(data);
147     if (manager != nullptr) {
148         NETSTACK_LOGI("manager != nullpt");
149         int clientIndex = -1;
150         std::lock_guard<std::mutex> lock(g_mutex);
151         for (auto it = g_clientEventManagers.begin(); it != g_clientEventManagers.end(); ++it) {
152             if (it->second == manager) {
153                 clientIndex = it->first;
154                 g_clientEventManagers.erase(it);
155                 break;
156             }
157         }
158         auto clientIter = g_clientFDs.find(clientIndex);
159         if (clientIter != g_clientFDs.end()) {
160             if (clientIter->second != -1) {
161                 NETSTACK_LOGI("close socketfd %{public}d", clientIter->second);
162                 shutdown(clientIter->second, SHUT_RDWR);
163                 clientIter->second = -1;
164             }
165         }
166     }
167     EventManager::SetInvalid(manager);
168 }
169 
NotifyRegisterEvent()170 void NotifyRegisterEvent()
171 {
172     std::lock_guard<std::mutex> lock(g_mutex);
173     g_cv.notify_one();
174 }
175 
NewInstanceWithConstructor(napi_env env,napi_callback_info info,napi_value jsConstructor,int32_t counter)176 napi_value NewInstanceWithConstructor(napi_env env, napi_callback_info info, napi_value jsConstructor, int32_t counter)
177 {
178     napi_value result = nullptr;
179     NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
180 
181     EventManager *manager = new EventManager();
182     {
183         std::lock_guard<std::mutex> lock(g_mutex);
184         g_clientEventManagers.insert(std::pair<int32_t, EventManager *>(counter, manager));
185         g_cv.notify_one();
186     }
187 
188     manager->SetData(reinterpret_cast<void *>(counter));
189     EventManager::SetValid(manager);
190     napi_wrap(env, result, reinterpret_cast<void *>(manager), TcpServerConnectionFinalize, nullptr, nullptr);
191     return result;
192 } // namespace OHOS::NetStack::Socket::SocketExec
193 
ConstructTCPSocketConnection(napi_env env,napi_callback_info info,int32_t counter)194 napi_value ConstructTCPSocketConnection(napi_env env, napi_callback_info info, int32_t counter)
195 {
196     napi_value jsConstructor = nullptr;
197     std::initializer_list<napi_property_descriptor> properties = {
198         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_SEND,
199                               SocketModuleExports::TCPConnection::Send),
200         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_CLOSE,
201                               SocketModuleExports::TCPConnection::Close),
202         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_GET_REMOTE_ADDRESS,
203                               SocketModuleExports::TCPConnection::GetRemoteAddress),
204         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_GET_LOCAL_ADDRESS,
205                               SocketModuleExports::TCPConnection::GetLocalAddress),
206         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_ON, SocketModuleExports::TCPConnection::On),
207         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_OFF,
208                               SocketModuleExports::TCPConnection::Off),
209     };
210 
211     auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
212         napi_value thisVal = nullptr;
213         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
214 
215         return thisVal;
216     };
217 
218     napi_property_descriptor descriptors[properties.size()];
219     std::copy(properties.begin(), properties.end(), descriptors);
220 
221     NAPI_CALL_BASE(env,
222                    napi_define_class(env, TCP_SOCKET_CONNECTION, NAPI_AUTO_LENGTH, constructor, nullptr,
223                                      properties.size(), descriptors, &jsConstructor),
224                    NapiUtils::GetUndefined(env));
225 
226     if (jsConstructor != nullptr) {
227         napi_value result = NewInstanceWithConstructor(env, info, jsConstructor, counter);
228         NapiUtils::SetInt32Property(env, result, SocketModuleExports::TCPConnection::PROPERTY_CLIENT_ID, counter);
229         return result;
230     }
231     return NapiUtils::GetUndefined(env);
232 }
233 
MakeTcpConnectionMessage(napi_env env,void * para)234 static napi_value MakeTcpConnectionMessage(napi_env env, void *para)
235 {
236     auto netConnection = reinterpret_cast<TcpConnection *>(para);
237     auto deleter = [](const TcpConnection *p) { delete p; };
238     std::unique_ptr<TcpConnection, decltype(deleter)> handler(netConnection, deleter);
239 
240     napi_callback_info info = nullptr;
241     return ConstructTCPSocketConnection(env, info, netConnection->clientId);
242 }
243 
MakeAddressString(sockaddr * addr)244 static std::string MakeAddressString(sockaddr *addr)
245 {
246     if (addr->sa_family == AF_INET) {
247         auto *addr4 = reinterpret_cast<sockaddr_in *>(addr);
248         const char *str = inet_ntoa(addr4->sin_addr);
249         if (str == nullptr || strlen(str) == 0) {
250             return {};
251         }
252         return str;
253     } else if (addr->sa_family == AF_INET6) {
254         auto *addr6 = reinterpret_cast<sockaddr_in6 *>(addr);
255         char str[INET6_ADDRSTRLEN] = {0};
256         if (inet_ntop(AF_INET6, &addr6->sin6_addr, str, INET6_ADDRSTRLEN) == nullptr || strlen(str) == 0) {
257             return {};
258         }
259         return str;
260     }
261     return {};
262 }
263 
MakeJsMessageParam(napi_env env,napi_value msgBuffer,SocketRemoteInfo * remoteInfo)264 static napi_value MakeJsMessageParam(napi_env env, napi_value msgBuffer, SocketRemoteInfo *remoteInfo)
265 {
266     napi_value obj = NapiUtils::CreateObject(env);
267     if (NapiUtils::GetValueType(env, obj) != napi_object) {
268         return nullptr;
269     }
270     if (NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
271         NapiUtils::SetNamedProperty(env, obj, KEY_MESSAGE, msgBuffer);
272     }
273     napi_value jsRemoteInfo = NapiUtils::CreateObject(env);
274     if (NapiUtils::GetValueType(env, jsRemoteInfo) != napi_object) {
275         return nullptr;
276     }
277     NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_ADDRESS, remoteInfo->GetAddress());
278     NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_FAMILY, remoteInfo->GetFamily());
279     NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_PORT, remoteInfo->GetPort());
280     NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_SIZE, remoteInfo->GetSize());
281 
282     NapiUtils::SetNamedProperty(env, obj, KEY_REMOTE_INFO, jsRemoteInfo);
283     return obj;
284 }
285 
MakeMessage(napi_env env,void * para)286 static napi_value MakeMessage(napi_env env, void *para)
287 {
288     auto manager = reinterpret_cast<EventManager *>(para);
289     auto messageData = reinterpret_cast<MessageData *>(manager->GetQueueData());
290     auto deleter = [](const MessageData *p) { delete p; };
291     std::unique_ptr<MessageData, decltype(deleter)> handler(messageData, deleter);
292 
293     if (messageData == nullptr) {
294         SocketRemoteInfo remoteInfo;
295         return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &remoteInfo);
296     }
297 
298     if (messageData->data == nullptr || messageData->len == 0) {
299         return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &messageData->remoteInfo);
300     }
301 
302     void *dataHandle = nullptr;
303     napi_value msgBuffer = NapiUtils::CreateArrayBuffer(env, messageData->len, &dataHandle);
304     if (dataHandle == nullptr || !NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
305         return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &messageData->remoteInfo);
306     }
307 
308     int result = memcpy_s(dataHandle, messageData->len, messageData->data, messageData->len);
309     if (result != EOK) {
310         NETSTACK_LOGI("copy ret %{public}d", result);
311         return NapiUtils::GetUndefined(env);
312     }
313 
314     return MakeJsMessageParam(env, msgBuffer, &messageData->remoteInfo);
315 }
316 
OnRecvMessage(EventManager * manager,void * data,size_t len,sockaddr * addr)317 static bool OnRecvMessage(EventManager *manager, void *data, size_t len, sockaddr *addr)
318 {
319     if (data == nullptr || len == 0) {
320         return false;
321     }
322 
323     SocketRemoteInfo remoteInfo;
324     std::string address = MakeAddressString(addr);
325     if (address.empty()) {
326         manager->EmitByUv(EVENT_ERROR, new int32_t(ADDRESS_INVALID), CallbackTemplate<MakeError>);
327         return false;
328     }
329     remoteInfo.SetAddress(address);
330     remoteInfo.SetFamily(addr->sa_family);
331     if (addr->sa_family == AF_INET) {
332         auto *addr4 = reinterpret_cast<sockaddr_in *>(addr);
333         remoteInfo.SetPort(ntohs(addr4->sin_port));
334     } else if (addr->sa_family == AF_INET6) {
335         auto *addr6 = reinterpret_cast<sockaddr_in6 *>(addr);
336         remoteInfo.SetPort(ntohs(addr6->sin6_port));
337     }
338     remoteInfo.SetSize(len);
339 
340     auto *messageStruct = new MessageData(data, len, remoteInfo);
341     if (EventManager::IsManagerValid(manager)) {
342         manager->SetQueueData(reinterpret_cast<void *>(messageStruct));
343         manager->EmitByUv(EVENT_MESSAGE, manager, CallbackTemplate<MakeMessage>);
344         return true;
345     }
346     return false;
347 }
348 
GetEventManager() const349 EventManager *MessageCallback::GetEventManager() const
350 {
351     return manager_;
352 }
353 
354 class TcpMessageCallback final : public MessageCallback {
355 public:
356     TcpMessageCallback() = delete;
357 
358     ~TcpMessageCallback() override = default;
359 
TcpMessageCallback(EventManager * manager)360     explicit TcpMessageCallback(EventManager *manager) : MessageCallback(manager) {}
361 
OnError(int err) const362     void OnError(int err) const override
363     {
364         if (EventManager::IsManagerValid(manager_)) {
365             manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
366             return;
367         }
368         NETSTACK_LOGI("tcp socket handle has been finalized, manager is invalid");
369     }
370 
OnCloseMessage(EventManager * manager) const371     void OnCloseMessage(EventManager *manager) const override
372     {
373         manager->EmitByUv(EVENT_CLOSE, nullptr, CallbackTemplate<MakeClose>);
374     }
375 
OnMessage(void * data,size_t dataLen,sockaddr * addr) const376     bool OnMessage(void *data, size_t dataLen, sockaddr *addr) const override
377     {
378         (void)addr;
379         if (!EventManager::IsManagerValid(manager_)) {
380             NETSTACK_LOGE("invalid manager");
381             return false;
382         }
383         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData()));
384         if (sock == 0) {
385             return false;
386         }
387         sockaddr sockAddr = {0};
388         socklen_t len = sizeof(sockaddr);
389         int ret = getsockname(sock, &sockAddr, &len);
390         if (ret < 0) {
391             return false;
392         }
393 
394         if (sockAddr.sa_family == AF_INET) {
395             sockaddr_in addr4 = {0};
396             socklen_t len4 = sizeof(sockaddr_in);
397 
398             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr4), &len4);
399             if (ret < 0) {
400                 return false;
401             }
402             return OnRecvMessage(manager_, data, dataLen, reinterpret_cast<sockaddr *>(&addr4));
403         } else if (sockAddr.sa_family == AF_INET6) {
404             sockaddr_in6 addr6 = {0};
405             socklen_t len6 = sizeof(sockaddr_in6);
406 
407             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr6), &len6);
408             if (ret < 0) {
409                 return false;
410             }
411             return OnRecvMessage(manager_, data, dataLen, reinterpret_cast<sockaddr *>(&addr6));
412         }
413         return false;
414     }
415 
OnMessage(int sock,void * data,size_t dataLen,sockaddr * addr,EventManager * manager) const416     bool OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr, EventManager *manager) const override
417     {
418         (void)addr;
419         if (static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData())) == 0) {
420             return false;
421         }
422         sockaddr sockAddr = {0};
423         socklen_t len = sizeof(sockaddr);
424         int ret = getsockname(sock, &sockAddr, &len);
425         if (ret < 0) {
426             return false;
427         }
428 
429         if (sockAddr.sa_family == AF_INET) {
430             sockaddr_in addr4 = {0};
431             socklen_t len4 = sizeof(sockaddr_in);
432 
433             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr4), &len4);
434             if (ret < 0) {
435                 return false;
436             }
437             return OnRecvMessage(manager, data, dataLen, reinterpret_cast<sockaddr *>(&addr4));
438         } else if (sockAddr.sa_family == AF_INET6) {
439             sockaddr_in6 addr6 = {0};
440             socklen_t len6 = sizeof(sockaddr_in6);
441 
442             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr6), &len6);
443             if (ret < 0) {
444                 return false;
445             }
446             return OnRecvMessage(manager, data, dataLen, reinterpret_cast<sockaddr *>(&addr6));
447         }
448         return false;
449     }
450 
OnTcpConnectionMessage(int32_t id) const451     void OnTcpConnectionMessage(int32_t id) const override
452     {
453         manager_->EmitByUv(EVENT_CONNECT, new TcpConnection(id), CallbackTemplate<MakeTcpConnectionMessage>);
454     }
455 };
456 
457 class UdpMessageCallback final : public MessageCallback {
458 public:
459     UdpMessageCallback() = delete;
460 
461     ~UdpMessageCallback() override = default;
462 
UdpMessageCallback(EventManager * manager)463     explicit UdpMessageCallback(EventManager *manager) : MessageCallback(manager) {}
464 
OnError(int err) const465     void OnError(int err) const override
466     {
467         if (EventManager::IsManagerValid(manager_)) {
468             manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
469             return;
470         }
471         NETSTACK_LOGI("udp socket handle has been finalized, manager is invalid");
472     }
473 
OnCloseMessage(EventManager * manager) const474     void OnCloseMessage(EventManager *manager) const override {}
475 
OnMessage(void * data,size_t dataLen,sockaddr * addr) const476     bool OnMessage(void *data, size_t dataLen, sockaddr *addr) const override
477     {
478         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData()));
479         if (sock == 0) {
480             return false;
481         }
482         return OnRecvMessage(manager_, data, dataLen, addr);
483     }
484 
OnMessage(int sock,void * data,size_t dataLen,sockaddr * addr,EventManager * manager) const485     bool OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr, EventManager *manager) const override
486     {
487         if (static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData())) == 0) {
488             return false;
489         }
490         return true;
491     }
492 
OnTcpConnectionMessage(int32_t id) const493     void OnTcpConnectionMessage(int32_t id) const override {}
494 };
495 
GetAddr(NetAddress * address,sockaddr_in * addr4,sockaddr_in6 * addr6,sockaddr ** addr,socklen_t * len)496 static void GetAddr(NetAddress *address, sockaddr_in *addr4, sockaddr_in6 *addr6, sockaddr **addr, socklen_t *len)
497 {
498     sa_family_t family = address->GetSaFamily();
499     if (family == AF_INET) {
500         addr4->sin_family = AF_INET;
501         addr4->sin_port = htons(address->GetPort());
502         addr4->sin_addr.s_addr = inet_addr(address->GetAddress().c_str());
503         *addr = reinterpret_cast<sockaddr *>(addr4);
504         *len = sizeof(sockaddr_in);
505     } else if (family == AF_INET6) {
506         addr6->sin6_family = AF_INET6;
507         addr6->sin6_port = htons(address->GetPort());
508         inet_pton(AF_INET6, address->GetAddress().c_str(), &addr6->sin6_addr);
509         *addr = reinterpret_cast<sockaddr *>(addr6);
510         *len = sizeof(sockaddr_in6);
511     }
512 }
513 
PollFd(pollfd * fds,nfds_t num,int timeout)514 static bool PollFd(pollfd *fds, nfds_t num, int timeout)
515 {
516     int ret = poll(fds, num, timeout);
517     if (ret == -1) {
518         NETSTACK_LOGE("poll to send failed, socket is %{public}d, errno is %{public}d", fds->fd, errno);
519         return false;
520     }
521     if (ret == 0) {
522         NETSTACK_LOGE("poll to send timeout, socket is %{public}d, timeout is %{public}d", fds->fd, timeout);
523         return false;
524     }
525     return true;
526 }
527 
ConfirmSocketTimeoutMs(int sock,int type,int defaultValue)528 static int ConfirmSocketTimeoutMs(int sock, int type, int defaultValue)
529 {
530     timeval timeout;
531     socklen_t optlen = sizeof(timeout);
532     if (getsockopt(sock, SOL_SOCKET, type, reinterpret_cast<void *>(&timeout), &optlen) < 0) {
533         NETSTACK_LOGE("get timeout failed, type: %{public}d, sock: %{public}d, errno: %{public}d", type, sock, errno);
534         return defaultValue;
535     }
536     auto socketTimeoutMs = timeout.tv_sec * UNIT_CONVERSION_1000 + timeout.tv_usec / UNIT_CONVERSION_1000;
537     return socketTimeoutMs == 0 ? defaultValue : socketTimeoutMs;
538 }
539 
PollSendData(int sock,const char * data,size_t size,sockaddr * addr,socklen_t addrLen)540 static bool PollSendData(int sock, const char *data, size_t size, sockaddr *addr, socklen_t addrLen)
541 {
542     NETSTACK_LOGD("js send RawSize: %{public}zu", size);
543     int bufferSize = DEFAULT_BUFFER_SIZE;
544     int opt = 0;
545     socklen_t optLen = sizeof(opt);
546     if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
547         bufferSize = opt;
548     }
549     int sockType = 0;
550     optLen = sizeof(sockType);
551     if (getsockopt(sock, SOL_SOCKET, SO_TYPE, reinterpret_cast<void *>(&sockType), &optLen) < 0) {
552         NETSTACK_LOGI("get sock opt sock type failed, socket is %{public}d, errno is %{public}d", sock, errno);
553         return false;
554     }
555 
556     auto curPos = data;
557     auto leftSize = size;
558     nfds_t num = 1;
559     pollfd fds[1] = {{0}};
560     fds[0].fd = sock;
561     fds[0].events = 0;
562     fds[0].events |= POLLOUT;
563     int sendTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_SNDTIMEO, DEFAULT_TIMEOUT_MS);
564     while (leftSize > 0) {
565         if (!PollFd(fds, num, sendTimeoutMs)) {
566             if (errno != EINTR) {
567                 return false;
568             }
569         }
570         size_t sendSize = (sockType == SOCK_STREAM ? leftSize : std::min<size_t>(leftSize, bufferSize));
571         auto sendLen = sendto(sock, curPos, sendSize, 0, addr, addrLen);
572         NETSTACK_LOGD("socketFD: %{public}d, send len: %{public}zu", sock, sendLen);
573         if (sendLen < 0) {
574             if (errno == EAGAIN || errno == EINTR) {
575                 continue;
576             }
577             NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", sock, errno);
578             return false;
579         }
580         if (sendLen == 0) {
581             break;
582         }
583         curPos += sendLen;
584         leftSize -= sendLen;
585     }
586 
587     if (leftSize != 0) {
588         NETSTACK_LOGE("send not complete, socket is %{public}d, errno is %{public}d", sock, errno);
589         return false;
590     }
591     return true;
592 }
593 
TcpSendEvent(TcpSendContext * context)594 static bool TcpSendEvent(TcpSendContext *context)
595 {
596     std::string encoding = context->options.GetEncoding();
597     (void)encoding;
598     /* no use for now */
599 
600     sockaddr sockAddr = {0};
601     socklen_t len = sizeof(sockaddr);
602     if (getsockname(context->GetSocketFd(), &sockAddr, &len) < 0) {
603         ERROR_RETURN(context, "getsockname failed, sock:%{public}d, errno:%{public}d", context->GetSocketFd(), errno);
604     }
605     bool connected = false;
606     if (sockAddr.sa_family == AF_INET) {
607         sockaddr_in addr4 = {0};
608         socklen_t len4 = sizeof(addr4);
609         int ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr4), &len4);
610         if (ret >= 0 && addr4.sin_port != 0) {
611             connected = true;
612         }
613     } else if (sockAddr.sa_family == AF_INET6) {
614         sockaddr_in6 addr6 = {0};
615         socklen_t len6 = sizeof(addr6);
616         int ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr6), &len6);
617         if (ret >= 0 && addr6.sin6_port != 0) {
618             connected = true;
619         }
620     }
621 
622     if (!connected) {
623         NETSTACK_LOGE("sock is not connect to remote, socket is %{public}d, errno is %{public}d",
624                       context->GetSocketFd(), errno);
625         context->SetErrorCode(errno);
626         return false;
627     }
628 
629     if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(),
630                       nullptr, 0)) {
631         ERROR_RETURN(context, "send failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
632     }
633     return true;
634 }
635 
UdpSendEvent(UdpSendContext * context)636 static bool UdpSendEvent(UdpSendContext *context)
637 {
638     sockaddr_in addr4 = {0};
639     sockaddr_in6 addr6 = {0};
640     sockaddr *addr = nullptr;
641     socklen_t len;
642     context->options.address.SetRawAddress(
643         ConvertAddressToIp(context->options.address.GetAddress(), context->options.address.GetSaFamily()));
644     GetAddr(&context->options.address, &addr4, &addr6, &addr, &len);
645     if (addr == nullptr) {
646         NETSTACK_LOGE("get sock name failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
647         context->SetErrorCode(ADDRESS_INVALID);
648         context->SetExecOK(false);
649         return false;
650     }
651 
652     if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(),
653                       addr, len)) {
654         ERROR_RETURN(context, "send failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
655     }
656     return true;
657 }
658 
ConfirmBufferSize(int sock)659 static int ConfirmBufferSize(int sock)
660 {
661     int bufferSize = DEFAULT_BUFFER_SIZE;
662     int opt = 0;
663     socklen_t optLen = sizeof(opt);
664     if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
665         bufferSize = opt;
666     }
667     return bufferSize;
668 }
669 
IsTCPSocket(int sockfd)670 static bool IsTCPSocket(int sockfd)
671 {
672     int optval;
673     socklen_t optlen = sizeof(optval);
674 
675     if (getsockopt(sockfd, SOL_SOCKET, SO_PROTOCOL, &optval, &optlen) != 0) {
676         return false;
677     }
678     return optval == IPPROTO_TCP;
679 }
680 
UpdateRecvBuffer(int sock,int & bufferSize,std::unique_ptr<char[]> & buf,const MessageCallback & callback)681 static int UpdateRecvBuffer(int sock, int &bufferSize, std::unique_ptr<char[]> &buf, const MessageCallback &callback)
682 {
683     if (int currentRecvBufferSize = ConfirmBufferSize(sock); currentRecvBufferSize != bufferSize) {
684         bufferSize = currentRecvBufferSize;
685         if (bufferSize <= 0 || bufferSize > MAX_SOCKET_BUFFER_SIZE) {
686             NETSTACK_LOGD("buffer size is out of range, size: %{public}d", bufferSize);
687             bufferSize = DEFAULT_BUFFER_SIZE;
688         }
689         buf.reset(new (std::nothrow) char[bufferSize]);
690         if (buf == nullptr) {
691             callback.OnError(NO_MEMORY);
692             return NO_MEMORY;
693         }
694     }
695     (void)memset_s(buf.get(), bufferSize, 0, bufferSize);
696     return 0;
697 }
698 
ExitOrAbnormal(int sock,ssize_t recvLen,const MessageCallback & callback)699 static int ExitOrAbnormal(int sock, ssize_t recvLen, const MessageCallback &callback)
700 {
701     if (errno == EAGAIN || errno == EINTR) {
702         return 0;
703     }
704     if (!IsTCPSocket(sock)) {
705         NETSTACK_LOGI("not tcpsocket, continue loop, recvLen: %{public}zd, err: %{public}d", recvLen, errno);
706         return 0;
707     }
708     if (errno == 0 && recvLen == 0) {
709         NETSTACK_LOGI("closed by peer, socket:%{public}d, recvLen:%{public}zd", sock, recvLen);
710         callback.OnCloseMessage(callback.GetEventManager());
711     } else {
712         if (EventManager::IsManagerValid(callback.GetEventManager()) && static_cast<int>(
713             reinterpret_cast<uint64_t>(callback.GetEventManager()->GetData())) > 0) {
714             NETSTACK_LOGE("recv fail, socket:%{public}d, recvLen:%{public}zd, errno:%{public}d", sock, recvLen, errno);
715             callback.OnError(errno);
716         }
717     }
718     return -1;
719 }
720 
IsValidSock(int & currentFd,const MessageCallback & callback)721 static bool IsValidSock(int &currentFd, const MessageCallback &callback)
722 {
723     auto manager = callback.GetEventManager();
724     if (EventManager::IsManagerValid(manager)) {
725         currentFd = static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData()));
726         if (currentFd <= 0) {
727             NETSTACK_LOGE("currentfd is error");
728             return false;
729         }
730     } else {
731         NETSTACK_LOGE("manager is error");
732         return false;
733     }
734     return true;
735 }
736 
PollRecvFinish(const MessageCallback & callback)737 static inline void PollRecvFinish(const MessageCallback &callback)
738 {
739     auto manager = callback.GetEventManager();
740     if (EventManager::IsManagerValid(manager)) {
741         manager->NotifyRcvThdExit();
742     } else {
743         NETSTACK_LOGE("manager is error");
744     }
745 }
746 
ProcessPollResult(int currentFd,const MessageCallback & callback)747 static void ProcessPollResult(int currentFd, const MessageCallback &callback)
748 {
749     if (EventManager::IsManagerValid(callback.GetEventManager()) &&
750         static_cast<int>(reinterpret_cast<uint64_t>(callback.GetEventManager()->GetData())) > 0) {
751         NETSTACK_LOGE("poll to recv failed, socket is %{public}d, errno is %{public}d", currentFd, errno);
752         callback.OnError(errno);
753     }
754 }
755 
PollRecvData(int sock,sockaddr * addr,socklen_t addrLen,const MessageCallback & callback)756 static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const MessageCallback &callback)
757 {
758     int bufferSize = ConfirmBufferSize(sock);
759     auto buf = std::make_unique<char[]>(bufferSize);
760     if (buf == nullptr) {
761         callback.OnError(NO_MEMORY);
762         PollRecvFinish(callback);
763         return;
764     }
765 
766     auto addrDeleter = [](sockaddr *a) { free(reinterpret_cast<void *>(a)); };
767     std::unique_ptr<sockaddr, decltype(addrDeleter)> pAddr(addr, addrDeleter);
768 
769     int recvTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_RCVTIMEO, DEFAULT_POLL_TIMEOUT);
770     while (true) {
771         int currentFd = -1;
772         if (!IsValidSock(currentFd, callback)) {
773             break;
774         }
775 
776         pollfd fds[1] = {{currentFd, POLLIN, 0}};
777         int ret = poll(fds, 1, recvTimeoutMs);
778         if (ret < 0) {
779             if (errno == EINTR) {
780                 continue;
781             }
782             ProcessPollResult(currentFd, callback);
783             break;
784         } else if (ret == 0) {
785             continue;
786         }
787         if (UpdateRecvBuffer(currentFd, bufferSize, buf, callback) < 0) {
788             break;
789         }
790         socklen_t tempAddrLen = addrLen;
791         auto recvLen = recvfrom(currentFd, buf.get(), bufferSize, 0, addr, &tempAddrLen);
792         if (recvLen <= 0) {
793             if (ExitOrAbnormal(currentFd, recvLen, callback) < 0) {
794                 break;
795             }
796             continue;
797         }
798 
799         void *data = malloc(recvLen);
800         if (data == nullptr) {
801             callback.OnError(NO_MEMORY);
802             break;
803         }
804         if (memcpy_s(data, recvLen, buf.get(), recvLen) != EOK || !callback.OnMessage(data, recvLen, addr)) {
805             free(data);
806         }
807     }
808 
809     PollRecvFinish(callback);
810 }
811 
NonBlockConnect(int sock,sockaddr * addr,socklen_t addrLen,uint32_t timeoutMSec)812 static bool NonBlockConnect(int sock, sockaddr *addr, socklen_t addrLen, uint32_t timeoutMSec)
813 {
814     int ret = connect(sock, addr, addrLen);
815     if (ret >= 0) {
816         return true;
817     }
818     if (errno != EINPROGRESS) {
819         return false;
820     }
821     struct pollfd fds[1] = {{.fd = sock, .events = POLLOUT}};
822     int timeoutMs = (timeoutMSec == 0) ? DEFAULT_CONNECT_TIMEOUT : timeoutMSec;
823     while (true) {
824         auto startTime = std::chrono::steady_clock::now();
825         ret = poll(fds, 1, timeoutMs);
826         if (ret > 0) {
827             break;
828         } else if (ret == 0) {
829             NETSTACK_LOGE("connect poll timeout, socket is %{public}d", sock);
830             return false;
831         }
832 
833         if (errno == EINTR) {
834             auto endTime = std::chrono::steady_clock::now();
835             auto intervalMs = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
836             timeoutMs -= static_cast<int>(intervalMs.count());
837             if (timeoutMs <= 0) {
838                 NETSTACK_LOGE("invalid timeout");
839                 return false;
840             }
841             continue;
842         }
843         NETSTACK_LOGE("connect poll failed, socket is %{public}d, errno is %{public}d", sock, errno);
844         return false;
845     }
846 
847     int err = 0;
848     socklen_t optLen = sizeof(err);
849     ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, reinterpret_cast<void *>(&err), &optLen);
850     if (ret < 0) {
851         return false;
852     }
853     if (err != 0) {
854         NETSTACK_LOGE("NonBlockConnect exec failed, socket is %{public}d, errno is %{public}d", sock, errno);
855         return false;
856     }
857     return true;
858 }
859 
SetBaseOptions(int sock,ExtraOptionsBase * option)860 static bool SetBaseOptions(int sock, ExtraOptionsBase *option)
861 {
862     if (option->AlreadySetRecvBufSize()) {
863         int size = static_cast<int>(option->GetReceiveBufferSize());
864         if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
865             NETSTACK_LOGE("set SO_RCVBUF failed, fd: %{public}d", sock);
866             return false;
867         }
868     }
869 
870     if (option->AlreadySetSendBufSize()) {
871         int size = static_cast<int>(option->GetSendBufferSize());
872         if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
873             NETSTACK_LOGE("set SO_SNDBUF failed, fd: %{public}d", sock);
874             return false;
875         }
876     }
877 
878     if (option->AlreadySetReuseAddr()) {
879         int reuse = static_cast<int>(option->IsReuseAddress());
880         if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&reuse), sizeof(reuse)) < 0) {
881             NETSTACK_LOGE("set SO_REUSEADDR failed, fd: %{public}d", sock);
882             return false;
883         }
884     }
885 
886     if (option->AlreadySetTimeout()) {
887         int value = static_cast<int>(option->GetSocketTimeout());
888         timeval timeout = {value / UNIT_CONVERSION_1000, (value % UNIT_CONVERSION_1000) * UNIT_CONVERSION_1000};
889         if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
890             NETSTACK_LOGE("set SO_RCVTIMEO failed, fd: %{public}d", sock);
891             return false;
892         }
893         if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
894             NETSTACK_LOGE("set SO_SNDTIMEO failed, fd: %{public}d", sock);
895             return false;
896         }
897     }
898 
899     return true;
900 }
901 
ExecBind(BindContext * context)902 bool ExecBind(BindContext *context)
903 {
904     sockaddr_in addr4 = {0};
905     sockaddr_in6 addr6 = {0};
906     sockaddr *addr = nullptr;
907     socklen_t len;
908     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
909     if (addr == nullptr) {
910         NETSTACK_LOGE("addr family error, address invalid");
911         context->SetErrorCode(ADDRESS_INVALID);
912         return false;
913     }
914 
915     int reuse = 0;
916     auto manager = context->GetManager();
917     if (manager != nullptr) {
918         reuse = manager->GetReuseAddr();
919         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&reuse),
920                        sizeof(reuse)) < 0) {
921             NETSTACK_LOGE("set SO_REUSEADDR failed, fd: %{public}d", context->GetSocketFd());
922             context->SetErrorCode(errno);
923             return false;
924         }
925     }
926 
927     if (bind(context->GetSocketFd(), addr, len) < 0) {
928         if (errno != EADDRINUSE) {
929             ERROR_RETURN(context, "bind failed, socket:%{public}d, errno:%{public}d", context->GetSocketFd(), errno);
930         }
931         if (addr->sa_family == AF_INET) {
932             NETSTACK_LOGI("distribute a random port");
933             addr4.sin_port = 0; /* distribute a random port */
934         } else if (addr->sa_family == AF_INET6) {
935             NETSTACK_LOGI("distribute a random port");
936             addr6.sin6_port = 0; /* distribute a random port */
937         }
938         if (bind(context->GetSocketFd(), addr, len) < 0) {
939             ERROR_RETURN(context, "rebind failed, socket:%{public}d, errno:%{public}d", context->GetSocketFd(), errno);
940         }
941         NETSTACK_LOGI("rebind success");
942     }
943     NETSTACK_LOGI("bind success, sock:%{public}d", context->GetSocketFd());
944 
945     return true;
946 }
947 
ExecUdpBind(BindContext * context)948 bool ExecUdpBind(BindContext *context)
949 {
950     if (!ExecBind(context)) {
951         return false;
952     }
953 
954     sockaddr_in addr4 = {0};
955     sockaddr_in6 addr6 = {0};
956     sockaddr *addr = nullptr;
957     socklen_t len;
958     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
959     if (addr == nullptr) {
960         NETSTACK_LOGE("get addr failed, addr family error, address invalid");
961         context->SetErrorCode(ADDRESS_INVALID);
962         return false;
963     }
964 
965     if (addr->sa_family == AF_INET) {
966         void *pTmpAddr = malloc(sizeof(addr4));
967         auto pAddr4 = reinterpret_cast<sockaddr *>(pTmpAddr);
968         if (pAddr4 == nullptr) {
969             NETSTACK_LOGE("no memory!");
970             return false;
971         }
972         NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr4, sizeof(addr4), &addr4, sizeof(addr4)));
973         std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr4, sizeof(addr4),
974                                   UdpMessageCallback(context->GetManager()));
975 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
976         pthread_setname_np(SOCKET_EXEC_UDP_BIND);
977 #else
978         pthread_setname_np(serviceThread.native_handle(), SOCKET_EXEC_UDP_BIND);
979 #endif
980         serviceThread.detach();
981     } else if (addr->sa_family == AF_INET6) {
982         void *pTmpAddr = malloc(len);
983         auto pAddr6 = reinterpret_cast<sockaddr *>(pTmpAddr);
984         if (pAddr6 == nullptr) {
985             NETSTACK_LOGE("no memory!");
986             return false;
987         }
988         NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr6, sizeof(addr6), &addr6, sizeof(addr6)));
989         std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr6, sizeof(addr6),
990                                   UdpMessageCallback(context->GetManager()));
991 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
992         pthread_setname_np(SOCKET_EXEC_UDP_BIND);
993 #else
994         pthread_setname_np(serviceThread.native_handle(), SOCKET_EXEC_UDP_BIND);
995 #endif
996         serviceThread.detach();
997     }
998 
999     return true;
1000 }
1001 
ExecUdpSend(UdpSendContext * context)1002 bool ExecUdpSend(UdpSendContext *context)
1003 {
1004 #ifdef FUZZ_TEST
1005     return true;
1006 #endif
1007     if (!context->IsParseOK()) {
1008         return false;
1009     }
1010 
1011     if (!CommonUtils::HasInternetPermission()) {
1012         context->SetPermissionDenied(true);
1013         return false;
1014     }
1015 
1016     bool result = UdpSendEvent(context);
1017     NapiUtils::CreateUvQueueWorkEnhanced(context->GetEnv(), context, SocketAsyncWork::UdpSendCallback);
1018     return result;
1019 }
1020 
ExecTcpBind(BindContext * context)1021 bool ExecTcpBind(BindContext *context)
1022 {
1023     return ExecBind(context);
1024 }
1025 
ExecConnect(ConnectContext * context)1026 bool ExecConnect(ConnectContext *context)
1027 {
1028     if (!CommonUtils::HasInternetPermission()) {
1029         context->SetPermissionDenied(true);
1030         return false;
1031     }
1032 
1033     sockaddr_in addr4 = {0};
1034     sockaddr_in6 addr6 = {0};
1035     sockaddr *addr = nullptr;
1036     socklen_t len;
1037     context->options.address.SetRawAddress(
1038         ConvertAddressToIp(context->options.address.GetAddress(), context->options.address.GetSaFamily()));
1039     GetAddr(&context->options.address, &addr4, &addr6, &addr, &len);
1040     if (addr == nullptr) {
1041         NETSTACK_LOGE("addr family error, address invalid");
1042         context->SetErrorCode(ADDRESS_INVALID);
1043         return false;
1044     }
1045 
1046     if (!NonBlockConnect(context->GetSocketFd(), addr, len, context->options.GetTimeout())) {
1047         ERROR_RETURN(context, "connect errno %{public}d", errno);
1048     }
1049 
1050     NETSTACK_LOGI("connect success, sock:%{public}d", context->GetSocketFd());
1051     std::thread serviceThread(PollRecvData, context->GetSocketFd(), nullptr, 0,
1052                               TcpMessageCallback(context->GetManager()));
1053 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
1054     pthread_setname_np(SOCKET_EXEC_CONNECT);
1055 #else
1056     pthread_setname_np(serviceThread.native_handle(), SOCKET_EXEC_CONNECT);
1057 #endif
1058     serviceThread.detach();
1059     return true;
1060 }
1061 
ExecTcpSend(TcpSendContext * context)1062 bool ExecTcpSend(TcpSendContext *context)
1063 {
1064 #ifdef FUZZ_TEST
1065     return true;
1066 #endif
1067     if (!context->IsParseOK()) {
1068         return false;
1069     }
1070 
1071     if (!CommonUtils::HasInternetPermission()) {
1072         context->SetPermissionDenied(true);
1073         return false;
1074     }
1075 
1076     bool result = TcpSendEvent(context);
1077     NapiUtils::CreateUvQueueWorkEnhanced(context->GetEnv(), context, SocketAsyncWork::TcpSendCallback);
1078     return result;
1079 }
1080 
ExecClose(CloseContext * context)1081 bool ExecClose(CloseContext *context)
1082 {
1083     if (!CommonUtils::HasInternetPermission()) {
1084         context->SetPermissionDenied(true);
1085         return false;
1086     }
1087 
1088     int ret = close(context->GetSocketFd());
1089     if (ret < 0) {
1090         NETSTACK_LOGE("sock closed failed , socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1091         context->SetErrorCode(UNKNOW_ERROR);
1092         return false;
1093     }
1094     NETSTACK_LOGI("sock %{public}d closed success", context->GetSocketFd());
1095 
1096     context->state_.SetIsClose(true);
1097     context->SetSocketFd(-1);
1098 
1099     return true;
1100 }
1101 
CheckClosed(GetStateContext * context,int & opt)1102 static bool CheckClosed(GetStateContext *context, int &opt)
1103 {
1104     socklen_t optLen = sizeof(int);
1105     int r = getsockopt(context->GetSocketFd(), SOL_SOCKET, SO_TYPE, &opt, &optLen);
1106     if (r < 0) {
1107         context->state_.SetIsClose(true);
1108         return true;
1109     }
1110     return false;
1111 }
1112 
CheckSocketFd(GetStateContext * context,sockaddr & sockAddr)1113 static bool CheckSocketFd(GetStateContext *context, sockaddr &sockAddr)
1114 {
1115     socklen_t len = sizeof(sockaddr);
1116     int ret = getsockname(context->GetSocketFd(), &sockAddr, &len);
1117     if (ret < 0) {
1118         context->SetErrorCode(errno);
1119         return false;
1120     }
1121     return true;
1122 }
1123 
GetSocketState(GetStateContext * context)1124 static bool GetSocketState(GetStateContext *context)
1125 {
1126     int opt;
1127     if (CheckClosed(context, opt)) {
1128         return true;
1129     }
1130 
1131     sockaddr sockAddr = {0};
1132     if (!CheckSocketFd(context, sockAddr)) {
1133         return false;
1134     }
1135 
1136     sockaddr_in addr4 = {0};
1137     sockaddr_in6 addr6 = {0};
1138     sockaddr *addr = nullptr;
1139     socklen_t addrLen;
1140     if (sockAddr.sa_family == AF_INET) {
1141         addr = reinterpret_cast<sockaddr *>(&addr4);
1142         addrLen = sizeof(addr4);
1143     } else if (sockAddr.sa_family == AF_INET6) {
1144         addr = reinterpret_cast<sockaddr *>(&addr6);
1145         addrLen = sizeof(addr6);
1146     }
1147 
1148     if (addr == nullptr) {
1149         NETSTACK_LOGE("addr family error, address invalid");
1150         context->SetErrorCode(ADDRESS_INVALID);
1151         return false;
1152     }
1153 
1154     (void)memset_s(addr, addrLen, 0, addrLen);
1155     socklen_t len = addrLen;
1156     int ret = getsockname(context->GetSocketFd(), addr, &len);
1157     if (ret < 0) {
1158         context->SetErrorCode(errno);
1159         return false;
1160     }
1161 
1162     SetIsBound(sockAddr.sa_family, context, &addr4, &addr6);
1163 
1164     if (opt != SOCK_STREAM) {
1165         return true;
1166     }
1167 
1168     (void)memset_s(addr, addrLen, 0, addrLen);
1169     len = addrLen;
1170     (void)getpeername(context->GetSocketFd(), addr, &len);
1171     SetIsConnected(sockAddr.sa_family, context, &addr4, &addr6);
1172     return true;
1173 }
1174 
ExecGetState(GetStateContext * context)1175 bool ExecGetState(GetStateContext *context)
1176 {
1177     if (!CommonUtils::HasInternetPermission()) {
1178         context->SetPermissionDenied(true);
1179         return false;
1180     }
1181     auto manager = context->GetManager();
1182     if (manager == nullptr) {
1183         NETSTACK_LOGI("manager is nullptr");
1184         return false;
1185     }
1186     if (!manager->GetData()) {
1187         return true;
1188     }
1189 
1190     return GetSocketState(context);
1191 }
1192 
IsAddressAndRetValid(const int & ret,const std::string & address,GetRemoteAddressContext * context)1193 bool IsAddressAndRetValid(const int &ret, const std::string &address, GetRemoteAddressContext *context)
1194 {
1195     if (ret < 0) {
1196         context->SetErrorCode(errno);
1197         return false;
1198     }
1199     if (address.empty()) {
1200         NETSTACK_LOGE("addr family error, address invalid");
1201         context->SetErrorCode(ADDRESS_INVALID);
1202         return false;
1203     }
1204     return true;
1205 }
1206 
ExecGetRemoteAddress(GetRemoteAddressContext * context)1207 bool ExecGetRemoteAddress(GetRemoteAddressContext *context)
1208 {
1209     if (!CommonUtils::HasInternetPermission()) {
1210         context->SetPermissionDenied(true);
1211         return false;
1212     }
1213 
1214     sockaddr sockAddr = {0};
1215     socklen_t len = sizeof(sockaddr);
1216     int ret = getsockname(context->GetSocketFd(), &sockAddr, &len);
1217     if (ret < 0) {
1218         context->SetErrorCode(errno);
1219         return false;
1220     }
1221 
1222     if (sockAddr.sa_family == AF_INET) {
1223         sockaddr_in addr4 = {0};
1224         socklen_t len4 = sizeof(sockaddr_in);
1225 
1226         ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr4), &len4);
1227         std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr4));
1228         if (!IsAddressAndRetValid(ret, address, context)) {
1229             return false;
1230         }
1231         context->address_.SetRawAddress(address);
1232         context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1233         context->address_.SetPort(ntohs(addr4.sin_port));
1234         return true;
1235     } else if (sockAddr.sa_family == AF_INET6) {
1236         sockaddr_in6 addr6 = {0};
1237         socklen_t len6 = sizeof(sockaddr_in6);
1238 
1239         ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr6), &len6);
1240         std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr6));
1241         if (!IsAddressAndRetValid(ret, address, context)) {
1242             return false;
1243         }
1244         context->address_.SetRawAddress(address);
1245         context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1246         context->address_.SetPort(ntohs(addr6.sin6_port));
1247         return true;
1248     }
1249 
1250     return false;
1251 }
1252 
SocketSetTcpExtraOptions(int sockfd,TCPExtraOptions & option)1253 static bool SocketSetTcpExtraOptions(int sockfd, TCPExtraOptions& option)
1254 {
1255     if (!SetBaseOptions(sockfd, &option)) {
1256         return false;
1257     }
1258     if (option.AlreadySetKeepAlive()) {
1259         int alive = static_cast<int>(option.IsKeepAlive());
1260         if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast<void*>(&alive), sizeof(alive)) < 0) {
1261             NETSTACK_LOGE("set SO_KEEPALIVE failed, fd: %{public}d", sockfd);
1262             return false;
1263         }
1264     }
1265 
1266     if (option.AlreadySetOobInline()) {
1267         int oob = static_cast<int>(option.IsOOBInline());
1268         if (setsockopt(sockfd, SOL_SOCKET, SO_OOBINLINE, reinterpret_cast<void*>(&oob), sizeof(oob)) < 0) {
1269             NETSTACK_LOGE("set SO_OOBINLINE failed, fd: %{public}d", sockfd);
1270             return false;
1271         }
1272     }
1273 
1274     if (option.AlreadySetTcpNoDelay()) {
1275         int noDelay = static_cast<int>(option.IsTCPNoDelay());
1276         if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<void*>(&noDelay), sizeof(noDelay)) < 0) {
1277             NETSTACK_LOGE("set TCP_NODELAY failed, fd: %{public}d", sockfd);
1278             return false;
1279         }
1280     }
1281 
1282     if (option.AlreadySetLinger()) {
1283         linger soLinger = {.l_onoff = option.socketLinger.IsOn(),
1284                            .l_linger = static_cast<int>(option.socketLinger.GetLinger())};
1285         if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger)) < 0) {
1286             NETSTACK_LOGE("set SO_LINGER failed, fd: %{public}d", sockfd);
1287             return false;
1288         }
1289     }
1290     return true;
1291 }
1292 
ExecTcpSetExtraOptions(TcpSetExtraOptionsContext * context)1293 bool ExecTcpSetExtraOptions(TcpSetExtraOptionsContext *context)
1294 {
1295     if (!CommonUtils::HasInternetPermission()) {
1296         context->SetPermissionDenied(true);
1297         return false;
1298     }
1299 
1300     if (context->GetSocketFd() <= 0) {
1301         context->SetError(ERRNO_BAD_FD, strerror(ERRNO_BAD_FD));
1302         return false;
1303     }
1304 
1305     if (!SocketSetTcpExtraOptions(context->GetSocketFd(), context->options_)) {
1306         context->SetErrorCode(errno);
1307         return false;
1308     }
1309     return true;
1310 }
1311 
ExecUdpSetExtraOptions(UdpSetExtraOptionsContext * context)1312 bool ExecUdpSetExtraOptions(UdpSetExtraOptionsContext *context)
1313 {
1314     if (!CommonUtils::HasInternetPermission()) {
1315         context->SetPermissionDenied(true);
1316         return false;
1317     }
1318 
1319     if (context->GetSocketFd() <= 0) {
1320         context->SetError(ERRNO_BAD_FD, strerror(ERRNO_BAD_FD));
1321         return false;
1322     }
1323 
1324     if (!SetBaseOptions(context->GetSocketFd(), &context->options)) {
1325         context->SetErrorCode(errno);
1326         return false;
1327     }
1328 
1329     if (context->options.AlreadySetBroadcast()) {
1330         int broadcast = static_cast<int>(context->options.IsBroadcast());
1331         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
1332             context->SetErrorCode(errno);
1333             return false;
1334         }
1335     }
1336 
1337     return true;
1338 }
1339 
RecvfromMulticastSetThreadName(pthread_t threadhandle)1340 void RecvfromMulticastSetThreadName(pthread_t threadhandle)
1341 {
1342 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
1343     pthread_setname_np(SOCKET_RECV_FROM_MULTI_CAST);
1344 #else
1345     pthread_setname_np(threadhandle, SOCKET_RECV_FROM_MULTI_CAST);
1346 #endif
1347 }
1348 
RecvfromMulticast(MulticastMembershipContext * context)1349 bool RecvfromMulticast(MulticastMembershipContext *context)
1350 {
1351     sockaddr_in addr4 = {0};
1352     sockaddr_in6 addr6 = {0};
1353     sockaddr *addr = nullptr;
1354     socklen_t len = 0;
1355     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
1356     if (addr == nullptr) {
1357         NETSTACK_LOGE("get addr failed, addr family error, address invalid");
1358         context->SetErrorCode(ADDRESS_INVALID);
1359         return false;
1360     }
1361 
1362     if (addr->sa_family == AF_INET) {
1363         void *pTmpAddr = malloc(sizeof(addr4));
1364         auto pAddr4 = reinterpret_cast<sockaddr *>(pTmpAddr);
1365         if (pAddr4 == nullptr) {
1366             return false;
1367         }
1368         addr4.sin_addr.s_addr = htonl(INADDR_ANY);
1369         if (bind(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&addr4), sizeof(addr4)) < 0) {
1370             free(pTmpAddr);
1371             ERROR_RETURN(context, "v4bind err, port:%{public}d, errno:%{public}d", context->address_.GetPort(), errno);
1372         }
1373         NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr4, sizeof(addr4), &addr4, sizeof(addr4)));
1374         std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr4, sizeof(addr4),
1375                                   UdpMessageCallback(context->GetManager()));
1376         RecvfromMulticastSetThreadName(serviceThread.native_handle());
1377         serviceThread.detach();
1378     } else if (addr->sa_family == AF_INET6) {
1379         void *pTmpAddr = malloc(sizeof(addr6));
1380         auto pAddr6 = reinterpret_cast<sockaddr *>(pTmpAddr);
1381         if (pAddr6 == nullptr) {
1382             return false;
1383         }
1384         addr6.sin6_addr = in6addr_any;
1385         if (bind(context->GetSocketFd(), reinterpret_cast<struct sockaddr *>(&addr6), sizeof(addr6)) < 0) {
1386             free(pTmpAddr);
1387             ERROR_RETURN(context, "v6bind err, port:%{public}d, errno:%{public}d", context->address_.GetPort(), errno);
1388         }
1389         NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr6, sizeof(addr6), &addr6, sizeof(addr6)));
1390         std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr6, sizeof(addr6),
1391                                   UdpMessageCallback(context->GetManager()));
1392         RecvfromMulticastSetThreadName(serviceThread.native_handle());
1393         serviceThread.detach();
1394     }
1395     return true;
1396 }
1397 
GetSockFamily(int fd)1398 static inline int GetSockFamily(int fd)
1399 {
1400     sockaddr sockAddr = {0};
1401     socklen_t len = sizeof(sockaddr);
1402     return (getsockname(fd, &sockAddr, &len) < 0) ? -1 : sockAddr.sa_family;
1403 }
1404 
ExecUdpAddMembership(MulticastMembershipContext * context)1405 bool ExecUdpAddMembership(MulticastMembershipContext *context)
1406 {
1407     if (!CommonUtils::HasInternetPermission()) {
1408         context->SetPermissionDenied(true);
1409         return false;
1410     }
1411 
1412     if (context->address_.GetFamily() == NetAddress::Family::IPv4) {
1413         ip_mreq mreq = {};
1414         mreq.imr_multiaddr.s_addr = inet_addr(context->address_.GetAddress().c_str());
1415         mreq.imr_interface.s_addr = INADDR_ANY;
1416         if (setsockopt(context->GetSocketFd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<void *>(&mreq),
1417                        sizeof(mreq)) == -1) {
1418             NETSTACK_LOGE("ipv4 addmembership err: %{public}d", errno);
1419             context->SetErrorCode(errno);
1420             return false;
1421         }
1422     } else {
1423         ipv6_mreq mreq = {};
1424         inet_pton(AF_INET6, context->address_.GetAddress().c_str(), &mreq.ipv6mr_multiaddr);
1425         mreq.ipv6mr_interface = 0;
1426         if (setsockopt(context->GetSocketFd(), IPPROTO_IPV6, IPV6_JOIN_GROUP, reinterpret_cast<void *>(&mreq),
1427                        sizeof(mreq)) == -1) {
1428             NETSTACK_LOGE("ipv6 addmembership err: %{public}d", errno);
1429             context->SetErrorCode(errno);
1430             return false;
1431         }
1432     }
1433     NETSTACK_LOGI("addmembership ok, sock:%{public}d", context->GetSocketFd());
1434     return RecvfromMulticast(context);
1435 }
1436 
ExecUdpDropMembership(MulticastMembershipContext * context)1437 bool ExecUdpDropMembership(MulticastMembershipContext *context)
1438 {
1439     if (!CommonUtils::HasInternetPermission()) {
1440         context->SetPermissionDenied(true);
1441         return false;
1442     }
1443     if (context->address_.GetFamily() == NetAddress::Family::IPv4) {
1444         ip_mreq mreq = {};
1445         mreq.imr_multiaddr.s_addr = inet_addr(context->address_.GetAddress().c_str());
1446         mreq.imr_interface.s_addr = INADDR_ANY;
1447         if (setsockopt(context->GetSocketFd(), IPPROTO_IP, IP_DROP_MEMBERSHIP, reinterpret_cast<void *>(&mreq),
1448                        sizeof(mreq)) == -1) {
1449             NETSTACK_LOGE("ipv4 dropmembership err: %{public}d", errno);
1450             context->SetErrorCode(errno);
1451             return false;
1452         }
1453     } else {
1454         ipv6_mreq mreq = {};
1455         inet_pton(AF_INET6, context->address_.GetAddress().c_str(), &mreq.ipv6mr_multiaddr);
1456         mreq.ipv6mr_interface = 0;
1457         if (setsockopt(context->GetSocketFd(), IPPROTO_IPV6, IPV6_LEAVE_GROUP, reinterpret_cast<void *>(&mreq),
1458                        sizeof(mreq)) == -1) {
1459             NETSTACK_LOGE("ipv6 dropmembership err: %{public}d", errno);
1460             context->SetErrorCode(errno);
1461             return false;
1462         }
1463     }
1464 
1465     if (close(context->GetSocketFd()) < 0) {
1466         NETSTACK_LOGE("sock closed failed , socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1467         context->SetErrorCode(errno);
1468         return false;
1469     }
1470     NETSTACK_LOGI("ExecUdpDropMembership sock: %{public}d closed success", context->GetSocketFd());
1471     context->SetSocketFd(0);
1472     return true;
1473 }
1474 
ExecSetMulticastTTL(MulticastSetTTLContext * context)1475 bool ExecSetMulticastTTL(MulticastSetTTLContext *context)
1476 {
1477     if (!CommonUtils::HasInternetPermission()) {
1478         context->SetPermissionDenied(true);
1479         return false;
1480     }
1481     int ttl = context->GetMulticastTTL();
1482     int family = GetSockFamily(context->GetSocketFd());
1483     if (setsockopt(context->GetSocketFd(), (family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6, (family == AF_INET) ?
1484         IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS, reinterpret_cast<void *>(&ttl), sizeof(ttl)) == -1) {
1485         ERROR_RETURN(context, "set ttl err, ttl:%{public}d, family:%{public}d, errno:%{public}d", ttl, family, errno);
1486     }
1487     return true;
1488 }
1489 
ExecGetMulticastTTL(MulticastGetTTLContext * context)1490 bool ExecGetMulticastTTL(MulticastGetTTLContext *context)
1491 {
1492     if (!CommonUtils::HasInternetPermission()) {
1493         context->SetPermissionDenied(true);
1494         return false;
1495     }
1496     int ttl = 0;
1497     socklen_t ttlLen = sizeof(ttl);
1498     int family = GetSockFamily(context->GetSocketFd());
1499     if (getsockopt(context->GetSocketFd(), (family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6, (family == AF_INET) ?
1500         IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS, reinterpret_cast<void *>(&ttl), &ttlLen) == -1) {
1501         ERROR_RETURN(context, "get ttl err, family:%{public}d, errno:%{public}d", family, errno);
1502     }
1503     context->SetMulticastTTL(ttl);
1504     return true;
1505 }
1506 
ExecSetLoopbackMode(MulticastSetLoopbackContext * context)1507 bool ExecSetLoopbackMode(MulticastSetLoopbackContext *context)
1508 {
1509     if (!CommonUtils::HasInternetPermission()) {
1510         context->SetPermissionDenied(true);
1511         return false;
1512     }
1513     int mode = static_cast<int>(context->GetLoopbackMode());
1514     int family = GetSockFamily(context->GetSocketFd());
1515     if (setsockopt(context->GetSocketFd(), (family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6, (family == AF_INET) ?
1516         IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP, reinterpret_cast<void *>(&mode), sizeof(mode)) == -1) {
1517         ERROR_RETURN(context, "setloopback err, mode:%{public}d, fa:%{public}d, err:%{public}d", mode, family, errno);
1518     }
1519     return true;
1520 }
1521 
ExecGetLoopbackMode(MulticastGetLoopbackContext * context)1522 bool ExecGetLoopbackMode(MulticastGetLoopbackContext *context)
1523 {
1524     if (!CommonUtils::HasInternetPermission()) {
1525         context->SetPermissionDenied(true);
1526         return false;
1527     }
1528     int mode = 0;
1529     socklen_t len = sizeof(mode);
1530     int family = GetSockFamily(context->GetSocketFd());
1531     if (getsockopt(context->GetSocketFd(), (family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6, (family == AF_INET) ?
1532         IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP, reinterpret_cast<void *>(&mode), &len) == -1) {
1533         ERROR_RETURN(context, "getloopback err, family:%{public}d, errno:%{public}d", family, errno);
1534     }
1535     context->SetLoopbackMode(static_cast<bool>(mode));
1536     return true;
1537 }
1538 
ExecTcpGetSocketFd(GetSocketFdContext * context)1539 bool ExecTcpGetSocketFd(GetSocketFdContext *context)
1540 {
1541     return true;
1542 }
1543 
ExecUdpGetSocketFd(GetSocketFdContext * context)1544 bool ExecUdpGetSocketFd(GetSocketFdContext *context)
1545 {
1546     return true;
1547 }
1548 
GetIPv4Address(TcpServerGetRemoteAddressContext * context,int32_t fd,sockaddr sockAddr)1549 static bool GetIPv4Address(TcpServerGetRemoteAddressContext *context, int32_t fd, sockaddr sockAddr)
1550 {
1551     sockaddr_in addr4 = {0};
1552     socklen_t len4 = sizeof(sockaddr_in);
1553 
1554     int ret = getpeername(fd, reinterpret_cast<sockaddr *>(&addr4), &len4);
1555     if (ret < 0) {
1556         context->SetErrorCode(errno);
1557         return false;
1558     }
1559 
1560     std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr4));
1561     if (address.empty()) {
1562         NETSTACK_LOGE("addr family error, address invalid");
1563         context->SetErrorCode(ADDRESS_INVALID);
1564         return false;
1565     }
1566     context->address_.SetRawAddress(address);
1567     context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1568     context->address_.SetPort(ntohs(addr4.sin_port));
1569     return true;
1570 }
1571 
GetIPv6Address(TcpServerGetRemoteAddressContext * context,int32_t fd,sockaddr sockAddr)1572 static bool GetIPv6Address(TcpServerGetRemoteAddressContext *context, int32_t fd, sockaddr sockAddr)
1573 {
1574     sockaddr_in6 addr6 = {0};
1575     socklen_t len6 = sizeof(sockaddr_in6);
1576 
1577     int ret = getpeername(fd, reinterpret_cast<sockaddr *>(&addr6), &len6);
1578     if (ret < 0) {
1579         context->SetErrorCode(errno);
1580         return false;
1581     }
1582 
1583     std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr6));
1584     if (address.empty()) {
1585         NETSTACK_LOGE("addr family error, address invalid");
1586         context->SetErrorCode(ADDRESS_INVALID);
1587         return false;
1588     }
1589     context->address_.SetRawAddress(address);
1590     context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1591     context->address_.SetPort(ntohs(addr6.sin6_port));
1592     return true;
1593 }
1594 
ExecTcpConnectionGetRemoteAddress(TcpServerGetRemoteAddressContext * context)1595 bool ExecTcpConnectionGetRemoteAddress(TcpServerGetRemoteAddressContext *context)
1596 {
1597     if (!CommonUtils::HasInternetPermission()) {
1598         context->SetPermissionDenied(true);
1599         return false;
1600     }
1601 
1602     int32_t clientFd = -1;
1603     bool fdValid = false;
1604 
1605     {
1606         std::lock_guard<std::mutex> lock(g_mutex);
1607         auto iter = g_clientFDs.find(context->clientId_);
1608         if (iter != g_clientFDs.end()) {
1609             fdValid = true;
1610             clientFd = iter->second;
1611         } else {
1612             NETSTACK_LOGE("not find clientId");
1613         }
1614     }
1615 
1616     if (!fdValid) {
1617         NETSTACK_LOGE("client fd is invalid");
1618         context->SetError(OTHER_ERROR, "client fd is invalid");
1619         return false;
1620     }
1621 
1622     sockaddr sockAddr = {0};
1623     socklen_t len = sizeof(sockaddr);
1624     int ret = getsockname(clientFd, &sockAddr, &len);
1625     if (ret < 0) {
1626         context->SetError(errno, strerror(errno));
1627         return false;
1628     }
1629 
1630     if (sockAddr.sa_family == AF_INET) {
1631         return GetIPv4Address(context, clientFd, sockAddr);
1632     } else if (sockAddr.sa_family == AF_INET6) {
1633         return GetIPv6Address(context, clientFd, sockAddr);
1634     }
1635 
1636     return false;
1637 }
1638 
ExecTcpConnectionGetLocalAddress(TcpConnectionGetLocalAddressContext * context)1639 bool ExecTcpConnectionGetLocalAddress(TcpConnectionGetLocalAddressContext *context)
1640 {
1641     if (context == nullptr) {
1642         NETSTACK_LOGE("context is nullptr");
1643         return false;
1644     }
1645     int32_t clientFd = -1;
1646     {
1647         std::lock_guard<std::mutex> lock(g_mutex);
1648         auto iter = g_clientFDs.find(context->clientId_);
1649         if (iter != g_clientFDs.end()) {
1650             clientFd = iter->second;
1651         } else {
1652             NETSTACK_LOGE("not find clientId");
1653         }
1654     }
1655     struct sockaddr_storage addr{};
1656     socklen_t addrLen = sizeof(addr);
1657     if (getsockname(clientFd, reinterpret_cast<struct sockaddr *>(&addr), &addrLen) < 0) {
1658         context->SetNeedThrowException(true);
1659         context->SetErrorCode(errno);
1660         return false;
1661     }
1662 
1663     char ipStr[INET6_ADDRSTRLEN] = {0};
1664     Socket::NetAddress localAddress;
1665     if (addr.ss_family == AF_INET) {
1666         auto *addrIn = reinterpret_cast<struct sockaddr_in *>(&addr);
1667         inet_ntop(AF_INET, &addrIn->sin_addr, ipStr, sizeof(ipStr));
1668         localAddress.SetFamilyBySaFamily(AF_INET);
1669         localAddress.SetRawAddress(ipStr);
1670         localAddress.SetPort(ntohs(addrIn->sin_port));
1671         context->localAddress_ = localAddress;
1672     } else if (addr.ss_family == AF_INET6) {
1673         auto *addrIn6 = reinterpret_cast<struct sockaddr_in6 *>(&addr);
1674         inet_ntop(AF_INET6, &addrIn6->sin6_addr, ipStr, sizeof(ipStr));
1675         localAddress.SetFamilyBySaFamily(AF_INET6);
1676         localAddress.SetRawAddress(ipStr);
1677         localAddress.SetPort(ntohs(addrIn6->sin6_port));
1678         context->localAddress_ = localAddress;
1679     }
1680     return true;
1681 }
1682 
IsRemoteConnect(TcpServerSendContext * context,int32_t clientFd)1683 static bool IsRemoteConnect(TcpServerSendContext *context, int32_t clientFd)
1684 {
1685     sockaddr sockAddr = {0};
1686     socklen_t len = sizeof(sockaddr);
1687     if (getsockname(clientFd, &sockAddr, &len) < 0) {
1688         NETSTACK_LOGE("get sock name failed, address invalid");
1689         context->SetErrorCode(ADDRESS_INVALID);
1690         return false;
1691     }
1692     bool connected = false;
1693     if (sockAddr.sa_family == AF_INET) {
1694         sockaddr_in addr4 = {0};
1695         socklen_t len4 = sizeof(addr4);
1696         int ret = getpeername(clientFd, reinterpret_cast<sockaddr *>(&addr4), &len4);
1697         if (ret >= 0 && addr4.sin_port != 0) {
1698             connected = true;
1699         }
1700     } else if (sockAddr.sa_family == AF_INET6) {
1701         sockaddr_in6 addr6 = {0};
1702         socklen_t len6 = sizeof(addr6);
1703         int ret = getpeername(clientFd, reinterpret_cast<sockaddr *>(&addr6), &len6);
1704         if (ret >= 0 && addr6.sin6_port != 0) {
1705             connected = true;
1706         }
1707     }
1708 
1709     if (!connected) {
1710         ERROR_RETURN(context, "sock is not connect to remote, socket:%{public}d, errno:%{public}d", clientFd, errno);
1711     }
1712     return true;
1713 }
1714 
ExecTcpConnectionSend(TcpServerSendContext * context)1715 bool ExecTcpConnectionSend(TcpServerSendContext *context)
1716 {
1717     if (!CommonUtils::HasInternetPermission()) {
1718         context->SetPermissionDenied(true);
1719         return false;
1720     }
1721 
1722     int32_t clientFd = -1;
1723     bool fdValid = false;
1724 
1725     {
1726         std::lock_guard<std::mutex> lock(g_mutex);
1727         auto iter = g_clientFDs.find(context->clientId_);
1728         if (iter != g_clientFDs.end()) {
1729             fdValid = true;
1730             clientFd = iter->second;
1731         } else {
1732             NETSTACK_LOGE("not find clientId");
1733         }
1734     }
1735 
1736     if (!fdValid) {
1737         NETSTACK_LOGE("client fd is invalid");
1738         context->SetError(OTHER_ERROR, "client fd is invalid");
1739         return false;
1740     }
1741 
1742     std::string encoding = context->options.GetEncoding();
1743     (void)encoding;
1744     /* no use for now */
1745 
1746     if (!IsRemoteConnect(context, clientFd)) {
1747         return false;
1748     }
1749 
1750     if (!PollSendData(clientFd, context->options.GetData().c_str(), context->options.GetData().size(), nullptr, 0)) {
1751         NETSTACK_LOGE("send failed, , socket is %{public}d, errno is %{public}d", clientFd, errno);
1752         context->SetError(errno, strerror(errno));
1753         return false;
1754     }
1755     return true;
1756 }
1757 
ExecTcpConnectionClose(TcpServerCloseContext * context)1758 bool ExecTcpConnectionClose(TcpServerCloseContext *context)
1759 {
1760     if (!CommonUtils::HasInternetPermission()) {
1761         context->SetPermissionDenied(true);
1762         return false;
1763     }
1764     bool fdValid = false;
1765 
1766     {
1767         std::lock_guard<std::mutex> lock(g_mutex);
1768         auto iter = g_clientFDs.find(context->clientId_);
1769         if (iter != g_clientFDs.end()) {
1770             fdValid = true;
1771         } else {
1772             NETSTACK_LOGE("not find clientId");
1773         }
1774     }
1775 
1776     if (!fdValid) {
1777         NETSTACK_LOGE("client fd is invalid");
1778         context->SetError(OTHER_ERROR, "client fd is invalid");
1779         return false;
1780     }
1781 
1782     return true;
1783 }
1784 
ServerBind(TcpServerListenContext * context)1785 static bool ServerBind(TcpServerListenContext *context)
1786 {
1787     sockaddr_in addr4 = {0};
1788     sockaddr_in6 addr6 = {0};
1789     sockaddr *addr = nullptr;
1790     socklen_t len;
1791     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
1792     if (addr == nullptr) {
1793         NETSTACK_LOGE("addr family error, address invalid");
1794         context->SetError(ADDRESS_INVALID, "addr family error, address invalid");
1795         return false;
1796     }
1797 
1798     if (bind(context->GetSocketFd(), addr, len) < 0) {
1799         if (errno != EADDRINUSE) {
1800             NETSTACK_LOGE("bind failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1801             context->SetError(errno, strerror(errno));
1802             return false;
1803         }
1804         if (addr->sa_family == AF_INET) {
1805             NETSTACK_LOGI("distribute a random port");
1806             addr4.sin_port = 0; /* distribute a random port */
1807         } else if (addr->sa_family == AF_INET6) {
1808             NETSTACK_LOGI("distribute a random port");
1809             addr6.sin6_port = 0; /* distribute a random port */
1810         }
1811         if (bind(context->GetSocketFd(), addr, len) < 0) {
1812             NETSTACK_LOGE("rebind failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1813             context->SetError(errno, strerror(errno));
1814             return false;
1815         }
1816         NETSTACK_LOGI("rebind success");
1817     }
1818     NETSTACK_LOGI("bind success");
1819 
1820     return true;
1821 }
1822 
IsClientFdClosed(int32_t clientFd)1823 static bool IsClientFdClosed(int32_t clientFd)
1824 {
1825     return (fcntl(clientFd, F_GETFL) == -1 && errno == EBADF);
1826 }
1827 
RemoveClientConnection(int32_t clientId)1828 static void RemoveClientConnection(int32_t clientId)
1829 {
1830     std::lock_guard<std::mutex> lock(g_mutex);
1831     for (auto it = g_clientFDs.begin(); it != g_clientFDs.end(); ++it) {
1832         if (it->first == clientId) {
1833             NETSTACK_LOGI("remove clientfd and eventmanager clientid: %{public}d clientFd:%{public}d", it->second,
1834                           it->first);
1835             if (!IsClientFdClosed(it->second)) {
1836                 NETSTACK_LOGE("connectFD not close should close");
1837                 shutdown(it->second, SHUT_RDWR);
1838                 close(it->second);
1839             }
1840 
1841             g_clientFDs.erase(it->first);
1842             break;
1843         }
1844     }
1845 }
1846 
WaitForManagerReady(int32_t clientId,int & connectFd)1847 static EventManager *WaitForManagerReady(int32_t clientId, int &connectFd)
1848 {
1849     EventManager *manager = nullptr;
1850     std::unique_lock<std::mutex> lock(g_mutex);
1851     g_cv.wait(lock, [&manager, &clientId]() {
1852         auto iter = g_clientEventManagers.find(clientId);
1853         if (iter != g_clientEventManagers.end()) {
1854             manager = iter->second;
1855             if (manager->HasEventListener(EVENT_MESSAGE)) {
1856                 NETSTACK_LOGI("manager is ready with registering message event");
1857                 return true;
1858             }
1859         } else {
1860             NETSTACK_LOGE("iter==g_clientEventManagers.end()");
1861         }
1862         return false;
1863     });
1864     connectFd = g_clientFDs[clientId];
1865     return manager;
1866 }
1867 
RecvInErrorCondition(int reason,int clientId,int connectFD,const TcpMessageCallback & callback)1868 static inline void RecvInErrorCondition(int reason, int clientId, int connectFD, const TcpMessageCallback &callback)
1869 {
1870     RemoveClientConnection(clientId);
1871     SingletonSocketConfig::GetInstance().RemoveAcceptSocket(connectFD);
1872     callback.OnError(reason);
1873 }
1874 
CloseClientHandler(int clientId,int connectFD,EventManager * manager,const TcpMessageCallback & callback)1875 static inline void CloseClientHandler(int clientId, int connectFD,
1876                                       EventManager *manager, const TcpMessageCallback &callback)
1877 {
1878     callback.OnCloseMessage(manager);
1879     RemoveClientConnection(clientId);
1880     SingletonSocketConfig::GetInstance().RemoveAcceptSocket(connectFD);
1881 }
1882 
ClientPollRecv(int clientId,int connectFD,uint32_t recvBufferSize,EventManager * manager,const TcpMessageCallback & callback)1883 static void ClientPollRecv(int clientId, int connectFD, uint32_t recvBufferSize, EventManager *manager,
1884                            const TcpMessageCallback &callback)
1885 {
1886     auto buffer = std::make_unique<char[]>(recvBufferSize);
1887     if (buffer == nullptr) {
1888         NETSTACK_LOGE("client malloc failed, connectFd: %{public}d, size: %{public}d", connectFD, recvBufferSize);
1889         RecvInErrorCondition(NO_MEMORY, clientId, connectFD, callback);
1890         return;
1891     }
1892     while (true) {
1893         if (memset_s(buffer.get(), recvBufferSize, 0, recvBufferSize) != EOK) {
1894             RecvInErrorCondition(UNKNOW_ERROR, clientId, connectFD, callback);
1895             break;
1896         }
1897         pollfd fds[1] = {{connectFD, POLLIN, 0}};
1898         int ret = poll(fds, 1, DEFAULT_POLL_TIMEOUT);
1899         if (ret < 0) {
1900             NETSTACK_LOGE("Client poll to recv failed, socket is %{public}d, errno is %{public}d", connectFD, errno);
1901             callback.OnCloseMessage(manager);
1902             CloseClientHandler(clientId, connectFD, manager, callback);
1903             break;
1904         } else if (ret == 0) {
1905             continue;
1906         }
1907 
1908         int32_t recvSize = recv(connectFD, buffer.get(), recvBufferSize, 0);
1909         int flags = fcntl(connectFD, F_GETFL, 0);
1910         if (flags == -1) {
1911             NETSTACK_LOGE("read flag fail");
1912             CloseClientHandler(clientId, connectFD, manager, callback);
1913             break;
1914         }
1915 
1916         if (recvSize <= 0) {
1917             NETSTACK_LOGI("ClientRecv: fd:%{public}d, size:%{public}d, errno:%{public}d, is non blocking:%{public}s",
1918                           connectFD, recvSize, errno, static_cast<uint32_t>(flags) & O_NONBLOCK ? "true" : "false");
1919             if ((recvSize == 0) || (recvSize < 0 && errno != EAGAIN && errno != EINTR)) {
1920                 CloseClientHandler(clientId, connectFD, manager, callback);
1921                 break;
1922             }
1923         } else {
1924             void *data = malloc(recvSize);
1925             if (data == nullptr) {
1926                 RecvInErrorCondition(NO_MEMORY, clientId, connectFD, callback);
1927                 break;
1928             }
1929             if (memcpy_s(data, recvSize, buffer.get(), recvSize) != EOK ||
1930                 !callback.OnMessage(connectFD, data, recvSize, nullptr, manager)) {
1931                 free(data);
1932                 RecvInErrorCondition(UNKNOW_ERROR, clientId, connectFD, callback);
1933             }
1934         }
1935     }
1936 }
1937 
ClientHandler(int32_t sock,int32_t clientId,const TcpMessageCallback & callback)1938 static void ClientHandler(int32_t sock, int32_t clientId, const TcpMessageCallback &callback)
1939 {
1940     int32_t connectFD = 0;
1941     EventManager *manager = WaitForManagerReady(clientId, connectFD);
1942 
1943     uint32_t recvBufferSize = DEFAULT_BUFFER_SIZE;
1944     TCPExtraOptions option;
1945     if (SingletonSocketConfig::GetInstance().GetTcpExtraOptions(sock, option)) {
1946         if (option.GetReceiveBufferSize() != 0) {
1947             recvBufferSize = option.GetReceiveBufferSize();
1948         }
1949     }
1950     ClientPollRecv(clientId, connectFD, recvBufferSize, manager, callback);
1951 }
1952 
AcceptRecvData(int sock,sockaddr * addr,socklen_t addrLen,const TcpMessageCallback & callback)1953 static void AcceptRecvData(int sock, sockaddr *addr, socklen_t addrLen, const TcpMessageCallback &callback)
1954 {
1955     while (true) {
1956         sockaddr_in clientAddress;
1957         socklen_t clientAddrLength = sizeof(clientAddress);
1958         int32_t connectFD = accept(sock, reinterpret_cast<sockaddr *>(&clientAddress), &clientAddrLength);
1959         if (connectFD < 0) {
1960             continue;
1961         }
1962         {
1963             std::lock_guard<std::mutex> lock(g_mutex);
1964             if (g_clientFDs.size() >= MAX_CLIENTS) {
1965                 NETSTACK_LOGE("Maximum number of clients reached, connection rejected");
1966                 close(connectFD);
1967                 continue;
1968             }
1969             NETSTACK_LOGI("Server accept new client SUCCESS, fd = %{public}d", connectFD);
1970             g_userCounter++;
1971             g_clientFDs[g_userCounter] = connectFD;
1972         }
1973         callback.OnTcpConnectionMessage(g_userCounter);
1974         int clientId = g_userCounter;
1975 
1976         SingletonSocketConfig::GetInstance().AddNewAcceptSocket(sock, connectFD);
1977         if (TCPExtraOptions option; SingletonSocketConfig::GetInstance().GetTcpExtraOptions(sock, option)) {
1978             SocketSetTcpExtraOptions(connectFD, option);
1979         }
1980         std::thread handlerThread(ClientHandler, sock, clientId, callback);
1981 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
1982         pthread_setname_np(TCP_SERVER_HANDLE_CLIENT);
1983 #else
1984         pthread_setname_np(handlerThread.native_handle(), TCP_SERVER_HANDLE_CLIENT);
1985 #endif
1986         handlerThread.detach();
1987     }
1988 }
1989 
ExecTcpServerListen(TcpServerListenContext * context)1990 bool ExecTcpServerListen(TcpServerListenContext *context)
1991 {
1992     int ret = 0;
1993     if (!ServerBind(context)) {
1994         return false;
1995     }
1996 
1997     ret = listen(context->GetSocketFd(), USER_LIMIT);
1998     if (ret < 0) {
1999         NETSTACK_LOGE("tcp server listen error");
2000         return false;
2001     }
2002     SingletonSocketConfig::GetInstance().AddNewListenSocket(context->GetSocketFd());
2003     NETSTACK_LOGI("listen success");
2004     std::thread serviceThread(AcceptRecvData, context->GetSocketFd(), nullptr, 0,
2005                               TcpMessageCallback(context->GetManager()));
2006 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
2007     pthread_setname_np(TCP_SERVER_ACCEPT_RECV_DATA);
2008 #else
2009     pthread_setname_np(serviceThread.native_handle(), TCP_SERVER_ACCEPT_RECV_DATA);
2010 #endif
2011     serviceThread.detach();
2012     return true;
2013 }
2014 
ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext * context)2015 bool ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext *context)
2016 {
2017     if (!CommonUtils::HasInternetPermission()) {
2018         context->SetPermissionDenied(true);
2019         return false;
2020     }
2021     if (context->GetSocketFd() <= 0) {
2022         context->SetError(ERRNO_BAD_FD, strerror(ERRNO_BAD_FD));
2023         return false;
2024     }
2025     auto clients = SingletonSocketConfig::GetInstance().GetClients(context->GetSocketFd());
2026     if (std::any_of(clients.begin(), clients.end(), [&context](int32_t fd) {
2027             return !SocketSetTcpExtraOptions(fd, context->options_);
2028         })) {
2029         context->SetError(errno, strerror(errno));
2030         return false;
2031     }
2032 
2033     SingletonSocketConfig::GetInstance().SetTcpExtraOptions(context->GetSocketFd(), context->options_);
2034     return true;
2035 }
2036 
SetIsConnected(TcpServerGetStateContext * context)2037 static void SetIsConnected(TcpServerGetStateContext *context)
2038 {
2039     std::lock_guard<std::mutex> lock(g_mutex);
2040     if (g_clientFDs.empty()) {
2041         context->state_.SetIsConnected(false);
2042     } else {
2043         context->state_.SetIsConnected(true);
2044     }
2045 }
2046 
SetIsBound(sa_family_t family,TcpServerGetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)2047 static void SetIsBound(sa_family_t family, TcpServerGetStateContext *context, const sockaddr_in *addr4,
2048                        const sockaddr_in6 *addr6)
2049 {
2050     if (family == AF_INET) {
2051         context->state_.SetIsBound(ntohs(addr4->sin_port) != 0);
2052     } else if (family == AF_INET6) {
2053         context->state_.SetIsBound(ntohs(addr6->sin6_port) != 0);
2054     }
2055 }
2056 
GetTcpServerState(TcpServerGetStateContext * context)2057 static bool GetTcpServerState(TcpServerGetStateContext *context)
2058 {
2059     int opt;
2060     socklen_t optLen = sizeof(int);
2061     if (getsockopt(context->GetSocketFd(), SOL_SOCKET, SO_TYPE, &opt, &optLen) < 0) {
2062         context->state_.SetIsClose(true);
2063         return true;
2064     }
2065 
2066     sockaddr sockAddr = {0};
2067     socklen_t len = sizeof(sockaddr);
2068     if (getsockname(context->GetSocketFd(), &sockAddr, &len) < 0) {
2069         context->SetError(errno, strerror(errno));
2070         return false;
2071     }
2072 
2073     sockaddr_in addr4 = {0};
2074     sockaddr_in6 addr6 = {0};
2075     sockaddr *addr = nullptr;
2076     socklen_t addrLen;
2077     if (sockAddr.sa_family == AF_INET) {
2078         addr = reinterpret_cast<sockaddr *>(&addr4);
2079         addrLen = sizeof(addr4);
2080     } else if (sockAddr.sa_family == AF_INET6) {
2081         addr = reinterpret_cast<sockaddr *>(&addr6);
2082         addrLen = sizeof(addr6);
2083     }
2084 
2085     if (addr == nullptr) {
2086         NETSTACK_LOGE("addr family error, address invalid");
2087         context->SetErrorCode(ADDRESS_INVALID);
2088         return false;
2089     }
2090 
2091     if (memset_s(addr, addrLen, 0, addrLen) != EOK) {
2092         NETSTACK_LOGE("memset_s failed!");
2093         return false;
2094     }
2095     len = addrLen;
2096     if (getsockname(context->GetSocketFd(), addr, &len) < 0) {
2097         context->SetError(errno, strerror(errno));
2098         return false;
2099     }
2100 
2101     SetIsBound(sockAddr.sa_family, context, &addr4, &addr6);
2102 
2103     if (opt != SOCK_STREAM) {
2104         return true;
2105     }
2106     SetIsConnected(context);
2107     return true;
2108 }
2109 
ExecTcpServerGetState(TcpServerGetStateContext * context)2110 bool ExecTcpServerGetState(TcpServerGetStateContext *context)
2111 {
2112     if (!CommonUtils::HasInternetPermission()) {
2113         context->SetPermissionDenied(true);
2114         return false;
2115     }
2116     auto manager = context->GetManager();
2117     if (manager == nullptr) {
2118         NETSTACK_LOGE("manager is nullptr");
2119         return false;
2120     }
2121     if (!manager->GetData()) {
2122         return true;
2123     }
2124 
2125     return GetTcpServerState(context);
2126 }
2127 
BindCallback(BindContext * context)2128 napi_value BindCallback(BindContext *context)
2129 {
2130     context->Emit(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
2131                                                   NapiUtils::GetUndefined(context->GetEnv())));
2132     return NapiUtils::GetUndefined(context->GetEnv());
2133 }
2134 
UdpSendCallback(UdpSendContext * context)2135 napi_value UdpSendCallback(UdpSendContext *context)
2136 {
2137     return NapiUtils::GetUndefined(context->GetEnv());
2138 }
2139 
UdpAddMembershipCallback(MulticastMembershipContext * context)2140 napi_value UdpAddMembershipCallback(MulticastMembershipContext *context)
2141 {
2142     return NapiUtils::GetUndefined(context->GetEnv());
2143 }
2144 
UdpDropMembershipCallback(MulticastMembershipContext * context)2145 napi_value UdpDropMembershipCallback(MulticastMembershipContext *context)
2146 {
2147     context->Emit(EVENT_CLOSE, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
2148                                               NapiUtils::GetUndefined(context->GetEnv())));
2149     return NapiUtils::GetUndefined(context->GetEnv());
2150 }
2151 
UdpSetMulticastTTLCallback(MulticastSetTTLContext * context)2152 napi_value UdpSetMulticastTTLCallback(MulticastSetTTLContext *context)
2153 {
2154     return NapiUtils::GetUndefined(context->GetEnv());
2155 }
2156 
UdpGetMulticastTTLCallback(MulticastGetTTLContext * context)2157 napi_value UdpGetMulticastTTLCallback(MulticastGetTTLContext *context)
2158 {
2159     return NapiUtils::CreateInt32(context->GetEnv(), context->GetMulticastTTL());
2160 }
2161 
UdpSetLoopbackModeCallback(MulticastSetLoopbackContext * context)2162 napi_value UdpSetLoopbackModeCallback(MulticastSetLoopbackContext *context)
2163 {
2164     return NapiUtils::GetUndefined(context->GetEnv());
2165 }
2166 
UdpGetLoopbackModeCallback(MulticastGetLoopbackContext * context)2167 napi_value UdpGetLoopbackModeCallback(MulticastGetLoopbackContext *context)
2168 {
2169     return NapiUtils::GetBoolean(context->GetEnv(), context->GetLoopbackMode());
2170 }
2171 
ConnectCallback(ConnectContext * context)2172 napi_value ConnectCallback(ConnectContext *context)
2173 {
2174     context->Emit(EVENT_CONNECT, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
2175                                                 NapiUtils::GetUndefined(context->GetEnv())));
2176     return NapiUtils::GetUndefined(context->GetEnv());
2177 }
2178 
TcpSendCallback(TcpSendContext * context)2179 napi_value TcpSendCallback(TcpSendContext *context)
2180 {
2181     return NapiUtils::GetUndefined(context->GetEnv());
2182 }
2183 
CloseCallback(CloseContext * context)2184 napi_value CloseCallback(CloseContext *context)
2185 {
2186     context->Emit(EVENT_CLOSE, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
2187                                               NapiUtils::GetUndefined(context->GetEnv())));
2188     return NapiUtils::GetUndefined(context->GetEnv());
2189 }
2190 
GetStateCallback(GetStateContext * context)2191 napi_value GetStateCallback(GetStateContext *context)
2192 {
2193     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
2194     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
2195         return NapiUtils::GetUndefined(context->GetEnv());
2196     }
2197 
2198     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
2199     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
2200     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
2201 
2202     return obj;
2203 }
2204 
GetRemoteAddressCallback(GetRemoteAddressContext * context)2205 napi_value GetRemoteAddressCallback(GetRemoteAddressContext *context)
2206 {
2207     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
2208     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
2209         return NapiUtils::GetUndefined(context->GetEnv());
2210     }
2211 
2212     NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
2213     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
2214     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
2215 
2216     return obj;
2217 }
2218 
TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext * context)2219 napi_value TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext *context)
2220 {
2221     return NapiUtils::GetUndefined(context->GetEnv());
2222 }
2223 
UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext * context)2224 napi_value UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext *context)
2225 {
2226     return NapiUtils::GetUndefined(context->GetEnv());
2227 }
2228 
TcpGetSocketFdCallback(GetSocketFdContext * context)2229 napi_value TcpGetSocketFdCallback(GetSocketFdContext *context)
2230 {
2231     int sockFd = context->GetSocketFd();
2232     if (sockFd == -1) {
2233         return NapiUtils::GetUndefined(context->GetEnv());
2234     }
2235     return NapiUtils::CreateUint32(context->GetEnv(), sockFd);
2236 }
2237 
UdpGetSocketFdCallback(GetSocketFdContext * context)2238 napi_value UdpGetSocketFdCallback(GetSocketFdContext *context)
2239 {
2240     int sockFd = context->GetSocketFd();
2241     if (sockFd == -1) {
2242         return NapiUtils::GetUndefined(context->GetEnv());
2243     }
2244     return NapiUtils::CreateUint32(context->GetEnv(), sockFd);
2245 }
2246 
TcpConnectionSendCallback(TcpServerSendContext * context)2247 napi_value TcpConnectionSendCallback(TcpServerSendContext *context)
2248 {
2249     return NapiUtils::GetUndefined(context->GetEnv());
2250 }
2251 
TcpConnectionCloseCallback(TcpServerCloseContext * context)2252 napi_value TcpConnectionCloseCallback(TcpServerCloseContext *context)
2253 {
2254     int32_t clientFd = -1;
2255 
2256     {
2257         std::lock_guard<std::mutex> lock(g_mutex);
2258         auto iter = g_clientFDs.find(context->clientId_);
2259         if (iter != g_clientFDs.end()) {
2260             clientFd = iter->second;
2261         } else {
2262             NETSTACK_LOGE("not find clientId");
2263         }
2264     }
2265 
2266     if (shutdown(clientFd, SHUT_RDWR) != 0) {
2267         NETSTACK_LOGE("socket shutdown failed, socket is %{public}d, errno is %{public}d", clientFd, errno);
2268     }
2269     int ret = close(clientFd);
2270     if (ret < 0) {
2271         NETSTACK_LOGE("sock closed failed, socket is %{public}d, errno is %{public}d", clientFd, errno);
2272     } else {
2273         NETSTACK_LOGI("sock %{public}d closed success", clientFd);
2274         RemoveClientConnection(context->clientId_);
2275     }
2276 
2277     return NapiUtils::GetUndefined(context->GetEnv());
2278 }
2279 
TcpConnectionGetRemoteAddressCallback(TcpServerGetRemoteAddressContext * context)2280 napi_value TcpConnectionGetRemoteAddressCallback(TcpServerGetRemoteAddressContext *context)
2281 {
2282     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
2283     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
2284         return NapiUtils::GetUndefined(context->GetEnv());
2285     }
2286 
2287     NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
2288     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
2289     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
2290 
2291     return obj;
2292 }
2293 
ListenCallback(TcpServerListenContext * context)2294 napi_value ListenCallback(TcpServerListenContext *context)
2295 {
2296     return NapiUtils::GetUndefined(context->GetEnv());
2297 }
2298 
TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext * context)2299 napi_value TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext *context)
2300 {
2301     return NapiUtils::GetUndefined(context->GetEnv());
2302 }
2303 
TcpServerGetStateCallback(TcpServerGetStateContext * context)2304 napi_value TcpServerGetStateCallback(TcpServerGetStateContext *context)
2305 {
2306     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
2307     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
2308         return NapiUtils::GetUndefined(context->GetEnv());
2309     }
2310 
2311     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
2312     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
2313     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
2314 
2315     return obj;
2316 }
2317 } // namespace OHOS::NetStack::Socket::SocketExec
2318 
ConvertAddressToIp(const std::string & address,sa_family_t family)2319 std::string ConvertAddressToIp(const std::string &address, sa_family_t family)
2320 {
2321     if (address.empty()) {
2322         return {};
2323     }
2324     addrinfo hints{};
2325     hints.ai_family = family;
2326     char ipStr[INET6_ADDRSTRLEN] = {0};
2327     addrinfo *res = nullptr;
2328     auto status = getaddrinfo(address.c_str(), nullptr, &hints, &res);
2329     if (status != 0 || res == nullptr) {
2330         return {};
2331     }
2332     std::string ip;
2333     if (res->ai_family == AF_INET) {
2334         auto *ipv4 = reinterpret_cast<struct sockaddr_in *>(res->ai_addr);
2335         auto addr = &(ipv4->sin_addr);
2336         inet_ntop(res->ai_family, addr, ipStr, sizeof(ipStr));
2337         ip = ipStr;
2338     } else {
2339         auto *ipv6 = reinterpret_cast<struct sockaddr_in6 *>(res->ai_addr);
2340         auto addr = &(ipv6->sin6_addr);
2341         inet_ntop(res->ai_family, addr, ipStr, sizeof(ipStr));
2342         ip = ipStr;
2343     }
2344     freeaddrinfo(res);
2345     return ip;
2346 }
2347 
IpMatchFamily(const std::string & address,sa_family_t family)2348 bool IpMatchFamily(const std::string &address, sa_family_t family)
2349 {
2350     if (family == AF_INET6) {
2351         in_addr ipv4{};
2352         if (inet_pton(AF_INET, address.c_str(), &(ipv4.s_addr)) > 0) {
2353             return false;
2354         }
2355     } else if (family == AF_INET) {
2356         in6_addr ipv6{};
2357         if (inet_pton(AF_INET6, address.c_str(), &ipv6) > 0) {
2358             return false;
2359         }
2360     }
2361     return true;
2362 }
2363