• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 
41 static constexpr const int DEFAULT_BUFFER_SIZE = 8192;
42 
43 static constexpr const int DEFAULT_POLL_TIMEOUT = 500; // 0.5 Seconds
44 
45 static constexpr const int ADDRESS_INVALID = 99;
46 
47 static constexpr const int OTHER_ERROR = 100;
48 
49 static constexpr const int SOCKET_ENOTSTR = 60;
50 
51 static constexpr const int UNKNOW_ERROR = -1;
52 
53 static constexpr const int NO_MEMORY = -2;
54 
55 static constexpr const int MSEC_TO_USEC = 1000;
56 
57 static constexpr const int MAX_SEC = 999999999;
58 
59 static constexpr const int USER_LIMIT = 511;
60 
61 static constexpr const int MAX_CLIENTS = 1024;
62 static constexpr const int UNIT_CONVERSION_1000 = 1000;
63 
64 static constexpr const char *TCP_SOCKET_CONNECTION = "TCPSocketConnection";
65 
66 static constexpr const char *TCP_SERVER_ACCEPT_RECV_DATA = "TCPServerAcceptRecvData";
67 
68 static constexpr const char *TCP_SERVER_HANDLE_CLIENT = "TCPServerHandleClient";
69 
70 namespace OHOS::NetStack::Socket::SocketExec {
71 std::map<int32_t, int32_t> g_clientFDs;
72 std::map<int32_t, EventManager *> g_clientEventManagers;
73 std::condition_variable g_cv;
74 std::mutex g_mutex;
75 std::atomic_int g_userCounter = 0;
76 
77 struct MessageData {
78     MessageData() = delete;
MessageDataOHOS::NetStack::Socket::SocketExec::MessageData79     MessageData(void *d, size_t l, const SocketRemoteInfo &info) : data(d), len(l), remoteInfo(info) {}
~MessageDataOHOS::NetStack::Socket::SocketExec::MessageData80     ~MessageData()
81     {
82         if (data) {
83             free(data);
84         }
85     }
86 
87     void *data;
88     size_t len;
89     SocketRemoteInfo remoteInfo;
90 };
91 
92 struct TcpConnection {
93     TcpConnection() = delete;
TcpConnectionOHOS::NetStack::Socket::SocketExec::TcpConnection94     explicit TcpConnection(int32_t clientid) : clientId(clientid) {}
95     ~TcpConnection() = default;
96 
97     int32_t clientId;
98 };
99 
SetIsBound(sa_family_t family,GetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)100 static void SetIsBound(sa_family_t family, GetStateContext *context, const sockaddr_in *addr4,
101                        const sockaddr_in6 *addr6)
102 {
103     if (family == AF_INET) {
104         context->state_.SetIsBound(ntohs(addr4->sin_port) != 0);
105     } else if (family == AF_INET6) {
106         context->state_.SetIsBound(ntohs(addr6->sin6_port) != 0);
107     }
108 }
109 
SetIsConnected(sa_family_t family,GetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)110 static void SetIsConnected(sa_family_t family, GetStateContext *context, const sockaddr_in *addr4,
111                            const sockaddr_in6 *addr6)
112 {
113     if (family == AF_INET) {
114         context->state_.SetIsConnected(ntohs(addr4->sin_port) != 0);
115     } else if (family == AF_INET6) {
116         context->state_.SetIsConnected(ntohs(addr6->sin6_port) != 0);
117     }
118 }
119 
CallbackTemplate(uv_work_t * work,int status)120 template <napi_value (*MakeJsValue)(napi_env, void *)> static void CallbackTemplate(uv_work_t *work, int status)
121 {
122     (void)status;
123 
124     auto workWrapper = static_cast<UvWorkWrapper *>(work->data);
125     napi_env env = workWrapper->env;
126     auto closeScope = [env](napi_handle_scope scope) { NapiUtils::CloseScope(env, scope); };
127     std::unique_ptr<napi_handle_scope__, decltype(closeScope)> scope(NapiUtils::OpenScope(env), closeScope);
128 
129     napi_value obj = MakeJsValue(env, workWrapper->data);
130 
131     std::pair<napi_value, napi_value> arg = {NapiUtils::GetUndefined(workWrapper->env), obj};
132     workWrapper->manager->Emit(workWrapper->type, arg);
133 
134     delete workWrapper;
135     delete work;
136 }
137 
MakeError(napi_env env,void * errCode)138 static napi_value MakeError(napi_env env, void *errCode)
139 {
140     auto code = reinterpret_cast<int32_t *>(errCode);
141     auto deleter = [](const int32_t *p) { delete p; };
142     std::unique_ptr<int32_t, decltype(deleter)> handler(code, deleter);
143 
144     napi_value err = NapiUtils::CreateObject(env);
145     if (NapiUtils::GetValueType(env, err) != napi_object) {
146         return NapiUtils::GetUndefined(env);
147     }
148     NapiUtils::SetInt32Property(env, err, KEY_ERROR_CODE, *code);
149     return err;
150 }
151 
MakeClose(napi_env env,void * data)152 static napi_value MakeClose(napi_env env, void *data)
153 {
154     (void)data;
155     NETSTACK_LOGI("go to MakeClose");
156     napi_value obj = NapiUtils::CreateObject(env);
157     if (NapiUtils::GetValueType(env, obj) != napi_object) {
158         return NapiUtils::GetUndefined(env);
159     }
160 
161     return obj;
162 }
163 
TcpServerConnectionFinalize(napi_env,void * data,void *)164 void TcpServerConnectionFinalize(napi_env, void *data, void *)
165 {
166     NETSTACK_LOGI("socket handle is finalized");
167     auto manager = static_cast<EventManager *>(data);
168     if (manager != nullptr) {
169         NETSTACK_LOGI("manager != nullpt");
170         int clientIndex = -1;
171         std::lock_guard<std::mutex> lock(g_mutex);
172         for (auto it = g_clientEventManagers.begin(); it != g_clientEventManagers.end(); ++it) {
173             if (it->second == manager) {
174                 clientIndex = it->first;
175                 g_clientEventManagers.erase(it);
176                 break;
177             }
178         }
179         auto clientIter = g_clientFDs.find(clientIndex);
180         if (clientIter != g_clientFDs.end()) {
181             if (clientIter->second != -1) {
182                 NETSTACK_LOGI("close socketfd %{public}d", clientIter->second);
183                 close(clientIter->second);
184                 clientIter->second = -1;
185             }
186         }
187     }
188     EventManager::SetInvalid(manager);
189 }
190 
NewInstanceWithConstructor(napi_env env,napi_callback_info info,napi_value jsConstructor,int32_t counter)191 napi_value NewInstanceWithConstructor(napi_env env, napi_callback_info info, napi_value jsConstructor, int32_t counter)
192 {
193     napi_value result = nullptr;
194     NAPI_CALL(env, napi_new_instance(env, jsConstructor, 0, nullptr, &result));
195 
196     EventManager *manager = new EventManager();
197     {
198         std::lock_guard<std::mutex> lock(g_mutex);
199         g_clientEventManagers.insert(std::pair<int32_t, EventManager *>(counter, manager));
200         g_cv.notify_one();
201     }
202 
203     manager->SetData(reinterpret_cast<void *>(counter));
204     EventManager::SetValid(manager);
205     napi_wrap(env, result, reinterpret_cast<void *>(manager), TcpServerConnectionFinalize, nullptr, nullptr);
206     return result;
207 } // namespace OHOS::NetStack::Socket::SocketExec
208 
ConstructTCPSocketConnection(napi_env env,napi_callback_info info,int32_t counter)209 napi_value ConstructTCPSocketConnection(napi_env env, napi_callback_info info, int32_t counter)
210 {
211     napi_value jsConstructor = nullptr;
212     std::initializer_list<napi_property_descriptor> properties = {
213         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_SEND,
214                               SocketModuleExports::TCPConnection::Send),
215         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_CLOSE,
216                               SocketModuleExports::TCPConnection::Close),
217         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_GET_REMOTE_ADDRESS,
218                               SocketModuleExports::TCPConnection::GetRemoteAddress),
219         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_ON, SocketModuleExports::TCPConnection::On),
220         DECLARE_NAPI_FUNCTION(SocketModuleExports::TCPConnection::FUNCTION_OFF,
221                               SocketModuleExports::TCPConnection::Off),
222     };
223 
224     auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
225         napi_value thisVal = nullptr;
226         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVal, nullptr));
227 
228         return thisVal;
229     };
230 
231     napi_property_descriptor descriptors[properties.size()];
232     std::copy(properties.begin(), properties.end(), descriptors);
233 
234     NAPI_CALL_BASE(env,
235                    napi_define_class(env, TCP_SOCKET_CONNECTION, NAPI_AUTO_LENGTH, constructor, nullptr,
236                                      properties.size(), descriptors, &jsConstructor),
237                    NapiUtils::GetUndefined(env));
238 
239     if (jsConstructor != nullptr) {
240         napi_value result = NewInstanceWithConstructor(env, info, jsConstructor, counter);
241         NapiUtils::SetInt32Property(env, result, SocketModuleExports::TCPConnection::PROPERTY_CLIENT_ID, counter);
242         return result;
243     }
244     return NapiUtils::GetUndefined(env);
245 }
246 
MakeTcpConnectionMessage(napi_env env,void * para)247 static napi_value MakeTcpConnectionMessage(napi_env env, void *para)
248 {
249     auto netConnection = reinterpret_cast<TcpConnection *>(para);
250     auto deleter = [](const TcpConnection *p) { delete p; };
251     std::unique_ptr<TcpConnection, decltype(deleter)> handler(netConnection, deleter);
252 
253     napi_callback_info info = nullptr;
254     return ConstructTCPSocketConnection(env, info, netConnection->clientId);
255 }
256 
MakeAddressString(sockaddr * addr)257 static std::string MakeAddressString(sockaddr *addr)
258 {
259     if (addr->sa_family == AF_INET) {
260         auto *addr4 = reinterpret_cast<sockaddr_in *>(addr);
261         const char *str = inet_ntoa(addr4->sin_addr);
262         if (str == nullptr || strlen(str) == 0) {
263             return {};
264         }
265         return str;
266     } else if (addr->sa_family == AF_INET6) {
267         auto *addr6 = reinterpret_cast<sockaddr_in6 *>(addr);
268         char str[INET6_ADDRSTRLEN] = {0};
269         if (inet_ntop(AF_INET6, &addr6->sin6_addr, str, INET6_ADDRSTRLEN) == nullptr || strlen(str) == 0) {
270             return {};
271         }
272         return str;
273     }
274     return {};
275 }
276 
MakeJsMessageParam(napi_env env,napi_value msgBuffer,SocketRemoteInfo * remoteInfo)277 static napi_value MakeJsMessageParam(napi_env env, napi_value msgBuffer, SocketRemoteInfo *remoteInfo)
278 {
279     napi_value obj = NapiUtils::CreateObject(env);
280     if (NapiUtils::GetValueType(env, obj) != napi_object) {
281         return nullptr;
282     }
283     if (NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
284         NapiUtils::SetNamedProperty(env, obj, KEY_MESSAGE, msgBuffer);
285     }
286     napi_value jsRemoteInfo = NapiUtils::CreateObject(env);
287     if (NapiUtils::GetValueType(env, jsRemoteInfo) != napi_object) {
288         return nullptr;
289     }
290     NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_ADDRESS, remoteInfo->GetAddress());
291     NapiUtils::SetStringPropertyUtf8(env, jsRemoteInfo, KEY_FAMILY, remoteInfo->GetFamily());
292     NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_PORT, remoteInfo->GetPort());
293     NapiUtils::SetUint32Property(env, jsRemoteInfo, KEY_SIZE, remoteInfo->GetSize());
294 
295     NapiUtils::SetNamedProperty(env, obj, KEY_REMOTE_INFO, jsRemoteInfo);
296     return obj;
297 }
298 
MakeMessage(napi_env env,void * para)299 static napi_value MakeMessage(napi_env env, void *para)
300 {
301     auto manager = reinterpret_cast<EventManager *>(para);
302     auto messageData = reinterpret_cast<MessageData *>(manager->GetQueueData());
303     manager->PopQueueData();
304     auto deleter = [](const MessageData *p) { delete p; };
305     std::unique_ptr<MessageData, decltype(deleter)> handler(messageData, deleter);
306 
307     if (messageData == nullptr || messageData->data == nullptr || messageData->len == 0) {
308         return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &messageData->remoteInfo);
309     }
310 
311     void *dataHandle = nullptr;
312     napi_value msgBuffer = NapiUtils::CreateArrayBuffer(env, messageData->len, &dataHandle);
313     if (dataHandle == nullptr || !NapiUtils::ValueIsArrayBuffer(env, msgBuffer)) {
314         return MakeJsMessageParam(env, NapiUtils::GetUndefined(env), &messageData->remoteInfo);
315     }
316 
317     int result = memcpy_s(dataHandle, messageData->len, messageData->data, messageData->len);
318     if (result != EOK) {
319         NETSTACK_LOGI("copy ret %{public}d", result);
320         return NapiUtils::GetUndefined(env);
321     }
322 
323     return MakeJsMessageParam(env, msgBuffer, &messageData->remoteInfo);
324 }
325 
OnRecvMessage(EventManager * manager,void * data,size_t len,sockaddr * addr)326 static bool OnRecvMessage(EventManager *manager, void *data, size_t len, sockaddr *addr)
327 {
328     if (data == nullptr || len == 0) {
329         return false;
330     }
331 
332     SocketRemoteInfo remoteInfo;
333     std::string address = MakeAddressString(addr);
334     if (address.empty()) {
335         manager->EmitByUv(EVENT_ERROR, new int32_t(ADDRESS_INVALID), CallbackTemplate<MakeError>);
336         return false;
337     }
338     remoteInfo.SetAddress(address);
339     remoteInfo.SetFamily(addr->sa_family);
340     if (addr->sa_family == AF_INET) {
341         auto *addr4 = reinterpret_cast<sockaddr_in *>(addr);
342         remoteInfo.SetPort(ntohs(addr4->sin_port));
343     } else if (addr->sa_family == AF_INET6) {
344         auto *addr6 = reinterpret_cast<sockaddr_in6 *>(addr);
345         remoteInfo.SetPort(ntohs(addr6->sin6_port));
346     }
347     remoteInfo.SetSize(len);
348 
349     auto *messageStruct = new MessageData(data, len, remoteInfo);
350     manager->SetQueueData(reinterpret_cast<void *>(messageStruct));
351     manager->EmitByUv(EVENT_MESSAGE, manager, CallbackTemplate<MakeMessage>);
352     return true;
353 }
354 
355 class MessageCallback {
356 public:
357     MessageCallback() = delete;
358 
359     virtual ~MessageCallback() = default;
360 
MessageCallback(EventManager * manager)361     explicit MessageCallback(EventManager *manager) : manager_(manager) {}
362 
363     virtual void OnError(int err) const = 0;
364 
365     virtual void OnCloseMessage(EventManager *manager) const = 0;
366 
367     virtual bool OnMessage(void *data, size_t dataLen, sockaddr *addr) const = 0;
368 
369     virtual bool OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr, EventManager *manager) const = 0;
370 
371     virtual void OnTcpConnectionMessage(int32_t id) const = 0;
372 
373     [[nodiscard]] EventManager *GetEventManager() const;
374 
375 protected:
376     EventManager *manager_;
377 };
378 
GetEventManager() const379 EventManager *MessageCallback::GetEventManager() const
380 {
381     return manager_;
382 }
383 
384 class TcpMessageCallback final : public MessageCallback {
385 public:
386     TcpMessageCallback() = delete;
387 
388     ~TcpMessageCallback() override = default;
389 
TcpMessageCallback(EventManager * manager)390     explicit TcpMessageCallback(EventManager *manager) : MessageCallback(manager) {}
391 
OnError(int err) const392     void OnError(int err) const override
393     {
394         if (EventManager::IsManagerValid(manager_)) {
395             manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
396             return;
397         }
398         NETSTACK_LOGI("tcp socket handle has been finalized, manager is invalid");
399     }
400 
OnCloseMessage(EventManager * manager) const401     void OnCloseMessage(EventManager *manager) const override
402     {
403         manager->EmitByUv(EVENT_CLOSE, nullptr, CallbackTemplate<MakeClose>);
404     }
405 
OnMessage(void * data,size_t dataLen,sockaddr * addr) const406     bool OnMessage(void *data, size_t dataLen, sockaddr *addr) const override
407     {
408         (void)addr;
409         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData()));
410         if (sock == 0) {
411             return false;
412         }
413         sockaddr sockAddr = {0};
414         socklen_t len = sizeof(sockaddr);
415         int ret = getsockname(sock, &sockAddr, &len);
416         if (ret < 0) {
417             return false;
418         }
419 
420         if (sockAddr.sa_family == AF_INET) {
421             sockaddr_in addr4 = {0};
422             socklen_t len4 = sizeof(sockaddr_in);
423 
424             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr4), &len4);
425             if (ret < 0) {
426                 return false;
427             }
428             return OnRecvMessage(manager_, data, dataLen, reinterpret_cast<sockaddr *>(&addr4));
429         } else if (sockAddr.sa_family == AF_INET6) {
430             sockaddr_in6 addr6 = {0};
431             socklen_t len6 = sizeof(sockaddr_in6);
432 
433             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr6), &len6);
434             if (ret < 0) {
435                 return false;
436             }
437             return OnRecvMessage(manager_, data, dataLen, reinterpret_cast<sockaddr *>(&addr6));
438         }
439         return false;
440     }
441 
OnMessage(int sock,void * data,size_t dataLen,sockaddr * addr,EventManager * manager) const442     bool OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr, EventManager *manager) const override
443     {
444         (void)addr;
445         if (static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData())) == 0) {
446             return false;
447         }
448         sockaddr sockAddr = {0};
449         socklen_t len = sizeof(sockaddr);
450         int ret = getsockname(sock, &sockAddr, &len);
451         if (ret < 0) {
452             return false;
453         }
454 
455         if (sockAddr.sa_family == AF_INET) {
456             sockaddr_in addr4 = {0};
457             socklen_t len4 = sizeof(sockaddr_in);
458 
459             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr4), &len4);
460             if (ret < 0) {
461                 return false;
462             }
463             return OnRecvMessage(manager, data, dataLen, reinterpret_cast<sockaddr *>(&addr4));
464         } else if (sockAddr.sa_family == AF_INET6) {
465             sockaddr_in6 addr6 = {0};
466             socklen_t len6 = sizeof(sockaddr_in6);
467 
468             ret = getpeername(sock, reinterpret_cast<sockaddr *>(&addr6), &len6);
469             if (ret < 0) {
470                 return false;
471             }
472             return OnRecvMessage(manager, data, dataLen, reinterpret_cast<sockaddr *>(&addr6));
473         }
474         return false;
475     }
476 
OnTcpConnectionMessage(int32_t id) const477     void OnTcpConnectionMessage(int32_t id) const override
478     {
479         manager_->EmitByUv(EVENT_CONNECT, new TcpConnection(id), CallbackTemplate<MakeTcpConnectionMessage>);
480     }
481 };
482 
483 class UdpMessageCallback final : public MessageCallback {
484 public:
485     UdpMessageCallback() = delete;
486 
487     ~UdpMessageCallback() override = default;
488 
UdpMessageCallback(EventManager * manager)489     explicit UdpMessageCallback(EventManager *manager) : MessageCallback(manager) {}
490 
OnError(int err) const491     void OnError(int err) const override
492     {
493         if (EventManager::IsManagerValid(manager_)) {
494             manager_->EmitByUv(EVENT_ERROR, new int(err), CallbackTemplate<MakeError>);
495             return;
496         }
497         NETSTACK_LOGI("udp socket handle has been finalized, manager is invalid");
498     }
499 
OnCloseMessage(EventManager * manager) const500     void OnCloseMessage(EventManager *manager) const override {}
501 
OnMessage(void * data,size_t dataLen,sockaddr * addr) const502     bool OnMessage(void *data, size_t dataLen, sockaddr *addr) const override
503     {
504         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData()));
505         if (sock == 0) {
506             return false;
507         }
508         return OnRecvMessage(manager_, data, dataLen, addr);
509     }
510 
OnMessage(int sock,void * data,size_t dataLen,sockaddr * addr,EventManager * manager) const511     bool OnMessage(int sock, void *data, size_t dataLen, sockaddr *addr, EventManager *manager) const override
512     {
513         if (static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData())) == 0) {
514             return false;
515         }
516         return true;
517     }
518 
OnTcpConnectionMessage(int32_t id) const519     void OnTcpConnectionMessage(int32_t id) const override {}
520 };
521 
GetAddr(NetAddress * address,sockaddr_in * addr4,sockaddr_in6 * addr6,sockaddr ** addr,socklen_t * len)522 static void GetAddr(NetAddress *address, sockaddr_in *addr4, sockaddr_in6 *addr6, sockaddr **addr, socklen_t *len)
523 {
524     sa_family_t family = address->GetSaFamily();
525     if (family == AF_INET) {
526         addr4->sin_family = AF_INET;
527         addr4->sin_port = htons(address->GetPort());
528         addr4->sin_addr.s_addr = inet_addr(address->GetAddress().c_str());
529         *addr = reinterpret_cast<sockaddr *>(addr4);
530         *len = sizeof(sockaddr_in);
531     } else if (family == AF_INET6) {
532         addr6->sin6_family = AF_INET6;
533         addr6->sin6_port = htons(address->GetPort());
534         inet_pton(AF_INET6, address->GetAddress().c_str(), &addr6->sin6_addr);
535         *addr = reinterpret_cast<sockaddr *>(addr6);
536         *len = sizeof(sockaddr_in6);
537     }
538 }
539 
MakeNonBlock(int sock)540 static bool MakeNonBlock(int sock)
541 {
542     int flags = fcntl(sock, F_GETFL, 0);
543     while (flags == -1 && errno == EINTR) {
544         flags = fcntl(sock, F_GETFL, 0);
545     }
546     if (flags == -1) {
547         NETSTACK_LOGE("make non block failed, socket is %{public}d, errno is %{public}d", sock, errno);
548         return false;
549     }
550     int ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
551     while (ret == -1 && errno == EINTR) {
552         ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
553     }
554     if (ret == -1) {
555         NETSTACK_LOGE("make non block failed, socket is %{public}d, errno is %{public}d", sock, errno);
556         return false;
557     }
558     return true;
559 }
560 
PollFd(pollfd * fds,nfds_t num,int timeout)561 static bool PollFd(pollfd *fds, nfds_t num, int timeout)
562 {
563     int ret = poll(fds, num, timeout);
564     if (ret == -1) {
565         NETSTACK_LOGE("poll to send failed, socket is %{public}d, errno is %{public}d", fds->fd, errno);
566         return false;
567     }
568     if (ret == 0) {
569         NETSTACK_LOGE("poll to send timeout, socket is %{public}d, errno is %{public}d", fds->fd, errno);
570         return false;
571     }
572     return true;
573 }
574 
ConfirmSocketTimeoutMs(int sock,int type,int defaultValue)575 static int ConfirmSocketTimeoutMs(int sock, int type, int defaultValue)
576 {
577     timeval timeout;
578     socklen_t optlen = sizeof(timeout);
579     if (getsockopt(sock, SOL_SOCKET, type, reinterpret_cast<void *>(&timeout), &optlen) < 0) {
580         NETSTACK_LOGE("get timeout failed, type: %{public}d, sock: %{public}d, errno: %{public}d", type, sock, errno);
581         return defaultValue;
582     }
583     auto socketTimeoutMs = timeout.tv_sec * UNIT_CONVERSION_1000 + timeout.tv_usec / UNIT_CONVERSION_1000;
584     return socketTimeoutMs == 0 ? defaultValue : socketTimeoutMs;
585 }
586 
PollSendData(int sock,const char * data,size_t size,sockaddr * addr,socklen_t addrLen)587 static bool PollSendData(int sock, const char *data, size_t size, sockaddr *addr, socklen_t addrLen)
588 {
589     int bufferSize = DEFAULT_BUFFER_SIZE;
590     int opt = 0;
591     socklen_t optLen = sizeof(opt);
592     if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
593         bufferSize = opt;
594     }
595     int sockType = 0;
596     optLen = sizeof(sockType);
597     if (getsockopt(sock, SOL_SOCKET, SO_TYPE, reinterpret_cast<void *>(&sockType), &optLen) < 0) {
598         NETSTACK_LOGI("get sock opt sock type failed, socket is %{public}d, errno is %{public}d", sock, errno);
599         return false;
600     }
601 
602     auto curPos = data;
603     auto leftSize = size;
604     nfds_t num = 1;
605     pollfd fds[1] = {{0}};
606     fds[0].fd = sock;
607     fds[0].events = 0;
608     fds[0].events |= POLLOUT;
609 
610     while (leftSize > 0) {
611         if (!PollFd(fds, num, DEFAULT_BUFFER_SIZE)) {
612             return false;
613         }
614         size_t sendSize = (sockType == SOCK_STREAM ? leftSize : std::min<size_t>(leftSize, bufferSize));
615         auto sendLen = sendto(sock, curPos, sendSize, 0, addr, addrLen);
616         if (sendLen < 0) {
617             if (errno == EAGAIN) {
618                 continue;
619             }
620             NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", sock, errno);
621             return false;
622         }
623         if (sendLen == 0) {
624             break;
625         }
626         curPos += sendLen;
627         leftSize -= sendLen;
628     }
629 
630     if (leftSize != 0) {
631         NETSTACK_LOGE("send not complete, socket is %{public}d, errno is %{public}d", sock, errno);
632         return false;
633     }
634     return true;
635 }
636 
TcpSendEvent(TcpSendContext * context)637 static bool TcpSendEvent(TcpSendContext *context)
638 {
639     std::string encoding = context->options.GetEncoding();
640     (void)encoding;
641     /* no use for now */
642 
643     sockaddr sockAddr = {0};
644     socklen_t len = sizeof(sockaddr);
645     if (getsockname(context->GetSocketFd(), &sockAddr, &len) < 0) {
646         NETSTACK_LOGE("get sock name failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
647         context->SetErrorCode(SOCKET_ENOTSTR);
648         // reason: Crossplatform; Possible causes: socketfd error, socket type error, socket status error
649         // socket net connect, socket closed, socket option error
650         NETSTACK_LOGE("set errorCode is %{public}d", SOCKET_ENOTSTR);
651         return false;
652     }
653     bool connected = false;
654     if (sockAddr.sa_family == AF_INET) {
655         sockaddr_in addr4 = {0};
656         socklen_t len4 = sizeof(addr4);
657         int ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr4), &len4);
658         if (ret >= 0 && addr4.sin_port != 0) {
659             connected = true;
660         }
661     } else if (sockAddr.sa_family == AF_INET6) {
662         sockaddr_in6 addr6 = {0};
663         socklen_t len6 = sizeof(addr6);
664         int ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr6), &len6);
665         if (ret >= 0 && addr6.sin6_port != 0) {
666             connected = true;
667         }
668     }
669 
670     if (!connected) {
671         NETSTACK_LOGE("sock is not connect to remote, socket is %{public}d, errno is %{public}d",
672                       context->GetSocketFd(), errno);
673         context->SetErrorCode(errno);
674         return false;
675     }
676 
677     if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(),
678                       nullptr, 0)) {
679         NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
680         context->SetErrorCode(errno);
681         return false;
682     }
683     return true;
684 }
685 
UdpSendEvent(UdpSendContext * context)686 static bool UdpSendEvent(UdpSendContext *context)
687 {
688     sockaddr_in addr4 = {0};
689     sockaddr_in6 addr6 = {0};
690     sockaddr *addr = nullptr;
691     socklen_t len;
692     GetAddr(&context->options.address, &addr4, &addr6, &addr, &len);
693     if (addr == nullptr) {
694         NETSTACK_LOGE("get sock name failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
695         context->SetErrorCode(ADDRESS_INVALID);
696         return false;
697     }
698 
699     if (!PollSendData(context->GetSocketFd(), context->options.GetData().c_str(), context->options.GetData().size(),
700                       addr, len)) {
701         NETSTACK_LOGE("send failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
702         context->SetErrorCode(errno);
703         return false;
704     }
705     return true;
706 }
707 
ConfirmBufferSize(int sock)708 static int ConfirmBufferSize(int sock)
709 {
710     int bufferSize = DEFAULT_BUFFER_SIZE;
711     int opt = 0;
712     socklen_t optLen = sizeof(opt);
713     if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&opt), &optLen) >= 0 && opt > 0) {
714         bufferSize = opt;
715     }
716     return bufferSize;
717 }
718 
IsTCPSocket(int sockfd)719 static bool IsTCPSocket(int sockfd)
720 {
721     int optval;
722     socklen_t optlen = sizeof(optval);
723 
724     if (getsockopt(sockfd, SOL_SOCKET, SO_PROTOCOL, &optval, &optlen) != 0) {
725         return false;
726     }
727     return optval == IPPROTO_TCP;
728 }
729 
PollRecvData(int sock,sockaddr * addr,socklen_t addrLen,const MessageCallback & callback)730 static void PollRecvData(int sock, sockaddr *addr, socklen_t addrLen, const MessageCallback &callback)
731 {
732     int bufferSize = ConfirmBufferSize(sock);
733 
734     auto deleter = [](char *s) { free(reinterpret_cast<void *>(s)); };
735     std::unique_ptr<char, decltype(deleter)> buf(reinterpret_cast<char *>(malloc(bufferSize)), deleter);
736     if (buf == nullptr) {
737         callback.OnError(NO_MEMORY);
738         return;
739     }
740 
741     auto addrDeleter = [](sockaddr *a) { free(reinterpret_cast<void *>(a)); };
742     std::unique_ptr<sockaddr, decltype(addrDeleter)> pAddr(addr, addrDeleter);
743 
744     nfds_t num = 1;
745     pollfd fds[1] = {{sock, POLLIN, 0}};
746 
747     int recvTimeoutMs = ConfirmSocketTimeoutMs(sock, SO_RCVTIMEO, DEFAULT_POLL_TIMEOUT);
748     while (true) {
749         int ret = poll(fds, num, recvTimeoutMs);
750         if (ret < 0) {
751             NETSTACK_LOGE("poll to recv failed, socket is %{public}d, errno is %{public}d", sock, errno);
752             callback.OnError(errno);
753             return;
754         }
755         if (ret == 0) {
756             continue;
757         }
758         if (!EventManager::IsManagerValid(callback.GetEventManager()) ||
759             static_cast<int>(reinterpret_cast<uint64_t>(callback.GetEventManager()->GetData())) == 0) {
760             return;
761         }
762         (void)memset_s(buf.get(), bufferSize, 0, bufferSize);
763         socklen_t tempAddrLen = addrLen;
764         auto recvLen = recvfrom(sock, buf.get(), bufferSize, 0, addr, &tempAddrLen);
765         if (recvLen <= 0) {
766             if (errno == EAGAIN || (recvLen == 0 && !IsTCPSocket(sock))) {
767                 continue;
768             }
769             NETSTACK_LOGE("recv fail, socket:%{public}d, recvLen:%{public}zd, errno:%{public}d", sock, recvLen, errno);
770             callback.OnError(recvLen == 0 && IsTCPSocket(sock) ? UNKNOW_ERROR : errno);
771             return;
772         }
773 
774         void *data = malloc(recvLen);
775         if (data == nullptr) {
776             callback.OnError(NO_MEMORY);
777             return;
778         }
779         if (memcpy_s(data, recvLen, buf.get(), recvLen) != EOK || !callback.OnMessage(data, recvLen, addr)) {
780             free(data);
781         }
782     }
783 }
784 
NonBlockConnect(int sock,sockaddr * addr,socklen_t addrLen,uint32_t timeoutMSec)785 static bool NonBlockConnect(int sock, sockaddr *addr, socklen_t addrLen, uint32_t timeoutMSec)
786 {
787     int ret = connect(sock, addr, addrLen);
788     if (ret >= 0) {
789         return true;
790     }
791     if (errno != EINPROGRESS) {
792         return false;
793     }
794 
795     fd_set set = {0};
796     FD_ZERO(&set);
797     FD_SET(sock, &set);
798     if (timeoutMSec == 0) {
799         timeoutMSec = DEFAULT_CONNECT_TIMEOUT;
800     }
801 
802     timeval timeout = {
803         .tv_sec = (timeoutMSec / MSEC_TO_USEC) % MAX_SEC,
804         .tv_usec = (timeoutMSec % MSEC_TO_USEC) * MSEC_TO_USEC,
805     };
806 
807     ret = select(sock + 1, nullptr, &set, nullptr, &timeout);
808     if (ret < 0) {
809         NETSTACK_LOGE("select failed, socket is %{public}d, errno is %{public}d", sock, errno);
810         return false;
811     } else if (ret == 0) {
812         NETSTACK_LOGE("timeout!");
813         return false;
814     }
815 
816     int err = 0;
817     socklen_t optLen = sizeof(err);
818     ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, reinterpret_cast<void *>(&err), &optLen);
819     if (ret < 0) {
820         return false;
821     }
822     if (err != 0) {
823         NETSTACK_LOGE("NonBlockConnect exec failed, socket is %{public}d, errno is %{public}d", sock, errno);
824         return false;
825     }
826     return true;
827 }
828 
SetBaseOptions(int sock,ExtraOptionsBase * option)829 static bool SetBaseOptions(int sock, ExtraOptionsBase *option)
830 {
831     if (option->GetReceiveBufferSize() != 0) {
832         int size = (int)option->GetReceiveBufferSize();
833         if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
834             return false;
835         }
836     }
837 
838     if (option->GetSendBufferSize() != 0) {
839         int size = (int)option->GetSendBufferSize();
840         if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<void *>(&size), sizeof(size)) < 0) {
841             return false;
842         }
843     }
844 
845     if (option->IsReuseAddress()) {
846         int reuse = 1;
847         if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&reuse), sizeof(reuse)) < 0) {
848             return false;
849         }
850     }
851 
852     if (option->GetSocketTimeout() != 0) {
853         timeval timeout = {(int)option->GetSocketTimeout(), 0};
854         if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
855             return false;
856         }
857         if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<void *>(&timeout), sizeof(timeout)) < 0) {
858             return false;
859         }
860     }
861 
862     return true;
863 }
864 
MakeTcpSocket(sa_family_t family)865 int MakeTcpSocket(sa_family_t family)
866 {
867     if (family != AF_INET && family != AF_INET6) {
868         return -1;
869     }
870     int sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
871     NETSTACK_LOGI("new tcp socket is %{public}d", sock);
872     if (sock < 0) {
873         NETSTACK_LOGE("make tcp socket failed, errno is %{public}d", errno);
874         return -1;
875     }
876     if (!MakeNonBlock(sock)) {
877         close(sock);
878         return -1;
879     }
880     return sock;
881 }
882 
MakeUdpSocket(sa_family_t family)883 int MakeUdpSocket(sa_family_t family)
884 {
885     if (family != AF_INET && family != AF_INET6) {
886         return -1;
887     }
888     int sock = socket(family, SOCK_DGRAM, IPPROTO_UDP);
889     NETSTACK_LOGI("new udp socket is %{public}d", sock);
890     if (sock < 0) {
891         NETSTACK_LOGE("make udp socket failed, errno is %{public}d", errno);
892         return -1;
893     }
894     if (!MakeNonBlock(sock)) {
895         close(sock);
896         return -1;
897     }
898     return sock;
899 }
900 
ExecBind(BindContext * context)901 bool ExecBind(BindContext *context)
902 {
903     sockaddr_in addr4 = {0};
904     sockaddr_in6 addr6 = {0};
905     sockaddr *addr = nullptr;
906     socklen_t len;
907     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
908     if (addr == nullptr) {
909         NETSTACK_LOGE("addr family error, address invalid");
910         context->SetErrorCode(ADDRESS_INVALID);
911         return false;
912     }
913 
914     if (bind(context->GetSocketFd(), addr, len) < 0) {
915         if (errno != EADDRINUSE) {
916             NETSTACK_LOGE("bind failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
917             context->SetErrorCode(errno);
918             return false;
919         }
920         if (addr->sa_family == AF_INET) {
921             NETSTACK_LOGI("distribute a random port");
922             addr4.sin_port = 0; /* distribute a random port */
923         } else if (addr->sa_family == AF_INET6) {
924             NETSTACK_LOGI("distribute a random port");
925             addr6.sin6_port = 0; /* distribute a random port */
926         }
927         if (bind(context->GetSocketFd(), addr, len) < 0) {
928             NETSTACK_LOGE("rebind failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
929             context->SetErrorCode(errno);
930             return false;
931         }
932         NETSTACK_LOGI("rebind success");
933     }
934     NETSTACK_LOGI("bind success");
935 
936     return true;
937 }
938 
ExecUdpBind(BindContext * context)939 bool ExecUdpBind(BindContext *context)
940 {
941     if (!ExecBind(context)) {
942         return false;
943     }
944 
945     sockaddr_in addr4 = {0};
946     sockaddr_in6 addr6 = {0};
947     sockaddr *addr = nullptr;
948     socklen_t len;
949     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
950     if (addr == nullptr) {
951         NETSTACK_LOGE("get addr failed, addr family error, address invalid");
952         context->SetErrorCode(ADDRESS_INVALID);
953         return false;
954     }
955 
956     if (addr->sa_family == AF_INET) {
957         void *pTmpAddr = malloc(sizeof(addr4));
958         auto pAddr4 = reinterpret_cast<sockaddr *>(pTmpAddr);
959         if (pAddr4 == nullptr) {
960             NETSTACK_LOGE("no memory!");
961             return false;
962         }
963         NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr4, sizeof(addr4), &addr4, sizeof(addr4)));
964         std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr4, sizeof(addr4),
965                                   UdpMessageCallback(context->GetManager()));
966         serviceThread.detach();
967     } else if (addr->sa_family == AF_INET6) {
968         void *pTmpAddr = malloc(len);
969         auto pAddr6 = reinterpret_cast<sockaddr *>(pTmpAddr);
970         if (pAddr6 == nullptr) {
971             NETSTACK_LOGE("no memory!");
972             return false;
973         }
974         NETSTACK_LOGI("copy ret = %{public}d", memcpy_s(pAddr6, sizeof(addr6), &addr6, sizeof(addr6)));
975         std::thread serviceThread(PollRecvData, context->GetSocketFd(), pAddr6, sizeof(addr6),
976                                   UdpMessageCallback(context->GetManager()));
977         serviceThread.detach();
978     }
979 
980     return true;
981 }
982 
ExecUdpSend(UdpSendContext * context)983 bool ExecUdpSend(UdpSendContext *context)
984 {
985     if (!CommonUtils::HasInternetPermission()) {
986         context->SetPermissionDenied(true);
987         return false;
988     }
989     bool result = true;
990 #ifdef ENABLE_EVENT_HANDLER
991     auto manager = context->GetManager();
992     auto eventHandler = manager->GetNetstackEventHandler();
993     if (!eventHandler) {
994         NETSTACK_LOGE("netstack eventHandler is nullptr");
995         return false;
996     }
997     eventHandler->PostSyncTask([&result, context]() { result = UdpSendEvent(context); });
998     NapiUtils::CreateUvQueueWorkEnhanced(context->GetEnv(), context, SocketAsyncWork::UdpSendCallback);
999 #endif
1000     return result;
1001 }
1002 
ExecTcpBind(BindContext * context)1003 bool ExecTcpBind(BindContext *context)
1004 {
1005     return ExecBind(context);
1006 }
1007 
ExecConnect(ConnectContext * context)1008 bool ExecConnect(ConnectContext *context)
1009 {
1010     if (!CommonUtils::HasInternetPermission()) {
1011         context->SetPermissionDenied(true);
1012         return false;
1013     }
1014 
1015     sockaddr_in addr4 = {0};
1016     sockaddr_in6 addr6 = {0};
1017     sockaddr *addr = nullptr;
1018     socklen_t len;
1019     GetAddr(&context->options.address, &addr4, &addr6, &addr, &len);
1020     if (addr == nullptr) {
1021         NETSTACK_LOGE("addr family error, address invalid");
1022         context->SetErrorCode(ADDRESS_INVALID);
1023         return false;
1024     }
1025 
1026     if (!NonBlockConnect(context->GetSocketFd(), addr, len, context->options.GetTimeout())) {
1027         NETSTACK_LOGE("connect errno %{public}d", errno);
1028         context->SetErrorCode(errno);
1029         return false;
1030     }
1031 
1032     NETSTACK_LOGI("connect success");
1033     std::thread serviceThread(PollRecvData, context->GetSocketFd(), nullptr, 0,
1034                               TcpMessageCallback(context->GetManager()));
1035     serviceThread.detach();
1036     return true;
1037 }
1038 
ExecTcpSend(TcpSendContext * context)1039 bool ExecTcpSend(TcpSendContext *context)
1040 {
1041     if (!CommonUtils::HasInternetPermission()) {
1042         context->SetPermissionDenied(true);
1043         return false;
1044     }
1045 
1046     bool result = true;
1047 #ifdef ENABLE_EVENT_HANDLER
1048     auto manager = context->GetManager();
1049     auto eventHandler = manager->GetNetstackEventHandler();
1050     if (!eventHandler) {
1051         NETSTACK_LOGE("netstack eventHandler is nullptr");
1052         return false;
1053     }
1054     eventHandler->PostSyncTask([&result, context]() { result = TcpSendEvent(context); });
1055     NapiUtils::CreateUvQueueWorkEnhanced(context->GetEnv(), context, SocketAsyncWork::TcpSendCallback);
1056 #endif
1057     return result;
1058 }
1059 
ExecClose(CloseContext * context)1060 bool ExecClose(CloseContext *context)
1061 {
1062     if (!CommonUtils::HasInternetPermission()) {
1063         context->SetPermissionDenied(true);
1064         return false;
1065     }
1066 
1067     int ret = close(context->GetSocketFd());
1068     if (ret < 0) {
1069         NETSTACK_LOGE("sock closed failed , socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1070         context->SetErrorCode(UNKNOW_ERROR);
1071         return false;
1072     }
1073     NETSTACK_LOGI("sock %{public}d closed success", context->GetSocketFd());
1074 
1075     context->state_.SetIsClose(true);
1076     context->SetSocketFd(0);
1077 
1078     return true;
1079 }
1080 
CheckClosed(GetStateContext * context,int & opt)1081 static bool CheckClosed(GetStateContext *context, int &opt)
1082 {
1083     socklen_t optLen = sizeof(int);
1084     int r = getsockopt(context->GetSocketFd(), SOL_SOCKET, SO_TYPE, &opt, &optLen);
1085     if (r < 0) {
1086         context->state_.SetIsClose(true);
1087         return true;
1088     }
1089     return false;
1090 }
1091 
CheckSocketFd(GetStateContext * context,sockaddr & sockAddr)1092 static bool CheckSocketFd(GetStateContext *context, sockaddr &sockAddr)
1093 {
1094     socklen_t len = sizeof(sockaddr);
1095     int ret = getsockname(context->GetSocketFd(), &sockAddr, &len);
1096     if (ret < 0) {
1097         context->SetErrorCode(errno);
1098         return false;
1099     }
1100     return true;
1101 }
1102 
ExecGetState(GetStateContext * context)1103 bool ExecGetState(GetStateContext *context)
1104 {
1105     if (!CommonUtils::HasInternetPermission()) {
1106         context->SetPermissionDenied(true);
1107         return false;
1108     }
1109 
1110     int opt;
1111     if (CheckClosed(context, opt)) {
1112         return true;
1113     }
1114 
1115     sockaddr sockAddr = {0};
1116     if (!CheckSocketFd(context, sockAddr)) {
1117         return false;
1118     }
1119 
1120     sockaddr_in addr4 = {0};
1121     sockaddr_in6 addr6 = {0};
1122     sockaddr *addr = nullptr;
1123     socklen_t addrLen;
1124     if (sockAddr.sa_family == AF_INET) {
1125         addr = reinterpret_cast<sockaddr *>(&addr4);
1126         addrLen = sizeof(addr4);
1127     } else if (sockAddr.sa_family == AF_INET6) {
1128         addr = reinterpret_cast<sockaddr *>(&addr6);
1129         addrLen = sizeof(addr6);
1130     }
1131 
1132     if (addr == nullptr) {
1133         NETSTACK_LOGE("addr family error, address invalid");
1134         context->SetErrorCode(ADDRESS_INVALID);
1135         return false;
1136     }
1137 
1138     (void)memset_s(addr, addrLen, 0, addrLen);
1139     socklen_t len = addrLen;
1140     int ret = getsockname(context->GetSocketFd(), addr, &len);
1141     if (ret < 0) {
1142         context->SetErrorCode(errno);
1143         return false;
1144     }
1145 
1146     SetIsBound(sockAddr.sa_family, context, &addr4, &addr6);
1147 
1148     if (opt != SOCK_STREAM) {
1149         return true;
1150     }
1151 
1152     (void)memset_s(addr, addrLen, 0, addrLen);
1153     len = addrLen;
1154     (void)getpeername(context->GetSocketFd(), addr, &len);
1155     SetIsConnected(sockAddr.sa_family, context, &addr4, &addr6);
1156     return true;
1157 }
1158 
IsAddressAndRetValid(const int & ret,const std::string & address,GetRemoteAddressContext * context)1159 bool IsAddressAndRetValid(const int &ret, const std::string &address, GetRemoteAddressContext *context)
1160 {
1161     if (ret < 0) {
1162         context->SetErrorCode(errno);
1163         return false;
1164     }
1165     if (address.empty()) {
1166         NETSTACK_LOGE("addr family error, address invalid");
1167         context->SetErrorCode(ADDRESS_INVALID);
1168         return false;
1169     }
1170     return true;
1171 }
1172 
ExecGetRemoteAddress(GetRemoteAddressContext * context)1173 bool ExecGetRemoteAddress(GetRemoteAddressContext *context)
1174 {
1175     if (!CommonUtils::HasInternetPermission()) {
1176         context->SetPermissionDenied(true);
1177         return false;
1178     }
1179 
1180     sockaddr sockAddr = {0};
1181     socklen_t len = sizeof(sockaddr);
1182     int ret = getsockname(context->GetSocketFd(), &sockAddr, &len);
1183     if (ret < 0) {
1184         context->SetErrorCode(errno);
1185         return false;
1186     }
1187 
1188     if (sockAddr.sa_family == AF_INET) {
1189         sockaddr_in addr4 = {0};
1190         socklen_t len4 = sizeof(sockaddr_in);
1191 
1192         ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr4), &len4);
1193         std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr4));
1194         if (!IsAddressAndRetValid(ret, address, context)) {
1195             return false;
1196         }
1197         context->address_.SetAddress(address);
1198         context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1199         context->address_.SetPort(ntohs(addr4.sin_port));
1200         return true;
1201     } else if (sockAddr.sa_family == AF_INET6) {
1202         sockaddr_in6 addr6 = {0};
1203         socklen_t len6 = sizeof(sockaddr_in6);
1204 
1205         ret = getpeername(context->GetSocketFd(), reinterpret_cast<sockaddr *>(&addr6), &len6);
1206         std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr6));
1207         if (!IsAddressAndRetValid(ret, address, context)) {
1208             return false;
1209         }
1210         context->address_.SetAddress(address);
1211         context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1212         context->address_.SetPort(ntohs(addr6.sin6_port));
1213         return true;
1214     }
1215 
1216     return false;
1217 }
1218 
ExecTcpSetExtraOptions(TcpSetExtraOptionsContext * context)1219 bool ExecTcpSetExtraOptions(TcpSetExtraOptionsContext *context)
1220 {
1221     if (!CommonUtils::HasInternetPermission()) {
1222         context->SetPermissionDenied(true);
1223         return false;
1224     }
1225 
1226     if (!SetBaseOptions(context->GetSocketFd(), &context->options_)) {
1227         context->SetErrorCode(errno);
1228         return false;
1229     }
1230 
1231     if (context->options_.IsKeepAlive()) {
1232         int keepalive = 1;
1233         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) {
1234             context->SetErrorCode(errno);
1235             return false;
1236         }
1237     }
1238 
1239     if (context->options_.IsOOBInline()) {
1240         int oobInline = 1;
1241         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_OOBINLINE, &oobInline, sizeof(oobInline)) < 0) {
1242             context->SetErrorCode(errno);
1243             return false;
1244         }
1245     }
1246 
1247     if (context->options_.IsTCPNoDelay()) {
1248         int tcpNoDelay = 1;
1249         if (setsockopt(context->GetSocketFd(), IPPROTO_TCP, TCP_NODELAY, &tcpNoDelay, sizeof(tcpNoDelay)) < 0) {
1250             context->SetErrorCode(errno);
1251             return false;
1252         }
1253     }
1254 
1255     linger soLinger = {0};
1256     soLinger.l_onoff = context->options_.socketLinger.IsOn();
1257     soLinger.l_linger = (int)context->options_.socketLinger.GetLinger();
1258     if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger)) < 0) {
1259         context->SetErrorCode(errno);
1260         return false;
1261     }
1262 
1263     return true;
1264 }
1265 
ExecUdpSetExtraOptions(UdpSetExtraOptionsContext * context)1266 bool ExecUdpSetExtraOptions(UdpSetExtraOptionsContext *context)
1267 {
1268     if (!CommonUtils::HasInternetPermission()) {
1269         context->SetPermissionDenied(true);
1270         return false;
1271     }
1272 
1273     if (!SetBaseOptions(context->GetSocketFd(), &context->options)) {
1274         context->SetErrorCode(errno);
1275         return false;
1276     }
1277 
1278     if (context->options.IsBroadcast()) {
1279         int broadcast = 1;
1280         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
1281             context->SetErrorCode(errno);
1282             return false;
1283         }
1284     }
1285 
1286     return true;
1287 }
1288 
ExecTcpGetSocketFd(GetSocketFdContext * context)1289 bool ExecTcpGetSocketFd(GetSocketFdContext *context)
1290 {
1291     return true;
1292 }
1293 
ExecUdpGetSocketFd(GetSocketFdContext * context)1294 bool ExecUdpGetSocketFd(GetSocketFdContext *context)
1295 {
1296     return true;
1297 }
1298 
GetIPv4Address(TcpServerGetRemoteAddressContext * context,int32_t fd,sockaddr sockAddr)1299 static bool GetIPv4Address(TcpServerGetRemoteAddressContext *context, int32_t fd, sockaddr sockAddr)
1300 {
1301     sockaddr_in addr4 = {0};
1302     socklen_t len4 = sizeof(sockaddr_in);
1303 
1304     int ret = getpeername(fd, reinterpret_cast<sockaddr *>(&addr4), &len4);
1305     if (ret < 0) {
1306         context->SetErrorCode(errno);
1307         return false;
1308     }
1309 
1310     std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr4));
1311     if (address.empty()) {
1312         NETSTACK_LOGE("addr family error, address invalid");
1313         context->SetErrorCode(ADDRESS_INVALID);
1314         return false;
1315     }
1316     context->address_.SetAddress(address);
1317     context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1318     context->address_.SetPort(ntohs(addr4.sin_port));
1319     return true;
1320 }
1321 
GetIPv6Address(TcpServerGetRemoteAddressContext * context,int32_t fd,sockaddr sockAddr)1322 static bool GetIPv6Address(TcpServerGetRemoteAddressContext *context, int32_t fd, sockaddr sockAddr)
1323 {
1324     sockaddr_in6 addr6 = {0};
1325     socklen_t len6 = sizeof(sockaddr_in6);
1326 
1327     int ret = getpeername(fd, reinterpret_cast<sockaddr *>(&addr6), &len6);
1328     if (ret < 0) {
1329         context->SetErrorCode(errno);
1330         return false;
1331     }
1332 
1333     std::string address = MakeAddressString(reinterpret_cast<sockaddr *>(&addr6));
1334     if (address.empty()) {
1335         NETSTACK_LOGE("addr family error, address invalid");
1336         context->SetErrorCode(ADDRESS_INVALID);
1337         return false;
1338     }
1339     context->address_.SetAddress(address);
1340     context->address_.SetFamilyBySaFamily(sockAddr.sa_family);
1341     context->address_.SetPort(ntohs(addr6.sin6_port));
1342     return true;
1343 }
1344 
ExecTcpConnectionGetRemoteAddress(TcpServerGetRemoteAddressContext * context)1345 bool ExecTcpConnectionGetRemoteAddress(TcpServerGetRemoteAddressContext *context)
1346 {
1347     if (!CommonUtils::HasInternetPermission()) {
1348         context->SetPermissionDenied(true);
1349         return false;
1350     }
1351 
1352     int32_t clientFd = -1;
1353     bool fdValid = false;
1354 
1355     {
1356         std::lock_guard<std::mutex> lock(g_mutex);
1357         auto iter = g_clientFDs.find(context->clientId_);
1358         if (iter != g_clientFDs.end()) {
1359             fdValid = true;
1360             clientFd = iter->second;
1361         } else {
1362             NETSTACK_LOGE("not find clientId");
1363         }
1364     }
1365 
1366     if (!fdValid) {
1367         NETSTACK_LOGE("client fd is invalid");
1368         context->SetError(OTHER_ERROR, "client fd is invalid");
1369         return false;
1370     }
1371 
1372     sockaddr sockAddr = {0};
1373     socklen_t len = sizeof(sockaddr);
1374     int ret = getsockname(clientFd, &sockAddr, &len);
1375     if (ret < 0) {
1376         context->SetError(errno, strerror(errno));
1377         return false;
1378     }
1379 
1380     if (sockAddr.sa_family == AF_INET) {
1381         return GetIPv4Address(context, clientFd, sockAddr);
1382     } else if (sockAddr.sa_family == AF_INET6) {
1383         return GetIPv6Address(context, clientFd, sockAddr);
1384     }
1385 
1386     return false;
1387 }
1388 
IsRemoteConnect(TcpServerSendContext * context,int32_t clientFd)1389 static bool IsRemoteConnect(TcpServerSendContext *context, int32_t clientFd)
1390 {
1391     sockaddr sockAddr = {0};
1392     socklen_t len = sizeof(sockaddr);
1393     if (getsockname(clientFd, &sockAddr, &len) < 0) {
1394         NETSTACK_LOGE("get sock name failed, address invalid");
1395         context->SetErrorCode(ADDRESS_INVALID);
1396         return false;
1397     }
1398     bool connected = false;
1399     if (sockAddr.sa_family == AF_INET) {
1400         sockaddr_in addr4 = {0};
1401         socklen_t len4 = sizeof(addr4);
1402         int ret = getpeername(clientFd, reinterpret_cast<sockaddr *>(&addr4), &len4);
1403         if (ret >= 0 && addr4.sin_port != 0) {
1404             connected = true;
1405         }
1406     } else if (sockAddr.sa_family == AF_INET6) {
1407         sockaddr_in6 addr6 = {0};
1408         socklen_t len6 = sizeof(addr6);
1409         int ret = getpeername(clientFd, reinterpret_cast<sockaddr *>(&addr6), &len6);
1410         if (ret >= 0 && addr6.sin6_port != 0) {
1411             connected = true;
1412         }
1413     }
1414 
1415     if (!connected) {
1416         NETSTACK_LOGE("sock is not connect to remote, socket is %{public}d, errno is %{public}d", clientFd, errno);
1417         context->SetErrorCode(errno);
1418         return false;
1419     }
1420     return true;
1421 }
1422 
ExecTcpConnectionSend(TcpServerSendContext * context)1423 bool ExecTcpConnectionSend(TcpServerSendContext *context)
1424 {
1425     if (!CommonUtils::HasInternetPermission()) {
1426         context->SetPermissionDenied(true);
1427         return false;
1428     }
1429 
1430     int32_t clientFd = -1;
1431     bool fdValid = false;
1432 
1433     {
1434         std::lock_guard<std::mutex> lock(g_mutex);
1435         auto iter = g_clientFDs.find(context->clientId_);
1436         if (iter != g_clientFDs.end()) {
1437             fdValid = true;
1438             clientFd = iter->second;
1439         } else {
1440             NETSTACK_LOGE("not find clientId");
1441         }
1442     }
1443 
1444     if (!fdValid) {
1445         NETSTACK_LOGE("client fd is invalid");
1446         context->SetError(OTHER_ERROR, "client fd is invalid");
1447         return false;
1448     }
1449 
1450     std::string encoding = context->options.GetEncoding();
1451     (void)encoding;
1452     /* no use for now */
1453 
1454     if (!IsRemoteConnect(context, clientFd)) {
1455         return false;
1456     }
1457 
1458     if (!PollSendData(clientFd, context->options.GetData().c_str(), context->options.GetData().size(), nullptr, 0)) {
1459         NETSTACK_LOGE("send failed, , socket is %{public}d, errno is %{public}d", clientFd, errno);
1460         context->SetError(errno, strerror(errno));
1461         return false;
1462     }
1463     return true;
1464 }
1465 
ExecTcpConnectionClose(TcpServerCloseContext * context)1466 bool ExecTcpConnectionClose(TcpServerCloseContext *context)
1467 {
1468     if (!CommonUtils::HasInternetPermission()) {
1469         context->SetPermissionDenied(true);
1470         return false;
1471     }
1472     bool fdValid = false;
1473 
1474     {
1475         std::lock_guard<std::mutex> lock(g_mutex);
1476         auto iter = g_clientFDs.find(context->clientId_);
1477         if (iter != g_clientFDs.end()) {
1478             fdValid = true;
1479         } else {
1480             NETSTACK_LOGE("not find clientId");
1481         }
1482     }
1483 
1484     if (!fdValid) {
1485         NETSTACK_LOGE("client fd is invalid");
1486         context->SetError(OTHER_ERROR, "client fd is invalid");
1487         return false;
1488     }
1489 
1490     return true;
1491 }
1492 
ServerBind(TcpServerListenContext * context)1493 static bool ServerBind(TcpServerListenContext *context)
1494 {
1495     sockaddr_in addr4 = {0};
1496     sockaddr_in6 addr6 = {0};
1497     sockaddr *addr = nullptr;
1498     socklen_t len;
1499     GetAddr(&context->address_, &addr4, &addr6, &addr, &len);
1500     if (addr == nullptr) {
1501         NETSTACK_LOGE("addr family error, address invalid");
1502         context->SetError(ADDRESS_INVALID, "addr family error, address invalid");
1503         return false;
1504     }
1505 
1506     if (bind(context->GetSocketFd(), addr, len) < 0) {
1507         if (errno != EADDRINUSE) {
1508             NETSTACK_LOGE("bind failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1509             context->SetError(errno, strerror(errno));
1510             return false;
1511         }
1512         if (addr->sa_family == AF_INET) {
1513             NETSTACK_LOGI("distribute a random port");
1514             addr4.sin_port = 0; /* distribute a random port */
1515         } else if (addr->sa_family == AF_INET6) {
1516             NETSTACK_LOGI("distribute a random port");
1517             addr6.sin6_port = 0; /* distribute a random port */
1518         }
1519         if (bind(context->GetSocketFd(), addr, len) < 0) {
1520             NETSTACK_LOGE("rebind failed, socket is %{public}d, errno is %{public}d", context->GetSocketFd(), errno);
1521             context->SetError(errno, strerror(errno));
1522             return false;
1523         }
1524         NETSTACK_LOGI("rebind success");
1525     }
1526     NETSTACK_LOGI("bind success");
1527 
1528     return true;
1529 }
1530 
IsClientFdClosed(int32_t clientFd)1531 static bool IsClientFdClosed(int32_t clientFd)
1532 {
1533     return (fcntl(clientFd, F_GETFL) == -1 && errno == EBADF);
1534 }
1535 
RemoveClientConnection(int32_t clientId)1536 static void RemoveClientConnection(int32_t clientId)
1537 {
1538     std::lock_guard<std::mutex> lock(g_mutex);
1539     for (auto it = g_clientFDs.begin(); it != g_clientFDs.end(); ++it) {
1540         if (it->first == clientId) {
1541             NETSTACK_LOGI("remove clientfd and eventmanager clientid: %{public}d clientFd:%{public}d", it->second,
1542                           it->first);
1543             if (!IsClientFdClosed(it->second)) {
1544                 NETSTACK_LOGE("connectFD not close should close");
1545                 shutdown(it->second, SHUT_RDWR);
1546                 close(it->second);
1547             }
1548 
1549             g_clientFDs.erase(it->first);
1550             break;
1551         }
1552     }
1553 }
1554 
ClientHandler(int32_t clientId,sockaddr * addr,socklen_t addrLen,const TcpMessageCallback & callback)1555 static void ClientHandler(int32_t clientId, sockaddr *addr, socklen_t addrLen, const TcpMessageCallback &callback)
1556 {
1557     char buffer[DEFAULT_BUFFER_SIZE];
1558 
1559     EventManager *manager = nullptr;
1560     {
1561         std::unique_lock<std::mutex> lock(g_mutex);
1562         g_cv.wait(lock, [&manager, &clientId]() {
1563             auto iter = g_clientEventManagers.find(clientId);
1564             if (iter != g_clientEventManagers.end()) {
1565                 manager = iter->second;
1566                 NETSTACK_LOGE("manager!=nullptr");
1567                 return true;
1568             } else {
1569                 NETSTACK_LOGE("iter==g_clientEventManagers.end()");
1570                 return false;
1571             }
1572         });
1573     }
1574 
1575     auto connectFD = g_clientFDs[clientId]; // std::lock_guard<std::mutex> lock(g_mutex);]
1576 
1577     while (true) {
1578         if (memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)) != EOK) {
1579             NETSTACK_LOGE("memset_s failed!");
1580             break;
1581         }
1582         int32_t recvSize = recv(connectFD, buffer, sizeof(buffer), 0);
1583         NETSTACK_LOGI("ClientRecv: fd is %{public}d, buf is %{public}s, size is %{public}d bytes", connectFD, buffer,
1584                       recvSize);
1585         if (recvSize <= 0) {
1586             NETSTACK_LOGE("close ClientHandler: recvSize is %{public}d, errno is %{public}d", recvSize, errno);
1587 
1588             if (errno != EAGAIN) {
1589                 callback.OnCloseMessage(manager);
1590                 RemoveClientConnection(clientId);
1591                 break;
1592             }
1593         } else {
1594             void *data = malloc(recvSize);
1595             if (data == nullptr) {
1596                 callback.OnError(NO_MEMORY);
1597                 break;
1598             }
1599             if (memcpy_s(data, recvSize, buffer, recvSize) != EOK ||
1600                 !callback.OnMessage(connectFD, data, recvSize, addr, manager)) {
1601                 free(data);
1602             }
1603         }
1604     }
1605 }
1606 
AcceptRecvData(int sock,sockaddr * addr,socklen_t addrLen,const TcpMessageCallback & callback)1607 static void AcceptRecvData(int sock, sockaddr *addr, socklen_t addrLen, const TcpMessageCallback &callback)
1608 {
1609     while (true) {
1610         sockaddr_in clientAddress;
1611         socklen_t clientAddrLength = sizeof(clientAddress);
1612         int32_t connectFD = accept(sock, reinterpret_cast<sockaddr *>(&clientAddress), &clientAddrLength);
1613         if (connectFD < 0) {
1614             continue;
1615         }
1616         {
1617             std::lock_guard<std::mutex> lock(g_mutex);
1618             if (g_clientFDs.size() >= MAX_CLIENTS) {
1619                 NETSTACK_LOGE("Maximum number of clients reached, connection rejected");
1620                 close(connectFD);
1621                 continue;
1622             }
1623             NETSTACK_LOGI("Server accept new client SUCCESS, fd = %{public}d", connectFD);
1624             g_userCounter++;
1625             g_clientFDs[g_userCounter] = connectFD;
1626         }
1627         callback.OnTcpConnectionMessage(g_userCounter);
1628         int clientId = g_userCounter;
1629         std::thread handlerThread(ClientHandler, clientId, nullptr, 0, callback);
1630 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
1631         pthread_setname_np(TCP_SERVER_HANDLE_CLIENT);
1632 #else
1633         pthread_setname_np(handlerThread.native_handle(), TCP_SERVER_HANDLE_CLIENT);
1634 #endif
1635         handlerThread.detach();
1636     }
1637 }
1638 
ExecTcpServerListen(TcpServerListenContext * context)1639 bool ExecTcpServerListen(TcpServerListenContext *context)
1640 {
1641     int ret = 0;
1642     if (!ServerBind(context)) {
1643         return false;
1644     }
1645 
1646     ret = listen(context->GetSocketFd(), USER_LIMIT);
1647     if (ret < 0) {
1648         NETSTACK_LOGE("tcp server listen error");
1649         return false;
1650     }
1651 
1652     NETSTACK_LOGI("listen success");
1653     std::thread serviceThread(AcceptRecvData, context->GetSocketFd(), nullptr, 0,
1654                               TcpMessageCallback(context->GetManager()));
1655 #if defined(MAC_PLATFORM) || defined(IOS_PLATFORM)
1656     pthread_setname_np(TCP_SERVER_ACCEPT_RECV_DATA);
1657 #else
1658     pthread_setname_np(serviceThread.native_handle(), TCP_SERVER_ACCEPT_RECV_DATA);
1659 #endif
1660     serviceThread.detach();
1661     return true;
1662 }
1663 
ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext * context)1664 bool ExecTcpServerSetExtraOptions(TcpServerSetExtraOptionsContext *context)
1665 {
1666     if (!CommonUtils::HasInternetPermission()) {
1667         context->SetPermissionDenied(true);
1668         return false;
1669     }
1670 
1671     if (!SetBaseOptions(context->GetSocketFd(), &context->options_)) {
1672         context->SetError(errno, strerror(errno));
1673         return false;
1674     }
1675 
1676     if (context->options_.IsKeepAlive()) {
1677         int keepalive = 1;
1678         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0) {
1679             context->SetError(errno, strerror(errno));
1680             return false;
1681         }
1682     }
1683 
1684     if (context->options_.IsOOBInline()) {
1685         int oobInline = 1;
1686         if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_OOBINLINE, &oobInline, sizeof(oobInline)) < 0) {
1687             context->SetError(errno, strerror(errno));
1688             return false;
1689         }
1690     }
1691 
1692     if (context->options_.IsTCPNoDelay()) {
1693         int tcpNoDelay = 1;
1694         if (setsockopt(context->GetSocketFd(), IPPROTO_TCP, TCP_NODELAY, &tcpNoDelay, sizeof(tcpNoDelay)) < 0) {
1695             context->SetError(errno, strerror(errno));
1696             return false;
1697         }
1698     }
1699 
1700     linger soLinger = {0};
1701     soLinger.l_onoff = context->options_.socketLinger.IsOn();
1702     soLinger.l_linger = (int)context->options_.socketLinger.GetLinger();
1703     if (setsockopt(context->GetSocketFd(), SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger)) < 0) {
1704         context->SetError(errno, strerror(errno));
1705         return false;
1706     }
1707 
1708     return true;
1709 }
1710 
SetIsConnected(TcpServerGetStateContext * context)1711 static void SetIsConnected(TcpServerGetStateContext *context)
1712 {
1713     std::lock_guard<std::mutex> lock(g_mutex);
1714     if (g_clientFDs.empty()) {
1715         context->state_.SetIsConnected(false);
1716     } else {
1717         context->state_.SetIsConnected(true);
1718     }
1719 }
1720 
SetIsBound(sa_family_t family,TcpServerGetStateContext * context,const sockaddr_in * addr4,const sockaddr_in6 * addr6)1721 static void SetIsBound(sa_family_t family, TcpServerGetStateContext *context, const sockaddr_in *addr4,
1722                        const sockaddr_in6 *addr6)
1723 {
1724     if (family == AF_INET) {
1725         context->state_.SetIsBound(ntohs(addr4->sin_port) != 0);
1726     } else if (family == AF_INET6) {
1727         context->state_.SetIsBound(ntohs(addr6->sin6_port) != 0);
1728     }
1729 }
1730 
ExecTcpServerGetState(TcpServerGetStateContext * context)1731 bool ExecTcpServerGetState(TcpServerGetStateContext *context)
1732 {
1733     if (!CommonUtils::HasInternetPermission()) {
1734         context->SetPermissionDenied(true);
1735         return false;
1736     }
1737 
1738     int opt;
1739     socklen_t optLen = sizeof(int);
1740     if (getsockopt(context->GetSocketFd(), SOL_SOCKET, SO_TYPE, &opt, &optLen) < 0) {
1741         context->state_.SetIsClose(true);
1742         return true;
1743     }
1744 
1745     sockaddr sockAddr = {0};
1746     socklen_t len = sizeof(sockaddr);
1747     if (getsockname(context->GetSocketFd(), &sockAddr, &len) < 0) {
1748         context->SetError(errno, strerror(errno));
1749         return false;
1750     }
1751 
1752     sockaddr_in addr4 = {0};
1753     sockaddr_in6 addr6 = {0};
1754     sockaddr *addr = nullptr;
1755     socklen_t addrLen;
1756     if (sockAddr.sa_family == AF_INET) {
1757         addr = reinterpret_cast<sockaddr *>(&addr4);
1758         addrLen = sizeof(addr4);
1759     } else if (sockAddr.sa_family == AF_INET6) {
1760         addr = reinterpret_cast<sockaddr *>(&addr6);
1761         addrLen = sizeof(addr6);
1762     }
1763 
1764     if (addr == nullptr) {
1765         NETSTACK_LOGE("addr family error, address invalid");
1766         context->SetErrorCode(ADDRESS_INVALID);
1767         return false;
1768     }
1769 
1770     if (memset_s(addr, addrLen, 0, addrLen) != EOK) {
1771         NETSTACK_LOGE("memset_s failed!");
1772         return false;
1773     }
1774     len = addrLen;
1775     if (getsockname(context->GetSocketFd(), addr, &len) < 0) {
1776         context->SetError(errno, strerror(errno));
1777         return false;
1778     }
1779 
1780     SetIsBound(sockAddr.sa_family, context, &addr4, &addr6);
1781 
1782     if (opt != SOCK_STREAM) {
1783         return true;
1784     }
1785     SetIsConnected(context);
1786     return true;
1787 }
1788 
BindCallback(BindContext * context)1789 napi_value BindCallback(BindContext *context)
1790 {
1791     context->Emit(EVENT_LISTENING, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1792                                                   NapiUtils::GetUndefined(context->GetEnv())));
1793     return NapiUtils::GetUndefined(context->GetEnv());
1794 }
1795 
UdpSendCallback(UdpSendContext * context)1796 napi_value UdpSendCallback(UdpSendContext *context)
1797 {
1798     return NapiUtils::GetUndefined(context->GetEnv());
1799 }
1800 
ConnectCallback(ConnectContext * context)1801 napi_value ConnectCallback(ConnectContext *context)
1802 {
1803     context->Emit(EVENT_CONNECT, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1804                                                 NapiUtils::GetUndefined(context->GetEnv())));
1805     return NapiUtils::GetUndefined(context->GetEnv());
1806 }
1807 
TcpSendCallback(TcpSendContext * context)1808 napi_value TcpSendCallback(TcpSendContext *context)
1809 {
1810     return NapiUtils::GetUndefined(context->GetEnv());
1811 }
1812 
CloseCallback(CloseContext * context)1813 napi_value CloseCallback(CloseContext *context)
1814 {
1815     context->Emit(EVENT_CLOSE, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1816                                               NapiUtils::GetUndefined(context->GetEnv())));
1817     return NapiUtils::GetUndefined(context->GetEnv());
1818 }
1819 
GetStateCallback(GetStateContext * context)1820 napi_value GetStateCallback(GetStateContext *context)
1821 {
1822     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1823     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1824         return NapiUtils::GetUndefined(context->GetEnv());
1825     }
1826 
1827     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
1828     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
1829     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
1830 
1831     return obj;
1832 }
1833 
GetRemoteAddressCallback(GetRemoteAddressContext * context)1834 napi_value GetRemoteAddressCallback(GetRemoteAddressContext *context)
1835 {
1836     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1837     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1838         return NapiUtils::GetUndefined(context->GetEnv());
1839     }
1840 
1841     NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
1842     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
1843     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
1844 
1845     return obj;
1846 }
1847 
TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext * context)1848 napi_value TcpSetExtraOptionsCallback(TcpSetExtraOptionsContext *context)
1849 {
1850     return NapiUtils::GetUndefined(context->GetEnv());
1851 }
1852 
UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext * context)1853 napi_value UdpSetExtraOptionsCallback(UdpSetExtraOptionsContext *context)
1854 {
1855     return NapiUtils::GetUndefined(context->GetEnv());
1856 }
1857 
TcpGetSocketFdCallback(GetSocketFdContext * context)1858 napi_value TcpGetSocketFdCallback(GetSocketFdContext *context)
1859 {
1860     int sockFd = context->GetSocketFd();
1861     if (sockFd == -1) {
1862         return NapiUtils::GetUndefined(context->GetEnv());
1863     }
1864     return NapiUtils::CreateUint32(context->GetEnv(), sockFd);
1865 }
1866 
UdpGetSocketFdCallback(GetSocketFdContext * context)1867 napi_value UdpGetSocketFdCallback(GetSocketFdContext *context)
1868 {
1869     int sockFd = context->GetSocketFd();
1870     if (sockFd == -1) {
1871         return NapiUtils::GetUndefined(context->GetEnv());
1872     }
1873     return NapiUtils::CreateUint32(context->GetEnv(), sockFd);
1874 }
1875 
TcpConnectionSendCallback(TcpServerSendContext * context)1876 napi_value TcpConnectionSendCallback(TcpServerSendContext *context)
1877 {
1878     return NapiUtils::GetUndefined(context->GetEnv());
1879 }
1880 
TcpConnectionCloseCallback(TcpServerCloseContext * context)1881 napi_value TcpConnectionCloseCallback(TcpServerCloseContext *context)
1882 {
1883     int32_t clientFd = -1;
1884 
1885     {
1886         std::lock_guard<std::mutex> lock(g_mutex);
1887         auto iter = g_clientFDs.find(context->clientId_);
1888         if (iter != g_clientFDs.end()) {
1889             clientFd = iter->second;
1890         } else {
1891             NETSTACK_LOGE("not find clientId");
1892         }
1893     }
1894 
1895     if (shutdown(clientFd, SHUT_RDWR) != 0) {
1896         NETSTACK_LOGE("socket shutdown failed, socket is %{public}d, errno is %{public}d", clientFd, errno);
1897     }
1898     int ret = close(clientFd);
1899     if (ret < 0) {
1900         NETSTACK_LOGE("sock closed failed, socket is %{public}d, errno is %{public}d", clientFd, errno);
1901     } else {
1902         NETSTACK_LOGI("sock %{public}d closed success", clientFd);
1903         RemoveClientConnection(context->clientId_);
1904         context->Emit(EVENT_CLOSE, std::make_pair(NapiUtils::GetUndefined(context->GetEnv()),
1905                                                   NapiUtils::GetUndefined(context->GetEnv())));
1906     }
1907 
1908     return NapiUtils::GetUndefined(context->GetEnv());
1909 }
1910 
TcpConnectionGetRemoteAddressCallback(TcpServerGetRemoteAddressContext * context)1911 napi_value TcpConnectionGetRemoteAddressCallback(TcpServerGetRemoteAddressContext *context)
1912 {
1913     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1914     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1915         return NapiUtils::GetUndefined(context->GetEnv());
1916     }
1917 
1918     NapiUtils::SetStringPropertyUtf8(context->GetEnv(), obj, KEY_ADDRESS, context->address_.GetAddress());
1919     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_FAMILY, context->address_.GetJsValueFamily());
1920     NapiUtils::SetUint32Property(context->GetEnv(), obj, KEY_PORT, context->address_.GetPort());
1921 
1922     return obj;
1923 }
1924 
ListenCallback(TcpServerListenContext * context)1925 napi_value ListenCallback(TcpServerListenContext *context)
1926 {
1927     return NapiUtils::GetUndefined(context->GetEnv());
1928 }
1929 
TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext * context)1930 napi_value TcpServerSetExtraOptionsCallback(TcpServerSetExtraOptionsContext *context)
1931 {
1932     return NapiUtils::GetUndefined(context->GetEnv());
1933 }
1934 
TcpServerGetStateCallback(TcpServerGetStateContext * context)1935 napi_value TcpServerGetStateCallback(TcpServerGetStateContext *context)
1936 {
1937     napi_value obj = NapiUtils::CreateObject(context->GetEnv());
1938     if (NapiUtils::GetValueType(context->GetEnv(), obj) != napi_object) {
1939         return NapiUtils::GetUndefined(context->GetEnv());
1940     }
1941 
1942     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_BOUND, context->state_.IsBound());
1943     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CLOSE, context->state_.IsClose());
1944     NapiUtils::SetBooleanProperty(context->GetEnv(), obj, KEY_IS_CONNECTED, context->state_.IsConnected());
1945 
1946     return obj;
1947 }
1948 } // namespace OHOS::NetStack::Socket::SocketExec
1949