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