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

Generated by: LCOV version 2.0-1