1 /*
2 * Copyright (c) 2021 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 "softbus_base_listener.h"
17
18 #include <fcntl.h>
19 #include <securec.h>
20 #include <stdatomic.h>
21 #include <unistd.h>
22
23 #include "common_list.h"
24 #include "conn_event.h"
25 #include "conn_log.h"
26 #include "softbus_adapter_errcode.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_adapter_socket.h"
29 #include "softbus_conn_common.h"
30 #include "softbus_conn_interface.h"
31 #include "softbus_def.h"
32 #include "softbus_feature_config.h"
33 #include "softbus_socket.h"
34 #include "softbus_utils.h"
35 #include "softbus_watch_event_interface.h"
36
37 #define DEFAULT_BACKLOG 4
38 #define FDARR_EXPAND_BASE 2
39 #define WATCH_UNEXPECT_FAIL_RETRY_WAIT_MILLIS (3 * 1000)
40 #define WATCH_ABNORMAL_EVENT_RETRY_WAIT_MILLIS (3 * 10) /* wait retry time for an abnotmal event by watch*/
41 #define SOFTBUS_LISTENER_WATCH_TIMEOUT_MSEC (6 * 60 * 60 * 1000)
42
43 enum BaseListenerStatus {
44 LISTENER_IDLE = 0,
45 LISTENER_RUNNING,
46 };
47
48 typedef struct {
49 ListNode waitEventFds;
50 uint32_t waitEventFdsLen;
51
52 ModeType modeType;
53 int32_t listenFd;
54 int32_t listenPort;
55
56 enum BaseListenerStatus status;
57 LocalListenerInfo listenerInfo;
58 } SoftbusBaseListenerInfo;
59
60 typedef struct {
61 ListenerModule module;
62 SoftBusMutex lock;
63 SoftbusBaseListener listener;
64 const SocketInterface *socketIf;
65 SoftbusBaseListenerInfo info;
66 int32_t objectRc;
67 } SoftbusListenerNode;
68
69 typedef struct {
70 uint32_t traceId;
71 int32_t referenceCount;
72 SoftBusMutex lock;
73 } WatchThreadState;
74
75 static int32_t ShutdownBaseListener(SoftbusListenerNode *node);
76 static int32_t StartWatchThread(void);
77 static int32_t StopWatchThread(void);
78 static SoftbusListenerNode *CreateSpecifiedListenerModule(ListenerModule module);
79
80 static SoftBusMutex g_listenerListLock = { 0 };
81 static SoftbusListenerNode *g_listenerList[UNUSE_BUTT] = { 0 };
82 static SoftBusMutex g_watchThreadStateLock = { 0 };
83 static WatchThreadState *g_watchThreadState = NULL;
84 static EventWatcher *g_eventWatcher = NULL;
85 static _Atomic bool g_initBaseListener = false;
86
GetListenerNodeCommon(ListenerModule module,bool create)87 static SoftbusListenerNode *GetListenerNodeCommon(ListenerModule module, bool create)
88 {
89 int32_t status = SoftBusMutexLock(&g_listenerListLock);
90 CONN_CHECK_AND_RETURN_RET_LOGE(
91 status == SOFTBUS_OK, NULL, CONN_COMMON, "lock failed, module=%{public}d, error=%{public}d",
92 module, status);
93 SoftbusListenerNode *node = g_listenerList[module];
94 do {
95 if (node == NULL) {
96 if (create) {
97 node = CreateSpecifiedListenerModule(module);
98 }
99 if (node == NULL) {
100 break;
101 }
102 g_listenerList[module] = node;
103 }
104 status = SoftBusMutexLock(&node->lock);
105 if (status != SOFTBUS_OK) {
106 CONN_LOGE(CONN_COMMON, "lock listener failed, module=%{public}d, error=%{public}d", module, status);
107 node = NULL;
108 break;
109 }
110 node->objectRc += 1;
111 SoftBusMutexUnlock(&node->lock);
112 } while (false);
113 (void)SoftBusMutexUnlock(&g_listenerListLock);
114 return node;
115 }
116
GetListenerNode(ListenerModule module)117 static SoftbusListenerNode *GetListenerNode(ListenerModule module)
118 {
119 return GetListenerNodeCommon(module, false);
120 }
121
GetOrCreateListenerNode(ListenerModule module)122 static SoftbusListenerNode *GetOrCreateListenerNode(ListenerModule module)
123 {
124 return GetListenerNodeCommon(module, true);
125 }
126
RemoveListenerNode(SoftbusListenerNode * node)127 static void RemoveListenerNode(SoftbusListenerNode *node)
128 {
129 int32_t status = SoftBusMutexLock(&g_listenerListLock);
130 CONN_CHECK_AND_RETURN_LOGE(
131 status == SOFTBUS_OK, CONN_COMMON, "lock listener lists failed, module=%{public}d, error=%{public}d",
132 node->module, status);
133 do {
134 if (g_listenerList[node->module] != node) {
135 CONN_LOGW(CONN_COMMON, "listener node is not in listener list, just skip, module=%{public}d",
136 node->module);
137 break;
138 }
139 status = SoftBusMutexLock(&node->lock);
140 if (status != SOFTBUS_OK) {
141 CONN_LOGE(CONN_COMMON, "lock listener node failed, module=%{public}d", node->module);
142 break;
143 }
144 // decrease root object reference
145 node->objectRc -= 1;
146 g_listenerList[node->module] = NULL;
147 (void)SoftBusMutexUnlock(&node->lock);
148 } while (false);
149 (void)SoftBusMutexUnlock(&g_listenerListLock);
150 }
151
ReturnListenerNode(SoftbusListenerNode ** nodePtr)152 static void ReturnListenerNode(SoftbusListenerNode **nodePtr)
153 {
154 SoftbusListenerNode *node = *nodePtr;
155 do {
156 int32_t status = SoftBusMutexLock(&node->lock);
157 if (status != SOFTBUS_OK) {
158 CONN_LOGE(CONN_COMMON, "lock listener node failed, module=%{public}d", node->module);
159 break;
160 }
161 node->objectRc -= 1;
162 int32_t objectRc = node->objectRc;
163 (void)SoftBusMutexUnlock(&node->lock);
164
165 if (objectRc > 0) {
166 break;
167 }
168 CONN_LOGI(CONN_COMMON, "object reference count <= 0, free listener node, module=%{public}d, "
169 "objectReference=%{public}d", node->module, objectRc);
170 (void)ShutdownBaseListener(node);
171 SoftBusMutexDestroy(&node->lock);
172 SoftBusFree(node);
173 } while (false);
174
175 *nodePtr = NULL;
176 }
177
CreateSpecifiedListenerModule(ListenerModule module)178 static SoftbusListenerNode *CreateSpecifiedListenerModule(ListenerModule module)
179 {
180 SoftbusListenerNode *node = (SoftbusListenerNode *)SoftBusCalloc(sizeof(SoftbusListenerNode));
181 CONN_CHECK_AND_RETURN_RET_LOGE(
182 node != NULL, NULL, CONN_COMMON, "calloc failed, module=%{public}d", module);
183
184 node->module = module;
185 // NOT apply recursive lock on purpose, problem will be exposes quickly if exist
186 int32_t status = SoftBusMutexInit(&node->lock, NULL);
187 if (status != SOFTBUS_OK) {
188 CONN_LOGE(CONN_COMMON, "init lock failed, module=%{public}d, error=%{public}d", module, status);
189 SoftBusFree(node);
190 return NULL;
191 }
192 node->listener.onConnectEvent = NULL;
193 node->listener.onDataEvent = NULL;
194
195 node->socketIf = NULL;
196
197 ListInit(&node->info.waitEventFds);
198 node->info.waitEventFdsLen = 0;
199 node->info.modeType = UNSET_MODE;
200 (void)memset_s(&node->info.listenerInfo, sizeof(LocalListenerInfo), 0, sizeof(LocalListenerInfo));
201 node->info.listenFd = -1;
202 node->info.listenPort = -1;
203 // set root object reference count 1
204 node->objectRc = 1;
205 return node;
206 }
207
AddFdNode(ListNode * fdList,int32_t fd,uint32_t event)208 static int32_t AddFdNode(ListNode *fdList, int32_t fd, uint32_t event)
209 {
210 struct FdNode *fdNode = (struct FdNode *)SoftBusCalloc(sizeof(struct FdNode));
211 CONN_CHECK_AND_RETURN_RET_LOGE(fdNode != NULL, SOFTBUS_MALLOC_ERR, CONN_COMMON, "calloc fdNode failed");
212 ListInit(&fdNode->node);
213 fdNode->fd = fd;
214 fdNode->triggerSet = event;
215 ListAdd(fdList, &fdNode->node);
216 return SOFTBUS_OK;
217 }
218
CollectModuleFdEvent(SoftbusListenerNode * node,ListNode * list)219 static int32_t CollectModuleFdEvent(SoftbusListenerNode *node, ListNode *list)
220 {
221 int32_t ret = SoftBusMutexLock(&node->lock);
222 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_COMMON,
223 "lock failed, module=%{public}d, error=%{public}d", node->module, ret);
224
225 if (node->info.status != LISTENER_RUNNING) {
226 (void)SoftBusMutexUnlock(&node->lock);
227 return 0;
228 }
229
230 ret = SOFTBUS_OK;
231 if (node->info.modeType == SERVER_MODE && node->info.listenFd > 0) {
232 ret = AddFdNode(list, node->info.listenFd, READ_TRIGGER);
233 if (ret != SOFTBUS_OK) {
234 CONN_LOGE(CONN_COMMON, "add fd node failed, fd=%{public}d, status=%{public}d", node->info.listenFd, ret);
235 (void)SoftBusMutexUnlock(&node->lock);
236 return ret;
237 }
238 }
239
240 struct FdNode *it = NULL;
241 LIST_FOR_EACH_ENTRY(it, &node->info.waitEventFds, struct FdNode, node) {
242 ret = AddFdNode(list, it->fd, it->triggerSet);
243 if (ret != SOFTBUS_OK) {
244 CONN_LOGE(CONN_COMMON, "add fd node failed, fd=%{public}d, status=%{public}d", it->fd, ret);
245 (void)SoftBusMutexUnlock(&node->lock);
246 return ret;
247 }
248 }
249 (void)SoftBusMutexUnlock(&node->lock);
250 return ret;
251 }
252
OnGetAllFdEvent(ListNode * list)253 static int32_t OnGetAllFdEvent(ListNode *list)
254 {
255 int32_t status = SOFTBUS_OK;
256 for (ListenerModule module = 0; module < UNUSE_BUTT; module++) {
257 SoftbusListenerNode *node = GetListenerNode(module);
258 if (node == NULL) {
259 continue;
260 }
261 status = CollectModuleFdEvent(node, list);
262 ReturnListenerNode(&node);
263 if (status != SOFTBUS_OK) {
264 ReleaseFdNode(list);
265 CONN_LOGE(CONN_COMMON, "collect wait event fd set failed: module=%{public}d, error=%{public}d",
266 module, status);
267 break;
268 }
269 }
270 return status;
271 }
272
InitBaseListenerLock(void)273 static int32_t InitBaseListenerLock(void)
274 {
275 // stop watch thread need re-enter lock
276 SoftBusMutexAttr attr = {
277 .type = SOFTBUS_MUTEX_RECURSIVE,
278 };
279 int32_t status = SoftBusMutexInit(&g_watchThreadStateLock, &attr);
280 if (status != SOFTBUS_OK) {
281 CONN_LOGE(CONN_INIT, "init watch thread lock failed, error=%{public}d", status);
282 return SOFTBUS_LOCK_ERR;
283 }
284 // NOT apply recursive lock on purpose, problem will be exposes quickly if exist
285 status = SoftBusMutexInit(&g_listenerListLock, NULL);
286 if (status != SOFTBUS_OK) {
287 SoftBusMutexDestroy(&g_watchThreadStateLock);
288 CONN_LOGE(CONN_INIT, "init listener list lock failed, error=%{public}d", status);
289 return SOFTBUS_LOCK_ERR;
290 }
291 return SOFTBUS_OK;
292 }
293
InitBaseListener(void)294 int32_t InitBaseListener(void)
295 {
296 if (atomic_load_explicit(&g_initBaseListener, memory_order_acquire)) {
297 return SOFTBUS_OK;
298 }
299 // flag : if the client and server are in the same process, this function can be executed only once.
300 static bool flag = false;
301 if (flag) {
302 return SOFTBUS_OK;
303 }
304 flag = true;
305
306 CONN_CHECK_AND_RETURN_RET_LOGE(InitBaseListenerLock() == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_COMMON,
307 "init lock failed");
308 int32_t status = SoftBusMutexLock(&g_listenerListLock);
309 if (status != SOFTBUS_OK) {
310 CONN_LOGE(CONN_INIT, "lock listener list failed, error=%{public}d", status);
311 SoftBusMutexDestroy(&g_watchThreadStateLock);
312 SoftBusMutexDestroy(&g_listenerListLock);
313 return SOFTBUS_LOCK_ERR;
314 }
315 (void)memset_s(g_listenerList, sizeof(g_listenerList), 0, sizeof(g_listenerList));
316 (void)SoftBusMutexUnlock(&g_listenerListLock);
317 g_eventWatcher = RegisterEventWatcher(OnGetAllFdEvent);
318 if (g_eventWatcher == NULL) {
319 CONN_LOGE(CONN_INIT, "register event watcher failed");
320 SoftBusMutexDestroy(&g_watchThreadStateLock);
321 SoftBusMutexDestroy(&g_listenerListLock);
322 return SOFTBUS_MEM_ERR;
323 }
324 atomic_store_explicit(&g_initBaseListener, true, memory_order_release);
325 return SOFTBUS_OK;
326 }
327
DeinitBaseListener(void)328 void DeinitBaseListener(void)
329 {
330 if (!atomic_load_explicit(&g_initBaseListener, memory_order_acquire)) {
331 return;
332 }
333
334 for (ListenerModule module = 0; module < UNUSE_BUTT; module++) {
335 SoftbusListenerNode *node = GetListenerNode(module);
336 if (node == NULL) {
337 continue;
338 }
339 RemoveListenerNode(node);
340 ReturnListenerNode(&node);
341 }
342
343 CloseEventWatcher(g_eventWatcher);
344 atomic_store_explicit(&g_initBaseListener, false, memory_order_release);
345 }
346
CreateListenerModule(void)347 uint32_t CreateListenerModule(void)
348 {
349 int32_t status = SoftBusMutexLock(&g_listenerListLock);
350 CONN_CHECK_AND_RETURN_RET_LOGE(
351 status == SOFTBUS_OK, UNUSE_BUTT, CONN_COMMON, "lock failed, error=%{public}d", status);
352
353 ListenerModule module = LISTENER_MODULE_DYNAMIC_START;
354 for (; module <= LISTENER_MODULE_DYNAMIC_END; module++) {
355 if (g_listenerList[module] != NULL) {
356 continue;
357 }
358 SoftbusListenerNode *node = CreateSpecifiedListenerModule(module);
359 if (node == NULL) {
360 CONN_LOGE(CONN_COMMON, "create specified listener module failed, module=%{public}d", module);
361 module = UNUSE_BUTT;
362 } else {
363 CONN_LOGI(CONN_COMMON, "create listener module success, module=%{public}d", module);
364 g_listenerList[module] = node;
365 }
366 break;
367 }
368 (void)SoftBusMutexUnlock(&g_listenerListLock);
369 return module;
370 }
371
DestroyBaseListener(ListenerModule module)372 void DestroyBaseListener(ListenerModule module)
373 {
374 CONN_CHECK_AND_RETURN_LOGW(module >= LISTENER_MODULE_DYNAMIC_START && module <= LISTENER_MODULE_DYNAMIC_END,
375 CONN_COMMON, "only dynamic module support destroy, module=%{public}d", module);
376
377 CONN_LOGI(CONN_COMMON, "receive request, module=%{public}d", module);
378 SoftbusListenerNode *node = GetListenerNode(module);
379 if (node == NULL) {
380 CONN_LOGW(CONN_COMMON, "listener not exist, module=%{public}d", module);
381 return;
382 }
383 RemoveListenerNode(node);
384 ReturnListenerNode(&node);
385 }
386
StartBaseClient(ListenerModule module,const SoftbusBaseListener * listener)387 int32_t StartBaseClient(ListenerModule module, const SoftbusBaseListener *listener)
388 {
389 CONN_CHECK_AND_RETURN_RET_LOGW(module >= 0 && module < UNUSE_BUTT, SOFTBUS_INVALID_PARAM, CONN_COMMON,
390 "invalid module, module=%{public}d", module);
391 CONN_CHECK_AND_RETURN_RET_LOGW(listener != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
392 "listener is null, module=%{public}d", module);
393 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectEvent != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
394 "listener onConnectEvent is null, module=%{public}d", module);
395 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onDataEvent != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
396 "listener onDataEvent is null, module=%{public}d", module);
397
398 SoftbusListenerNode *node = GetOrCreateListenerNode(module);
399 CONN_CHECK_AND_RETURN_RET_LOGW(
400 node != NULL, SOFTBUS_NOT_FIND, CONN_COMMON, "get listener node failed, module=%{public}d", module);
401
402 int32_t status = SoftBusMutexLock(&node->lock);
403 if (status != SOFTBUS_OK) {
404 CONN_LOGE(CONN_COMMON, "lock listener node failed, module=%{public}d, error=%{public}d", module, status);
405 ReturnListenerNode(&node);
406 return SOFTBUS_LOCK_ERR;
407 }
408 do {
409 if (node->info.status != LISTENER_IDLE) {
410 CONN_LOGE(CONN_COMMON, "listener is not idle status, module=%{public}d, status=%{public}d",
411 module, node->info.status);
412 status = SOFTBUS_CONN_LISTENER_NOT_IDLE;
413 break;
414 }
415 node->listener.onConnectEvent = listener->onConnectEvent;
416 node->listener.onDataEvent = listener->onDataEvent;
417 status = StartWatchThread();
418 if (status != SOFTBUS_OK) {
419 CONN_LOGE(CONN_COMMON, "start watch thread failed, module=%{public}d, "
420 "status=%{public}d", module, status);
421 break;
422 }
423 node->info.status = LISTENER_RUNNING;
424 CONN_LOGI(CONN_COMMON, "start base client listener success, module=%{public}d", module);
425 } while (false);
426 (void)SoftBusMutexUnlock(&node->lock);
427 ReturnListenerNode(&node);
428 return status;
429 }
430
StartServerListenUnsafe(SoftbusListenerNode * node,const LocalListenerInfo * info)431 static int32_t StartServerListenUnsafe(SoftbusListenerNode *node, const LocalListenerInfo *info)
432 {
433 ListenerModule module = node->module;
434 ProtocolType protocol = info->socketOption.protocol;
435 const SocketInterface *socketIf = GetSocketInterface(protocol);
436 if (socketIf == NULL) {
437 CONN_LOGE(CONN_COMMON, "not find protocal implement, module=%{public}d, protocal=%{public}d", module, protocol);
438 return SOFTBUS_NOT_FIND;
439 }
440 node->socketIf = socketIf;
441
442 int32_t listenFd = -1;
443 int32_t listenPort = -1;
444 int32_t status = SOFTBUS_OK;
445 do {
446 listenFd = socketIf->OpenServerSocket(info);
447 if (listenFd < 0) {
448 CONN_LOGE(CONN_COMMON, "create server socket failed: module=%{public}d, listenFd=%{public}d",
449 module, listenFd);
450 status = listenFd;
451 break;
452 }
453 status = SoftBusSocketListen(listenFd, DEFAULT_BACKLOG);
454 if (status != SOFTBUS_OK) {
455 CONN_LOGE(CONN_COMMON, "listen server socket failed: module=%{public}d, error=%{public}d", module, status);
456 break;
457 }
458 listenPort = socketIf->GetSockPort(listenFd);
459 if (listenPort < 0) {
460 CONN_LOGE(CONN_COMMON, "get listen server port failed: module=%{public}d, listenFd=%{public}d, "
461 "error=%{public}d", module, listenFd, status);
462 status = SOFTBUS_TCP_SOCKET_ERR;
463 break;
464 }
465 if (memcpy_s(&node->info.listenerInfo, sizeof(LocalListenerInfo), info, sizeof(LocalListenerInfo)) != EOK) {
466 CONN_LOGE(CONN_COMMON, "memcpy_s local listener info object failed: module=%{public}d", module);
467 status = SOFTBUS_MEM_ERR;
468 break;
469 }
470 node->info.modeType = SERVER_MODE;
471 node->info.listenFd = listenFd;
472 node->info.listenPort = listenPort;
473 } while (false);
474 if (status != SOFTBUS_OK && listenFd > 0) {
475 ConnShutdownSocket(listenFd);
476 }
477 return status == SOFTBUS_OK ? listenPort : status;
478 }
479
CleanupServerListenInfoUnsafe(SoftbusListenerNode * node)480 static void CleanupServerListenInfoUnsafe(SoftbusListenerNode *node)
481 {
482 memset_s(&node->info.listenerInfo, sizeof(SoftbusBaseListenerInfo), 0, sizeof(SoftbusBaseListenerInfo));
483 if (node->info.listenFd > 0) {
484 ConnShutdownSocket(node->info.listenFd);
485 }
486 node->info.listenFd = -1;
487 node->info.listenPort = -1;
488 }
489
FillConnEventExtra(const LocalListenerInfo * info,ConnEventExtra * extra,int32_t err)490 static void FillConnEventExtra(const LocalListenerInfo *info, ConnEventExtra *extra, int32_t err)
491 {
492 if (info == NULL || extra == NULL) {
493 return;
494 }
495 extra->errcode = err;
496 extra->result = err == SOFTBUS_OK ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
497 extra->linkType = info->type;
498 extra->moduleId = info->socketOption.moduleId;
499 extra->proType = info->socketOption.protocol;
500 }
501
StartBaseListener(const LocalListenerInfo * info,const SoftbusBaseListener * listener)502 int32_t StartBaseListener(const LocalListenerInfo *info, const SoftbusBaseListener *listener)
503 {
504 ConnEventExtra extra = {
505 .result = 0
506 };
507 CONN_EVENT(EVENT_SCENE_START_BASE_LISTENER, EVENT_STAGE_TCP_COMMON_ONE, extra);
508 CONN_CHECK_AND_RETURN_RET_LOGW(info != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON, "info is null");
509 CONN_CHECK_AND_RETURN_RET_LOGW(info->type == CONNECT_TCP || info->type == CONNECT_P2P || info->type == CONNECT_HML,
510 SOFTBUS_INVALID_PARAM, CONN_COMMON, "only CONNECT_TCP, CONNECT_P2P and CONNECT_HML is permitted, "
511 "CONNECT_TCP=%{public}d, CONNECT_P2P=%{public}d, CONNECT_HML=%{public}d, type=%{public}d",
512 CONNECT_TCP, CONNECT_P2P, CONNECT_HML, info->type);
513 CONN_CHECK_AND_RETURN_RET_LOGW(info->socketOption.port >= 0, SOFTBUS_INVALID_PARAM, CONN_COMMON,
514 "port is invalid, port=%{public}d", info->socketOption.port);
515 CONN_CHECK_AND_RETURN_RET_LOGW(info->socketOption.moduleId >= 0 && info->socketOption.moduleId < UNUSE_BUTT,
516 SOFTBUS_INVALID_PARAM, CONN_COMMON, "invalid module, module=%{public}d", info->socketOption.moduleId);
517 CONN_CHECK_AND_RETURN_RET_LOGW(listener != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
518 "listener is null, module=%{public}d", info->socketOption.moduleId);
519 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectEvent != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
520 "listener onConnectEvent is null, module=%{public}d", info->socketOption.moduleId);
521 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onDataEvent != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
522 "listener onDataEvent is null, module=%{public}d", info->socketOption.moduleId);
523
524 ListenerModule module = info->socketOption.moduleId;
525 SoftbusListenerNode *node = GetOrCreateListenerNode(module);
526 CONN_CHECK_AND_RETURN_RET_LOGW(
527 node != NULL, SOFTBUS_NOT_FIND, CONN_COMMON, "get listener node failed, module=%{public}d", module);
528 int32_t status = SoftBusMutexLock(&node->lock);
529 if (status != SOFTBUS_OK) {
530 CONN_LOGE(CONN_COMMON, "lock failed, module=%{public}d, error=%{public}d", module, status);
531 ReturnListenerNode(&node);
532 FillConnEventExtra(info, &extra, SOFTBUS_LOCK_ERR);
533 CONN_EVENT(EVENT_SCENE_START_BASE_LISTENER, EVENT_STAGE_TCP_COMMON_ONE, extra);
534 return SOFTBUS_LOCK_ERR;
535 }
536
537 int32_t listenPort = -1;
538 do {
539 if (node->info.status != LISTENER_IDLE) {
540 CONN_LOGE(CONN_COMMON, "listener is not idle status, module=%{public}d, status=%{public}d",
541 module, node->info.status);
542 status = SOFTBUS_CONN_LISTENER_NOT_IDLE;
543 break;
544 }
545
546 node->listener.onConnectEvent = listener->onConnectEvent;
547 node->listener.onDataEvent = listener->onDataEvent;
548 if (memcpy_s(&node->info.listenerInfo, sizeof(LocalListenerInfo), info, sizeof(LocalListenerInfo)) != EOK) {
549 CONN_LOGE(CONN_COMMON, "memcpy_s listener info failed, module=%{public}d", node->module);
550 status = SOFTBUS_LOCK_ERR;
551 break;
552 }
553 listenPort = StartServerListenUnsafe(node, info);
554 if (listenPort <= 0) {
555 CONN_LOGE(CONN_COMMON, "start server failed, module=%{public}d, listenPort=%{public}d",
556 module, listenPort);
557 status = listenPort;
558 break;
559 }
560
561 status = StartWatchThread();
562 if (status != SOFTBUS_OK) {
563 CONN_LOGE(CONN_COMMON, "start listener thread failed, module=%{public}d, status=%{public}d",
564 module, status);
565 CleanupServerListenInfoUnsafe(node);
566 break;
567 }
568 status = AddEvent(g_eventWatcher, node->info.listenFd, READ_TRIGGER);
569 if (status != SOFTBUS_OK) {
570 CONN_LOGE(CONN_COMMON, "add fd trigger to watch failed, module=%{public}d", module);
571 StopWatchThread();
572 CleanupServerListenInfoUnsafe(node);
573 break;
574 }
575 node->info.status = LISTENER_RUNNING;
576 CONN_LOGI(CONN_COMMON, "start base listener success, module=%{public}d, listenFd=%{public}d, "
577 "listenPort=%{public}d", module, node->info.listenFd, listenPort);
578 } while (false);
579 (void)SoftBusMutexUnlock(&node->lock);
580 ReturnListenerNode(&node);
581 FillConnEventExtra(info, &extra, status);
582 CONN_EVENT(EVENT_SCENE_START_BASE_LISTENER, EVENT_STAGE_TCP_COMMON_ONE, extra);
583 return status == SOFTBUS_OK ? listenPort : status;
584 }
585
StopBaseListener(ListenerModule module)586 int32_t StopBaseListener(ListenerModule module)
587 {
588 ConnEventExtra extra = {
589 .moduleId = module,
590 .result = 0
591 };
592 CONN_EVENT(EVENT_SCENE_STOP_BASE_LISTENER, EVENT_STAGE_TCP_COMMON_ONE, extra);
593 CONN_CHECK_AND_RETURN_RET_LOGW(
594 module >= 0 && module < UNUSE_BUTT, SOFTBUS_INVALID_PARAM, CONN_COMMON,
595 "invalid module, module=%{public}d", module);
596
597 CONN_LOGI(CONN_COMMON, "receive request, module=%{public}d", module);
598 SoftbusListenerNode *node = GetListenerNode(module);
599 CONN_CHECK_AND_RETURN_RET_LOGW(
600 node != NULL, SOFTBUS_NOT_FIND, CONN_COMMON, "listener node not exist, module=%{public}d", module);
601
602 int32_t status = ShutdownBaseListener(node);
603 if (status != SOFTBUS_OK) {
604 CONN_LOGE(CONN_COMMON, "stop listen thread failed, module=%{public}d, error=%{public}d", module, status);
605 }
606 ReturnListenerNode(&node);
607 extra.errcode = status;
608 extra.result = status == SOFTBUS_OK ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
609 CONN_EVENT(EVENT_SCENE_STOP_BASE_LISTENER, EVENT_STAGE_TCP_COMMON_ONE, extra);
610 return status;
611 }
612
ShutdownBaseListener(SoftbusListenerNode * node)613 static int32_t ShutdownBaseListener(SoftbusListenerNode *node)
614 {
615 int32_t status = SoftBusMutexLock(&node->lock);
616 CONN_CHECK_AND_RETURN_RET_LOGE(status == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_COMMON,
617 "lock failed, module=%{public}d, error=%{public}d", node->module, status);
618
619 do {
620 if (node->info.status != LISTENER_RUNNING) {
621 CONN_LOGW(CONN_COMMON, "listener is not running, just skip, module=%{public}d, error=%{public}d",
622 node->module, node->info.status);
623 break;
624 }
625 status = StopWatchThread();
626 if (status != SOFTBUS_OK) {
627 CONN_LOGE(CONN_COMMON, "stop watch thread failed, module=%{public}d, error=%{public}d",
628 node->module, status);
629 // fall-through
630 }
631 node->info.status = LISTENER_IDLE;
632
633 struct FdNode *it = NULL;
634 struct FdNode *next = NULL;
635 LIST_FOR_EACH_ENTRY_SAFE(it, next, &node->info.waitEventFds, struct FdNode, node) {
636 CONN_LOGE(CONN_COMMON, "listener node there is fd not close, module=%{public}d, fd=%{public}d, "
637 "triggerSet=%{public}u", node->module, it->fd, it->triggerSet);
638 // not close fd, repeat close will crash process
639 (void)RemoveEvent(g_eventWatcher, it->fd);
640 ListDelete(&it->node);
641 SoftBusFree(it);
642 }
643 node->info.waitEventFdsLen = 0;
644
645 int32_t listenFd = node->info.listenFd;
646 int32_t listenPort = node->info.listenPort;
647 if (node->info.modeType == SERVER_MODE && listenFd > 0) {
648 CONN_LOGE(CONN_COMMON, "close server, module=%{public}d, listenFd=%{public}d, port=%{public}d",
649 node->module, listenFd, listenPort);
650 (void)RemoveEvent(g_eventWatcher, listenFd);
651 ConnCloseSocket(listenFd);
652 }
653 node->info.modeType = UNSET_MODE;
654 node->info.listenFd = -1;
655 node->info.listenPort = -1;
656 (void)memset_s(&node->info.listenerInfo, sizeof(LocalListenerInfo), 0, sizeof(LocalListenerInfo));
657 } while (false);
658
659 SoftBusMutexUnlock(&node->lock);
660 return status;
661 }
662
IsValidTriggerType(TriggerType trigger)663 static bool IsValidTriggerType(TriggerType trigger)
664 {
665 switch (trigger) {
666 case READ_TRIGGER:
667 case WRITE_TRIGGER:
668 case EXCEPT_TRIGGER:
669 case RW_TRIGGER:
670 return true;
671 default:
672 return false;
673 }
674 }
675
IsListenerNodeExist(ListenerModule module)676 bool IsListenerNodeExist(ListenerModule module)
677 {
678 SoftbusListenerNode *node = GetListenerNode(module);
679 bool exist = false;
680 if (node != NULL) {
681 exist = true;
682 ReturnListenerNode(&node);
683 }
684 return exist;
685 }
686
AddTrigger(ListenerModule module,int32_t fd,TriggerType trigger)687 int32_t AddTrigger(ListenerModule module, int32_t fd, TriggerType trigger)
688 {
689 CONN_CHECK_AND_RETURN_RET_LOGW(module >= 0 && module < UNUSE_BUTT, SOFTBUS_INVALID_PARAM, CONN_COMMON,
690 "invalid module, module=%{public}d", module);
691 CONN_CHECK_AND_RETURN_RET_LOGW(
692 fd > 0, SOFTBUS_INVALID_PARAM, CONN_COMMON, "invalid fd, module=%{public}d, fd=%{public}d", module, fd);
693 CONN_CHECK_AND_RETURN_RET_LOGW(IsValidTriggerType(trigger), SOFTBUS_INVALID_PARAM, CONN_COMMON,
694 "invalid trigger, module=%{public}d, fd=%{public}d, trigger=%{public}d", module, fd, trigger);
695
696 SoftbusListenerNode *node = GetListenerNode(module);
697 CONN_CHECK_AND_RETURN_RET_LOGW(node != NULL, SOFTBUS_NOT_FIND, CONN_COMMON,
698 "listener node not exist, module=%{public}d, fd=%{public}d, trigger=%{public}d", module, fd, trigger);
699
700 int32_t status = SoftBusMutexLock(&node->lock);
701 if (status != SOFTBUS_OK) {
702 CONN_LOGE(CONN_COMMON, "lock failed, module=%{public}d, fd=%{public}d, trigger=%{public}d, "
703 "error=%{public}d", module, fd, trigger, status);
704 ReturnListenerNode(&node);
705 return SOFTBUS_LOCK_ERR;
706 }
707
708 do {
709 if (node->info.status != LISTENER_RUNNING) {
710 CONN_LOGE(CONN_COMMON, "module is not running, module=%{public}d, fd=%{public}d, trigger=%{public}d",
711 module, fd, trigger);
712 status = SOFTBUS_CONN_FAIL;
713 break;
714 }
715
716 struct FdNode *target = NULL;
717 struct FdNode *it = NULL;
718 LIST_FOR_EACH_ENTRY(it, &node->info.waitEventFds, struct FdNode, node) {
719 if (fd == it->fd) {
720 target = it;
721 break;
722 }
723 }
724
725 if (target != NULL) {
726 if ((target->triggerSet & trigger) == trigger) {
727 CONN_LOGW(CONN_COMMON, "repeat add trigger, just skip, module=%{public}d, fd=%{public}d, "
728 "trigger=%{public}d, triggerSet=%{public}u",
729 module, fd, trigger, target->triggerSet);
730 break;
731 }
732 status = ModifyEvent(g_eventWatcher, fd, target->triggerSet | trigger);
733 if (status == SOFTBUS_OK) {
734 target->triggerSet |= trigger;
735 CONN_LOGI(CONN_COMMON, "add trigger success, module=%{public}d, fd=%{public}d, "
736 "AddTrigger=%{public}d, triggerSet=%{public}u", module, fd, trigger, target->triggerSet);
737 }
738 break;
739 }
740
741 struct FdNode *fdNode = (struct FdNode *)SoftBusCalloc(sizeof(struct FdNode));
742 if (fdNode == NULL) {
743 CONN_LOGE(CONN_COMMON, "calloc failed, module=%{public}d, fd=%{public}d, trigger=%{public}d",
744 module, fd, trigger);
745 status = SOFTBUS_MALLOC_ERR;
746 break;
747 }
748 status = AddEvent(g_eventWatcher, fd, trigger);
749 if (status == SOFTBUS_OK) {
750 ListInit(&fdNode->node);
751 fdNode->fd = fd;
752 fdNode->triggerSet = trigger;
753 ListAdd(&node->info.waitEventFds, &fdNode->node);
754 node->info.waitEventFdsLen += 1;
755 CONN_LOGI(CONN_COMMON, "add trigger success, module=%{public}d, fd=%{public}d, trigger=%{public}d",
756 module, fd, trigger);
757 break;
758 }
759 SoftBusFree(fdNode);
760 } while (false);
761
762 (void)SoftBusMutexUnlock(&node->lock);
763 ReturnListenerNode(&node);
764 return status;
765 }
766
DelTrigger(ListenerModule module,int32_t fd,TriggerType trigger)767 int32_t DelTrigger(ListenerModule module, int32_t fd, TriggerType trigger)
768 {
769 CONN_CHECK_AND_RETURN_RET_LOGW(module >= 0 && module < UNUSE_BUTT, SOFTBUS_INVALID_PARAM, CONN_COMMON,
770 "invalid module, module=%{public}d", module);
771 CONN_CHECK_AND_RETURN_RET_LOGW(fd > 0, SOFTBUS_INVALID_PARAM, CONN_COMMON,
772 "invalid fd, module=%{public}d, fd=%{public}d", module, fd);
773 CONN_CHECK_AND_RETURN_RET_LOGW(IsValidTriggerType(trigger), SOFTBUS_INVALID_PARAM, CONN_COMMON,
774 "invalid trigger, module=%{public}d, fd=%{public}d, trigger=%{public}d", module, fd, trigger);
775
776 SoftbusListenerNode *node = GetListenerNode(module);
777 CONN_CHECK_AND_RETURN_RET_LOGW(node != NULL, SOFTBUS_NOT_FIND, CONN_COMMON,
778 "listener node not exist, module=%{public}d, fd=%{public}d, trigger=%{public}d", module, fd, trigger);
779
780 int32_t status = SoftBusMutexLock(&node->lock);
781 if (status != SOFTBUS_OK) {
782 CONN_LOGE(CONN_COMMON, "lock failed, module=%{public}d, fd=%{public}d, trigger=%{public}d, "
783 "error=%{public}d", module, fd, trigger, status);
784 ReturnListenerNode(&node);
785 return SOFTBUS_LOCK_ERR;
786 }
787
788 do {
789 struct FdNode *target = NULL;
790 struct FdNode *it = NULL;
791 LIST_FOR_EACH_ENTRY(it, &node->info.waitEventFds, struct FdNode, node) {
792 if (fd == it->fd) {
793 target = it;
794 break;
795 }
796 }
797
798 if (target == NULL) {
799 CONN_LOGW(CONN_COMMON, "fd node not exist, module=%{public}d, fd=%{public}d, trigger=%{public}d",
800 module, fd, trigger);
801 // consider delete trigger success,
802 status = SOFTBUS_NOT_FIND;
803 break;
804 }
805
806 if ((target->triggerSet & trigger) == 0) {
807 CONN_LOGW(CONN_COMMON,
808 "without add trigger before, repeat delete trigger or mismatch module. "
809 "module=%{public}d, fd=%{public}d, wantDeleteTrigger=%{public}d, triggerSet=%{public}u",
810 module, fd, trigger, target->triggerSet);
811 // consider delete trigger success,
812 status = SOFTBUS_OK;
813 break;
814 }
815
816 target->triggerSet &= ~trigger;
817 if (target->triggerSet != 0) {
818 (void)ModifyEvent(g_eventWatcher, fd, target->triggerSet);
819 CONN_LOGI(CONN_COMMON, "delete trigger success, module=%{public}d, fd=%{public}d, trigger=%{public}d, "
820 "triggerSet=%{public}u", module, fd, trigger, target->triggerSet);
821 status = SOFTBUS_OK;
822 break;
823 }
824 (void)RemoveEvent(g_eventWatcher, fd);
825 CONN_LOGI(
826 CONN_COMMON,
827 "delete trigger success, module=%{public}d, fd=%{public}d, trigger=%{public}d",
828 module, fd, trigger);
829 ListDelete(&target->node);
830 SoftBusFree(target);
831 node->info.waitEventFdsLen -= 1;
832 } while (false);
833
834 SoftBusMutexUnlock(&node->lock);
835 ReturnListenerNode(&node);
836 return status;
837 }
838
CleanupWatchThreadState(WatchThreadState ** statePtr)839 static void CleanupWatchThreadState(WatchThreadState **statePtr)
840 {
841 WatchThreadState *state = *statePtr;
842
843 CONN_LOGI(CONN_COMMON, "cleanup watch thread state, traceId=%{public}d", state->traceId);
844 (void)SoftBusMutexDestroy(&state->lock);
845 SoftBusFree(state);
846 *statePtr = NULL;
847 }
848
DispatchFdEvent(int32_t fd,ListenerModule module,enum SocketEvent event,const SoftbusBaseListener * listener,int32_t wakeupTrace)849 static void DispatchFdEvent(
850 int32_t fd, ListenerModule module, enum SocketEvent event, const SoftbusBaseListener *listener, int32_t wakeupTrace)
851 {
852 if (listener->onDataEvent != NULL) {
853 listener->onDataEvent(module, event, fd);
854 CONN_LOGI(CONN_COMMON,
855 "wakeupTrace=%{public}d, module=%{public}d, fd=%{public}d, event=%{public}d",
856 wakeupTrace, module, fd, event);
857 } else {
858 CONN_LOGE(CONN_COMMON,
859 "listener not registered, to avoid repeat wakeup, close it,"
860 "wakeupTrace=%{public}d, module=%{public}d, fd=%{public}d, event=%{public}d",
861 wakeupTrace, module, fd, event);
862 ConnCloseSocket(fd);
863 }
864 }
865
ProcessSpecifiedServerAcceptEvent(ListenerModule module,int32_t listenFd,ConnectType connectType,const SocketInterface * socketIf,const SoftbusBaseListener * listener,int32_t wakeupTrace)866 static int32_t ProcessSpecifiedServerAcceptEvent(ListenerModule module, int32_t listenFd, ConnectType connectType,
867 const SocketInterface *socketIf, const SoftbusBaseListener *listener, int32_t wakeupTrace)
868 {
869 CONN_CHECK_AND_RETURN_RET_LOGW(socketIf != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
870 "socket interface implement is null, wakeupTrace=%{public}d, module=%{public}d", wakeupTrace, module);
871 CONN_CHECK_AND_RETURN_RET_LOGW(socketIf->AcceptClient != NULL, SOFTBUS_INVALID_PARAM, CONN_COMMON,
872 "socket interface implement not support AcceptClient method, wakeupTrace=%{public}d, module=%{public}d",
873 wakeupTrace, module);
874
875 int32_t status = SOFTBUS_OK;
876 while (true) {
877 int32_t clientFd = -1;
878 ConnectOption clientAddr = {
879 .type = connectType,
880 .socketOption = {
881 .addr = { 0 },
882 .port = 0,
883 .moduleId = module,
884 .protocol = 0,
885 .keepAlive = 0,
886 },
887 };
888 status = SOFTBUS_TEMP_FAILURE_RETRY(socketIf->AcceptClient(listenFd, &clientAddr, &clientFd));
889 if (status != SOFTBUS_OK) {
890 break;
891 }
892
893 char animizedIp[IP_LEN] = { 0 };
894 ConvertAnonymizeIpAddress(animizedIp, IP_LEN, clientAddr.socketOption.addr, IP_LEN);
895 if (listener->onConnectEvent != NULL) {
896 CONN_LOGI(CONN_COMMON,
897 "trigger ACCEPT event, wakeupTrace=%{public}d, module=%{public}d, listenFd=%{public}d, "
898 "clientIp=%{public}s, clientFd=%{public}d", wakeupTrace, module, listenFd, animizedIp, clientFd);
899 listener->onConnectEvent(module, clientFd, &clientAddr);
900 } else {
901 CONN_LOGE(CONN_COMMON,
902 "event listener not registered, wakeupTrace=%{public}d, module=%{public}d, "
903 "listenFd=%{public}d, clientIp=%{public}s, clientFd=%{public}d",
904 wakeupTrace, module, listenFd, animizedIp, clientFd);
905 ConnCloseSocket(clientFd);
906 }
907 }
908 return status;
909 }
910
CopyWaitEventFdsUnsafe(const SoftbusListenerNode * node,struct FdNode ** outArray,uint32_t * outArrayLen)911 static int32_t CopyWaitEventFdsUnsafe(const SoftbusListenerNode *node, struct FdNode **outArray, uint32_t *outArrayLen)
912 {
913 if (node->info.waitEventFdsLen == 0) {
914 *outArray = NULL;
915 outArrayLen = 0;
916 return SOFTBUS_OK;
917 }
918
919 uint32_t fdArrayLen = node->info.waitEventFdsLen;
920 struct FdNode *fdArray = (struct FdNode *)SoftBusCalloc(fdArrayLen * sizeof(struct FdNode));
921 CONN_CHECK_AND_RETURN_RET_LOGE(fdArray != NULL, SOFTBUS_MALLOC_ERR, CONN_COMMON,
922 "calloc failed, module=%{public}d, eventLen=%{public}u", node->module, fdArrayLen);
923
924 uint32_t i = 0;
925 struct FdNode *item = NULL;
926 bool expand = false;
927 LIST_FOR_EACH_ENTRY(item, &node->info.waitEventFds, struct FdNode, node) {
928 if (i >= fdArrayLen) {
929 uint32_t tmpLen = fdArrayLen * FDARR_EXPAND_BASE;
930 struct FdNode *tmp = (struct FdNode *)SoftBusCalloc(tmpLen * sizeof(struct FdNode));
931 if (tmp == NULL) {
932 CONN_LOGE(CONN_COMMON, "expand calloc fd node array object failed, module=%{public}d, "
933 "eventLen=%{public}u", node->module, tmpLen);
934 SoftBusFree(fdArray);
935 return SOFTBUS_MALLOC_ERR;
936 }
937 for (uint32_t j = 0; j < fdArrayLen; j++) {
938 tmp[j].fd = fdArray[j].fd;
939 tmp[j].triggerSet = fdArray[j].triggerSet;
940 }
941 SoftBusFree(fdArray);
942 fdArray = tmp;
943 fdArrayLen = tmpLen;
944 expand = true;
945 }
946 fdArray[i].fd = item->fd;
947 fdArray[i].triggerSet = item->triggerSet;
948 i++;
949 }
950
951 // diagnose by the way
952 if (expand) {
953 CONN_LOGE(CONN_COMMON, "listener node 'waitEventFdsLen' field is unexpected, "
954 "actualWaitEventFdsLen=%{public}u > waitEventFdsLen=%{public}u, module=%{public}d",
955 i, node->info.waitEventFdsLen, node->module);
956 } else if (i != fdArrayLen) {
957 CONN_LOGE(CONN_COMMON, "listener node 'waitEventFdsLen' field is unexpected, "
958 "actualWaitEventFdsLen=%{public}u < waitEventFdsLen=%{public}u, module=%{public}d",
959 i, node->info.waitEventFdsLen, node->module);
960 }
961
962 *outArrayLen = i;
963 *outArray = fdArray;
964 return SOFTBUS_OK;
965 }
966
CloseInvalidListenForcely(SoftbusListenerNode * node,int32_t listenFd,const char * anomizedIp,int32_t reason)967 static void CloseInvalidListenForcely(SoftbusListenerNode *node, int32_t listenFd, const char *anomizedIp,
968 int32_t reason)
969 {
970 int32_t ret = SoftBusMutexLock(&node->lock);
971 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_COMMON, "lock failed, module=%{public}d, error=%{public}d",
972 node->module, ret);
973 do {
974 if (node->info.status != LISTENER_RUNNING || node->info.modeType != SERVER_MODE ||
975 node->info.listenFd != listenFd) {
976 break;
977 }
978 CONN_LOGW(CONN_COMMON, "forcely close to prevent repeat wakeup watch, module=%{public}d, "
979 "listenFd=%{public}d, port=%{public}d, ip=%{public}s, error=%{public}d",
980 node->module, node->info.listenFd, node->info.listenPort, anomizedIp, reason);
981 (void)RemoveEvent(g_eventWatcher, listenFd);
982 ConnCloseSocket(node->info.listenFd);
983 node->info.listenFd = -1;
984 node->info.listenPort = -1;
985 } while (false);
986 SoftBusMutexUnlock(&node->lock);
987 }
988
ProcessServerAcceptEvent(SoftbusListenerNode * node,ListNode * fdNode,int32_t wakeupTrace,SoftbusBaseListener * listener)989 static void ProcessServerAcceptEvent(
990 SoftbusListenerNode *node, ListNode *fdNode, int32_t wakeupTrace, SoftbusBaseListener *listener)
991 {
992 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&node->lock) == SOFTBUS_OK, CONN_COMMON,
993 "lock failed, wakeupTrace=%{public}d, module=%{public}d", wakeupTrace, node->module);
994 int32_t listenFd = -1;
995 int32_t listenPort = -1;
996 char animizedIp[IP_LEN] = { 0 };
997 if (node->info.modeType == SERVER_MODE && node->info.listenFd > 0) {
998 listenFd = node->info.listenFd;
999 listenPort = node->info.listenPort;
1000 ConvertAnonymizeIpAddress(animizedIp, IP_LEN, node->info.listenerInfo.socketOption.addr, IP_LEN);
1001 }
1002 const SocketInterface *socketIf = node->socketIf;
1003 ConnectType connectType = node->info.listenerInfo.type;
1004 SoftBusMutexUnlock(&node->lock);
1005
1006 if (listenFd > 0) {
1007 int32_t status = SOFTBUS_OK;
1008 struct FdNode *it = NULL;
1009 struct FdNode *next = NULL;
1010 LIST_FOR_EACH_ENTRY_SAFE(it, next, fdNode, struct FdNode, node) {
1011 if (it->fd == listenFd) {
1012 if ((it->triggerSet & READ_TRIGGER) != 0) {
1013 status = ProcessSpecifiedServerAcceptEvent(
1014 node->module, listenFd, connectType, socketIf, listener, wakeupTrace);
1015 }
1016 }
1017 }
1018 switch (status) {
1019 case SOFTBUS_OK:
1020 case SOFTBUS_ADAPTER_SOCKET_EAGAIN:
1021 break;
1022 case SOFTBUS_ADAPTER_SOCKET_EINVAL:
1023 case SOFTBUS_ADAPTER_SOCKET_EBADF:
1024 CloseInvalidListenForcely(node, listenFd, animizedIp, status);
1025 break;
1026 default:
1027 CONN_LOGD(CONN_COMMON,
1028 "accept client failed, wakeupTrace=%{public}d, module=%{public}d, listenFd=%{public}d, "
1029 "port=%{public}d, ip=%{public}s, error=%{public}d",
1030 wakeupTrace, node->module, listenFd, listenPort, animizedIp, status);
1031 break;
1032 }
1033 }
1034 }
1035
ProcessFdEvent(SoftbusListenerNode * node,struct FdNode fdEvent,ListNode * fdNode,SoftbusBaseListener * listener,int32_t wakeupTrace)1036 static void ProcessFdEvent(SoftbusListenerNode *node, struct FdNode fdEvent,
1037 ListNode *fdNode, SoftbusBaseListener *listener, int32_t wakeupTrace)
1038 {
1039 struct FdNode *it = NULL;
1040 struct FdNode *next = NULL;
1041 LIST_FOR_EACH_ENTRY_SAFE(it, next, fdNode, struct FdNode, node) {
1042 if (it->fd == fdEvent.fd) {
1043 uint32_t triggerSet = fdEvent.triggerSet & it->triggerSet;
1044 if ((triggerSet & READ_TRIGGER) != 0) {
1045 CONN_LOGD(CONN_COMMON, "trigger IN event, wakeupTrace=%{public}d, "
1046 "module=%{public}d, fd=%{public}d, triggerSet=%{public}u",
1047 wakeupTrace, node->module, fdEvent.fd, fdEvent.triggerSet);
1048 DispatchFdEvent(fdEvent.fd, node->module, SOFTBUS_SOCKET_IN, listener, wakeupTrace);
1049 }
1050 if ((triggerSet & WRITE_TRIGGER) != 0) {
1051 CONN_LOGD(CONN_COMMON, "trigger OUT event, wakeupTrace=%{public}d, "
1052 "module=%{public}d, fd=%{public}d, triggerSet=%{public}u",
1053 wakeupTrace, node->module, fdEvent.fd, fdEvent.triggerSet);
1054 DispatchFdEvent(fdEvent.fd, node->module, SOFTBUS_SOCKET_OUT, listener, wakeupTrace);
1055 }
1056 if ((triggerSet & EXCEPT_TRIGGER) != 0) {
1057 CONN_LOGW(CONN_COMMON, "trigger EXCEPTION(out-of-band data) event, wakeupTrace=%{public}d, "
1058 "module=%{public}d, fd=%{public}d, triggerSet=%{public}u",
1059 wakeupTrace, node->module, fdEvent.fd, fdEvent.triggerSet);
1060 DispatchFdEvent(fdEvent.fd, node->module, SOFTBUS_SOCKET_EXCEPTION, listener, wakeupTrace);
1061 }
1062 }
1063 }
1064 }
1065
ProcessSpecifiedListenerNodeEvent(SoftbusListenerNode * node,ListNode * fdNode,int32_t wakeupTrace)1066 static void ProcessSpecifiedListenerNodeEvent(SoftbusListenerNode *node, ListNode *fdNode, int32_t wakeupTrace)
1067 {
1068 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&node->lock) == SOFTBUS_OK, CONN_COMMON,
1069 "lock failed, wakeupTrace=%{public}d, module=%{public}d", wakeupTrace, node->module);
1070 if (node->info.status != LISTENER_RUNNING) {
1071 SoftBusMutexUnlock(&node->lock);
1072 return;
1073 }
1074 SoftbusBaseListener listener = node->listener;
1075 struct FdNode *fdArray = NULL;
1076 uint32_t fdArrayLen = 0;
1077 int32_t status = CopyWaitEventFdsUnsafe(node, &fdArray, &fdArrayLen);
1078 SoftBusMutexUnlock(&node->lock);
1079 if (status != SOFTBUS_OK) {
1080 CONN_LOGE(CONN_COMMON,
1081 "copy wait event fds failed, wakeupTrace=%{public}d, module=%{public}d, error=%{public}d",
1082 wakeupTrace, node->module, status);
1083 return;
1084 }
1085 ProcessServerAcceptEvent(node, fdNode, wakeupTrace, &listener);
1086
1087 for (uint32_t i = 0; i < fdArrayLen; i++) {
1088 ProcessFdEvent(node, fdArray[i], fdNode, &listener, wakeupTrace);
1089 }
1090 SoftBusFree(fdArray);
1091 }
1092
ProcessEvent(ListNode * fdNode,const WatchThreadState * watchState,int32_t wakeupTrace)1093 static void ProcessEvent(ListNode *fdNode, const WatchThreadState *watchState, int32_t wakeupTrace)
1094 {
1095 for (ListenerModule module = 0; module < UNUSE_BUTT; module++) {
1096 SoftbusListenerNode *node = GetListenerNode(module);
1097 if (node == NULL) {
1098 continue;
1099 }
1100 ProcessSpecifiedListenerNodeEvent(node, fdNode, wakeupTrace);
1101 ReturnListenerNode(&node);
1102 }
1103 }
1104
RemoveBadFd(void)1105 static void RemoveBadFd(void)
1106 {
1107 for (ListenerModule module = 0; module < UNUSE_BUTT; module++) {
1108 SoftbusListenerNode *node = GetListenerNode(module);
1109 if (node == NULL) {
1110 continue;
1111 }
1112 int32_t ret = SoftBusMutexLock(&node->lock);
1113 if (ret != SOFTBUS_OK) {
1114 CONN_LOGE(CONN_COMMON, "lock failed, module=%{public}d", module);
1115 ReturnListenerNode(&node);
1116 continue;
1117 }
1118 if (node->info.status != LISTENER_RUNNING) {
1119 SoftBusMutexUnlock(&node->lock);
1120 ReturnListenerNode(&node);
1121 continue;
1122 }
1123 if (node->info.listenFd > 0 && SoftBusSocketGetError(node->info.listenFd) == SOFTBUS_CONN_BAD_FD) {
1124 CONN_LOGE(CONN_COMMON, "remove bad listen fd, fd=%{public}d, module=%{public}d",
1125 node->info.listenFd, module);
1126 node->info.listenFd = -1;
1127 }
1128 struct FdNode *it = NULL;
1129 struct FdNode *next = NULL;
1130 LIST_FOR_EACH_ENTRY_SAFE(it, next, &node->info.waitEventFds, struct FdNode, node) {
1131 if (SoftBusSocketGetError(it->fd) == SOFTBUS_CONN_BAD_FD) {
1132 CONN_LOGE(CONN_COMMON, "remove bad fd, fd=%{public}d, module=%{public}d", it->fd, module);
1133 ListDelete(&it->node);
1134 SoftBusFree(it);
1135 }
1136 }
1137 SoftBusMutexUnlock(&node->lock);
1138 ReturnListenerNode(&node);
1139 }
1140 }
1141
1142
WatchTask(void * arg)1143 static void *WatchTask(void *arg)
1144 {
1145 static int32_t wakeupTraceIdGenerator = 0;
1146
1147 CONN_CHECK_AND_RETURN_RET_LOGW(arg != NULL, NULL, CONN_COMMON, "invalid param");
1148 WatchThreadState *watchState = (WatchThreadState *)arg;
1149 while (true) {
1150 int32_t status = SoftBusMutexLock(&watchState->lock);
1151 if (status != SOFTBUS_OK) {
1152 CONN_LOGE(CONN_COMMON, "lock failed, retry after some times. "
1153 "waitDelay=%{public}dms, watchTrace=%{public}d, error=%{public}d",
1154 WATCH_UNEXPECT_FAIL_RETRY_WAIT_MILLIS, watchState->traceId, status);
1155 SoftBusSleepMs(WATCH_UNEXPECT_FAIL_RETRY_WAIT_MILLIS);
1156 continue;
1157 }
1158 int32_t referenceCount = watchState->referenceCount;
1159 (void)SoftBusMutexUnlock(&watchState->lock);
1160
1161 if (referenceCount <= 0) {
1162 CONN_LOGW(CONN_COMMON, "watch task, watch task is not reference by others any more, exit... "
1163 "watchTrace=%{public}d", watchState->traceId);
1164 break;
1165 }
1166 ListNode fdEvents;
1167 ListInit(&fdEvents);
1168 CONN_LOGI(CONN_COMMON, "WatchEvent is start, traceId=%{public}d", watchState->traceId);
1169 int32_t nEvents = WatchEvent(g_eventWatcher, SOFTBUS_LISTENER_WATCH_TIMEOUT_MSEC, &fdEvents);
1170 int32_t wakeupTraceId = ++wakeupTraceIdGenerator;
1171 if (nEvents == 0) {
1172 ReleaseFdNode(&fdEvents);
1173 continue;
1174 }
1175 if (nEvents < 0) {
1176 CONN_LOGE(CONN_COMMON, "unexpect wakeup, retry after some times. "
1177 "waitDelay=%{public}dms, wakeupTraceId=%{public}d, events=%{public}d",
1178 WATCH_ABNORMAL_EVENT_RETRY_WAIT_MILLIS, wakeupTraceId, nEvents);
1179 ReleaseFdNode(&fdEvents);
1180 if (nEvents == SOFTBUS_ADAPTER_SOCKET_EBADF) {
1181 RemoveBadFd();
1182 }
1183 SoftBusSleepMs(WATCH_ABNORMAL_EVENT_RETRY_WAIT_MILLIS);
1184 continue;
1185 }
1186 CONN_LOGI(CONN_COMMON, "watch task, wakeup from watch, watchTrace=%{public}d, wakeupTraceId=%{public}d, "
1187 "events=%{public}d", watchState->traceId, wakeupTraceId, nEvents);
1188 ProcessEvent(&fdEvents, watchState, wakeupTraceId);
1189 ReleaseFdNode(&fdEvents);
1190 }
1191 CleanupWatchThreadState(&watchState);
1192 return NULL;
1193 }
1194
StartWatchThread(void)1195 static int32_t StartWatchThread(void)
1196 {
1197 static int32_t watchThreadTraceIdGenerator = 1;
1198
1199 int32_t status = SoftBusMutexLock(&g_watchThreadStateLock);
1200 CONN_CHECK_AND_RETURN_RET_LOGE(
1201 status == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_COMMON, "lock global watch thread state failed");
1202
1203 do {
1204 if (g_watchThreadState != NULL) {
1205 status = SoftBusMutexLock(&g_watchThreadState->lock);
1206 if (status != SOFTBUS_OK) {
1207 CONN_LOGE(CONN_COMMON, "lock watch thread state self failed, error=%{public}d", status);
1208 status = SOFTBUS_LOCK_ERR;
1209 break;
1210 }
1211 int32_t referenceCount = ++g_watchThreadState->referenceCount;
1212 (void)SoftBusMutexUnlock(&g_watchThreadState->lock);
1213
1214 CONN_LOGD(CONN_COMMON, "watch thread is already start, watchTrace=%{public}d, referenceCount=%{public}d",
1215 g_watchThreadState->traceId, referenceCount);
1216 break;
1217 }
1218
1219 WatchThreadState *state = SoftBusCalloc(sizeof(WatchThreadState));
1220 if (state == NULL) {
1221 status = SOFTBUS_MALLOC_ERR;
1222 break;
1223 }
1224 state->traceId = ++watchThreadTraceIdGenerator;
1225
1226 status = SoftBusMutexInit(&state->lock, NULL);
1227 if (status != SOFTBUS_OK) {
1228 CONN_LOGE(CONN_COMMON, "start watch task async failed, error=%{public}d", status);
1229 CleanupWatchThreadState(&state);
1230 break;
1231 }
1232 state->referenceCount = 1;
1233 status = ConnStartActionAsync(state, WatchTask, "Watch_Tsk");
1234 if (status != SOFTBUS_OK) {
1235 CONN_LOGE(CONN_COMMON, "init lock failed, error=%{public}d", status);
1236 CleanupWatchThreadState(&state);
1237 break;
1238 }
1239 CONN_LOGI(CONN_COMMON, "start watch thread success, traceId=%{public}d", state->traceId);
1240 g_watchThreadState = state;
1241 } while (false);
1242 (void)SoftBusMutexUnlock(&g_watchThreadStateLock);
1243 return status;
1244 }
1245
StopWatchThread(void)1246 static int32_t StopWatchThread(void)
1247 {
1248 int32_t status = SoftBusMutexLock(&g_watchThreadStateLock);
1249 CONN_CHECK_AND_RETURN_RET_LOGE(
1250 status == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_COMMON, "lock global watch thread state failed");
1251 do {
1252 if (g_watchThreadState == NULL) {
1253 CONN_LOGW(CONN_COMMON, "watch thread is already stop or never start");
1254 break;
1255 }
1256
1257 status = SoftBusMutexLock(&g_watchThreadState->lock);
1258 if (status != SOFTBUS_OK) {
1259 CONN_LOGE(CONN_COMMON, "lock watch thread state self");
1260 break;
1261 }
1262 g_watchThreadState->referenceCount -= 1;
1263 int32_t referenceCount = g_watchThreadState->referenceCount;
1264 (void)SoftBusMutexUnlock(&g_watchThreadState->lock);
1265 if (referenceCount <= 0) {
1266 CONN_LOGW(CONN_COMMON, "watch thread is not used by other module any more, notify "
1267 "exit, thread reference count=%{public}d", referenceCount);
1268 g_watchThreadState = NULL;
1269 }
1270 } while (false);
1271 (void)SoftBusMutexUnlock(&g_watchThreadStateLock);
1272 return status;
1273 }
1274