LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_service - rs_socket.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 68.0 % 1327 902
Test Date: 2026-08-04 10:52:23 Functions: 83.0 % 47 39

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #define _GNU_SOURCE
      12              : #include <unistd.h>
      13              : #include <stdlib.h>
      14              : #include <ifaddrs.h>
      15              : #include <netinet/in.h>
      16              : #include <arpa/inet.h>
      17              : #include <sys/types.h>
      18              : #include <dlfcn.h>
      19              : #include <fcntl.h>
      20              : #include <sys/stat.h>
      21              : #include <sys/epoll.h>
      22              : #include <sys/eventfd.h>
      23              : #include <sys/socket.h>
      24              : #include <errno.h>
      25              : #include <netinet/tcp.h>
      26              : #include "user_log.h"
      27              : #include "rs_tls.h"
      28              : #include "ssl_adp.h"
      29              : #include "securec.h"
      30              : #include "rs.h"
      31              : #include "ra_rs_err.h"
      32              : #include "rs_epoll.h"
      33              : #include "rs_common_inner.h"
      34              : #include "rs_inner.h"
      35              : #include "dl_hal_function.h"
      36              : #include "rs_drv_socket.h"
      37              : #include "rs_socket.h"
      38              : 
      39              : static unsigned int gVnics[RS_VNIC_MAX] = {0};
      40              : 
      41              : RS_ATTRI_VISI_DEF int RsSocketInit(const unsigned int *vnicIp, unsigned int num)
      42              : {
      43              :     int ret;
      44              : 
      45              :     // vnic_ip max num  is RA_MAX_VNIC_NUM(16) RS_MAX_VNIC_NUM is also 16
      46            2 :     CHK_PRT_RETURN(num > RS_MAX_VNIC_NUM || num == 0 || vnicIp == NULL,
      47              :         hccp_err("param error, num:%u is 0 or bigger than %d, or vnicIp is NULL", num, RS_MAX_VNIC_NUM), -EINVAL);
      48              : 
      49            1 :     ret = memcpy_s(&(gVnics), sizeof(gVnics), vnicIp, sizeof(unsigned int) * num);
      50            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s for vnic_ip failed ret[%d]", ret), -ESAFEFUNC);
      51              : 
      52            1 :     return 0;
      53              : }
      54              : 
      55              : int RsSocketNodeid2vnic(uint32_t nodeId, uint32_t *ipAddr)
      56              : {
      57          150 :     if (nodeId >= RS_VNIC_MAX) {
      58          148 :         return -1; /* it means real nic */
      59              :     }
      60              : 
      61            2 :     CHK_PRT_RETURN(ipAddr == NULL, hccp_err("ip_addr is NULL, invalid"), -EINVAL);
      62              : 
      63            1 :     *ipAddr = gVnics[nodeId];
      64              : 
      65            1 :     return RS_VNIC_FLAG;
      66              : }
      67              : 
      68           50 : STATIC uint32_t RsSocketVnic2nodeid(uint32_t ipAddr)
      69              : {
      70              :     uint32_t nodeId;
      71              : 
      72           50 :     if (ipAddr < RS_VNIC_MAX) { /* ip_addr is actually dev_id for vnic */
      73            0 :         return ipAddr;
      74              :     }
      75              : 
      76         6450 :     for (nodeId = 0; nodeId < RS_VNIC_MAX; nodeId++) {
      77         6400 :         if (gVnics[nodeId] == ipAddr) {
      78            0 :             break;
      79              :         }
      80              :     }
      81              : 
      82           50 :     if (nodeId == RS_VNIC_MAX) {
      83           50 :         return ipAddr;
      84              :     }
      85              : 
      86            0 :     return nodeId; /* it means virtual nic */
      87              : }
      88              : 
      89            2 : STATIC int RsServerSendWlistCheckResult(struct RsConnInfo *conn, bool flag)
      90              : {
      91              :     int ret;
      92            2 :     char invalid[] = "5a5a5";
      93            2 :     char valid[] = "a5a5a";
      94              : 
      95            2 :     if (flag == 0) {
      96            1 :         if ((gRsCb->sslEnable == RS_SSL_ENABLE) && (conn->ssl != NULL)) {
      97            0 :             ret = ssl_adp_write(conn->ssl, valid, sizeof(valid));
      98              :         } else {
      99            1 :             ret = RsSocketSend(conn->connfd, valid, sizeof(valid));
     100              :         }
     101            1 :         CHK_PRT_RETURN(ret != sizeof(valid), hccp_err("white list server send valid flag failed! fd[%d], ret[%d]",
     102              :             conn->connfd, ret), -1);
     103              :     } else {
     104            1 :         if ((gRsCb->sslEnable == RS_SSL_ENABLE) && (conn->ssl != NULL)) {
     105            0 :             ret = ssl_adp_write(conn->ssl, invalid, sizeof(invalid));
     106              :         } else {
     107            1 :             ret = RsSocketSend(conn->connfd, invalid, sizeof(invalid));
     108              :         }
     109            1 :         CHK_PRT_RETURN(ret != sizeof(invalid), hccp_err("white list server send invalid flag failed! fd[%d], ret[%d]",
     110              :             conn->connfd, ret), -1);
     111              :     }
     112            0 :     return 0;
     113              : }
     114              : 
     115            2 : STATIC int rs_socket_fill_wlist_by_phyID(unsigned int chipId, struct SocketWlistInfoT *whiteListNode,
     116              :     struct RsConnInfo *rsConn)
     117              : {
     118            2 :     unsigned int vnicIp = 0;
     119            2 :     int64_t deviceInfo = 0;
     120            2 :     char *tagTemp = NULL;
     121              :     unsigned int phyId;
     122              :     int ret;
     123              : 
     124            2 :     ret = memcpy_s(whiteListNode->tag, SOCK_CONN_TAG_SIZE, rsConn->tag, SOCK_CONN_TAG_SIZE);
     125            2 :     CHK_PRT_RETURN(ret, hccp_err("memcpy_s failed, ret[%d]", ret), -ESAFEFUNC);
     126              : 
     127            2 :     if (rsConn->clientIp.family == AF_INET) {
     128              :         // compare server_ip with current vnic_ip: use client_ip as remote_ip if it has bound or not vnic ip
     129            2 :         if (!RsSocketIsVnicIp(chipId, rsConn->serverIp.binAddr.addr.s_addr)) {
     130              :             // NIC IPv4
     131            1 :             whiteListNode->remoteIp.addr.s_addr = rsConn->clientIp.binAddr.addr.s_addr;
     132            1 :             return 0;
     133              :         }
     134              :     } else {
     135              :         // NIC IPv6
     136            0 :         whiteListNode->remoteIp = rsConn->clientIp.binAddr;
     137            0 :         return 0;
     138              :     }
     139              : 
     140            1 :     tagTemp = rsConn->tag + SOCK_CONN_TAG_SIZE;
     141            1 :     tagTemp[SOCK_CONN_DEV_ID_SIZE - 1] = '\0';
     142            1 :     RS_CHECK_POINTER_NULL_RETURN_INT(tagTemp);
     143            1 :     if (rsConn->clientIp.family == AF_INET) {
     144              :         // VNIC
     145            1 :         phyId = (unsigned int)strtol(tagTemp, NULL, 10); // Decimal(10)
     146            1 :         ret = DlHalGetDeviceInfo(phyId, MODULE_TYPE_SYSTEM, INFO_TYPE_VNIC_IP, &deviceInfo);
     147            1 :         CHK_PRT_RETURN(ret, hccp_err("dl_hal_get_device_info failed, ret(%d) tagTemp phyId(%u)", ret, phyId), ret);
     148            0 :         vnicIp = (unsigned int)deviceInfo;
     149            0 :         hccp_dbg("chip_id:%u phyId:%u vnic_ip:%u", chipId, phyId, vnicIp);
     150            0 :         whiteListNode->remoteIp.addr.s_addr = vnicIp;
     151              :     }
     152            0 :     return 0;
     153              : }
     154              : 
     155            1 : STATIC int RsServerValidAsyncInit(unsigned int chipId, struct RsConnInfo *conn,
     156              :     struct SocketWlistInfoT *whiteListExpect)
     157              : {
     158              :     int ret;
     159              : 
     160            1 :     ret = memset_s(whiteListExpect, sizeof(struct SocketWlistInfoT), 0, sizeof(struct SocketWlistInfoT));
     161            1 :     CHK_PRT_RETURN(ret, hccp_err("memset_s socket_wlist_info_t wlist failed, ret:%d", ret), -ESAFEFUNC);
     162              : 
     163            1 :     CHK_PRT_RETURN(conn->state != RS_CONN_STATE_TAG_SYNC, hccp_err("conn state is not RS_CONN_STATE_TAG_SYNC,"
     164              :         "state[%u]. ", conn->state), -1);
     165              : 
     166            1 :     ret = rs_socket_fill_wlist_by_phyID(chipId, whiteListExpect, conn);
     167            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_socket_fill_wlist_by_phyID failed, ret[%d]. ", ret), ret);
     168              : 
     169            1 :     return 0;
     170              : }
     171              : 
     172            2 : STATIC int RsServerValidAsync(unsigned int chipId, struct RsConnCb *connCb, struct RsConnInfo *conn)
     173              : {
     174              :     int ret;
     175            2 :     struct RsWhiteList *whiteListTmp = NULL;
     176            2 :     struct RsWhiteListInfo *whiteListNodeTmp = NULL;
     177              :     struct SocketWlistInfoT whiteListExpect;
     178              : 
     179            2 :     ret = RsServerValidAsyncInit(chipId, conn, &whiteListExpect);
     180            2 :     CHK_PRT_RETURN(ret, hccp_err("rs server valid async init failed, ret:%d", ret), -1);
     181              : 
     182            2 :     ret = RsFindWhiteList(connCb, &conn->serverIp, &whiteListTmp);
     183            2 :     if (ret) {
     184            0 :         ret = RsServerSendWlistCheckResult(conn, 1);
     185            0 :         CHK_PRT_RETURN(ret, hccp_err("rs server send wlist check invalid result failed, connfd[%d], ret[%d]",
     186              :             conn->connfd, ret), -1);
     187            0 :         hccp_info("white list can not be found, connfd[%d], serverIp[%s], ret[%d]", conn->connfd,
     188              :             conn->serverIp.readAddr, ret);
     189            0 :         return -1;
     190              :     }
     191              : 
     192            2 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
     193            2 :     ret = RsFindWhiteListNode(whiteListTmp, &whiteListExpect, (int)conn->clientIp.family,
     194              :         &whiteListNodeTmp);
     195            2 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
     196            2 :     if (ret) {
     197            1 :         ret = RsServerSendWlistCheckResult(conn, 1);
     198            1 :         CHK_PRT_RETURN(ret, hccp_err("rs server send wlist check invalid result failed, connfd[%d], ret[%d]",
     199              :             conn->connfd, ret), -1);
     200            1 :         hccp_info("white list node can not be found, connfd[%d], ret[%d]", conn->connfd, ret);
     201            1 :         return -1;
     202              :     }
     203              : 
     204            1 :     if (whiteListNodeTmp->connLimit < 1) {
     205            1 :         ret = RsServerSendWlistCheckResult(conn, 1);
     206            1 :         CHK_PRT_RETURN(ret, hccp_err("rs_server_send_wlist_check_result failed, connfd[%d], connLimit[%u], ret[%d]",
     207              :             conn->connfd, whiteListNodeTmp->connLimit, ret), -1);
     208            0 :         hccp_info("white list node limit has less than 1, connfd[%d], ret[%d]", conn->connfd, ret);
     209            0 :         return -1;
     210              :     }
     211              : 
     212            0 :     ret = RsServerSendWlistCheckResult(conn, 0);
     213            0 :     CHK_PRT_RETURN(ret, hccp_err("rs server send wlist check valid result failed, connfd[%d], ret[%d]",
     214              :         conn->connfd, ret), -1);
     215            0 :     whiteListNodeTmp->connLimit--;
     216            0 :     return 0;
     217              : }
     218              : 
     219           16 : int RsSocketCopyConnInfo(struct RsConnInfo *connTmp, struct RsConnInfo *conn)
     220              : {
     221              :     int ret;
     222              : 
     223           16 :     conn->serverIp = connTmp->serverIp;
     224           16 :     conn->clientIp = connTmp->clientIp;
     225           16 :     conn->connfd = connTmp->connfd;
     226           16 :     conn->state = connTmp->state;
     227           16 :     conn->port = connTmp->port;
     228           16 :     conn->ssl = connTmp->ssl;
     229           16 :     ret = memcpy_s(conn->tag, SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE, connTmp->tag, sizeof(connTmp->tag));
     230           16 :     if (ret) {
     231            0 :         hccp_err("rs_conn_info tag copy failed, ret[%d]", ret);
     232              :     }
     233           16 :     conn->isGot = false;
     234           16 :     return ret;
     235              : }
     236              : 
     237            0 : int RsWhiteListCheckValid(unsigned int chipId, struct RsConnCb *connCb, struct RsConnInfo *conn)
     238              : {
     239              :     int ret;
     240              : 
     241            0 :     ret = RsServerValidAsync(chipId, connCb, conn);
     242            0 :     if (ret) {
     243            0 :         RS_CLOSE_RETRY_FOR_EINTR(ret, conn->connfd);
     244            0 :         hccp_info("rs_server_valid_async, white list doesn't exist, ret[%d]", ret);
     245            0 :         return -1;
     246              :     } else {
     247            0 :         conn->state = RS_CONN_STATE_VALID_SYNC;
     248              :     }
     249            0 :     return 0;
     250              : }
     251              : 
     252            0 : STATIC int RsSetFdNonblock(int connfd)
     253              : {
     254              :     int flags, ret;
     255              : 
     256            0 :     flags = fcntl(connfd, F_GETFL, 0);
     257            0 :     CHK_PRT_RETURN(flags < 0, hccp_err("fcntl connfd %d GETFL errno %d flags %d", connfd, errno, flags), -EFILEOPER);
     258              : 
     259            0 :     ret = fcntl(connfd, F_SETFL, (unsigned int)flags | O_NONBLOCK);
     260            0 :     if (ret < 0) {
     261            0 :         ret = -EFILEOPER;
     262            0 :         hccp_err("fcntl connfd %d nonblock errno %d ret %d", connfd, errno, ret);
     263              :     }
     264              : 
     265            0 :     return ret;
     266              : }
     267              : 
     268           32 : STATIC int RsSocketSetFdTimeoutUsec(int connfd, unsigned int tvUsec)
     269              : {
     270           32 :     struct timeval tv = { 0 };
     271           32 :     int ret = 0;
     272              : 
     273           32 :     tv.tv_usec = tvUsec;
     274           32 :     ret = setsockopt(connfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv));
     275           32 :     CHK_PRT_RETURN(ret < 0, hccp_err("setsockopt connfd %d SO_SNDTIMEO tv_usec %u failed %d", connfd, tvUsec, ret),
     276              :         -EFILEOPER);
     277              : 
     278           32 :     ret = setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
     279           32 :     CHK_PRT_RETURN(ret < 0, hccp_err("setsockopt connfd %d SO_RCVTIMEO tv_usec %u failed %d", connfd, tvUsec, ret),
     280              :         -EFILEOPER);
     281              : 
     282           32 :     return 0;
     283              : }
     284              : 
     285            0 : STATIC void RsEpollEventSslListenInHandle(struct rs_cb *rsCb, struct RsListenInfo *listenInfo, int connfd,
     286              :     struct RsIpAddrInfo *remoteIp)
     287              : {
     288              :     /*lint -e593*/
     289              :     int ret;
     290            0 :     struct RsAcceptInfo *acceptInfo = NULL;
     291            0 :     struct RsListHead *listHead = NULL;
     292              : 
     293            0 :     ret = RsEpollCtl(rsCb->connCb.epollfd, EPOLL_CTL_ADD, connfd, EPOLLIN | EPOLLRDHUP);
     294            0 :     if (ret) {
     295            0 :         hccp_err("epoll ctl add fd %d failed", connfd);
     296            0 :         goto out;
     297              :     }
     298              : 
     299            0 :     hccp_info("epoll ctl add fd %d success", connfd);
     300            0 :     acceptInfo = calloc(1, sizeof(struct RsAcceptInfo));
     301            0 :     if (acceptInfo == NULL) {
     302            0 :         hccp_err("alloc mem for socket conn info failed!");
     303            0 :         goto out;
     304              :     }
     305              : 
     306            0 :     acceptInfo->sockPort = listenInfo->sockPort;
     307            0 :     acceptInfo->serverIpAddr = listenInfo->serverIpAddr;
     308            0 :     acceptInfo->clientIpAddr = *remoteIp;
     309            0 :     acceptInfo->connFd = connfd;
     310            0 :     RS_PTHREAD_MUTEX_LOCK(&rsCb->connCb.connMutex);
     311            0 :     listHead = &rsCb->connCb.serverAcceptList;
     312            0 :     RsListAddTail(&acceptInfo->list, listHead);
     313            0 :     RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
     314              : 
     315            0 :     return;
     316              : 
     317            0 : out:
     318            0 :     RS_CLOSE_RETRY_FOR_EINTR(ret, connfd);
     319            0 :     return;
     320              :     /*lint +e593*/
     321              : }
     322              : 
     323           19 : STATIC int RsTcpRecvTagInHandle(struct RsListenInfo *listenInfo, int connfd, struct RsConnInfo *connTmp,
     324              :     struct RsIpAddrInfo *remoteIp)
     325              : {
     326           19 :     int expSize = SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE;
     327           19 :     char *recvBuff = connTmp->tag;
     328              :     struct timeval startTime, now;
     329           19 :     float timeCost = 0.0;
     330           19 :     int size = expSize;
     331              : 
     332           19 :     RsGetCurTime(&startTime);
     333           36 :     while (expSize > 0 && size != 0) {
     334           19 :         connTmp->tagSyncTimes++;
     335           19 :         size = recv(connfd, recvBuff, expSize, 0);
     336           19 :         if ((size < 0) && (errno == EINTR)) {
     337            0 :             connTmp->tagEintrTimes++;
     338            0 :             continue;
     339              :         }
     340              :         // peer socket session has been closed
     341           19 :         if (size == 0) {
     342            1 :             hccp_run_info("session has been closed, server:{%s:%u} client:%s tagSyncTimes:%u tagEintrTimes:%u",
     343              :                 listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, remoteIp->readAddr,
     344              :                 connTmp->tagSyncTimes, connTmp->tagEintrTimes);
     345            1 :             return -ESOCKCLOSED;
     346              :         }
     347              : 
     348           18 :         expSize -= size;
     349           18 :         recvBuff += size;
     350           18 :         RsGetCurTime(&now);
     351           18 :         HccpTimeInterval(&now, &startTime, &timeCost);
     352              :         // enlarge the timeout threshold to make sure the connection can be established successfully
     353           18 :         if (timeCost >= RS_RECV_TAG_MAX_TIME) {
     354            1 :             hccp_run_info("recv tag time out, server:{%s:%u} client:%s tagSyncTimes:%u tagEintrTimes:%u",
     355              :                 listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, remoteIp->readAddr,
     356              :                 connTmp->tagSyncTimes, connTmp->tagEintrTimes);
     357            1 :             return -ETIME;
     358              :         }
     359              : 
     360           17 :         if (timeCost <= 0) {
     361            0 :             RsGetCurTime(&startTime);
     362              :         }
     363              :     }
     364              : 
     365           17 :     connTmp->serverIp = listenInfo->serverIpAddr;
     366           17 :     connTmp->clientIp = *remoteIp;
     367           17 :     connTmp->connfd = connfd;
     368           17 :     connTmp->state = RS_CONN_STATE_TAG_SYNC;
     369           17 :     connTmp->port = listenInfo->sockPort;
     370           17 :     if (timeCost >= RS_RECV_MAX_TIME) {
     371            1 :         hccp_run_info("recv tag success, server:{%s:%u} client:%s timeCost:%fms tagSyncTimes:%u tagEintrTimes:%u",
     372              :             listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, remoteIp->readAddr, timeCost,
     373              :             connTmp->tagSyncTimes, connTmp->tagEintrTimes);
     374            1 :         return 0;
     375              :     }
     376              : 
     377           16 :     hccp_info("recv tag success, server:{%s:%u} client:%s timeCost:%fms tagSyncTimes:%u tagEintrTimes:%u",
     378              :         listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, remoteIp->readAddr, timeCost,
     379              :         connTmp->tagSyncTimes, connTmp->tagEintrTimes);
     380           16 :     return 0;
     381              : }
     382              : 
     383           18 : STATIC void RsEpollEventTcpListenInHandle(struct rs_cb *rsCb, struct RsListenInfo *listenInfo, int connfd,
     384              :     struct RsIpAddrInfo *remoteIp)
     385              : {
     386           18 :     struct RsListenInfo listenInfoTmp = {0};
     387           18 :     struct RsConnInfo connTmp = {0};
     388              :     int ret;
     389              : 
     390           18 :     (void)memcpy_s(&listenInfoTmp, sizeof(struct RsListenInfo), listenInfo, sizeof(struct RsListenInfo));
     391              :     // unlock mutex to prevent RsTcpRecvTagInHandle from blocking
     392           18 :     RS_PTHREAD_MUTEX_ULOCK(&rsCb->mutex);
     393           18 :     ret = RsTcpRecvTagInHandle(&listenInfoTmp, connfd, &connTmp, remoteIp);
     394           18 :     RS_PTHREAD_MUTEX_LOCK(&rsCb->mutex);
     395           18 :     if (ret != 0) {
     396            1 :         hccp_warn("rs_tcp_recv_tag_in_handle unsuccessful, ret:%d", ret);
     397            1 :         RS_CLOSE_RETRY_FOR_EINTR(ret, connfd);
     398            1 :         return;
     399              :     }
     400              : 
     401           17 :     ret = RsWlistCheckConnAdd(rsCb, &connTmp);
     402           17 :     if (ret != 0) {
     403            1 :         hccp_warn("rs_wlist_check_conn_add unsuccessful, ret %d", ret);
     404            1 :         return;
     405              :     }
     406              : 
     407           16 :     return;
     408              : }
     409              : 
     410            0 : void RsSocketSaveErrInfo(int action, int errNo, struct SocketErrInfo *errInfo)
     411              : {
     412              :     // Only record the first occurrence of err information
     413            0 :     if (errInfo->errNo != 0) {
     414            0 :         return;
     415              :     }
     416              : 
     417            0 :     if (errNo == -EAGAIN || errNo == -EINTR) {
     418            0 :         return;
     419              :     }
     420              : 
     421            0 :     RsGetCurTime(&errInfo->time);
     422            0 :     errInfo->action = action;
     423            0 :     errInfo->errNo = errNo;
     424              : }
     425              : 
     426           17 : STATIC int RsSocketCheckCredit(struct RsConnCb *connCb, struct RsListenInfo *listenInfo)
     427              : {
     428              :     // not using accept_credit, no need to check
     429           17 :     if (!listenInfo->acceptCreditFlag) {
     430           16 :         return 0;
     431              :     }
     432              : 
     433              :     // accept_credit is exhausted, check failed
     434            1 :     if (listenInfo->acceptCreditLimit == 0) {
     435            0 :         return -EINVAL;
     436              :     }
     437              : 
     438            1 :     RS_PTHREAD_MUTEX_LOCK(&listenInfo->acceptCreditMutex);
     439            1 :     listenInfo->acceptCreditLimit--;
     440            1 :     RS_PTHREAD_MUTEX_ULOCK(&listenInfo->acceptCreditMutex);
     441              : 
     442              :     // accept_credit is exhausted, ignore return value to delete from epoll
     443            1 :     if (listenInfo->acceptCreditLimit == 0) {
     444            1 :         (void)RsSocketListenDelFromEpoll(connCb, listenInfo);
     445              :     }
     446              : 
     447            1 :     return 0;
     448              : }
     449              : 
     450           16 : int RsEpollEventListenInHandle(struct rs_cb *rsCb, int fd)
     451              : {
     452           16 :     struct RsListenInfo *listenInfo2 = NULL;
     453           16 :     struct RsListenInfo *listenInfo = NULL;
     454              :     struct RsSocketaddrInfo remoteSAddr;
     455              :     struct RsIpAddrInfo remoteIp;
     456           16 :     int connfd = RS_FD_INVALID;
     457           16 :     int tcpNodelayFlag = 1;
     458              :     int ret, retClose;
     459              :     socklen_t ipLen;
     460              : 
     461              :     /* Server event: Connection accept */
     462           16 :     RS_LIST_GET_HEAD_ENTRY(listenInfo, listenInfo2, &rsCb->connCb.listenList, list, struct RsListenInfo);
     463           16 :     for (; (&listenInfo->list) != &rsCb->connCb.listenList;
     464            0 :         listenInfo = listenInfo2, listenInfo2 = list_entry(listenInfo2->list.next, struct RsListenInfo, list)) {
     465              :         /* connection request for Server */
     466           16 :         if (fd == listenInfo->listenFd) {
     467           16 :             ret = RsSocketCheckCredit(&rsCb->connCb, listenInfo);
     468           32 :             CHK_PRT_RETURN(ret != 0,
     469              :                 hccp_warn("[server]rs_socket_check_credit unsuccessful, serverIp:%s serverPort:%u ret:%d",
     470              :                 listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, ret), -EINVAL);
     471              : 
     472           16 :             remoteSAddr.family = (int)listenInfo->serverIpAddr.family;
     473           16 :             ipLen = (remoteSAddr.family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
     474              :             do {
     475           16 :                 connfd = accept(fd, (struct sockaddr *)&remoteSAddr.addr, &ipLen);
     476           16 :             } while ((connfd < 0) && (errno == EINTR));
     477              : 
     478              :             // accept failed and errno is the same with the last time, avoid log flush
     479           16 :             ret = errno;
     480           16 :             if (connfd < 0 && listenInfo->lastAcceptErrno == ret) {
     481            0 :                 hccp_warn("[server]server_ip:%s server_port:%u accept() unsuccessful! errno:%d",
     482              :                     listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, ret);
     483            0 :                 return -EINVAL;
     484              :             }
     485           16 :             listenInfo->lastAcceptErrno = ret;
     486              : 
     487           16 :             if (connfd < 0) {
     488            0 :                 hccp_err("[server]server_ip:%s server_port:%u accept() failed! errno:%d",
     489              :                     listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, ret);
     490            0 :                 goto err_accept;
     491              :             }
     492              : 
     493           16 :             hccp_info("[server]server_ip:%s server_port:%u accept ok, listen_fd:%d, new fd:%d",
     494              :                 listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, fd, connfd);
     495              : 
     496           16 :             remoteIp.family = (uint32_t)remoteSAddr.family;
     497           16 :             if (remoteIp.family == AF_INET) {
     498           16 :                 remoteIp.binAddr.addr = remoteSAddr.addr.sAddr.sin_addr;
     499              :             } else {
     500            0 :                 remoteIp.binAddr.addr6 = remoteSAddr.addr.sAddr6.sin6_addr;
     501              :             }
     502              : 
     503           16 :             ret = RsInetNtop(remoteIp.family, &remoteIp.binAddr, remoteIp.readAddr, sizeof(remoteIp.readAddr));
     504           16 :             if (ret) {
     505            0 :                 hccp_err("[server]convert(ntop) ip failed, remoteIp.family:%d, remoteIp:%d, ret:%d, serverIp:%s "
     506              :                     "serverPort:%u", remoteIp.family, remoteIp.binAddr.addr.s_addr, ret,
     507              :                     listenInfo->serverIpAddr.readAddr, listenInfo->sockPort);
     508            0 :                 goto err_event_listen;
     509              :             }
     510              : 
     511           16 :             if (rsCb->sslEnable == RS_SSL_ENABLE) {
     512            0 :                 ret = RsSetFdNonblock(connfd);
     513            0 :                 if (ret) {
     514            0 :                     hccp_err("[server]fcntl connfd %d nonblock failed %d, serverIp:%s serverPort:%u",
     515              :                         connfd, ret, listenInfo->serverIpAddr.readAddr, listenInfo->sockPort);
     516            0 :                     goto err_event_listen;
     517              :                 }
     518              :             }
     519              : 
     520              :             /* set tcp socket tos RS_TCP_DSCP_0 */
     521           16 :             int tosLocal = (RS_TCP_DSCP_0 & RS_DSCP_MASK) << RS_DSCP_OFF;
     522           16 :             ret = setsockopt(connfd, IPPROTO_IP, IP_TOS, (void *)&tosLocal, sizeof(tosLocal));
     523           16 :             if (ret) {
     524            0 :                 hccp_err("[server]setsockopt(IP_TOS) failed, ret:%d, errno:%d, serverIp:%s serverPort:%u",
     525              :                     ret, errno, listenInfo->serverIpAddr.readAddr, listenInfo->sockPort);
     526            0 :                 goto err_socket_option;
     527              :             }
     528              : 
     529           16 :             ret = setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (void *)&tcpNodelayFlag, sizeof(int));
     530           16 :             if (ret < 0) {
     531            0 :                 hccp_err("[server]setsockopt(TCP_NODELAY) failed, ret:%d, errno:%d, serverIp:%s serverPort:%u",
     532              :                     ret, errno, listenInfo->serverIpAddr.readAddr, listenInfo->sockPort);
     533            0 :                 goto err_socket_option;
     534              :             }
     535              : 
     536           16 :             if (rsCb->sslEnable == RS_SSL_ENABLE) {
     537            0 :                 RsEpollEventSslListenInHandle(rsCb, listenInfo, connfd, &remoteIp);
     538              :             } else {
     539           16 :                 RsEpollEventTcpListenInHandle(rsCb, listenInfo, connfd, &remoteIp);
     540              :             }
     541           16 :             return 0;
     542              :         }
     543              :     }
     544              : 
     545            0 :     return -ENODEV;
     546              : 
     547            0 : err_socket_option:
     548            0 :     ret = -errno;
     549            0 : err_event_listen:
     550            0 :     RS_CLOSE_RETRY_FOR_EINTR(retClose, connfd);
     551            0 : err_accept:
     552            0 :     RsSocketSaveErrInfo((int)listenInfo->state, ret, &listenInfo->errInfo);
     553            0 :     return -ESYSFUNC;
     554              : }
     555              : 
     556           23 : STATIC int RsSocketListenBindListen(int listenFd, struct RsConnCb *connCb,
     557              :     struct SocketListenInfo *conn, struct RsListenInfo *listenInfo, uint32_t serverPort)
     558              : {
     559           23 :     int isReuseAddr = 1;
     560              :     int ret, errNo;
     561              : 
     562           23 :     ret = setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &isReuseAddr, sizeof(isReuseAddr));
     563           23 :     if (ret) {
     564            1 :         errNo = errno;
     565            1 :         hccp_err("set socket op failed! IP:%s, port:%u, sock:%d, ret:0x%x, error:%d",
     566              :             listenInfo->serverIpAddr.readAddr, serverPort, listenFd, ret, errNo);
     567            1 :         conn->phase = LISTEN_BIND_ERR;
     568            1 :         return -ESYSFUNC;
     569              :     }
     570              : 
     571           22 :     listenInfo->state = RS_CONN_STATE_INIT;
     572              : 
     573           22 :     hccp_info("listen state:%d, then bind for (IP %s : port %u)",
     574              :         listenInfo->state, listenInfo->serverIpAddr.readAddr, serverPort);
     575              : 
     576           22 :     hccp_run_info("socket bind: family %d, addr %s, port %u", conn->family, listenInfo->serverIpAddr.readAddr,
     577              :         serverPort);
     578           22 :     if (conn->family == AF_INET) {
     579           21 :         struct sockaddr_in addr = {0};
     580           21 :         addr.sin_family = conn->family;
     581           21 :         addr.sin_port = htons(serverPort);
     582           21 :         addr.sin_addr.s_addr = listenInfo->serverIpAddr.binAddr.addr.s_addr;
     583           21 :         hccp_info("socket bind: family %d, port %d, addr 0x%08x", addr.sin_family, addr.sin_port, addr.sin_addr.s_addr);
     584           21 :         ret = bind(listenFd, &addr, sizeof(addr));
     585              :     } else {
     586            1 :         struct sockaddr_in6 addr = {0};
     587            1 :         addr.sin6_family = conn->family;
     588            1 :         addr.sin6_port = htons(serverPort);
     589            1 :         addr.sin6_addr = listenInfo->serverIpAddr.binAddr.addr6;
     590            1 :         addr.sin6_scope_id = (uint32_t)connCb->scopeId;
     591            1 :         hccp_info("socket bind: family %d, port %d, scopeId %d", addr.sin6_family, addr.sin6_port, addr.sin6_scope_id);
     592           17 :         for (unsigned long i = 0; i < sizeof(addr.sin6_addr.s6_addr); i++) {
     593           16 :             hccp_info("socket bind: addr[%lu] 0x%02x", i, addr.sin6_addr.s6_addr[i]);
     594              :         }
     595            1 :         ret = bind(listenFd, &addr, sizeof(addr));
     596              :     }
     597              : 
     598           22 :     if (ret) {
     599            3 :         errNo = errno;
     600            3 :         if (errNo == EADDRINUSE) {
     601            1 :             hccp_run_warn("bind unsuccessful! family:%d, IP:%s, port:%u, sock:%d, ret:0x%x, error:%d, Possible Cause: "\
     602              :                 "the IP address and port have been bound already", conn->family, listenInfo->serverIpAddr.readAddr,
     603              :                 serverPort, listenFd, ret, errNo);
     604              :         } else {
     605            2 :             hccp_err("bind failed! family:%d, IP:%s, port:%u, sock:%d, ret:0x%x, error:%d", conn->family,
     606              :                 listenInfo->serverIpAddr.readAddr, serverPort, listenFd, ret, errNo);
     607              :         }
     608            3 :         conn->phase = LISTEN_BIND_ERR;
     609            3 :         return errNo;
     610              :     }
     611              : 
     612           19 :     listenInfo->state = RS_CONN_STATE_BIND;
     613              : 
     614           19 :     hccp_info("IP %s : port %u begin listen, fd:%d !", listenInfo->serverIpAddr.readAddr, serverPort, listenFd);
     615           19 :     ret = listen(listenFd, RS_SOCK_LISTEN_PARALLEL_NUM);
     616           19 :     if (ret) {
     617            1 :         errNo = errno;
     618            1 :         if (errNo == EADDRINUSE) {
     619            0 :             hccp_run_warn("listen unsuccessful! IP:%s, port:%u, sock:%d, ret:0x%x, errno:%d",
     620              :                 listenInfo->serverIpAddr.readAddr, serverPort, listenFd, ret, errNo);
     621              :         } else {
     622            1 :             hccp_err("listen failed! IP:%s, port:%u, sock:%d, ret:0x%x, errno:%d",
     623              :                 listenInfo->serverIpAddr.readAddr, serverPort, listenFd, ret, errNo);
     624              :         }
     625            1 :         conn->phase = LISTEN_BEGIN_ERR;
     626            1 :         return errNo;
     627              :     }
     628              : 
     629           18 :     return 0;
     630              : }
     631              : 
     632           27 : static int RsSocketInitListen(struct SocketListenInfo *conn, uint32_t i, struct RsConnCb **connCb,
     633              :     uint32_t serverPort, struct RsListenInfo **listenInfo)
     634              : {
     635              :     int ret;
     636              :     unsigned int chipId;
     637              : 
     638           27 :     CHK_PRT_RETURN(((conn[i].family != AF_INET) && (conn[i].family != AF_INET6)) || conn[i].phyId >= RS_MAX_DEV_NUM,
     639              :         hccp_err("family[%d] invalid, or phyId[%u] invalid, i:%u", conn[i].family, conn[i].phyId, i), -EINVAL);
     640              : 
     641           26 :     if (conn[i].family == AF_INET) {
     642           25 :         uint32_t *localIp = NULL;
     643           25 :         localIp = &(conn[i].localIp.addr.s_addr);
     644           25 :         ret = RsSocketNodeid2vnic(*localIp, localIp);
     645           25 :         hccp_info("listen [%u] IP 0x%llx, ret_vnic %d", i, *localIp, ret);
     646              :     }
     647              : 
     648           26 :     ret = rsGetLocalDevIDByHostDevID(conn[i].phyId, &chipId);
     649           26 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
     650              : 
     651           26 :     ret = RsDev2conncb(chipId, connCb);
     652           26 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed, ret:%d", ret), ret);
     653              : 
     654           26 :     struct RsIpAddrInfo ipInfo = {0};
     655           26 :     ret = RsConvertIpAddr(conn[i].family, &conn[i].localIp, &ipInfo);
     656           26 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
     657              : 
     658              :     struct RsListenInfo *tmpListenInfo;
     659           26 :     ret = RsFindListenNode(*connCb, &ipInfo, serverPort, &tmpListenInfo);
     660           26 :     if (ret == 0) {
     661            1 :         int counter = __sync_fetch_and_add(&(tmpListenInfo->counter), 1);
     662            1 :         if (counter > 0) {
     663            1 :             hccp_info("find listen node successful, counter:%d, IP:%s, port:%u", counter, ipInfo.readAddr, serverPort);
     664            1 :             return -EEXIST;
     665              :         }
     666              :     }
     667              : 
     668           25 :     ret = RsListenNodeAlloc(*connCb, &ipInfo, serverPort, listenInfo);
     669              :     // listen node found, degrade log level make it consistent with inner call
     670           25 :     if (ret == -EEXIST) {
     671            0 :         hccp_info("alloc listen info node unsuccessful, ret:%d, IP:%s, port:%u", ret, ipInfo.readAddr, serverPort);
     672           25 :     } else if (ret != 0) {
     673            1 :         hccp_err("alloc listen info node failed, ret:%d, IP:%s, port:%u", ret, ipInfo.readAddr, serverPort);
     674              :     }
     675           25 :     if (ret != 0) {
     676            1 :         conn[i].err = ENOMEM;
     677            1 :         return ret;
     678              :     }
     679              : 
     680           24 :     return 0;
     681              : }
     682              : 
     683           18 : static void RsSocketSetConnListenInfo(struct RsListenInfo *listenInfo, int listenFd,
     684              :     uint32_t serverPort, struct SocketListenInfo *conn)
     685              : {
     686           18 :     listenInfo->listenFd = listenFd;
     687           18 :     listenInfo->sockPort = serverPort;
     688           18 :     listenInfo->state = RS_CONN_STATE_LISTENING;
     689              : 
     690           18 :     if (conn->family == AF_INET) {
     691           18 :         conn->localIp.addr.s_addr = RsSocketVnic2nodeid(conn->localIp.addr.s_addr);
     692              :     }
     693           18 :     conn->err = 0;
     694           18 :     conn->port = serverPort;
     695           18 :     conn->phase = LISTEN_OK;
     696           18 : }
     697              : 
     698            8 : static void RsSocketHandleListenNodeErr(uint32_t i, struct RsConnCb *connCb,
     699              :     struct SocketListenInfo conn[], uint32_t serverPort)
     700              : {
     701              :     uint32_t j;
     702              :     int ret;
     703            8 :     struct RsListenInfo *listenInfo = NULL;
     704              : 
     705            9 :     for (j = 0; j < i; j++) {
     706            1 :         struct RsIpAddrInfo ipInfo = {0};
     707            1 :         ret = RsConvertIpAddr(conn[j].family, &conn[j].localIp, &ipInfo);
     708            1 :         if (ret) {
     709            0 :             hccp_err("convert(ntop) ip failed");
     710            0 :             continue;
     711              :         }
     712            1 :         ret = RsFindListenNode(connCb, &ipInfo, serverPort, &listenInfo);
     713            1 :         if (ret) {
     714            0 :             hccp_dbg("not find listen node, ret %d", ret);
     715              :         } else {
     716            1 :             ret = RsEpollCtl(connCb->epollfd, EPOLL_CTL_DEL, listenInfo->listenFd, EPOLLIN);
     717            1 :             if (ret) {
     718            0 :                 hccp_err("delete from epoll failed, ret:%d, epollfd:%d, listenFd:%d", ret, connCb->epollfd,
     719              :                     listenInfo->listenFd);
     720              :             }
     721            1 :             RS_CLOSE_RETRY_FOR_EINTR(ret, listenInfo->listenFd);
     722            1 :             RsListenNodeFree(connCb, listenInfo);
     723              :         }
     724              :     }
     725            8 : }
     726              : 
     727              : RS_ATTRI_VISI_DEF int RsSocketListenStart(struct SocketListenInfo conn[], uint32_t num)
     728              : {
     729           28 :     struct RsListenInfo *listenInfo = NULL;
     730           28 :     union RsSocketaddr serverAddr = {0};
     731           28 :     struct RsConnCb *connCb = NULL;
     732           28 :     socklen_t serverAddrLen = 0;
     733           28 :     unsigned int serverPort = 0;
     734           28 :     int listenFd = 0;
     735           28 :     int scopeId = 0;
     736           28 :     int errNo = 0;
     737              :     int ret, flag;
     738              :     uint32_t i;
     739              : 
     740           28 :     RS_SOCKET_PARA_CHECK(num, conn);
     741           26 :     if (conn[0].family == AF_INET6) {
     742            1 :         scopeId = RsGetIpv6ScopeId(conn[0].localIp.addr6);
     743            1 :         CHK_PRT_RETURN(scopeId < 0, hccp_err("scope_id[%d] is invalid", scopeId), -EINVAL);
     744              :     }
     745              : 
     746           45 :     for (i = 0; i < num; i++) {
     747           27 :         serverPort = conn[i].port;
     748           27 :         ret = RsSocketInitListen(conn, i, &connCb, serverPort, &listenInfo);
     749           27 :         if (ret == -EEXIST) {
     750            1 :             continue;
     751              :         }
     752           26 :         if (ret) {
     753            2 :             flag = -ENOMEM;
     754            2 :             hccp_err("listen init failed, ret:%d", ret);
     755            2 :             goto listen_node_err_handle;
     756              :         }
     757              : 
     758              :         /* socket */
     759           24 :         listenFd = socket(conn[i].family, SOCK_STREAM, 0);
     760           24 :         if (listenFd < 0) {
     761            1 :             errNo = errno;
     762            1 :             hccp_err("create socket for (IP %s : port %u) failed, family %d, errno %d",
     763              :                 listenInfo->serverIpAddr.readAddr, serverPort, conn[i].family, errNo);
     764            1 :             conn[i].phase = LISTEN_CREATE_FD_ERR;
     765            1 :             goto listen_err_handle;
     766              :         }
     767              : 
     768              :         /* bind and listen */
     769           23 :         connCb->scopeId = scopeId;
     770           23 :         ret = RsSocketListenBindListen(listenFd, connCb, conn + i, listenInfo, serverPort);
     771           23 :         errNo = ret;
     772           23 :         if (ret == EADDRINUSE) {
     773            1 :             hccp_run_warn("bind and listen unsuccessful, errNo:%d, listenFd:%d, state:%u, IP(%s) serverPort:%u",
     774              :                 errNo, listenFd, listenInfo->state, listenInfo->serverIpAddr.readAddr, serverPort);
     775            1 :             goto bind_err_handle;
     776           22 :         } else if (ret != 0) {
     777            4 :             hccp_err("bind and listen failed, errNo:%d, listenFd:%d, listen state:%u, IP(%s) serverPort:%u", errNo,
     778              :                 listenFd, listenInfo->state, listenInfo->serverIpAddr.readAddr, serverPort);
     779            4 :             goto bind_err_handle;
     780              :         }
     781              : 
     782           18 :         ret = RsEpollCtl(connCb->epollfd, EPOLL_CTL_ADD, listenFd, EPOLLIN);
     783           18 :         if (ret) {
     784            0 :             errNo = ret;
     785            0 :             hccp_err("RsEpollCtl for epollfd[%d] listen_fd[%d]failed, errno:%d", connCb->epollfd, listenFd, errNo);
     786            0 :             goto bind_err_handle;
     787              :         }
     788              : 
     789           18 :         serverAddrLen = (conn->family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
     790           18 :         getsockname(listenFd, (struct sockaddr *)&serverAddr, &serverAddrLen);
     791           18 :         serverPort = (conn->family == AF_INET) ? ntohs(serverAddr.sAddr.sin_port) :
     792            0 :             ntohs(serverAddr.sAddr6.sin6_port);
     793           18 :         RsSocketSetConnListenInfo(listenInfo, listenFd, serverPort, &conn[i]);
     794              :     }
     795              : 
     796           18 :     return 0;
     797              : 
     798            5 : bind_err_handle:
     799            5 :     RS_CLOSE_RETRY_FOR_EINTR(ret, listenFd);
     800            5 : listen_err_handle:
     801            6 :     RsListenNodeFree(connCb, listenInfo);
     802            6 :     conn[i].err = (unsigned int)errNo;
     803            6 :     flag = -errNo;
     804            8 : listen_node_err_handle:
     805            8 :     RsSocketHandleListenNodeErr(i, connCb, conn, serverPort);
     806            8 :     return flag;
     807              : }
     808              : 
     809              : RS_ATTRI_VISI_DEF int RsSocketAcceptCreditAdd(struct SocketListenInfo conn[], uint32_t num,
     810              :     unsigned int creditLimit)
     811              : {
     812            2 :     struct RsListenInfo *listenInfo = NULL;
     813            2 :     struct RsIpAddrInfo ipInfo = {0};
     814            2 :     struct RsConnCb *connCb = NULL;
     815              :     unsigned int tmpCreditLimit;
     816            2 :     int ret = 0;
     817              :     uint32_t i;
     818              : 
     819            2 :     RS_SOCKET_PARA_CHECK(num, conn);
     820            3 :     for (i = 0; i < num; i++) {
     821            2 :         ret = RsConvertIpAddr(conn[i].family, &conn[i].localIp, &ipInfo);
     822            2 :         CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, i:%d, ret:%d", i, ret), ret);
     823              : 
     824            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
     825            2 :         connCb = &gRsCb->connCb;
     826            2 :         ret = RsFindListenNode(connCb, &ipInfo, conn[i].port, &listenInfo);
     827            2 :         if (ret != 0) {
     828            1 :             hccp_err("rs_find_listen_node failed, i:%u, IP:%s serverPort:%u, ret:%d",
     829              :                 i, ipInfo.readAddr, conn[i].port, ret);
     830            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
     831            1 :             return ret;
     832              :         }
     833            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
     834              : 
     835              :         // prevent accept_credit_limit from overflow
     836            1 :         tmpCreditLimit = listenInfo->acceptCreditLimit + creditLimit;
     837            1 :         if (tmpCreditLimit < creditLimit) {
     838            0 :             hccp_err("credit_limit overflow, IP:%s serverPort:%u tmpCreditLimit:%u, creditLimit:%u",
     839              :                 ipInfo.readAddr, conn[i].port, tmpCreditLimit, creditLimit);
     840            0 :             return -EINVAL;
     841              :         }
     842            1 :         RS_PTHREAD_MUTEX_LOCK(&listenInfo->acceptCreditMutex);
     843            1 :         listenInfo->acceptCreditLimit += creditLimit;
     844            1 :         RS_PTHREAD_MUTEX_ULOCK(&listenInfo->acceptCreditMutex);
     845            1 :         RsSocketListenAddToEpoll(connCb, listenInfo);
     846            1 :         listenInfo->acceptCreditFlag = true;
     847              :     }
     848              : 
     849            1 :     return ret;
     850              : }
     851              : 
     852              : RS_ATTRI_VISI_DEF int RsSocketListenStop(struct SocketListenInfo conn[], uint32_t num)
     853              : {
     854           22 :     struct RsListenInfo *listenInfo = NULL;
     855           22 :     struct RsConnCb *connCb = NULL;
     856              :     unsigned int chipId;
     857              :     uint32_t i;
     858              :     int ret;
     859              : 
     860           22 :     RS_SOCKET_PARA_CHECK(num, conn);
     861           39 :     for (i = 0; i < num; i++) {
     862           20 :         CHK_PRT_RETURN(((conn[i].family != AF_INET) && (conn[i].family != AF_INET6)) ||
     863              :             conn[i].phyId >= RS_MAX_DEV_NUM,
     864              :             hccp_err("family[%d] invalid, or phyId[%u] invalid, i:%u", conn[i].family, conn[i].phyId, i), -EINVAL);
     865              : 
     866           19 :         if (conn[i].family == AF_INET) {
     867           18 :             uint32_t *localIp = NULL;
     868           18 :             localIp = &(conn[i].localIp.addr.s_addr);
     869           18 :             ret = RsSocketNodeid2vnic(*localIp, localIp);
     870           18 :             hccp_info("listen [%d] IP 0x%llx, ret_vnic %d", i, *localIp, ret);
     871              :         }
     872           19 :         ret = rsGetLocalDevIDByHostDevID(conn[i].phyId, &chipId);
     873           19 :         CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
     874           19 :         ret = RsDev2conncb(chipId, &connCb);
     875              :         // degrade log level, make it consistent with inner call
     876           19 :         CHK_PRT_RETURN(ret != 0, hccp_warn("get conncb from dev unsuccessful(%d)!", ret), -ENODEV);
     877              : 
     878           19 :         struct RsIpAddrInfo ipInfo = {0};
     879           19 :         ret = RsConvertIpAddr(conn[i].family, &conn[i].localIp, &ipInfo);
     880           19 :         CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
     881              : 
     882           19 :         ret = RsFindListenNode(connCb, &ipInfo, conn[i].port, &listenInfo);
     883           19 :         if (ret == 0 && __sync_fetch_and_sub(&(listenInfo->counter), 1) > 1) {
     884            3 :             continue;
     885              :         }
     886              :         // listen node not found, degrade log level due to this is non-fatal error
     887           18 :         if (ret != 0) {
     888            2 :             hccp_warn("get listen info unsuccessful(%d), IP(%s)!", ret, ipInfo.readAddr);
     889            2 :             conn[i].err = ENODEV;
     890            2 :             continue;
     891              :         }
     892              : 
     893           16 :         ret = RsSocketListenDelFromEpoll(connCb, listenInfo);
     894           16 :         CHK_PRT_RETURN(ret, hccp_err("delete from epoll failed, ret:%d, epollfd:%d, listenFd:%d",
     895              :             ret, connCb->epollfd, listenInfo->listenFd), ret);
     896              : 
     897              :         /* close socket */
     898           16 :         RS_CLOSE_RETRY_FOR_EINTR(ret, listenInfo->listenFd);
     899           16 :         hccp_info("IP(%s) close listen fd:%d !", ipInfo.readAddr, listenInfo->listenFd);
     900              : 
     901           16 :         listenInfo->listenFd = RS_FD_INVALID;
     902           16 :         listenInfo->state = RS_CONN_STATE_RESET;
     903              : 
     904           16 :         RsListenNodeFree(connCb, listenInfo);
     905              :     }
     906              : 
     907           19 :     return 0;
     908              : }
     909              : 
     910           16 : STATIC int RsAllocClientConnNode(struct RsConnCb *connCb,
     911              :     enum RsConnRole role, struct RsConnInfo **conn, struct SocketConnectInfo *socketConn,
     912              :     struct RsIpAddrInfo *clientIp, struct RsIpAddrInfo *serverIp, int serverPort)
     913              : {
     914           16 :     struct RsListHead *listHead = NULL;
     915              :     struct RsConnInfo *connInfo;
     916              :     int ret;
     917              : 
     918           16 :     connInfo = calloc(1, sizeof(struct RsConnInfo));
     919           16 :     CHK_PRT_RETURN(connInfo == NULL, hccp_err("alloc mem for socket conn info failed!"), -ENOMEM);
     920              : 
     921           16 :     connInfo->port = serverPort;
     922           16 :     connInfo->connfd = RS_FD_INVALID;
     923           16 :     connInfo->state = RS_CONN_STATE_RESET;
     924           16 :     connInfo->serverIp = *serverIp;
     925           16 :     connInfo->clientIp = *clientIp;
     926           16 :     connInfo->scopeId = connCb->scopeId;
     927              : 
     928           16 :     ret = strcpy_s(connInfo->tag, SOCK_CONN_TAG_SIZE, socketConn->tag);
     929           16 :     if (ret) {
     930            0 :         hccp_err("strcpy_s err, ret:%d, size of dest:%u, size of src:%u", ret, sizeof(connInfo->tag),
     931              :             sizeof(socketConn->tag));
     932            0 :         goto out;
     933              :     }
     934           16 :     ret = sprintf_s(connInfo->tag + SOCK_CONN_TAG_SIZE, SOCK_CONN_DEV_ID_SIZE, "%u", socketConn->phyId);
     935           16 :     if (ret < 0) {
     936            0 :         hccp_err("sprintf_s err, ret:%d, phyId:%u", ret, socketConn->phyId);
     937            0 :         goto out;
     938              :     }
     939              : 
     940           16 :     RsGetCurTime(&connInfo->startTime);
     941              : 
     942           16 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
     943           16 :     listHead = (role == RS_CONN_ROLE_SERVER) ? (&connCb->serverConnList) : (&connCb->clientConnList);
     944           16 :     RsListAddTail(&connInfo->list, listHead);
     945           16 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
     946              : 
     947           16 :     *conn = connInfo;
     948              : 
     949           16 :     return 0;
     950              : 
     951            0 : out:
     952            0 :     free(connInfo);
     953            0 :     connInfo = NULL;
     954            0 :     return -ESAFEFUNC;
     955              : }
     956              : 
     957            0 : STATIC void RsSocketClientValidSync(struct RsConnInfo *conn)
     958              : {
     959            0 :     char isvalid[RS_WLIST_VALID_FLAG_SIZE] = {0};
     960              :     int ret, retClose;
     961              : 
     962              :     do {
     963            0 :         ret = RsSocketRecv(conn->connfd, isvalid, RS_WLIST_VALID_FLAG_SIZE);
     964            0 :         if (ret == RS_WLIST_VALID_FLAG_SIZE && (strncmp(isvalid, "a5a5a", strlen("a5a5a")) == 0)) {
     965            0 :             hccp_info("[client]client is valid, ret:%d, clientIp:%s serverIp:%s serverPort:%u",
     966              :                 ret, conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port);
     967            0 :             conn->state = RS_CONN_STATE_VALID_SYNC;
     968            0 :             return;
     969            0 :         } else if (ret == RS_WLIST_VALID_FLAG_SIZE && (strncmp(isvalid, "5a5a5", strlen("5a5a5")) == 0)) {
     970            0 :             hccp_info("[client]client is invalid, errNo:%d, clientIp:%s serverIp:%s serverPort:%u",
     971              :                 errno, conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port);
     972            0 :             goto out;
     973            0 :         } else if (ret == -EAGAIN) {
     974            0 :             return;
     975              :         }
     976            0 :     } while ((ret < 0) && (errno == EINTR));
     977              : 
     978              :     // ret is -EFILEOPER or recv unexpected data. state machine will connect again
     979            0 :     hccp_run_warn("[client]recv isvalid unsuccessful, ret:%d errNo:%d, clientIp:%s serverIp:%s serverPort:%u fd:%d."
     980              :         " retry connect", ret, errno, conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->connfd);
     981            0 : out:
     982            0 :     if (gRsCb->sslEnable == RS_SSL_ENABLE) {
     983            0 :         ssl_adp_shutdown(conn->ssl);
     984            0 :         ssl_adp_free(conn->ssl);
     985            0 :         conn->ssl = NULL;
     986              :     }
     987            0 :     RS_CLOSE_RETRY_FOR_EINTR(retClose, conn->connfd);
     988            0 :     conn->connfd = RS_FD_INVALID;
     989            0 :     conn->state = RS_CONN_STATE_RESET;
     990            0 :     conn->tagSyncTimes = 0;
     991            0 :     return;
     992              : }
     993              : 
     994           16 : STATIC void RsSocketTagSync(struct RsConnInfo *conn)
     995              : {
     996              :     int ret;
     997              : 
     998              :     /* sync tag to server */
     999           16 :     conn->tagSyncTimes++;
    1000           16 :     ret = RsDrvSocketSend(conn->connfd, conn->tag, SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE, 0);
    1001           16 :     if (ret == SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE) {
    1002           16 :         conn->state = RS_CONN_STATE_TAG_SYNC;
    1003           16 :         hccp_info("[client]send tag success! ret:%d, tagSyncTimes:%u, clientIp:%s serverIp:%s serverPort:%u tag:%s",
    1004              :             ret, conn->tagSyncTimes, conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag);
    1005            0 :     } else if (ret == -EAGAIN) {
    1006            0 :         conn->state = RS_CONN_STATE_TIMEOUT;
    1007            0 :         hccp_info("[client]send tag incomplete! ret:%d, tagSyncTimes:%u, clientIp:%s serverIp:%s serverPort:%u "
    1008              :             "tag:%s", ret, conn->tagSyncTimes, conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port,
    1009              :             conn->tag);
    1010              :     } else {
    1011            0 :         hccp_run_info("[client]send tag unsuccessful, ret:%d, tagSyncTimes:%u, retry connect, clientIp:%s "
    1012              :             "serverIp:%s serverPort:%u tag:%s", ret, conn->tagSyncTimes, conn->clientIp.readAddr,
    1013              :             conn->serverIp.readAddr, conn->port, conn->tag);
    1014              : 
    1015            0 :         if (gRsCb->sslEnable == RS_SSL_ENABLE) {
    1016            0 :             ssl_adp_shutdown(conn->ssl);
    1017            0 :             ssl_adp_free(conn->ssl);
    1018            0 :             conn->ssl = NULL;
    1019              :         }
    1020            0 :         RS_CLOSE_RETRY_FOR_EINTR(ret, conn->connfd);
    1021            0 :         conn->connfd = RS_FD_INVALID;
    1022            0 :         conn->state = RS_CONN_STATE_RESET;
    1023            0 :         conn->tagSyncTimes = 0;
    1024              :     }
    1025              : 
    1026           16 :     return;
    1027              : }
    1028              : 
    1029              : /* ssl will connect again and again, HCCL get socke timeout after period time */
    1030            0 : STATIC int RsSocketSslConnect(struct RsConnInfo *conn, struct rs_cb *rscb)
    1031              : {
    1032              :     int ret, err;
    1033              : 
    1034            0 :     ret = ssl_adp_do_handshake(conn->ssl);
    1035            0 :     if (ret != 1) {
    1036            0 :         err = ssl_adp_get_error(conn->ssl, ret);
    1037            0 :         if (err == SSL_ERROR_WANT_WRITE) {
    1038            0 :             hccp_dbg("ssl fd %d return want write", conn->connfd);
    1039            0 :         } else if (err == SSL_ERROR_WANT_READ) {
    1040            0 :             hccp_dbg("ssl fd %d return want read", conn->connfd);
    1041              :         } else {
    1042            0 :             rs_ssl_err_string(conn->connfd, err);
    1043              :         }
    1044              : 
    1045            0 :         return -EAGAIN;
    1046              :     }
    1047            0 :     ret = rs_tls_peer_cert_verify(conn->ssl, rscb);
    1048            0 :     CHK_PRT_RETURN(ret, hccp_err("verify peer cert failed ret %d", ret), ret);
    1049              : 
    1050            0 :     return 0;
    1051              : }
    1052              : 
    1053           16 : STATIC int RsSocketStateSslFdBind(struct RsConnInfo *conn, uint32_t sslEnable, struct rs_cb *rscb)
    1054              : {
    1055              :     int ret;
    1056              : 
    1057           16 :     if (sslEnable == RS_SSL_ENABLE) {
    1058            0 :         ret = RsSocketSslConnect(conn, rscb);
    1059            0 :         if (ret) {
    1060            0 :             return ret;
    1061              :         }
    1062            0 :         conn->state = RS_CONN_STATE_SSL_CONNECTED;
    1063              :     }
    1064              : 
    1065           16 :     RsConnCostTime(conn);
    1066           16 :     RsSocketTagSync(conn);
    1067           16 :     return 0;
    1068              : }
    1069              : 
    1070           16 : STATIC int RsSocketStateConnected(struct RsConnInfo *conn, uint32_t sslEnable, struct rs_cb *rscb)
    1071              : {
    1072              :     int ret;
    1073              : 
    1074           16 :     if (sslEnable == RS_SSL_ENABLE) {
    1075            0 :         ret = RsDrvSslBindFd(conn, conn->connfd);
    1076            0 :         if (ret != 0) {
    1077            0 :             RsSocketSaveErrInfo(RS_CONN_STATE_CONNECTED, ret, &conn->errInfo);
    1078            0 :             hccp_err("[client]ssl bind failed, connfd:%d, ret:%d, clientIp:%s serverIp:%s serverPort:%u tag:%s",
    1079              :                 conn->connfd, ret, conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag);
    1080            0 :             return ret;
    1081              :         }
    1082            0 :         conn->state = RS_CONN_STATE_SSL_BIND_FD;
    1083              :     }
    1084              : 
    1085           16 :     return RsSocketStateSslFdBind(conn, sslEnable, rscb);
    1086              : }
    1087              : 
    1088           16 : STATIC int RsSocketStateInit(unsigned int chipId, struct RsConnInfo *conn, uint32_t sslEnable, struct rs_cb *rscb)
    1089              : {
    1090              :     int ret;
    1091              : 
    1092           16 :     conn->tag[SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE - 1] = '\0';
    1093              : 
    1094           16 :     ret = RsDrvConnect(conn->connfd, &conn->serverIp, &conn->clientIp, conn->port);
    1095           16 :     if (ret != 0) {
    1096            0 :         RsSocketSaveErrInfo(RS_CONN_STATE_INIT, ret, &conn->errInfo);
    1097            0 :         hccp_warn("[client]rs_socket_state_init conn unsuccessful! client_ip:%s server_ip:%s server_port:%u tag:%s, "
    1098              :             "fd:%d, ret:%d", conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag,
    1099              :             conn->connfd, ret);
    1100            0 :         return ret;
    1101              :     }
    1102              : 
    1103              :     // should set back tcp socket send/recv timeout to OS default when ssl is disabled
    1104           16 :     if (sslEnable == RS_SSL_DISABLE) {
    1105           16 :         ret = RsSocketSetFdTimeoutUsec(conn->connfd, 0);
    1106           16 :         if (ret != 0) {
    1107            0 :             hccp_warn("[client]rs_socket_set_fd_timeout_usec conn unsuccessful!, clientIp:%s serverIp:%s "
    1108              :                 "serverPort:%u tag:%s, fd:%d, ret:%d", conn->clientIp.readAddr, conn->serverIp.readAddr,
    1109              :                 conn->port, conn->tag, conn->connfd, ret);
    1110              :         }
    1111              :     }
    1112              : 
    1113           16 :     conn->state = RS_CONN_STATE_CONNECTED;
    1114              :     /*
    1115              :      * ssl will connect again and again, HCCL get socke timeout after period time,
    1116              :      * so there is no log info to prevent over log
    1117              :      */
    1118           16 :     ret = RsSocketStateConnected(conn, sslEnable, rscb);
    1119           16 :     if (ret) {
    1120            0 :         return ret;
    1121              :     }
    1122              : 
    1123           16 :     return 0;
    1124              : }
    1125              : 
    1126           16 : STATIC int RsConnectBindClient(int fd, struct RsConnInfo *conn)
    1127              : {
    1128              :     int errNo;
    1129              :     int ret;
    1130              : 
    1131           16 :     if (conn->clientIp.family == AF_INET) {
    1132           16 :         struct sockaddr_in clientAddr = {0};
    1133           16 :         clientAddr.sin_family = conn->clientIp.family;
    1134           16 :         clientAddr.sin_addr = conn->clientIp.binAddr.addr;
    1135              : 
    1136           16 :         hccp_dbg("socket bind: family %d, port %d, addr 0x%08x",
    1137              :             clientAddr.sin_family, clientAddr.sin_port, clientAddr.sin_addr.s_addr);
    1138           16 :         ret = bind(fd, &clientAddr, sizeof(clientAddr));
    1139              :     } else {
    1140            0 :         struct sockaddr_in6 clientAddr = {0};
    1141            0 :         clientAddr.sin6_family = conn->clientIp.family;
    1142            0 :         clientAddr.sin6_addr = conn->clientIp.binAddr.addr6;
    1143            0 :         clientAddr.sin6_scope_id = (uint32_t)conn->scopeId;
    1144              : 
    1145            0 :         hccp_dbg("socket bind: family %d, port %d, scopeId %d",
    1146              :             clientAddr.sin6_family, clientAddr.sin6_port, clientAddr.sin6_scope_id);
    1147            0 :         for (unsigned long i = 0; i < sizeof(struct in6_addr); i++) {
    1148            0 :             hccp_dbg("socket bind: addr[%lu] 0x%02x", i, clientAddr.sin6_addr.s6_addr[i]);
    1149              :         }
    1150              : 
    1151            0 :         ret = bind(fd, &clientAddr, sizeof(clientAddr));
    1152              :     }
    1153           16 :     if (ret) {
    1154            0 :         errNo = errno;
    1155            0 :         hccp_err("client bind failed! IP:%s, sock:%d, ret:%d, error:%d", conn->clientIp.readAddr, fd, ret, errNo);
    1156            0 :         return -errNo;
    1157              :     }
    1158           16 :     union RsSocketaddr clientAddr = { 0 };
    1159           16 :     socklen_t clientAddrLen =
    1160           16 :         (conn->clientIp.family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
    1161           16 :     getsockname(fd, (struct sockaddr *)&clientAddr, &clientAddrLen);
    1162           32 :     uint16_t clientPort =
    1163           16 :         (conn->clientIp.family == AF_INET) ? ntohs(clientAddr.sAddr.sin_port) : ntohs(clientAddr.sAddr6.sin6_port);
    1164           16 :     if ((clientPort < 60000) || (clientPort > 60015)) { // HCCL默认监听60000-60015端口,如client使用该端口,记录EVENT日志
    1165           16 :         hccp_info("client bind success. client family %d addr %s:%u, fd:%d", conn->clientIp.family,
    1166              :             conn->clientIp.readAddr, clientPort, fd);
    1167              :     } else {
    1168            0 :         hccp_run_info("client bind success. client family %d addr %s:%u, fd:%d", conn->clientIp.family,
    1169              :             conn->clientIp.readAddr, clientPort, fd);
    1170              :     }
    1171           16 :     return 0;
    1172              : }
    1173              : 
    1174           16 : STATIC int RsSocketBindClient(unsigned int chipId, int connFd, struct RsConnInfo *conn, int hccpMode)
    1175              : {
    1176           16 :     bool bindIp = true;
    1177              : 
    1178           16 :     if (conn->clientIp.family == AF_INET && hccpMode == NETWORK_OFFLINE) {
    1179              :         // compare client_ip with current vnic_ip for compatibility issues, 910A & 910B no need to bind vnic ip
    1180           15 :         bindIp = RsSocketIsVnicIp(chipId, conn->clientIp.binAddr.addr.s_addr) ? false : true;
    1181              :     }
    1182              : 
    1183              :     // chip force to bind: 310P & 910_93
    1184           16 :     if (!bindIp) {
    1185            0 :         RsSocketGetBindByChip(chipId, &bindIp);
    1186              :     }
    1187              : 
    1188              :     // no need to bind ip
    1189           16 :     if (!bindIp) {
    1190            0 :         return 0;
    1191              :     }
    1192              : 
    1193           16 :     return RsConnectBindClient(connFd, conn);
    1194              : }
    1195              : 
    1196           16 : STATIC int RsSocketStateReset(unsigned int chipId, struct RsConnInfo *conn, uint32_t sslEnable, struct rs_cb *rscb)
    1197              : {
    1198              : #define RS_SOCKET_CONNECT_TIMEOUT_USECS 100000
    1199              :     int connFd, retClose, hccpMode;
    1200           16 :     int tcpNodelayFlag = 1;
    1201           16 :     int ret = 0;
    1202              : 
    1203           16 :     hccpMode = RsGetHccpMode(chipId);
    1204              : 
    1205           16 :     connFd = socket(conn->clientIp.family, SOCK_STREAM, 0);
    1206           16 :     if (connFd < 0) {
    1207            0 :         ret = -errno;
    1208            0 :         hccp_err("[client]create socket failed, errno:%d", ret);
    1209            0 :         goto err_socket_create;
    1210              :     }
    1211              : 
    1212           16 :     ret = RsSocketBindClient(chipId, connFd, conn, hccpMode);
    1213           16 :     if (ret != 0) {
    1214            0 :         hccp_err("[client]rs_socket_bind_client failed, ret:%d", ret);
    1215            0 :         goto err_connect_reset;
    1216              :     }
    1217              : 
    1218           16 :     if (sslEnable == RS_SSL_ENABLE) {
    1219            0 :         ret = RsSetFdNonblock(connFd);
    1220            0 :         if (ret) {
    1221            0 :             goto err_connect_reset;
    1222              :         }
    1223              :     }
    1224              : 
    1225              :     /* set tcp socket tos RS_TCP_DSCP_0 */
    1226           16 :     int tosLocal = (RS_TCP_DSCP_0 & RS_DSCP_MASK) << RS_DSCP_OFF;
    1227           16 :     ret = setsockopt(connFd, IPPROTO_IP, IP_TOS, (void *)&tosLocal, sizeof(tosLocal));
    1228           16 :     if (ret) {
    1229            0 :         hccp_err("[client]setsockopt(IP_TOS) failed, connFd:%d, ret:%d, errno:%d", connFd, ret, errno);
    1230            0 :         goto err_socket_option;
    1231              :     }
    1232              : 
    1233           16 :     ret = setsockopt(connFd, IPPROTO_TCP, TCP_NODELAY, (void *)&tcpNodelayFlag, sizeof(int));
    1234           16 :     if (ret < 0) {
    1235            0 :         hccp_err("[client]setsockopt(TCP_NODELAY) failed, connFd:%d, ret:%d, errno:%d", connFd, ret, errno);
    1236            0 :         goto err_socket_option;
    1237              :     }
    1238              : 
    1239              :     // should set tcp socket send/recv timeout when ssl is disabled
    1240           16 :     if (sslEnable == RS_SSL_DISABLE) {
    1241           16 :         ret = RsSocketSetFdTimeoutUsec(connFd, RS_SOCKET_CONNECT_TIMEOUT_USECS);
    1242           16 :         if (ret != 0) {
    1243            0 :             goto err_connect_reset;
    1244              :         }
    1245              :     }
    1246              : 
    1247           16 :     conn->connfd = connFd;
    1248           16 :     conn->state = RS_CONN_STATE_INIT;
    1249              :     /*
    1250              :      * ssl will connect again and again, HCCL get socke timeout after period time,
    1251              :      * so there is no log info to prevent over log
    1252              :      */
    1253           16 :     ret = RsSocketStateInit(chipId, conn, sslEnable, rscb);
    1254           16 :     if (ret) {
    1255            0 :         return ret;
    1256              :     }
    1257              : 
    1258           16 :     return 0;
    1259              : 
    1260            0 : err_socket_option:
    1261            0 :     ret = -errno;
    1262            0 : err_connect_reset:
    1263            0 :     RS_CLOSE_RETRY_FOR_EINTR(retClose, connFd);
    1264            0 : err_socket_create:
    1265            0 :     RsSocketSaveErrInfo(RS_CONN_STATE_RESET, ret, &conn->errInfo);
    1266            0 :     return -ESYSFUNC;
    1267              : }
    1268              : 
    1269           21 : int RsSocketConnectAsync(struct RsConnInfo *conn, struct rs_cb *rscb)
    1270              : {
    1271           21 :     uint32_t sslEnable = rscb->sslEnable;
    1272           21 :     unsigned int chipId = rscb->chipId;
    1273           21 :     int ret = 0;
    1274              : 
    1275           21 :     RS_CHECK_POINTER_NULL_WITH_RET(conn);
    1276           21 :     switch (conn->state) {
    1277           16 :         case RS_CONN_STATE_RESET:
    1278              :             /* create socket for client */
    1279           16 :             ret = RsSocketStateReset(chipId, conn, sslEnable, rscb);
    1280           16 :             break;
    1281              : 
    1282            0 :         case RS_CONN_STATE_INIT:
    1283            0 :             ret = RsSocketStateInit(chipId, conn, sslEnable, rscb);
    1284            0 :             break;
    1285              : 
    1286            0 :         case RS_CONN_STATE_CONNECTED:
    1287            0 :             ret = RsSocketStateConnected(conn, sslEnable, rscb);
    1288            0 :             break;
    1289              : 
    1290            0 :         case RS_CONN_STATE_SSL_BIND_FD:
    1291            0 :             ret = RsSocketStateSslFdBind(conn, sslEnable, rscb);
    1292            0 :             break;
    1293              : 
    1294            0 :         case RS_CONN_STATE_SSL_CONNECTED:
    1295            0 :             hccp_info("[client]IP(%s) connect port %d, fd:%d OK!", conn->serverIp.readAddr, conn->port, conn->connfd);
    1296            0 :             RsSocketTagSync(conn);
    1297            0 :             break;
    1298              : 
    1299            4 :         case RS_CONN_STATE_TAG_SYNC:
    1300            4 :             if (gRsCb->connCb.wlistEnable == 1) {
    1301            0 :                 RsSocketClientValidSync(conn);
    1302              :             }
    1303            4 :             break;
    1304              : 
    1305            0 :         case RS_CONN_STATE_TIMEOUT:
    1306            0 :             hccp_info("[client]!send tag again! local_ip:%s server_ip:%s server_port:%u, tag:%s, fd:%d!",
    1307              :                 conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag, conn->connfd);
    1308            0 :             RsSocketTagSync(conn);
    1309            0 :             break;
    1310              : 
    1311            0 :         case RS_CONN_STATE_VALID_SYNC:
    1312            0 :             break;
    1313              : 
    1314            1 :         case RS_CONN_STATE_TX_TO_HCCL:
    1315            1 :             break;
    1316              : 
    1317            0 :         case RS_CONN_STATE_ERR:
    1318            0 :             break;
    1319              : 
    1320            0 :         default:
    1321            0 :             hccp_err("[client]Unknown state:%u, localIp:%s serverIp:%s serverPort:%u, tag:%s, fd:%d", conn->state,
    1322              :                 conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag, conn->connfd);
    1323            0 :             return -EINVAL;
    1324              :     }
    1325              : 
    1326           21 :     return ret;
    1327              : }
    1328              : 
    1329              : // 获取socket connect状态;返回值 0:connect中,1:connect完成
    1330           21 : int RsGetSocketConnectState(struct RsConnInfo *conn)
    1331              : {
    1332           21 :     if ((conn->state == RS_CONN_STATE_TX_TO_HCCL) ||
    1333           20 :         ((gRsCb->connCb.wlistEnable == 1) && (conn->state == RS_CONN_STATE_VALID_SYNC)) ||
    1334           20 :         ((gRsCb->connCb.wlistEnable == 0) && (conn->state == RS_CONN_STATE_TAG_SYNC))) {
    1335           21 :         return 1;
    1336              :     } else {
    1337            0 :         return 0;
    1338              :     }
    1339              : }
    1340              : 
    1341           15 : STATIC void RsSocketsIpAddrConverter(struct SocketConnectInfo conn[], int num)
    1342              : {
    1343              :     int j;
    1344              : 
    1345           31 :     for (j = 0; j < num; j++) {
    1346           16 :         if (conn[j].family == AF_INET) {
    1347           16 :             conn[j].localIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].localIp.addr.s_addr);
    1348           16 :             conn[j].remoteIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].remoteIp.addr.s_addr);
    1349              :         }
    1350              :     }
    1351           15 : }
    1352              : 
    1353            1 : static void RsSocketHandleConnNodeErr(uint32_t i, struct RsConnCb *connCb,
    1354              :     struct SocketConnectInfo conn[], uint32_t serverPort)
    1355              : {
    1356            1 :     struct RsConnInfo *connInfo = NULL;
    1357              :     uint32_t j;
    1358              :     int ret;
    1359              : 
    1360            1 :     for (j = 0; j < i; j++) {
    1361            0 :         ret = RsGetConnInfo(connCb, conn + j, &connInfo, serverPort);
    1362            0 :         if (ret) {
    1363            0 :             hccp_dbg("not find conn node, ret %d", ret);
    1364              :         } else {
    1365            0 :             RS_PTHREAD_MUTEX_LOCK(&connCb->rscb->mutex);
    1366            0 :             RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    1367            0 :             RsListDel(&connInfo->list);
    1368            0 :             free(connInfo);
    1369            0 :             connInfo = NULL;
    1370            0 :             RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    1371            0 :             RS_PTHREAD_MUTEX_ULOCK(&connCb->rscb->mutex);
    1372              :         }
    1373              :     }
    1374              : 
    1375            1 :     return;
    1376              : }
    1377              : 
    1378           17 : STATIC int RsSocketConnectCheckPara(struct SocketConnectInfo *connInfo)
    1379              : {
    1380           17 :     if (((connInfo->family != AF_INET) && (connInfo->family != AF_INET6)) || connInfo->phyId >= RS_MAX_DEV_NUM ||
    1381           17 :         strlen(connInfo->tag) >= SOCK_CONN_TAG_SIZE) {
    1382            0 :         hccp_err("family[%d] invalid, or phyId[%u] invalid, or conn tag len:%u more than max len:%d",
    1383              :             connInfo->family, connInfo->phyId, strlen(connInfo->tag), SOCK_CONN_TAG_SIZE);
    1384            0 :         return -EINVAL;
    1385              :     }
    1386              : 
    1387           17 :     return 0;
    1388              : }
    1389              : 
    1390           17 : STATIC int rs_socket_IP_convert(struct SocketConnectInfo *connInfo, struct RsIpAddrInfo *remoteIp,
    1391              :     struct RsIpAddrInfo *localIp)
    1392              : {
    1393           17 :     int retVal = 0;
    1394           17 :     int ret = 0;
    1395              : 
    1396           17 :     if (connInfo->family == AF_INET) {
    1397           16 :         uint32_t *remoteIpTmp = &(connInfo->remoteIp.addr.s_addr);
    1398           16 :         uint32_t *localIpTmp = &(connInfo->localIp.addr.s_addr);
    1399           16 :         retVal = RsSocketNodeid2vnic(*remoteIpTmp, remoteIpTmp);
    1400           16 :         ret = RsSocketNodeid2vnic(*localIpTmp, localIpTmp);
    1401           16 :         hccp_info("local IP[0x%llx], ret:%d, remote IP[0x%llx], ret:%d", *localIpTmp, ret, *remoteIpTmp, retVal);
    1402              :     }
    1403              : 
    1404           17 :     ret = RsConvertIpAddr(connInfo->family, &connInfo->remoteIp, remoteIp);
    1405           17 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) remote ip failed, ret:%d", ret), ret);
    1406              : 
    1407           17 :     ret = RsConvertIpAddr(connInfo->family, &connInfo->localIp, localIp);
    1408           17 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) local ip failed, ret:%d", ret), ret);
    1409              : 
    1410           17 :     hccp_info("local IP[%s], ret:%d, remote IP[%s], ret:%d", localIp->readAddr, ret, remoteIp->readAddr, retVal);
    1411           17 :     return 0;
    1412              : }
    1413              : 
    1414              : RS_ATTRI_VISI_DEF int RsSocketBatchConnect(struct SocketConnectInfo conn[], uint32_t num)
    1415              : {
    1416           16 :     struct RsConnInfo *connInfo = NULL;
    1417           16 :     struct RsConnCb *connCb = NULL;
    1418              :     unsigned int chipId, serverPort;
    1419              :     struct RsIpAddrInfo remoteIp;
    1420              :     struct RsIpAddrInfo localIp;
    1421              :     unsigned int i;
    1422              :     int ret;
    1423              : 
    1424           16 :     RS_SOCKET_PARA_CHECK(num, conn);
    1425           32 :     for (i = 0; i < num; i++) {
    1426           17 :         serverPort = conn[i].port;
    1427           17 :         ret = RsSocketConnectCheckPara(&conn[i]);
    1428           17 :         if (ret) {
    1429            0 :             hccp_err("rs_socket_connect_check_para for failed, ret:%d, i:%u", ret, i);
    1430            0 :             goto conn_node_err_handle;
    1431              :         }
    1432              : 
    1433           17 :         ret = rs_socket_IP_convert(&conn[i], &remoteIp, &localIp);
    1434           17 :         if (ret) {
    1435            0 :             hccp_err("convert ip invalid, ret %d", ret);
    1436            0 :             goto conn_node_err_handle;
    1437              :         }
    1438           17 :         ret = rsGetLocalDevIDByHostDevID(conn[i].phyId, &chipId);
    1439           17 :         if (ret) {
    1440            0 :             hccp_err("phyId invalid, ret %d", ret);
    1441            0 :             goto conn_node_err_handle;
    1442              :         }
    1443              : 
    1444           17 :         ret = RsDev2conncb(chipId, &connCb);
    1445           17 :         if (ret) {
    1446            0 :             hccp_err("get conncb from dev failed(%d)!", ret);
    1447            0 :             goto conn_node_err_handle;
    1448              :         }
    1449              : 
    1450           17 :         if (conn[i].family == AF_INET6) {
    1451            1 :             connCb->scopeId = RsGetIpv6ScopeId(conn[i].localIp.addr6);
    1452            1 :             if (connCb->scopeId < 0) {
    1453            1 :                 hccp_err("scope_id[%d] is invalid", connCb->scopeId);
    1454            1 :                 connCb->scopeId = 0;
    1455            1 :                 goto conn_node_err_handle;
    1456              :             }
    1457              :         }
    1458              : 
    1459           16 :         ret = RsGetConnInfo(connCb, conn + i, &connInfo, serverPort);
    1460           16 :         if (ret) {
    1461           16 :             ret = RsAllocClientConnNode(connCb, RS_CONN_ROLE_CLIENT, &connInfo, &conn[i], &localIp, &remoteIp,
    1462              :                 serverPort);
    1463           16 :             if (ret) {
    1464            0 :                 hccp_err("rs_alloc_client_conn_node failed, ret:%d, role:%d, localIp:%s, remoteIp:%s, serverPort:%u,"
    1465              :                     " tag:%s", ret, RS_CONN_ROLE_CLIENT, localIp.readAddr, remoteIp.readAddr, serverPort,
    1466              :                     conn[i].tag);
    1467            0 :                 goto conn_node_err_handle;
    1468              :             }
    1469              : 
    1470           16 :             hccp_info("create conn node for {remote_ip(%s), serverPort(%u), tag(%s)}!",
    1471              :                 remoteIp.readAddr, serverPort, connInfo->tag);
    1472              :         } else {
    1473            0 :             hccp_info("conn node for {remote_ip(%s), serverPort(%u), tag(%s)} exist! state:%u",
    1474              :                 remoteIp.readAddr, serverPort, connInfo->tag, connInfo->state);
    1475              :         }
    1476              :     }
    1477           15 :     sem_post(&gRsCb->connectTrigSem);
    1478           15 :     RsSocketsIpAddrConverter(conn, num);
    1479           15 :     return 0;
    1480              : 
    1481            1 : conn_node_err_handle:
    1482            1 :     RsSocketHandleConnNodeErr(i, connCb, conn, serverPort);
    1483            1 :     return ret;
    1484              : }
    1485              : 
    1486           30 : STATIC int RsSocketCloseFd(int fd)
    1487              : {
    1488           30 :     int errNo = -1;
    1489              :     int ret;
    1490              : 
    1491              :     do {
    1492           30 :         ret = close(fd);
    1493           30 :         if (ret < 0) {
    1494            0 :             errNo = errno;
    1495            0 :             CHK_PRT_RETURN(errNo != EINTR, hccp_err("close fd[%d] failed, ret:%d, errNo[%d]",
    1496              :                 fd, ret, errNo), -errNo);
    1497              :         }
    1498           30 :     } while ((ret < 0) && (errNo == EINTR));
    1499              : 
    1500           30 :     return 0;
    1501              : }
    1502              : 
    1503              : RS_ATTRI_VISI_DEF int RsSocketBatchClose(int disuseLinger, struct RsSocketCloseInfoT conn[], uint32_t num)
    1504              : {
    1505           34 :     struct RsConnInfo *connInfo = NULL;
    1506              :     struct linger soLinger;
    1507           34 :     int fd = RS_FD_INVALID;
    1508           34 :     int retVal = 0;
    1509              :     unsigned int i;
    1510              :     int ret;
    1511              : 
    1512           34 :     RS_SOCKET_PARA_CHECK(num, conn);
    1513              : 
    1514           62 :     for (i = 0; i < num; i++) {
    1515           32 :         fd = conn[i].fd;
    1516           32 :         CHK_PRT_RETURN(fd < 0, hccp_err("param error ! fd:%d, i:%d, num:%d", fd, i, num), -EINVAL);
    1517              : 
    1518              :         // strict mutex lock before find to make sure conn_info is valid on concurrent scenario
    1519           31 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1520           31 :         ret = RsFd2conn(fd, &connInfo);
    1521           31 :         if (ret != 0) {
    1522            1 :             hccp_err("get conn failed! ret:%d", ret);
    1523            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1524            1 :             return ret;
    1525              :         }
    1526              : 
    1527           30 :         hccp_info("conn node of IP(%s) fd:%d, state:%d",
    1528              :             connInfo->serverIp.readAddr, connInfo->connfd, connInfo->state);
    1529              : 
    1530           30 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->connCb.connMutex);
    1531           30 :         RsListDel(&connInfo->list);
    1532           30 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->connCb.connMutex);
    1533           30 :         if (gRsCb->sslEnable == RS_SSL_ENABLE) {
    1534            0 :             ssl_adp_shutdown(connInfo->ssl);
    1535            0 :             ssl_adp_free(connInfo->ssl);
    1536            0 :             connInfo->ssl = NULL;
    1537              :         }
    1538           30 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1539              : 
    1540           30 :         if (connInfo->state > RS_CONN_STATE_RESET) {
    1541           30 :             soLinger.l_onoff = 1;
    1542           30 :             soLinger.l_linger = disuseLinger == 0 ? RS_CLOSE_TIMEOUT : 0;
    1543           30 :             ret = setsockopt(connInfo->connfd, SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger));
    1544           30 :             if (ret) {
    1545            0 :                 hccp_err("setsockopt l_onoff:%d l_linger:%d failed err:%d", soLinger.l_onoff, soLinger.l_linger,
    1546              :                     errno);
    1547            0 :                 retVal = ret;
    1548              :             }
    1549              : 
    1550           30 :             ret = RsSocketCloseFd(connInfo->connfd);
    1551           30 :             if (ret) {
    1552            0 :                 hccp_err("rs_socket_close_fd for fd[%d] failed, ret[%d]", connInfo->connfd, ret);
    1553            0 :                 retVal = ret;
    1554              :             }
    1555              :         }
    1556              : 
    1557           30 :         free(connInfo);
    1558           30 :         connInfo = NULL;
    1559              :     }
    1560              : 
    1561           30 :     return retVal;
    1562              : }
    1563              : 
    1564              : RS_ATTRI_VISI_DEF int RsSocketBatchAbort(struct SocketConnectInfo conn[], uint32_t num)
    1565              : {
    1566            2 :     struct RsConnInfo *connInfo = NULL;
    1567            2 :     struct linger soLinger = { 0 };
    1568            2 :     int retVal = 0;
    1569              :     unsigned int i;
    1570              :     int ret;
    1571              : 
    1572            2 :     RS_SOCKET_PARA_CHECK(num, conn);
    1573              : 
    1574            3 :     for (i = 0; i < num; i++) {
    1575              :         // strict mutex lock before find to make sure conn_info is valid on concurrent scenario
    1576            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1577            2 :         ret = RsGetConnInfo(&gRsCb->connCb, &conn[i], &connInfo, conn[i].port);
    1578            2 :         if (ret != 0) {
    1579            1 :             hccp_err("rs_get_conn_info conn:%u failed! ret:%d", i, ret);
    1580            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1581            1 :             return ret;
    1582              :         }
    1583              : 
    1584            1 :         hccp_info("abort conn node of IP(%s) fd:%d, state:%d", connInfo->serverIp.readAddr, connInfo->connfd,
    1585              :             connInfo->state);
    1586              : 
    1587            1 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->connCb.connMutex);
    1588            1 :         RsListDel(&connInfo->list);
    1589            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->connCb.connMutex);
    1590            1 :         if (gRsCb->sslEnable == RS_SSL_ENABLE && connInfo->ssl != NULL) {
    1591            0 :             ssl_adp_shutdown(connInfo->ssl);
    1592            0 :             ssl_adp_free(connInfo->ssl);
    1593            0 :             connInfo->ssl = NULL;
    1594            0 :             ssl_adp_clear_error();
    1595              :         }
    1596            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1597              : 
    1598            1 :         if (connInfo->state > RS_CONN_STATE_RESET && connInfo->connfd != RS_FD_INVALID) {
    1599              :             // force to close fd
    1600            1 :             soLinger.l_onoff = 1;
    1601            1 :             ret = setsockopt(connInfo->connfd, SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger));
    1602            1 :             if (ret) {
    1603            1 :                 hccp_err("setsockopt l_onoff:%d l_linger:%d failed err:%d", soLinger.l_onoff, soLinger.l_linger,
    1604              :                     errno);
    1605            1 :                 retVal = ret;
    1606              :             }
    1607              : 
    1608            1 :             ret = RsSocketCloseFd(connInfo->connfd);
    1609            1 :             if (ret) {
    1610            1 :                 hccp_err("rs_socket_close_fd for fd[%d] failed, ret[%d]", connInfo->connfd, ret);
    1611            1 :                 retVal = ret;
    1612              :             }
    1613              :         }
    1614              : 
    1615            1 :         free(connInfo);
    1616            1 :         connInfo = NULL;
    1617              :     }
    1618              : 
    1619            1 :     return retVal;
    1620              : }
    1621              : 
    1622           30 : STATIC void RsSocketsBackfill(struct SocketFdData conn[], int sockNum,
    1623              :     struct RsConnInfo *connTmp, struct RsVnicInfo vnicInfo)
    1624              : {
    1625           30 :     conn[sockNum].fd = connTmp->connfd;
    1626              : 
    1627           30 :     if (vnicInfo.role == RS_CONN_ROLE_SERVER) {
    1628           14 :         conn[sockNum].remoteIp = connTmp->clientIp.binAddr;
    1629              :     } else {
    1630           16 :         conn[sockNum].remoteIp = connTmp->serverIp.binAddr;
    1631              :     }
    1632              : 
    1633           30 :     conn[sockNum].status = RS_SOCK_STATUS_OK;
    1634           30 :     connTmp->state = RS_CONN_STATE_TX_TO_HCCL;
    1635           30 :     connTmp->isGot = true;
    1636           30 : }
    1637              : 
    1638           30 : STATIC void RsSocketsServeripConverter(struct SocketFdData conn[], int num,
    1639              :     uint32_t vnicFlag)
    1640              : {
    1641              :     int j;
    1642              : 
    1643           30 :     if (vnicFlag) {
    1644            0 :         for (j = 0; j < num; j++) {
    1645            0 :             if (conn[j].family == AF_INET) {
    1646            0 :                 conn[j].localIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].localIp.addr.s_addr);
    1647            0 :                 conn[j].remoteIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].remoteIp.addr.s_addr);
    1648              :             }
    1649              :         }
    1650              :     }
    1651           30 : }
    1652              : 
    1653           30 : STATIC int RsFindSockets(struct RsConnInfo *connTmp, struct SocketFdData conn[], int num,
    1654              :     int role)
    1655              : {
    1656              :     int ret, i;
    1657              : 
    1658              :     /* normal process, no record log */
    1659           30 :     if (gRsCb->connCb.wlistEnable == 1) {
    1660            0 :         if (connTmp->state != RS_CONN_STATE_VALID_SYNC) {
    1661            0 :             return -EINVAL;
    1662              :         }
    1663              :     } else {
    1664           30 :         if (connTmp->state != RS_CONN_STATE_TAG_SYNC) {
    1665            0 :             return -EINVAL;
    1666              :         }
    1667              :     }
    1668              : 
    1669              :     // server skip to get current socket once socket already been got
    1670           30 :     if (role == RS_CONN_ROLE_SERVER && connTmp->isGot) {
    1671            0 :         return -EINVAL;
    1672              :     }
    1673              : 
    1674           30 :     if (role == RS_CONN_ROLE_SERVER) {
    1675           14 :         i = 0;
    1676              :         struct RsIpAddrInfo localIp;
    1677           14 :         ret = RsConvertIpAddr(conn->family, &conn->localIp, &localIp);
    1678           14 :         CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    1679              : 
    1680           14 :         CHK_PRT_RETURN(RsCompareIpAddr(&connTmp->serverIp, &localIp), hccp_warn("server_ip[%s] != local_ip[%s]",
    1681              :             connTmp->serverIp.readAddr, localIp.readAddr), -EINVAL);
    1682              :     } else {
    1683           16 :         for (i = 0; i < num; i++) {
    1684           16 :             if (conn[i].status == RS_SOCK_STATUS_OK) {
    1685            0 :                 continue;
    1686              :             }
    1687              : 
    1688              :             struct RsIpAddrInfo remoteIp;
    1689           16 :             remoteIp.family = (uint32_t)conn[i].family;
    1690           16 :             remoteIp.binAddr = conn[i].remoteIp;
    1691              :             struct RsIpAddrInfo localIp;
    1692           16 :             localIp.family = (uint32_t)conn[i].family;
    1693           16 :             localIp.binAddr = conn[i].localIp;
    1694           16 :             if ((!RsCompareIpAddr(&connTmp->serverIp, &remoteIp)) &&
    1695           16 :                 (!RsCompareIpAddr(&connTmp->clientIp, &localIp))) {
    1696           16 :                 break;
    1697              :             }
    1698              :         }
    1699              :     }
    1700              : 
    1701           30 :     CHK_PRT_RETURN(i == num, hccp_warn("i == num %d, not find serverIp[%s]", num, connTmp->serverIp.readAddr),
    1702              :         -EINVAL);
    1703              : 
    1704           30 :     conn[i].tag[SOCK_CONN_TAG_SIZE - 1] = '\0';
    1705           30 :     ret = strcmp(conn[i].tag, connTmp->tag);
    1706           30 :     CHK_PRT_RETURN(ret, hccp_warn("The %dth conn tag[%s] is different from conn_tmp_tag [%s]",
    1707              :         i, conn[i].tag, connTmp->tag), -EINVAL);
    1708              : 
    1709           30 :     return i;
    1710              : }
    1711              : 
    1712              : /* find it */
    1713           30 : STATIC int RsSocketsCompare(struct RsListHead *listHead, struct SocketFdData conn[],
    1714              :     uint32_t num, struct RsVnicInfo vnicInfo, struct RsConnCb *connCb)
    1715              : {
    1716           30 :     struct RsConnInfo *connTmp = NULL;
    1717           30 :     struct RsConnInfo *connTmp2 = NULL;
    1718           30 :     int sockNum = 0;
    1719              :     int i;
    1720              :     int sockIndex;
    1721              : 
    1722           30 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    1723           30 :     connTmp = list_entry((listHead)->next, struct RsConnInfo, list);
    1724           30 :     connTmp2 = list_entry(connTmp->list.next, struct RsConnInfo, list);
    1725           30 :     for (; &connTmp->list != (listHead);) {
    1726           30 :         i = RsFindSockets(connTmp, conn, num, vnicInfo.role);
    1727           30 :         if (i < 0) {
    1728            0 :             goto renew_conn;
    1729              :         }
    1730           30 :         sockIndex = (vnicInfo.role == RS_CONN_ROLE_SERVER) ? sockNum : i;
    1731           30 :         RsSocketsBackfill(conn, sockIndex, connTmp, vnicInfo);
    1732              : 
    1733           30 :         sockNum++;
    1734           30 :         if ((unsigned int)sockNum >= num) {
    1735           30 :             break;
    1736              :         }
    1737            0 : renew_conn:
    1738            0 :         connTmp = connTmp2;
    1739            0 :         connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list);
    1740              :     }
    1741           30 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    1742           30 :     RsSocketsServeripConverter(conn, num, vnicInfo.vnicFlag);
    1743           30 :     return sockNum;
    1744              : }
    1745              : 
    1746           31 : STATIC int RsGetVnicFlag(uint32_t role, uint32_t *localIp, uint32_t *remoteIp)
    1747              : {
    1748           31 :     int vnicFlag = 0;
    1749              : 
    1750           31 :     if (role == RS_CONN_ROLE_SERVER) {
    1751           14 :         if (RsSocketNodeid2vnic(*localIp, localIp) == RS_VNIC_FLAG) {
    1752            0 :             vnicFlag = 1;
    1753              :         }
    1754              :     } else {
    1755           17 :         if ((RsSocketNodeid2vnic(*remoteIp, remoteIp) == RS_VNIC_FLAG) &&
    1756            0 :             (RsSocketNodeid2vnic(*localIp, localIp) == RS_VNIC_FLAG)) {
    1757            0 :             vnicFlag = 1;
    1758              :         }
    1759              :     }
    1760           31 :     return vnicFlag;
    1761              : }
    1762              : 
    1763              : RS_ATTRI_VISI_DEF int RsGetSockets(uint32_t role, struct SocketFdData conn[], uint32_t num)
    1764              : {
    1765           31 :     struct RsListHead *listHead = NULL;
    1766           31 :     struct RsVnicInfo vnicInfo = {0};
    1767           31 :     struct RsConnCb *connCb = NULL;
    1768              :     unsigned int chipId;
    1769              :     uint32_t j;
    1770              :     int ret;
    1771              : 
    1772           31 :     vnicInfo.role = role;
    1773              : 
    1774           31 :     RS_SOCKET_PARA_CHECK(num, conn);
    1775           31 :     CHK_PRT_RETURN(role > RS_CONN_ROLE_CLIENT, hccp_err("para invalid. role[%u]", role), -EINVAL);
    1776              : 
    1777              :     /* set conn status to NA */
    1778           62 :     for (j = 0; j < num; j++) {
    1779           32 :         conn[j].status = 0;
    1780           32 :         CHK_PRT_RETURN(((conn[j].family != AF_INET) && (conn[j].family != AF_INET6)) ||
    1781              :             conn[j].phyId >= RS_MAX_DEV_NUM,
    1782              :             hccp_err("family[%d] invalid, or phyId[%u] invalid, j:%u", conn[j].family, conn[j].phyId, j), -EINVAL);
    1783              : 
    1784           31 :         CHK_PRT_RETURN(strlen(conn[j].tag) >= SOCK_CONN_TAG_SIZE, hccp_err("conn tag len:%u more than max len:%d",
    1785              :             strlen(conn[j].tag), SOCK_CONN_TAG_SIZE), -EINVAL);
    1786              : 
    1787           31 :         if (conn[j].family == AF_INET) {
    1788           31 :             uint32_t *localIp = &(conn[j].localIp.addr.s_addr);
    1789           31 :             uint32_t *remoteIp = &(conn[j].remoteIp.addr.s_addr);
    1790           31 :             vnicInfo.vnicFlag = (uint32_t)RsGetVnicFlag(role, localIp, remoteIp);
    1791              :         }
    1792              :     }
    1793              : 
    1794           30 :     ret = rsGetLocalDevIDByHostDevID(conn->phyId, &chipId);
    1795           30 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    1796              : 
    1797           30 :     ret = RsDev2conncb(chipId, &connCb);
    1798           30 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed! ret(%d)", ret), -ENODEV);
    1799              : 
    1800           30 :     listHead = (role == RS_CONN_ROLE_SERVER) ? (&connCb->serverConnList) : (&connCb->clientConnList);
    1801           30 :     return RsSocketsCompare(listHead, conn, num, vnicInfo, connCb);
    1802              : }
    1803              : 
    1804              : RS_ATTRI_VISI_DEF int RsGetSslEnable(uint32_t *sslEnable)
    1805              : {
    1806            0 :     CHK_PRT_RETURN(gRsCb == NULL, hccp_err("param error, gRsCb is NULL"), -ENODEV);
    1807            0 :     CHK_PRT_RETURN(sslEnable == NULL, hccp_err("param error, sslEnable is NULL"), -EINVAL);
    1808              : 
    1809            0 :     *sslEnable = gRsCb->sslEnable;
    1810            0 :     return 0;
    1811              : }
    1812              : 
    1813              : RS_ATTRI_VISI_DEF int RsSocketSend(int fd, const void *data, uint64_t size)
    1814              : {
    1815              :     int ret;
    1816              : 
    1817           83 :     ret = RsDrvSocketSend(fd, data, size, MSG_DONTWAIT | MSG_NOSIGNAL);
    1818              : 
    1819           83 :     hccp_dbg("send fd:%d, size:%llu, send %dB", fd, size, ret);
    1820           83 :     return ret;
    1821              : }
    1822              : 
    1823              : RS_ATTRI_VISI_DEF int RsHdcSocketSend(int fd, const void *data, uint64_t size)
    1824              : {
    1825              :     static __thread char buf[RS_BUF_SIZE] = {0};
    1826            0 :     const void *sendData = data;
    1827            0 :     uint64_t sendSize = size;
    1828              :     int ret;
    1829              : 
    1830            0 :     if (gRsCb->sslEnable == RS_SSL_ENABLE) {
    1831              :         // reuse buf to fix SSL_write retry issue
    1832            0 :         sendSize = (size > RS_BUF_SIZE) ? RS_BUF_SIZE : size;
    1833            0 :         (void)memcpy_s(buf, sendSize, data, sendSize);
    1834            0 :         sendData = buf;
    1835              :     }
    1836              : 
    1837            0 :     ret = RsDrvSocketSend(fd, sendData, sendSize, MSG_DONTWAIT | MSG_NOSIGNAL);
    1838              : 
    1839            0 :     hccp_dbg("send fd:%d, sendSize:%llu, send %dB", fd, sendSize, ret);
    1840            0 :     return ret;
    1841              : }
    1842              : 
    1843              : RS_ATTRI_VISI_DEF int RsPeerSocketSend(uint32_t sslEnable, int fd, const void *data, uint64_t size)
    1844              : {
    1845            4 :     struct RsConnInfo *conn = NULL;
    1846            4 :     int ret = 0;
    1847              :     int errNo;
    1848              : 
    1849            4 :     CHK_PRT_RETURN(fd < 0 || size == 0 || data == NULL, hccp_err("param error ! fd:%d < 0, size:%llu or data is NULL",
    1850              :         fd, size), -EINVAL);
    1851            2 :     if (sslEnable != RS_SSL_DISABLE) {
    1852            1 :         ret = RsFd2conn(fd, &conn);
    1853            1 :         CHK_PRT_RETURN(ret, hccp_err("fd to conn failed, ret:%d", ret), ret);
    1854            0 :         ret = ssl_adp_write(conn->ssl, data, (int)size);
    1855            0 :         if (ret <= 0) {
    1856            0 :             ret = RsSslWriteInnerCheck(conn, ret, size);
    1857              :         }
    1858              :     } else {
    1859            1 :         ret = (int)send(fd, data, size, MSG_DONTWAIT | MSG_NOSIGNAL);
    1860            1 :         if (ret < 0) {
    1861            1 :             errNo = errno;
    1862            1 :             if (errNo == EAGAIN || errNo == EINTR) {
    1863            0 :                 hccp_dbg("send to fd:%d need retry, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
    1864            0 :                 ret = -EAGAIN;
    1865              :             } else {
    1866            1 :                 hccp_run_info("send to fd:%d not success, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
    1867            1 :                 ret = -EFILEOPER;
    1868              :             }
    1869              :         }
    1870              :     }
    1871              : 
    1872            1 :     return ret;
    1873              : }
    1874              : 
    1875              : RS_ATTRI_VISI_DEF int RsSocketRecv(int fd, void *data, uint64_t size)
    1876              : {
    1877              :     int ret;
    1878              : 
    1879           28 :     ret = RsDrvSocketRecv(fd, data, size, MSG_DONTWAIT);
    1880              : 
    1881           28 :     return ret;
    1882              : }
    1883              : 
    1884              : RS_ATTRI_VISI_DEF int RsPeerSocketRecv(uint32_t sslEnable, int fd, void *data, uint64_t size)
    1885              : {
    1886            4 :     struct RsConnInfo *conn = NULL;
    1887            4 :     int ret = 0;
    1888              :     int errNo;
    1889              : 
    1890            4 :     CHK_PRT_RETURN(fd < 0 || data == NULL || size == 0, hccp_err("param error ! fd:%d < 0 or data is NULL, size:%llu",
    1891              :         fd, size), -EINVAL);
    1892            2 :     if (sslEnable != RS_SSL_DISABLE) {
    1893            1 :         ret = RsFd2conn(fd, &conn);
    1894            1 :         CHK_PRT_RETURN(ret, hccp_warn("can not find conn for fd[%d], ret:%d, the local fd may have been closed ",
    1895              :             fd, ret), ret);
    1896            0 :         ret = ssl_adp_read(conn->ssl, data, (int)size);
    1897            0 :         if (ret <= 0) {
    1898            0 :             ret = RsSslReadInnerCheck(conn, ret, size);
    1899              :         }
    1900              :     } else {
    1901            1 :         ret = (int)recv(fd, data, size, MSG_DONTWAIT);
    1902            1 :         if (ret < 0) {
    1903            1 :             errNo = errno;
    1904              :             // not to print to avoid log flush
    1905            1 :             if (errNo == EAGAIN || errNo == EINTR) {
    1906            0 :                 ret = -EAGAIN;
    1907              :             } else {
    1908            1 :                 hccp_run_info("recv for fd:%d not success, recv size:%llu, ret:%d, errNo:%d", fd, size, ret, errNo);
    1909            1 :                 ret = -EFILEOPER;
    1910              :             }
    1911              :         }
    1912              :     }
    1913              : 
    1914            1 :     return ret;
    1915              : }
    1916              : 
    1917              : RS_ATTRI_VISI_DEF int RsSocketGetClientSocketErrInfo(struct SocketConnectInfo conn[],
    1918              :     struct SocketErrInfo err[], unsigned int num)
    1919              : {
    1920            2 :     struct RsConnInfo *connInfo = NULL;
    1921              :     unsigned int i, serverPort;
    1922              :     int ret;
    1923              : 
    1924            2 :     RS_SOCKET_PARA_CHECK(num, conn);
    1925            2 :     RS_CHECK_POINTER_NULL_WITH_RET(err);
    1926            3 :     for (i = 0; i < num; i++) {
    1927            2 :         serverPort = conn[i].port;
    1928            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1929            2 :         ret = RsGetConnInfo(&gRsCb->connCb, &conn[i], &connInfo, serverPort);
    1930            2 :         if (ret != 0) {
    1931            1 :             hccp_err("rs_get_conn_info failed, i:%u ret:%d", i, ret);
    1932            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1933            1 :             return ret;
    1934              :         }
    1935              : 
    1936            1 :         (void)memcpy_s(&err[i], sizeof(struct SocketErrInfo), &connInfo->errInfo, sizeof(struct SocketErrInfo));
    1937              : 
    1938              :         // clear the singer socket connect err info
    1939            1 :         (void)memset_s(&connInfo->errInfo, sizeof(struct SocketErrInfo), 0, sizeof(struct SocketErrInfo));
    1940            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1941              :     }
    1942              : 
    1943            1 :     return 0;
    1944              : }
    1945              : 
    1946              : RS_ATTRI_VISI_DEF int RsSocketGetServerSocketErrInfo(struct SocketListenInfo conn[],
    1947              :     struct ServerSocketErrInfo err[], unsigned int num)
    1948              : {
    1949            2 :     struct RsListenInfo *listenInfo = NULL;
    1950            2 :     struct RsIpAddrInfo ipInfo = {0};
    1951            2 :     struct RsConnCb *connCb = NULL;
    1952              :     unsigned int i, serverPort;
    1953              :     int ret;
    1954              : 
    1955            2 :     RS_SOCKET_PARA_CHECK(num, conn);
    1956            2 :     RS_CHECK_POINTER_NULL_WITH_RET(err);
    1957            3 :     for (i = 0; i < num; i++) {
    1958            2 :         ret = RsConvertIpAddr(conn[i].family, &conn[i].localIp, &ipInfo);
    1959            2 :         CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, i:%u, ret:%d", i, ret), ret);
    1960              : 
    1961            2 :         serverPort = conn[i].port;
    1962            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1963            2 :         connCb = &gRsCb->connCb;
    1964            2 :         ret = RsFindListenNode(connCb, &ipInfo, serverPort, &listenInfo);
    1965            2 :         if (ret != 0) {
    1966            1 :             hccp_err("rs_find_listen_node failed, i:%u, ip:%s, serverPort:%u, ret:%d",
    1967              :                 i, ipInfo.readAddr, serverPort, ret);
    1968            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1969            1 :             return ret;
    1970              :         }
    1971              : 
    1972            1 :         (void)memcpy_s(&err[i].epollWait, sizeof(struct SocketErrInfo),
    1973            1 :             &connCb->epollErrInfo, sizeof(struct SocketErrInfo));
    1974            1 :         (void)memcpy_s(&err[i].accept, sizeof(struct SocketErrInfo),
    1975            1 :             &listenInfo->errInfo, sizeof(struct SocketErrInfo));
    1976              : 
    1977              :         // clear the single socket listen err info
    1978            1 :         (void)memset_s(&listenInfo->errInfo, sizeof(struct SocketErrInfo), 0, sizeof(struct SocketErrInfo));
    1979            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1980              :     }
    1981              : 
    1982            1 :     return 0;
    1983              : }
    1984              : 
    1985           13 : static void RsSocketGetIpInfo(unsigned int *serverIp, unsigned int *clientIp)
    1986              : {
    1987           13 :     uint32_t serverNodeId = *serverIp;
    1988           13 :     uint32_t clientNodeId = *clientIp;
    1989              :     int ret;
    1990              : 
    1991           13 :     ret = RsSocketNodeid2vnic(serverNodeId, serverIp);
    1992           13 :     hccp_info("white list listen IP 0x%llx, ret_vnic %d", *serverIp, ret);
    1993              : 
    1994           13 :     ret = RsSocketNodeid2vnic(clientNodeId, clientIp);
    1995           13 :     hccp_info("white list client IP 0x%llx, ret_vnic %d", *clientIp, ret);
    1996              : 
    1997           13 :     return;
    1998              : }
    1999              : 
    2000           13 : STATIC int RsSocketWhiteListAlloc(struct RsConnCb *connCb,
    2001              :     struct SocketWlistInfoT *whiteList, struct RsIpAddrInfo *serverIp)
    2002              : {
    2003              :     int ret;
    2004              :     /*lint -e429*/
    2005           13 :     struct RsWhiteListInfo *whiteListNodeTmp = NULL;
    2006           13 :     struct RsWhiteList *whiteListTmp = NULL;
    2007              :     struct SocketWlistInfoT wlist;
    2008              :     struct RsIpAddrInfo clientIp;
    2009           13 :     ret = memcpy_s(&wlist, sizeof(struct SocketWlistInfoT), whiteList, sizeof(struct SocketWlistInfoT));
    2010           13 :     CHK_PRT_RETURN(ret, hccp_err("memcpy socket_wlist_info_t wlist failed, ret[%d]!", ret), -ESAFEFUNC);
    2011              : 
    2012           13 :     if (serverIp->family == AF_INET) {
    2013           13 :         RsSocketGetIpInfo(&serverIp->binAddr.addr.s_addr, &(wlist.remoteIp.addr.s_addr));
    2014           13 :         RsInetNtop(serverIp->family, &serverIp->binAddr, (char *)&serverIp->readAddr,
    2015              :             sizeof(serverIp->readAddr));
    2016              :     }
    2017              : 
    2018           13 :     ret = RsConvertIpAddr(serverIp->family, &wlist.remoteIp, &clientIp);
    2019           13 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2020              : 
    2021           13 :     ret = RsFindWhiteList(connCb, serverIp, &whiteListTmp);
    2022           13 :     if (ret) {
    2023           11 :         whiteListTmp = calloc(1, sizeof(struct RsWhiteList));
    2024           11 :         CHK_PRT_RETURN(whiteListTmp == NULL, hccp_err("alloc mem for rs_white_list failed!"), -ENOMEM);
    2025           11 :         whiteListTmp->serverIp = *serverIp;
    2026           11 :         RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2027           11 :         RS_INIT_LIST_HEAD(&whiteListTmp->whiteList);
    2028           11 :         RsListAddTail(&whiteListTmp->list, &connCb->whiteList);
    2029           11 :         RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2030              :     }
    2031              : 
    2032           13 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2033           13 :     ret = RsFindWhiteListNode(whiteListTmp, &wlist, (int)serverIp->family, &whiteListNodeTmp);
    2034           13 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2035           13 :     if (ret == 0) {
    2036            0 :         whiteListNodeTmp->connLimit += wlist.connLimit;
    2037            0 :         return 0;
    2038              :     }
    2039              : 
    2040           13 :     whiteListNodeTmp = calloc(1, sizeof(struct RsWhiteListInfo));
    2041           13 :     CHK_PRT_RETURN(whiteListNodeTmp == NULL, hccp_err("alloc mem for socket_wlist_info_t failed!"), -ENOMEM);
    2042              : 
    2043           13 :     whiteListNodeTmp->clientIp = clientIp;
    2044           13 :     whiteListNodeTmp->connLimit = wlist.connLimit;
    2045           13 :     ret = memcpy_s(whiteListNodeTmp->tag, SOCK_CONN_TAG_SIZE, wlist.tag, sizeof(wlist.tag));
    2046           13 :     if (ret) {
    2047            0 :         hccp_err("memcpy_s failed, ret[%d]. ", ret);
    2048            0 :         free(whiteListNodeTmp);
    2049            0 :         whiteListNodeTmp = NULL;
    2050            0 :         return -ESAFEFUNC;
    2051              :     }
    2052              : 
    2053           13 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2054           13 :     RsListAddTail(&whiteListNodeTmp->list, &whiteListTmp->whiteList);
    2055           13 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2056           13 :     return 0;
    2057              :     /*lint +e429*/
    2058              : }
    2059              : 
    2060              : RS_ATTRI_VISI_DEF int RsSocketWhiteListSwitch(unsigned int phyId, unsigned int enable)
    2061              : {
    2062            0 :     struct RsConnCb *connCb = NULL;
    2063              :     int ret;
    2064              : 
    2065            0 :     ret = RsDev2conncb(phyId, &connCb);
    2066            0 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed, ret:%d", ret), -1);
    2067            0 :     connCb->wlistEnable = enable;
    2068            0 :     return 0;
    2069              : }
    2070              : 
    2071              : RS_ATTRI_VISI_DEF int RsSocketWhiteListAdd(struct rdev rdevInfo, struct SocketWlistInfoT whiteList[],
    2072              :     unsigned int num)
    2073              : {
    2074           13 :     struct RsConnCb *connCb = &(gRsCb->connCb);
    2075              :     struct RsIpAddrInfo serverIp;
    2076              :     unsigned int i, chipId;
    2077              :     int ret;
    2078              : 
    2079           13 :     ret = RsConvertIpAddr(rdevInfo.family, &rdevInfo.localIp, &serverIp);
    2080           13 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), -EINVAL);
    2081              : 
    2082           13 :     CHK_PRT_RETURN(num <= 0 || whiteList == NULL || num > RS_MAX_WLIST_NUM ||
    2083              :         ((rdevInfo.family != AF_INET) && (rdevInfo.family != AF_INET6)) || rdevInfo.phyId >= RS_MAX_DEV_NUM,
    2084              :         hccp_err("white list add param error, phyId[%u], server ip[%s], num[%u], family[%d]",
    2085              :         rdevInfo.phyId, serverIp.readAddr, num, rdevInfo.family), -EINVAL);
    2086              : 
    2087           13 :     ret = rsGetLocalDevIDByHostDevID(rdevInfo.phyId, &chipId);
    2088           13 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    2089              : 
    2090           26 :     for (i = 0; i < num; ++i) {
    2091           13 :         CHK_PRT_RETURN(strnlen(whiteList[i].tag, SOCK_CONN_TAG_SIZE) >= SOCK_CONN_TAG_SIZE,
    2092              :             hccp_err("white_list tag len:%u more than max len:%d", strlen(whiteList[i].tag), SOCK_CONN_TAG_SIZE),
    2093              :             -EINVAL);
    2094           13 :         ret = RsSocketWhiteListAlloc(connCb, &whiteList[i], &serverIp);
    2095           13 :         if (ret) {
    2096              :             struct RsIpAddrInfo clientIp;
    2097            0 :             ret = RsConvertIpAddr(serverIp.family, &whiteList->remoteIp, &clientIp);
    2098            0 :             CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2099            0 :             hccp_err("add white list node failed, server ip[%s], client ip[%s], tag[%s], ret:%d",
    2100              :                 serverIp.readAddr, clientIp.readAddr, whiteList[i].tag, ret);
    2101              :         }
    2102              :     }
    2103           13 :     return 0;
    2104              : }
    2105              : 
    2106            2 : STATIC int RsSocketWhiteListNodeDestroy(struct RsConnCb *connCb,
    2107              :     struct SocketWlistInfoT *whiteList, struct RsIpAddrInfo *serverIp)
    2108              : {
    2109            2 :     struct RsWhiteListInfo *whiteListNodeTmp = NULL;
    2110            2 :     struct RsWhiteList *whiteListTmp = NULL;
    2111              :     struct SocketWlistInfoT wlist;
    2112              :     struct RsIpAddrInfo clientIp;
    2113              :     int ret;
    2114              : 
    2115            2 :     ret = RsConvertIpAddr((int)serverIp->family, &whiteList->remoteIp, &clientIp);
    2116            2 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2117              : 
    2118            2 :     ret =  memset_s(&wlist, sizeof(struct SocketWlistInfoT), 0, sizeof(struct SocketWlistInfoT));
    2119            2 :     CHK_PRT_RETURN(ret, hccp_err("memset_s socket_wlist_info_t wlist failed, ret:%d", ret), -ESAFEFUNC);
    2120            2 :     ret = memcpy_s(&wlist, sizeof(struct SocketWlistInfoT), whiteList, sizeof(struct SocketWlistInfoT));
    2121            2 :     CHK_PRT_RETURN(ret, hccp_err("memcpy socket_wlist_info_t wlist failed!"), -ESAFEFUNC);
    2122              : 
    2123            2 :     if (serverIp->family == AF_INET) {
    2124            2 :         ret = RsSocketNodeid2vnic(serverIp->binAddr.addr.s_addr, &serverIp->binAddr.addr.s_addr);
    2125            2 :         hccp_info("listen IP 0x%llx, ret_vnic %d", serverIp->binAddr.addr.s_addr, ret);
    2126            2 :         ret = RsSocketNodeid2vnic(wlist.remoteIp.addr.s_addr, &(wlist.remoteIp.addr.s_addr));
    2127            2 :         hccp_info("client IP 0x%llx, ret_vnic %d", wlist.remoteIp.addr.s_addr, ret);
    2128              :     }
    2129              : 
    2130            2 :     ret = RsFindWhiteList(connCb, serverIp, &whiteListTmp);
    2131            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("white list for IP(%s) doesn't exist! state:%d", serverIp->readAddr, ret), ret);
    2132            2 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2133            2 :     ret = RsFindWhiteListNode(whiteListTmp, &wlist, (int)serverIp->family, &whiteListNodeTmp);
    2134            2 :     if (ret == 0) {
    2135            2 :         RsListDel(&whiteListNodeTmp->list);
    2136            2 :         free(whiteListNodeTmp);
    2137            2 :         whiteListNodeTmp = NULL;
    2138            2 :         RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2139            2 :         return 0;
    2140              :     }
    2141            0 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2142            0 :     hccp_info("can not find white list node: client ip[%s], tag[%s], ret:%d", clientIp.readAddr, wlist.tag, ret);
    2143            0 :     return ret;
    2144              : }
    2145              : 
    2146              : RS_ATTRI_VISI_DEF int RsSocketWhiteListDel(struct rdev rdevInfo,
    2147              :     struct SocketWlistInfoT whiteList[], unsigned int num)
    2148              : {
    2149            2 :     struct RsConnCb *connCb = &(gRsCb->connCb);
    2150              :     unsigned int i, chipId;
    2151              :     struct RsIpAddrInfo serverIp;
    2152              :     int ret;
    2153              : 
    2154            2 :     ret = RsConvertIpAddr(rdevInfo.family, &rdevInfo.localIp, &serverIp);
    2155            2 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2156              : 
    2157            2 :     CHK_PRT_RETURN(num <= 0 || whiteList == NULL || num > RS_MAX_WLIST_NUM ||
    2158              :         ((rdevInfo.family != AF_INET) && (rdevInfo.family != AF_INET6)) || rdevInfo.phyId >= RS_MAX_DEV_NUM,
    2159              :         hccp_err("white list del param error, phyId[%u], server ip[%s], num[%u] family[%d]", rdevInfo.phyId,
    2160              :         serverIp.readAddr, num, rdevInfo.family),
    2161              :         -EINVAL);
    2162              : 
    2163            2 :     ret = rsGetLocalDevIDByHostDevID(rdevInfo.phyId, &chipId);
    2164            2 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    2165              : 
    2166            4 :     for (i = 0; i < num; ++i) {
    2167            2 :         CHK_PRT_RETURN(strlen(whiteList[i].tag) >= SOCK_CONN_TAG_SIZE, hccp_err("white_list tag len:%u more than"
    2168              :             "max len:%d", strlen(whiteList[i].tag), SOCK_CONN_TAG_SIZE), -EINVAL);
    2169            2 :         ret = RsSocketWhiteListNodeDestroy(connCb, &whiteList[i], &serverIp);
    2170            2 :         if (ret) {
    2171              :             struct RsIpAddrInfo clientIp;
    2172            0 :             ret = RsConvertIpAddr(serverIp.family, &whiteList->remoteIp, &clientIp);
    2173            0 :             CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2174            0 :             hccp_info("white list node wait to delete, server ip[%s], client ip[%s], tag[%s], ret:%d",
    2175              :                 serverIp.readAddr, clientIp.readAddr, whiteList[i].tag, ret);
    2176              :         }
    2177              :     }
    2178            2 :     return 0;
    2179              : }
    2180              : 
    2181              : // 获取device网卡信息,当前device网卡只支持IPv4
    2182            0 : STATIC int RsFillIfaddrInfos(struct IfaddrInfo ifaddrInfos[], unsigned int *num, unsigned int phyId)
    2183              : {
    2184            0 :     struct ifaddrs *ifaddr = NULL;
    2185            0 :     struct ifaddrs *ifa = NULL;
    2186              :     int family, ret;
    2187            0 :     unsigned int numBak = *num;
    2188            0 :     *num = 0;
    2189              :     enum RsHardwareType type;
    2190              : 
    2191            0 :     type = RsGetDeviceType(phyId);
    2192            0 :     CHK_PRT_RETURN(type == RS_HARDWARE_UNKNOWN, hccp_err("rs_get_device_type failed, type[%d]", type), -EINVAL);
    2193            0 :     ret = getifaddrs(&ifaddr);
    2194            0 :     CHK_PRT_RETURN(ret == -1, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
    2195              :     /* Walk through linked list, maintaining head pointer so we can free list later */
    2196            0 :     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    2197            0 :         if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
    2198            0 :             continue;
    2199              :         }
    2200            0 :         family = ifa->ifa_addr->sa_family;
    2201              :         /* If not an AF_INET/AF_INET6 interface address, continue */
    2202            0 :         if (family != AF_INET) {
    2203            0 :             continue;
    2204              :         }
    2205            0 :         ret = RsCheckDstInterface(phyId, ifa->ifa_name, type, false);
    2206            0 :         if (ret < 0) {
    2207            0 :             hccp_err("rs_check_dst_interface failed, ret[%d]", ret);
    2208            0 :             goto out;
    2209              :         }
    2210            0 :         if (ret) {
    2211            0 :             (*num)++;
    2212            0 :             if ((*num) > numBak) {
    2213            0 :                 hccp_err("num of interfaces found is more than expect, expect[%u], actual[%u]", numBak, *num);
    2214            0 :                 goto out;
    2215              :             }
    2216            0 :             ifaddrInfos[*num - 1].ip.addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
    2217            0 :             ifaddrInfos[*num - 1].mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
    2218              :         }
    2219              :     }
    2220              : 
    2221            0 :     freeifaddrs(ifaddr);
    2222            0 :     ifaddr = NULL;
    2223            0 :     return 0;
    2224            0 : out:
    2225            0 :     freeifaddrs(ifaddr);
    2226            0 :     ifaddr = NULL;
    2227            0 :     return -EAGAIN;
    2228              : }
    2229              : 
    2230              : // 获取device网卡信息,支持IPv4/IPV6
    2231            0 : STATIC int RsFillIfaddrInfosV2(struct InterfaceInfo interfaceInfos[], unsigned int *num, unsigned int phyId,
    2232              :     bool isAll)
    2233              : {
    2234            0 :     struct ifaddrs *ifaddr = NULL;
    2235            0 :     struct ifaddrs *ifa = NULL;
    2236              :     enum RsHardwareType type;
    2237              :     unsigned int numBak;
    2238              :     int family, ret;
    2239              : 
    2240            0 :     numBak = *num;
    2241            0 :     *num = 0;
    2242            0 :     type = RsGetDeviceType(phyId);
    2243            0 :     CHK_PRT_RETURN(type == RS_HARDWARE_UNKNOWN, hccp_err("rs_get_device_type failed, type[%d]", type), -EINVAL);
    2244            0 :     ret = getifaddrs(&ifaddr);
    2245            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
    2246              :     /* Walk through linked list, maintaining head pointer so we can free list later */
    2247            0 :     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    2248            0 :         if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
    2249            0 :             continue;
    2250              :         }
    2251              : 
    2252              :         /* If not an AF_INET/AF_INET6 interface address, continue */
    2253            0 :         family = ifa->ifa_addr->sa_family;
    2254            0 :         if ((family != AF_INET) && (family != AF_INET6)) {
    2255            0 :             continue;
    2256              :         }
    2257              : 
    2258            0 :         ret = RsCheckDstInterface(phyId, ifa->ifa_name, type, isAll);
    2259            0 :         if (ret < 0) {
    2260            0 :             hccp_err("rs_check_dst_interface failed, ret[%d]", ret);
    2261            0 :             ret = -EAGAIN;
    2262            0 :             break;
    2263              :         }
    2264            0 :         if (ret) {
    2265            0 :             (*num)++;
    2266            0 :             if ((*num) > numBak) {
    2267            0 :                 hccp_err("num of interfaces found is more than expect, expect[%u], actual[%u]", numBak, *num);
    2268            0 :                 ret = -EAGAIN;
    2269            0 :                 break;
    2270              :             }
    2271              : 
    2272            0 :             ret = strcpy_s(interfaceInfos[*num - 1].ifname, MAX_INTERFACE_NAME_LEN, ifa->ifa_name);
    2273            0 :             if (ret) {
    2274            0 :                 hccp_err("strcpy interface name failed, ret[%d]", ret);
    2275            0 :                 ret = -EAGAIN;
    2276            0 :                 break;
    2277              :             }
    2278            0 :             interfaceInfos[*num - 1].scopeId = 0;
    2279            0 :             if (family == AF_INET) {
    2280            0 :                 interfaceInfos[*num - 1].ifaddr.ip.addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
    2281            0 :                 interfaceInfos[*num - 1].ifaddr.mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
    2282              :             } else {
    2283            0 :                 interfaceInfos[*num - 1].ifaddr.ip.addr6 = ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
    2284            0 :                 interfaceInfos[*num - 1].scopeId = (int)((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id;
    2285              :             }
    2286            0 :             interfaceInfos[*num - 1].family = family;
    2287              :         }
    2288              :     }
    2289              : 
    2290            0 :     freeifaddrs(ifaddr);
    2291            0 :     ifaddr = NULL;
    2292            0 :     return ret;
    2293              : }
    2294              : 
    2295            3 : STATIC int RsFillIfnum(unsigned int phyId, bool isAll, unsigned int *num, unsigned int isPeer)
    2296              : {
    2297            3 :     struct ifaddrs *ifaddr = NULL;
    2298            3 :     struct ifaddrs *ifa = NULL;
    2299            3 :     enum RsHardwareType type = RS_HARDWARE_UNKNOWN;
    2300              :     int family, ret;
    2301            3 :     *num = 0;
    2302              : 
    2303            3 :     if (isPeer == 0) {
    2304            2 :         type = RsGetDeviceType(phyId);
    2305            2 :         CHK_PRT_RETURN(type == RS_HARDWARE_UNKNOWN, hccp_err("rs_get_device_type failed, type[%d]", type), -EINVAL);
    2306              :     }
    2307            3 :     ret = getifaddrs(&ifaddr);
    2308            3 :     CHK_PRT_RETURN(ret == -1, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
    2309              :     /* Walk through linked list, maintaining head pointer so we can free list later */
    2310            8 :     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    2311            7 :         if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
    2312            4 :             continue;
    2313              :         }
    2314            3 :         family = ifa->ifa_addr->sa_family;
    2315              :         /* If not an AF_INET/AF_INET6 interface address, continue */
    2316            3 :         if ((family != AF_INET) && (family != AF_INET6)) {
    2317            0 :             continue;
    2318              :         }
    2319            3 :         if (isPeer == 0) {
    2320            3 :             ret = RsCheckDstInterface(phyId, ifa->ifa_name, type, isAll);
    2321            3 :             if (ret < 0) {
    2322            1 :                 hccp_err("rs_check_dst_interface failed, ret[%d]", ret);
    2323            1 :                 goto out;
    2324              :             }
    2325            2 :             if (ret) {
    2326            1 :                 (*num)++;
    2327              :             }
    2328              :         } else {
    2329            0 :             (*num)++;
    2330              :         }
    2331              :     }
    2332              : 
    2333            1 :     freeifaddrs(ifaddr);
    2334            1 :     ifaddr = NULL;
    2335            1 :     return 0;
    2336            1 : out:
    2337            1 :     freeifaddrs(ifaddr);
    2338            1 :     ifaddr = NULL;
    2339            1 :     return -EAGAIN;
    2340              : }
    2341              : 
    2342              : RS_ATTRI_VISI_DEF int RsPeerGetIfnum(unsigned int phyId, unsigned int *num)
    2343              : {
    2344              :     int ret;
    2345            1 :     CHK_PRT_RETURN(num == NULL, hccp_err("param error, num is NULL"), -EINVAL);
    2346            1 :     CHK_PRT_RETURN(gRsCb == NULL, hccp_err("param error, gRsCb is NULL"), -EINVAL);
    2347            1 :     ret = RsPeerFillIfnum(phyId, num, gRsCb->ifaddrList);
    2348            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_peer_fill_ifnum failed, ret[%d]", ret), ret);
    2349            1 :     return ret;
    2350              : }
    2351              : 
    2352              : RS_ATTRI_VISI_DEF int RsGetIfnum(unsigned int phyId, bool isAll, unsigned int *num)
    2353              : {
    2354              :     int ret;
    2355            3 :     CHK_PRT_RETURN(num == NULL, hccp_err("rs_get_ifaddrs param error, num is NULL"), -EINVAL);
    2356            2 :     ret = RsFillIfnum(phyId, isAll, num, 0);
    2357            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_fill_ifnum failed, ret[%d]", ret), ret);
    2358            1 :     return ret;
    2359              : }
    2360              : 
    2361              : RS_ATTRI_VISI_DEF int RsPeerGetIfaddrs(struct InterfaceInfo interfaceInfos[], unsigned int *num,
    2362              :     unsigned int phyId)
    2363              : {
    2364              :     int ret;
    2365            1 :     CHK_PRT_RETURN(interfaceInfos == NULL || num == NULL,
    2366              :         hccp_err("param error, interfaceInfos or num is NULL"), -EINVAL);
    2367            1 :     CHK_PRT_RETURN(gRsCb == NULL, hccp_err("param error, gRsCb is NULL"), -EINVAL);
    2368            1 :     ret = RsPeerFillIfaddrInfos(interfaceInfos, num, phyId, gRsCb->ifaddrList);
    2369            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_peer_fill_ifaddr_infos failed, ret[%d]", ret), ret);
    2370            1 :     return ret;
    2371              : }
    2372              : 
    2373              : RS_ATTRI_VISI_DEF int RsGetIfaddrs(struct IfaddrInfo ifaddrInfos[], unsigned int *num, unsigned int phyId)
    2374              : {
    2375              :     int ret;
    2376              : 
    2377            0 :     CHK_PRT_RETURN(ifaddrInfos == NULL || num == NULL, hccp_err("rs_get_ifaddrs param error,"
    2378              :         "ifaddrInfos or num is NULL"), -EINVAL);
    2379              : 
    2380            0 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM || *num > MAX_INTERFACE_NUM, hccp_err("rs_get_ifaddrs param error,"
    2381              :         "phyId[%u], num[%u]", phyId, *num), -EINVAL);
    2382              : 
    2383            0 :     ret = RsFillIfaddrInfos(ifaddrInfos, num, phyId);
    2384            0 :     CHK_PRT_RETURN(ret, hccp_err("rs_fill_ifaddr_infos failed, ret[%d]", ret), ret);
    2385              : 
    2386            0 :     return 0;
    2387              : }
    2388              : 
    2389              : RS_ATTRI_VISI_DEF int RsGetIfaddrsV2(struct InterfaceInfo interfaceInfos[], unsigned int *num,
    2390              :     unsigned int phyId, bool isAll)
    2391              : {
    2392              :     int ret;
    2393              : 
    2394            0 :     CHK_PRT_RETURN(interfaceInfos == NULL || num == NULL, hccp_err("rs_get_ifaddrs_v2 param error,"
    2395              :         "interfaceInfos or num is NULL"), -EINVAL);
    2396              : 
    2397            0 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM || *num > MAX_INTERFACE_NUM, hccp_err("rs_get_ifaddrs_v2 param error,"
    2398              :         "phyId[%u], num[%u]", phyId, *num), -EINVAL);
    2399              : 
    2400            0 :     ret = RsFillIfaddrInfosV2(interfaceInfos, num, phyId, isAll);
    2401            0 :     CHK_PRT_RETURN(ret, hccp_err("rs_fill_ifaddr_infos_v2 failed, ret[%d]", ret), ret);
    2402              : 
    2403            0 :     return 0;
    2404              : }
    2405              : 
    2406              : RS_ATTRI_VISI_DEF int RsSocketSetScopeId(unsigned int devId, int scopeId)
    2407              : {
    2408              :     int ret;
    2409              :     unsigned int chipId;
    2410            1 :     struct RsConnCb *connCb = NULL;
    2411            1 :     ret = rsGetLocalDevIDByHostDevID(devId, &chipId);
    2412            1 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    2413              : 
    2414            1 :     ret = RsDev2conncb(chipId, &connCb);
    2415            1 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed, ret:%d", ret), ret);
    2416              : 
    2417            1 :     connCb->scopeId = scopeId;
    2418            1 :     return 0;
    2419              : }
        

Generated by: LCOV version 2.0-1