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