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 <securec.h>
19 #include <unistd.h>
20
21 #include "common_list.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_adapter_socket.h"
24 #include "softbus_errcode.h"
25 #include "softbus_feature_config.h"
26 #include "softbus_log.h"
27 #include "softbus_tcp_socket.h"
28 #include "softbus_thread_pool.h"
29 #include "softbus_utils.h"
30
31 #define MAX_LISTEN_EVENTS 1024
32 #define TIMEOUT 10000
33 #define DEFAULT_BACKLOG 4
34 #define FDARR_START_SIZE 16
35 #define FDARR_EXPAND_BASE 2
36
37 #define THREADPOOL_THREADNUM 1
38 #define THREADPOOL_QUEUE_NUM 10
39
40 typedef enum {
41 LISTENER_IDLE,
42 LISTENER_PREPARED,
43 LISTENER_RUNNING,
44 LISTENER_ERROR,
45 } ListenerStatus;
46
47 typedef struct {
48 ListNode node;
49 int32_t fd;
50 } FdNode;
51
52 typedef struct {
53 ListNode node;
54 int32_t listenFd;
55 char ip[IP_LEN];
56 int32_t listenPort;
57 int32_t fdCount;
58 ModeType modeType;
59 ListenerStatus status;
60 } SoftbusBaseListenerInfo;
61
62 typedef struct {
63 ListenerModule module;
64 SoftbusBaseListener *listener;
65 SoftbusBaseListenerInfo *info;
66 SoftBusMutex lock;
67 bool lockInit;
68 } SoftbusListenerNode;
69
70 typedef struct {
71 SoftBusMutex lock;
72 bool lockInit;
73 }SoftBusSetLock;
74
75 static SoftbusListenerNode g_listenerList[UNUSE_BUTT] = {0};
76 static ThreadPool *g_threadPool = NULL;
77 static SoftBusFdSet g_readSet;
78 static SoftBusFdSet g_writeSet;
79 static SoftBusFdSet g_exceptSet;
80 static int32_t g_maxFd;
81 static SoftBusSetLock g_fdSetLock = {
82 .lockInit = false,
83 };
84 static bool g_fdSetInit = false;
85
FdCopy(const SoftBusFdSet * dest,const SoftBusFdSet * src)86 static int32_t FdCopy(const SoftBusFdSet *dest, const SoftBusFdSet *src)
87 {
88 return memcpy_s((void *)dest, sizeof(SoftBusFdSet), (void *)src, sizeof(SoftBusFdSet));
89 }
90
MaxFd(int32_t fd1,int32_t fd2)91 static int32_t MaxFd(int32_t fd1, int32_t fd2)
92 {
93 return (fd1 > fd2) ? fd1 : fd2;
94 }
95
UpdateMaxFd(void)96 static void UpdateMaxFd(void)
97 {
98 int32_t tmpMax = -1;
99
100 for (int i = 0; i < UNUSE_BUTT; i++) {
101 if (g_listenerList[i].info == NULL || g_listenerList[i].info->status != LISTENER_RUNNING) {
102 continue;
103 }
104
105 if (SoftBusMutexLock(&g_listenerList[i].lock) != SOFTBUS_OK) {
106 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
107 continue;
108 }
109
110 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[i].info;
111 if (listenerInfo == NULL) {
112 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "listenerInfo is NULL");
113 SoftBusMutexUnlock(&g_listenerList[i].lock);
114 continue;
115 }
116
117 tmpMax = MaxFd(listenerInfo->listenFd, tmpMax);
118 FdNode *item = NULL;
119 FdNode *nextItem = NULL;
120 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &listenerInfo->node, FdNode, node) {
121 tmpMax = MaxFd(item->fd, tmpMax);
122 }
123 SoftBusMutexUnlock(&g_listenerList[i].lock);
124 }
125
126 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
127 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
128 return;
129 }
130 g_maxFd = tmpMax;
131 SoftBusMutexUnlock(&(g_fdSetLock.lock));
132 }
133
CheckModule(ListenerModule module)134 static int32_t CheckModule(ListenerModule module)
135 {
136 if (module >= UNUSE_BUTT || module < PROXY) {
137 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid listener module.");
138 return SOFTBUS_INVALID_PARAM;
139 }
140 return SOFTBUS_OK;
141 }
142
CheckTrigger(TriggerType triggerType)143 static int32_t CheckTrigger(TriggerType triggerType)
144 {
145 if (triggerType < READ_TRIGGER || triggerType > RW_TRIGGER) {
146 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid listener trigger type.");
147 return SOFTBUS_INVALID_PARAM;
148 }
149 return SOFTBUS_OK;
150 }
151
ClearListenerFdList(const ListNode * cfdList)152 static void ClearListenerFdList(const ListNode *cfdList)
153 {
154 FdNode *item = NULL;
155
156 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
157 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
158 return;
159 }
160 while (!IsListEmpty(cfdList)) {
161 item = LIST_ENTRY(cfdList->next, FdNode, node);
162 ListDelete(&item->node);
163 SoftBusSocketFdClr(item->fd, &g_readSet);
164 SoftBusSocketFdClr(item->fd, &g_writeSet);
165 SoftBusSocketFdClr(item->fd, &g_exceptSet);
166 SoftBusFree(item);
167 }
168 SoftBusMutexUnlock(&(g_fdSetLock.lock));
169 }
170
InitListenFd(ListenerModule module,const char * ip,int32_t port)171 static int32_t InitListenFd(ListenerModule module, const char *ip, int32_t port)
172 {
173 if (CheckModule(module) != SOFTBUS_OK || ip == NULL || port < 0) {
174 return SOFTBUS_INVALID_PARAM;
175 }
176 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info;
177 if (listenerInfo == NULL) {
178 return SOFTBUS_ERR;
179 }
180 int32_t rc = OpenTcpServerSocket(ip, port);
181 if (rc < 0) {
182 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "OpenTcpServer failed, rc=%d", rc);
183 return SOFTBUS_TCP_SOCKET_ERR;
184 }
185 listenerInfo->listenFd = rc;
186 rc = SoftBusSocketListen(listenerInfo->listenFd, DEFAULT_BACKLOG);
187 if (rc != 0) {
188 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "listen failed, rc=%d", rc);
189 ResetBaseListener(module);
190 return SOFTBUS_TCP_SOCKET_ERR;
191 }
192 listenerInfo->fdCount = 1;
193 listenerInfo->listenPort = GetTcpSockPort(listenerInfo->listenFd);
194 if (memcpy_s(listenerInfo->ip, IP_LEN, ip, IP_LEN) != EOK) {
195 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Copy ip failed");
196 ResetBaseListener(module);
197 return SOFTBUS_MEM_ERR;
198 }
199 if (listenerInfo->listenPort < 0) {
200 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "GetSockPort failed, listenPort_=%d", listenerInfo->listenPort);
201 ResetBaseListener(module);
202 return SOFTBUS_ERR;
203 }
204
205 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
206 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
207 ResetBaseListener(module);
208 return SOFTBUS_ERR;
209 }
210 SoftBusSocketFdSet(listenerInfo->listenFd, &g_readSet);
211 g_maxFd = MaxFd(listenerInfo->listenFd, g_maxFd);
212 SoftBusMutexUnlock(&(g_fdSetLock.lock));
213
214 return SOFTBUS_OK;
215 }
216
ResetBaseListener(ListenerModule module)217 void ResetBaseListener(ListenerModule module)
218 {
219 if (CheckModule(module) != SOFTBUS_OK) {
220 return;
221 }
222 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
223 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
224 return;
225 }
226 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info;
227 if (listenerInfo == NULL) {
228 SoftBusMutexUnlock(&g_listenerList[module].lock);
229 return;
230 }
231 if (listenerInfo->listenFd >= 0) {
232 TcpShutDown(listenerInfo->listenFd);
233 }
234 listenerInfo->listenFd = -1;
235 listenerInfo->listenPort = -1;
236 listenerInfo->status = LISTENER_IDLE;
237 listenerInfo->modeType = UNSET_MODE;
238 listenerInfo->fdCount = 0;
239 ClearListenerFdList(&listenerInfo->node);
240 SoftBusMutexUnlock(&g_listenerList[module].lock);
241 UpdateMaxFd();
242 }
243
ResetBaseListenerSet(ListenerModule module)244 void ResetBaseListenerSet(ListenerModule module)
245 {
246 if (CheckModule(module) != SOFTBUS_OK) {
247 return;
248 }
249 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
250 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
251 return;
252 }
253 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info;
254 if (listenerInfo == NULL) {
255 SoftBusMutexUnlock(&g_listenerList[module].lock);
256 return;
257 }
258 ClearListenerFdList(&listenerInfo->node);
259 listenerInfo->fdCount = 0;
260 SoftBusMutexUnlock(&g_listenerList[module].lock);
261 UpdateMaxFd();
262 }
263
OnEvent(ListenerModule module,int32_t fd,uint32_t events)264 static int32_t OnEvent(ListenerModule module, int32_t fd, uint32_t events)
265 {
266 if (CheckModule(module) != SOFTBUS_OK) {
267 return SOFTBUS_INVALID_PARAM;
268 }
269 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
270 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "event lock failed");
271 return SOFTBUS_LOCK_ERR;
272 }
273 if (g_listenerList[module].info == NULL || g_listenerList[module].listener == NULL) {
274 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "info or listener is null");
275 SoftBusMutexUnlock(&g_listenerList[module].lock);
276 return SOFTBUS_ERR;
277 }
278 int32_t listenFd = g_listenerList[module].info->listenFd;
279 SoftbusBaseListener listener = {0};
280 listener.onConnectEvent = g_listenerList[module].listener->onConnectEvent;
281 listener.onDataEvent = g_listenerList[module].listener->onDataEvent;
282 SoftBusMutexUnlock(&g_listenerList[module].lock);
283
284 if (fd == listenFd) {
285 SoftBusSockAddrIn addr;
286 if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) {
287 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "memset failed");
288 return SOFTBUS_ERR;
289 }
290 uint32_t addrLen = sizeof(addr);
291 int32_t cfd;
292 int32_t ret = TEMP_FAILURE_RETRY(SoftBusSocketAccept(fd, (SoftBusSockAddr *)&addr, (int32_t *)&addrLen, &cfd));
293 if (ret < 0) {
294 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR,
295 "accept failed, cfd=%d, module=%d, fd=%d", cfd, module, fd);
296 return SOFTBUS_TCP_SOCKET_ERR;
297 }
298 char ip[IP_LEN] = {0};
299 SoftBusInetNtoP(SOFTBUS_AF_INET, &addr.sinAddr, ip, sizeof(ip));
300 if (listener.onConnectEvent != NULL) {
301 listener.onConnectEvent(events, cfd, ip);
302 } else {
303 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Please set onConnectEvent callback");
304 SoftBusSocketClose(cfd);
305 }
306 } else {
307 if (listener.onDataEvent != NULL) {
308 listener.onDataEvent(events, fd);
309 } else {
310 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Please set onDataEvent callback");
311 }
312 }
313 return SOFTBUS_OK;
314 }
315
CreateFdArr(int32_t ** fdArr,int32_t * fdArrLen,const ListNode * list)316 static int CreateFdArr(int32_t **fdArr, int32_t *fdArrLen, const ListNode *list)
317 {
318 if (list == NULL || list->next == list) {
319 *fdArrLen = 0;
320 return SOFTBUS_OK;
321 }
322
323 int32_t fdArrSize = FDARR_START_SIZE;
324 int32_t *tmpFdArr = NULL;
325
326 tmpFdArr = (int32_t *)SoftBusCalloc(sizeof(int32_t) * fdArrSize);
327 if (tmpFdArr == NULL) {
328 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "SoftBusCalloc failed, out of memory");
329 return SOFTBUS_MALLOC_ERR;
330 }
331 *fdArrLen = 0;
332
333 FdNode *item = NULL;
334 LIST_FOR_EACH_ENTRY(item, list, FdNode, node) {
335 if (*fdArrLen == fdArrSize) {
336 int32_t *tmp = NULL;
337
338 tmp = (int32_t *)SoftBusCalloc((int32_t)sizeof(int32_t) * fdArrSize * FDARR_EXPAND_BASE);
339 if (tmp == NULL) {
340 SoftBusFree(tmpFdArr);
341 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "SoftBusCalloc failed, out of memory");
342 return SOFTBUS_MALLOC_ERR;
343 }
344 for (int i = 0; i < *fdArrLen; i++) {
345 tmp[i] = tmpFdArr[i];
346 }
347 SoftBusFree(tmpFdArr);
348 tmpFdArr = tmp;
349 fdArrSize *= FDARR_EXPAND_BASE;
350 }
351 tmpFdArr[*fdArrLen] = item->fd;
352 *fdArrLen = *fdArrLen + 1;
353 }
354 *fdArr = tmpFdArr;
355 return SOFTBUS_OK;
356 }
357
ProcessData(SoftBusFdSet * readSet,SoftBusFdSet * writeSet,SoftBusFdSet * exceptSet)358 static void ProcessData(SoftBusFdSet *readSet, SoftBusFdSet *writeSet, SoftBusFdSet *exceptSet)
359 {
360 for (int i = 0; i < UNUSE_BUTT; i++) {
361 if (g_listenerList[i].info == NULL) {
362 continue;
363 }
364 if (SoftBusMutexLock(&g_listenerList[i].lock) != SOFTBUS_OK) {
365 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
366 continue;
367 }
368 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[i].info;
369 if (listenerInfo == NULL || listenerInfo->status != LISTENER_RUNNING) {
370 SoftBusMutexUnlock(&g_listenerList[i].lock);
371 continue;
372 }
373 int32_t listenFd = listenerInfo->listenFd;
374 int32_t *fdArr = NULL;
375 int32_t fdArrLen = 0;
376
377 if (CreateFdArr(&fdArr, &fdArrLen, &listenerInfo->node) != SOFTBUS_OK) {
378 SoftBusMutexUnlock(&g_listenerList[i].lock);
379 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "CreateFdArr failed, module:%d", i);
380 continue;
381 }
382 SoftBusMutexUnlock(&g_listenerList[i].lock);
383
384 if ((listenFd > 0) && SoftBusSocketFdIsset(listenFd, readSet)) {
385 OnEvent((ListenerModule)i, listenFd, SOFTBUS_SOCKET_IN);
386 }
387 for (int j = 0; j < fdArrLen; j++) {
388 if (SoftBusSocketFdIsset(fdArr[j], readSet)) {
389 OnEvent((ListenerModule)i, fdArr[j], SOFTBUS_SOCKET_IN);
390 }
391 if (SoftBusSocketFdIsset(fdArr[j], writeSet)) {
392 OnEvent((ListenerModule)i, fdArr[j], SOFTBUS_SOCKET_OUT);
393 }
394 if (SoftBusSocketFdIsset(fdArr[j], exceptSet)) {
395 OnEvent((ListenerModule)i, fdArr[j], SOFTBUS_SOCKET_EXCEPTION);
396 }
397 }
398 SoftBusFree(fdArr);
399 }
400 }
401
SetSelect(SoftBusFdSet * readSet,SoftBusFdSet * writeSet,SoftBusFdSet * exceptSet)402 static int32_t SetSelect(SoftBusFdSet *readSet, SoftBusFdSet *writeSet, SoftBusFdSet *exceptSet)
403 {
404 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
405 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
406 return SOFTBUS_ERR;
407 }
408 if (FdCopy(readSet, &g_readSet) != EOK) {
409 goto EXIT;
410 }
411 if (FdCopy(writeSet, &g_writeSet) != EOK) {
412 goto EXIT;
413 }
414 if (FdCopy(exceptSet, &g_exceptSet) != EOK) {
415 goto EXIT;
416 }
417 SoftBusMutexUnlock(&(g_fdSetLock.lock));
418
419 return SOFTBUS_OK;
420 EXIT:
421 SoftBusMutexUnlock(&(g_fdSetLock.lock));
422 SoftBusSocketFdZero(readSet);
423 SoftBusSocketFdZero(writeSet);
424 SoftBusSocketFdZero(exceptSet);
425 return SOFTBUS_MEM_ERR;
426 }
427
SelectThread(void)428 static int32_t SelectThread(void)
429 {
430 struct timeval tv;
431 tv.tv_sec = 0;
432 tv.tv_usec = TIMEOUT;
433 int32_t timeOut = 0;
434 if (SoftbusGetConfig(SOFTBUS_INT_SUPPORT_SECLECT_INTERVAL, (unsigned char *)&timeOut,
435 sizeof(timeOut)) == SOFTBUS_OK) {
436 tv.tv_usec = (long)timeOut;
437 }
438 SoftBusFdSet readSet;
439 SoftBusFdSet writeSet;
440 SoftBusFdSet exceptSet;
441 SoftBusSocketFdZero(&readSet);
442 SoftBusSocketFdZero(&writeSet);
443 SoftBusSocketFdZero(&exceptSet);
444 if (SetSelect(&readSet, &writeSet, &exceptSet) != SOFTBUS_OK) {
445 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "select failed with invalid listener");
446 return SOFTBUS_ERR;
447 }
448 int32_t maxFd = g_maxFd;
449 if (maxFd < 0) {
450 SoftBusSocketSelect(0, NULL, NULL, NULL, &tv);
451 return SOFTBUS_OK;
452 }
453
454 int32_t nEvents = SoftBusSocketSelect(maxFd + 1, &readSet, &writeSet, &exceptSet, &tv);
455 if (nEvents < 0) {
456 return SOFTBUS_TCP_SOCKET_ERR;
457 } else if (nEvents == 0) {
458 return SOFTBUS_OK;
459 } else {
460 ProcessData(&readSet, &writeSet, &exceptSet);
461 return SOFTBUS_OK;
462 }
463 }
464
StartThread(ListenerModule module,ModeType modeType)465 static int32_t StartThread(ListenerModule module, ModeType modeType)
466 {
467 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info;
468 if (listenerInfo == NULL) {
469 return SOFTBUS_ERR;
470 }
471 listenerInfo->modeType = modeType;
472 listenerInfo->status = LISTENER_RUNNING;
473
474 return ThreadPoolAddJob(g_threadPool, (int32_t(*)(void *))SelectThread,
475 NULL, PERSISTENT, (uintptr_t)0);
476 }
477
PrepareBaseListener(ListenerModule module,ModeType modeType)478 static int32_t PrepareBaseListener(ListenerModule module, ModeType modeType)
479 {
480 if (CheckModule(module) != SOFTBUS_OK) {
481 return SOFTBUS_INVALID_PARAM;
482 }
483
484 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info;
485 if (listenerInfo == NULL) {
486 return SOFTBUS_ERR;
487 }
488
489 if (g_threadPool == NULL) {
490 g_threadPool = ThreadPoolInit(THREADPOOL_THREADNUM, THREADPOOL_QUEUE_NUM);
491 if (g_threadPool == NULL) {
492 return SOFTBUS_MALLOC_ERR;
493 }
494 }
495
496 int ret = StartThread(module, modeType);
497 if (ret != SOFTBUS_OK && ret != SOFTBUS_ALREADY_EXISTED) {
498 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "StartThread failed");
499 return SOFTBUS_ERR;
500 }
501
502 return SOFTBUS_OK;
503 }
504
CreateNewListenerInfo(void)505 static SoftbusBaseListenerInfo *CreateNewListenerInfo(void)
506 {
507 SoftbusBaseListenerInfo *listenerInfo = (SoftbusBaseListenerInfo *)SoftBusCalloc(sizeof(SoftbusBaseListenerInfo));
508 if (listenerInfo == NULL) {
509 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Malloc error");
510 return NULL;
511 }
512 listenerInfo->modeType = UNSET_MODE;
513 listenerInfo->fdCount = 0;
514 listenerInfo->listenFd = -1;
515 listenerInfo->listenPort = -1;
516 listenerInfo->status = LISTENER_IDLE;
517 ListInit(&listenerInfo->node);
518
519 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
520 SoftBusFree(listenerInfo);
521 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock g_fdSetLock failed");
522 return NULL;
523 }
524 if (g_fdSetInit == false) {
525 SoftBusSocketFdZero(&g_readSet);
526 SoftBusSocketFdZero(&g_writeSet);
527 SoftBusSocketFdZero(&g_exceptSet);
528 g_fdSetInit = true;
529 }
530 SoftBusMutexUnlock(&(g_fdSetLock.lock));
531
532 return listenerInfo;
533 }
534
AddTriggerToSet(int32_t fd,TriggerType triggerType)535 static int32_t AddTriggerToSet(int32_t fd, TriggerType triggerType)
536 {
537 int32_t ret = SOFTBUS_OK;
538 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
539 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
540 return SOFTBUS_ERR;
541 }
542 switch (triggerType) {
543 case READ_TRIGGER:
544 SoftBusSocketFdSet(fd, &g_readSet);
545 break;
546 case WRITE_TRIGGER:
547 SoftBusSocketFdSet(fd, &g_writeSet);
548 break;
549 case EXCEPT_TRIGGER:
550 SoftBusSocketFdSet(fd, &g_exceptSet);
551 break;
552 case RW_TRIGGER:
553 SoftBusSocketFdSet(fd, &g_readSet);
554 SoftBusSocketFdSet(fd, &g_writeSet);
555 break;
556 default:
557 ret = SOFTBUS_INVALID_PARAM;
558 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid trigger type");
559 break;
560 }
561 SoftBusMutexUnlock(&(g_fdSetLock.lock));
562
563 return ret;
564 }
565
DelTriggerFromSet(int32_t fd,TriggerType triggerType)566 static int32_t DelTriggerFromSet(int32_t fd, TriggerType triggerType)
567 {
568 int32_t ret = SOFTBUS_OK;
569 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
570 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
571 return SOFTBUS_ERR;
572 }
573 switch (triggerType) {
574 case READ_TRIGGER:
575 SoftBusSocketFdClr(fd, &g_readSet);
576 break;
577 case WRITE_TRIGGER:
578 SoftBusSocketFdClr(fd, &g_writeSet);
579 break;
580 case EXCEPT_TRIGGER:
581 SoftBusSocketFdClr(fd, &g_exceptSet);
582 break;
583 case RW_TRIGGER:
584 SoftBusSocketFdClr(fd, &g_readSet);
585 SoftBusSocketFdClr(fd, &g_writeSet);
586 break;
587 default:
588 ret = SOFTBUS_INVALID_PARAM;
589 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid trigger type");
590 break;
591 }
592 SoftBusMutexUnlock(&(g_fdSetLock.lock));
593
594 return ret;
595 }
596
StartBaseClient(ListenerModule module)597 int32_t StartBaseClient(ListenerModule module)
598 {
599 if (CheckModule(module) != SOFTBUS_OK) {
600 return SOFTBUS_INVALID_PARAM;
601 }
602
603 if (g_fdSetLock.lockInit == false) {
604 if (SoftBusMutexInit(&g_fdSetLock.lock, NULL) != SOFTBUS_OK) {
605 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "g_fdSetLock init failed.");
606 return SOFTBUS_ERR;
607 }
608 g_fdSetLock.lockInit = true;
609 }
610 int32_t ret;
611
612 g_listenerList[module].module = module;
613 if (g_listenerList[module].listener == NULL) {
614 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BaseListener not set, start failed.");
615 return SOFTBUS_ERR;
616 }
617 if (g_listenerList[module].info == NULL) {
618 g_listenerList[module].info = CreateNewListenerInfo();
619 if (g_listenerList[module].info == NULL) {
620 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "malloc listenerInfo err");
621 return SOFTBUS_MALLOC_ERR;
622 }
623
624 if (g_listenerList[module].lockInit == false) {
625 SoftBusMutexAttr mutexAttr;
626 mutexAttr.type = SOFTBUS_MUTEX_RECURSIVE;
627 SoftBusMutexInit(&g_listenerList[module].lock, &mutexAttr);
628 g_listenerList[module].lockInit = true;
629 }
630 }
631 if (g_listenerList[module].info->status != LISTENER_IDLE) {
632 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "listener is not in idle status.");
633 return SOFTBUS_ERR;
634 }
635 g_listenerList[module].info->status = LISTENER_PREPARED;
636 ret = PrepareBaseListener(module, CLIENT_MODE);
637 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "StartBaseClient %s",
638 (ret == SOFTBUS_OK) ? "SUCCESS" : "FAILED");
639
640 return ret;
641 }
642
StartBaseListener(ListenerModule module,const char * ip,int32_t port,ModeType modeType)643 int32_t StartBaseListener(ListenerModule module, const char *ip, int32_t port, ModeType modeType)
644 {
645 if (CheckModule(module) != SOFTBUS_OK || port < 0 || ip == NULL) {
646 return SOFTBUS_INVALID_PARAM;
647 }
648
649 if (g_fdSetLock.lockInit == false) {
650 if (SoftBusMutexInit(&g_fdSetLock.lock, NULL) != SOFTBUS_OK) {
651 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "g_fdSetLock init failed.");
652 return SOFTBUS_ERR;
653 }
654 g_fdSetLock.lockInit = true;
655 }
656
657 int32_t ret;
658
659 g_listenerList[module].module = module;
660 if (g_listenerList[module].listener == NULL) {
661 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "BaseListener not set, start failed.");
662 return SOFTBUS_ERR;
663 }
664 if (g_listenerList[module].info == NULL) {
665 g_listenerList[module].info = CreateNewListenerInfo();
666 if (g_listenerList[module].info == NULL) {
667 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "malloc listenerInfo err");
668 return SOFTBUS_MALLOC_ERR;
669 }
670 if (g_listenerList[module].lockInit == false) {
671 SoftBusMutexAttr mutexAttr;
672 mutexAttr.type = SOFTBUS_MUTEX_RECURSIVE;
673 SoftBusMutexInit(&g_listenerList[module].lock, &mutexAttr);
674 g_listenerList[module].lockInit = true;
675 }
676 }
677 if (g_listenerList[module].info->status != LISTENER_IDLE) {
678 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "listener is not in idle status.");
679 return SOFTBUS_ERR;
680 }
681 ret = InitListenFd(module, ip, port);
682 if (ret != SOFTBUS_OK) {
683 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "InitListenFd failed");
684 return ret;
685 }
686 g_listenerList[module].info->status = LISTENER_PREPARED;
687 ret = PrepareBaseListener(module, modeType);
688 if (ret != SOFTBUS_OK) {
689 return ret;
690 }
691 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "StartBaseListener success, fd = %d, module = %d",
692 g_listenerList[module].info->listenPort, module);
693
694 return g_listenerList[module].info->listenPort;
695 }
696
GetSoftbusBaseListener(ListenerModule module,SoftbusBaseListener * listener)697 int32_t GetSoftbusBaseListener(ListenerModule module, SoftbusBaseListener *listener)
698 {
699 if (CheckModule(module) != SOFTBUS_OK || listener == NULL) {
700 return SOFTBUS_INVALID_PARAM;
701 }
702 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
703 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
704 return SOFTBUS_LOCK_ERR;
705 }
706 if (g_listenerList[module].listener != NULL) {
707 if (memcpy_s(listener, sizeof(SoftbusBaseListener), g_listenerList[module].listener,
708 sizeof(SoftbusBaseListener)) != EOK) {
709 SoftBusMutexUnlock(&g_listenerList[module].lock);
710 return SOFTBUS_MEM_ERR;
711 }
712 } else {
713 SoftBusFree(listener);
714 return SOFTBUS_ERR;
715 }
716 SoftBusMutexUnlock(&g_listenerList[module].lock);
717 return SOFTBUS_OK;
718 }
719
SetSoftbusBaseListener(ListenerModule module,const SoftbusBaseListener * listener)720 int32_t SetSoftbusBaseListener(ListenerModule module, const SoftbusBaseListener *listener)
721 {
722 if (CheckModule(module) != SOFTBUS_OK || listener == NULL ||
723 listener->onConnectEvent == NULL || listener->onDataEvent == NULL) {
724 return SOFTBUS_INVALID_PARAM;
725 }
726 if (g_listenerList[module].listener == NULL) {
727 g_listenerList[module].listener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener));
728 if (g_listenerList[module].listener == NULL) {
729 return SOFTBUS_MALLOC_ERR;
730 }
731 }
732 if (memcpy_s(g_listenerList[module].listener, sizeof(SoftbusBaseListener),
733 listener, sizeof(SoftbusBaseListener)) != EOK) {
734 return SOFTBUS_MEM_ERR;
735 }
736 return SOFTBUS_OK;
737 }
738
StopBaseListener(ListenerModule module)739 int32_t StopBaseListener(ListenerModule module)
740 {
741 if (CheckModule(module) != SOFTBUS_OK) {
742 return SOFTBUS_INVALID_PARAM;
743 }
744 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
745 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
746 return SOFTBUS_LOCK_ERR;
747 }
748 SoftbusBaseListenerInfo *listenerInfo = g_listenerList[module].info;
749 if (listenerInfo == NULL) {
750 SoftBusMutexUnlock(&g_listenerList[module].lock);
751 return SOFTBUS_ERR;
752 }
753 if (listenerInfo->status != LISTENER_RUNNING) {
754 listenerInfo->status = LISTENER_IDLE;
755 SoftBusMutexUnlock(&g_listenerList[module].lock);
756 return SOFTBUS_OK;
757 }
758 listenerInfo->status = LISTENER_IDLE;
759 if (listenerInfo->listenFd > 0) {
760 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "del listen fd from readSet, fd = %d, module = %d.",
761 listenerInfo->listenFd, module);
762 DelTriggerFromSet(listenerInfo->listenFd, READ_TRIGGER);
763 TcpShutDown(listenerInfo->listenFd);
764 UpdateMaxFd();
765 }
766 listenerInfo->listenFd = -1;
767 SoftBusMutexUnlock(&g_listenerList[module].lock);
768
769 return SOFTBUS_OK;
770 }
771
DestroyBaseListener(ListenerModule module)772 void DestroyBaseListener(ListenerModule module)
773 {
774 if (CheckModule(module) != SOFTBUS_OK) {
775 return;
776 }
777 ResetBaseListener(module);
778 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
779 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
780 return;
781 }
782 if (g_listenerList[module].info != NULL) {
783 SoftBusFree(g_listenerList[module].info);
784 g_listenerList[module].info = NULL;
785 }
786 if (g_listenerList[module].listener != NULL) {
787 SoftBusFree(g_listenerList[module].listener);
788 g_listenerList[module].listener = NULL;
789 }
790 SoftBusMutexUnlock(&g_listenerList[module].lock);
791 }
792
793
CheckFdIsExist(SoftbusBaseListenerInfo * info,int32_t fd)794 static bool CheckFdIsExist(SoftbusBaseListenerInfo *info, int32_t fd)
795 {
796 FdNode *item = NULL;
797 FdNode *nextItem = NULL;
798 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &info->node, FdNode, node) {
799 if (item->fd == fd) {
800 return true;
801 }
802 }
803 return false;
804 }
805
AddNewFdNode(SoftbusBaseListenerInfo * info,int32_t fd)806 static int32_t AddNewFdNode(SoftbusBaseListenerInfo *info, int32_t fd)
807 {
808 FdNode *newNode = (FdNode *)SoftBusCalloc(sizeof(FdNode));
809 if (newNode == NULL) {
810 return SOFTBUS_MALLOC_ERR;
811 }
812 newNode->fd = fd;
813 ListInit(&newNode->node);
814 ListNodeInsert(&info->node, &newNode->node);
815 info->fdCount++;
816 return SOFTBUS_OK;
817 }
818
DelFdNode(SoftbusBaseListenerInfo * info,int32_t fd)819 static void DelFdNode(SoftbusBaseListenerInfo *info, int32_t fd)
820 {
821 FdNode *item = NULL;
822 FdNode *nextItem = NULL;
823
824 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &info->node, FdNode, node) {
825 if (item->fd == fd) {
826 ListDelete(&item->node);
827 SoftBusFree(item);
828 info->fdCount--;
829 return;
830 }
831 }
832 }
833
AddTrigger(ListenerModule module,int32_t fd,TriggerType triggerType)834 int32_t AddTrigger(ListenerModule module, int32_t fd, TriggerType triggerType)
835 {
836 if (CheckModule(module) != SOFTBUS_OK || fd < 0 || CheckTrigger(triggerType) != SOFTBUS_OK) {
837 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid AddTrigger Param");
838 return SOFTBUS_INVALID_PARAM;
839 }
840
841 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
842 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
843 return SOFTBUS_LOCK_ERR;
844 }
845 SoftbusBaseListenerInfo *info = g_listenerList[module].info;
846 if (info == NULL || info->fdCount > MAX_LISTEN_EVENTS) {
847 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Cannot AddTrigger any more");
848 SoftBusMutexUnlock(&g_listenerList[module].lock);
849 return SOFTBUS_ERR;
850 }
851
852 if (AddTriggerToSet(fd, triggerType) != SOFTBUS_OK) {
853 SoftBusMutexUnlock(&g_listenerList[module].lock);
854 return SOFTBUS_ERR;
855 }
856
857 if (CheckFdIsExist(info, fd)) {
858 SoftBusMutexUnlock(&g_listenerList[module].lock);
859 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO, "fd exist");
860 return SOFTBUS_OK;
861 }
862
863 if (AddNewFdNode(info, fd) != SOFTBUS_OK) {
864 (void)DelTriggerFromSet(fd, triggerType);
865 SoftBusMutexUnlock(&g_listenerList[module].lock);
866 return SOFTBUS_ERR;
867 }
868 SoftBusMutexUnlock(&g_listenerList[module].lock);
869
870 if (SoftBusMutexLock(&(g_fdSetLock.lock)) != 0) {
871 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
872 return SOFTBUS_OK;
873 }
874 g_maxFd = MaxFd(fd, g_maxFd);
875 SoftBusMutexUnlock(&(g_fdSetLock.lock));
876
877 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO,
878 "AddTrigger fd:%d success, current fdcount:%d, module:%d, triggerType:%d",
879 fd, info->fdCount, module, triggerType);
880 return SOFTBUS_OK;
881 }
882
DelTrigger(ListenerModule module,int32_t fd,TriggerType triggerType)883 int32_t DelTrigger(ListenerModule module, int32_t fd, TriggerType triggerType)
884 {
885 if (CheckModule(module) != SOFTBUS_OK || fd < 0 || CheckTrigger(triggerType)) {
886 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Invalid AddTrigger Param");
887 return SOFTBUS_INVALID_PARAM;
888 }
889 if (SoftBusMutexLock(&g_listenerList[module].lock) != SOFTBUS_OK) {
890 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "lock failed");
891 return SOFTBUS_LOCK_ERR;
892 }
893 SoftbusBaseListenerInfo *info = g_listenerList[module].info;
894 if (info == NULL) {
895 SoftBusMutexUnlock(&g_listenerList[module].lock);
896 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "DelTrigger base listener info is NULL");
897 return SOFTBUS_ERR;
898 }
899
900 if (DelTriggerFromSet(fd, triggerType) != SOFTBUS_OK) {
901 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR,
902 "del trigger fail: fd = %d, trigger = %d", fd, triggerType);
903 }
904
905 if (SoftBusSocketFdIsset(fd, &g_writeSet) || SoftBusSocketFdIsset(fd, &g_readSet) ||
906 SoftBusSocketFdIsset(fd, &g_exceptSet)) {
907 SoftBusMutexUnlock(&g_listenerList[module].lock);
908 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO,
909 "DelTrigger [fd:%d] success, current fdcount:%d, module:%d, triggerType:%d",
910 fd, info->fdCount, module, triggerType);
911 return SOFTBUS_OK;
912 }
913
914 DelFdNode(info, fd);
915 SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_INFO,
916 "DelTrigger and node [fd:%d] success, current fdcount:%d, module:%d, triggerType:%d",
917 fd, info->fdCount, module, triggerType);
918 SoftBusMutexUnlock(&g_listenerList[module].lock);
919 UpdateMaxFd();
920
921 return SOFTBUS_OK;
922 }
923