• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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