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-18 17:47:01 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              :     (void)chipId;
    1096              :     int ret;
    1097              : 
    1098           16 :     conn->tag[SOCK_CONN_TAG_SIZE + SOCK_CONN_DEV_ID_SIZE - 1] = '\0';
    1099              : 
    1100           16 :     ret = RsDrvConnect(conn->connfd, &conn->serverIp, &conn->clientIp, conn->port);
    1101           16 :     if (ret != 0) {
    1102            0 :         RsSocketSaveErrInfo(RS_CONN_STATE_INIT, ret, &conn->errInfo);
    1103            0 :         hccp_warn("[client]rs_socket_state_init conn unsuccessful! client_ip:%s server_ip:%s server_port:%u tag:%s, "
    1104              :                   "fd:%d, ret:%d",
    1105              :             conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag, conn->connfd, ret);
    1106            0 :         return ret;
    1107              :     }
    1108              : 
    1109              :     // should set back tcp socket send/recv timeout to OS default when ssl is disabled
    1110           16 :     if (sslEnable == RS_SSL_DISABLE) {
    1111           16 :         ret = RsSocketSetFdTimeoutUsec(conn->connfd, 0);
    1112           16 :         if (ret != 0) {
    1113            0 :             hccp_warn("[client]rs_socket_set_fd_timeout_usec conn unsuccessful!, clientIp:%s serverIp:%s "
    1114              :                       "serverPort:%u tag:%s, fd:%d, ret:%d",
    1115              :                 conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag, conn->connfd, ret);
    1116              :         }
    1117              :     }
    1118              : 
    1119           16 :     conn->state = RS_CONN_STATE_CONNECTED;
    1120              :     /*
    1121              :      * ssl will connect again and again, HCCL get socke timeout after period time,
    1122              :      * so there is no log info to prevent over log
    1123              :      */
    1124           16 :     ret = RsSocketStateConnected(conn, sslEnable, rscb);
    1125           16 :     if (ret) {
    1126            0 :         return ret;
    1127              :     }
    1128              : 
    1129           16 :     return 0;
    1130              : }
    1131              : 
    1132           16 : STATIC int RsConnectBindClient(int fd, struct RsConnInfo *conn)
    1133              : {
    1134              :     int errNo;
    1135              :     int ret;
    1136              : 
    1137           16 :     if (conn->clientIp.family == AF_INET) {
    1138           16 :         struct sockaddr_in clientAddr = {0};
    1139           16 :         clientAddr.sin_family = conn->clientIp.family;
    1140           16 :         clientAddr.sin_addr = conn->clientIp.binAddr.addr;
    1141              : 
    1142           16 :         hccp_dbg("socket bind: family %d, port %d, addr 0x%08x", clientAddr.sin_family, clientAddr.sin_port,
    1143              :             clientAddr.sin_addr.s_addr);
    1144           16 :         ret = bind(fd, &clientAddr, sizeof(clientAddr));
    1145              :     } else {
    1146            0 :         struct sockaddr_in6 clientAddr = {0};
    1147            0 :         clientAddr.sin6_family = conn->clientIp.family;
    1148            0 :         clientAddr.sin6_addr = conn->clientIp.binAddr.addr6;
    1149            0 :         clientAddr.sin6_scope_id = (uint32_t)conn->scopeId;
    1150              : 
    1151            0 :         hccp_dbg("socket bind: family %d, port %d, scopeId %d", clientAddr.sin6_family, clientAddr.sin6_port,
    1152              :             clientAddr.sin6_scope_id);
    1153            0 :         for (unsigned long i = 0; i < sizeof(struct in6_addr); i++) {
    1154            0 :             hccp_dbg("socket bind: addr[%lu] 0x%02x", i, clientAddr.sin6_addr.s6_addr[i]);
    1155              :         }
    1156              : 
    1157            0 :         ret = bind(fd, &clientAddr, sizeof(clientAddr));
    1158              :     }
    1159           16 :     if (ret) {
    1160            0 :         errNo = errno;
    1161            0 :         hccp_err("client bind failed! IP:%s, sock:%d, ret:%d, error:%d", conn->clientIp.readAddr, fd, ret, errNo);
    1162            0 :         return -errNo;
    1163              :     }
    1164           16 :     union RsSocketaddr clientAddr = {0};
    1165           16 :     socklen_t clientAddrLen = (conn->clientIp.family == AF_INET) ? sizeof(struct sockaddr_in)
    1166              :                                                                  : sizeof(struct sockaddr_in6);
    1167           16 :     getsockname(fd, (struct sockaddr *)&clientAddr, &clientAddrLen);
    1168           16 :     uint16_t clientPort = (conn->clientIp.family == AF_INET) ? ntohs(clientAddr.sAddr.sin_port)
    1169            0 :                                                              : ntohs(clientAddr.sAddr6.sin6_port);
    1170           16 :     if ((clientPort < 60000) || (clientPort > 60015)) { // HCCL默认监听60000-60015端口,如client使用该端口,记录EVENT日志
    1171           16 :         hccp_info("client bind success. client family %d addr %s:%u, fd:%d", conn->clientIp.family,
    1172              :             conn->clientIp.readAddr, clientPort, fd);
    1173              :     } else {
    1174            0 :         hccp_run_info("client bind success. client family %d addr %s:%u, fd:%d", conn->clientIp.family,
    1175              :             conn->clientIp.readAddr, clientPort, fd);
    1176              :     }
    1177           16 :     return 0;
    1178              : }
    1179              : 
    1180           16 : STATIC int RsSocketBindClient(unsigned int chipId, int connFd, struct RsConnInfo *conn, int hccpMode)
    1181              : {
    1182           16 :     bool bindIp = true;
    1183              : 
    1184           16 :     if (conn->clientIp.family == AF_INET && hccpMode == NETWORK_OFFLINE) {
    1185              :         // compare client_ip with current vnic_ip for compatibility issues, 910A & 910B no need to bind vnic ip
    1186           15 :         bindIp = RsSocketIsVnicIp(chipId, conn->clientIp.binAddr.addr.s_addr) ? false : true;
    1187              :     }
    1188              : 
    1189              :     // chip force to bind: 310P & 910_93
    1190           16 :     if (!bindIp) {
    1191            0 :         RsSocketGetBindByChip(chipId, &bindIp);
    1192              :     }
    1193              : 
    1194              :     // no need to bind ip
    1195           16 :     if (!bindIp) {
    1196            0 :         return 0;
    1197              :     }
    1198              : 
    1199           16 :     return RsConnectBindClient(connFd, conn);
    1200              : }
    1201              : 
    1202           16 : STATIC int RsSocketStateReset(unsigned int chipId, struct RsConnInfo *conn, uint32_t sslEnable, struct rs_cb *rscb)
    1203              : {
    1204              : #define RS_SOCKET_CONNECT_TIMEOUT_USECS 100000
    1205              :     int connFd, retClose, hccpMode;
    1206           16 :     int tcpNodelayFlag = 1;
    1207           16 :     int ret = 0;
    1208              : 
    1209           16 :     hccpMode = RsGetHccpMode(chipId);
    1210              : 
    1211           16 :     connFd = socket(conn->clientIp.family, SOCK_STREAM, 0);
    1212           16 :     if (connFd < 0) {
    1213            0 :         ret = -errno;
    1214            0 :         hccp_err("[client]create socket failed, errno:%d", ret);
    1215            0 :         goto err_socket_create;
    1216              :     }
    1217              : 
    1218           16 :     ret = RsSocketBindClient(chipId, connFd, conn, hccpMode);
    1219           16 :     if (ret != 0) {
    1220            0 :         hccp_err("[client]rs_socket_bind_client failed, ret:%d", ret);
    1221            0 :         goto err_connect_reset;
    1222              :     }
    1223              : 
    1224           16 :     if (sslEnable == RS_SSL_ENABLE) {
    1225            0 :         ret = RsSetFdNonblock(connFd);
    1226            0 :         if (ret) {
    1227            0 :             goto err_connect_reset;
    1228              :         }
    1229              :     }
    1230              : 
    1231              :     /* set tcp socket tos RS_TCP_DSCP_0 */
    1232           16 :     int tosLocal = (RS_TCP_DSCP_0 & RS_DSCP_MASK) << RS_DSCP_OFF;
    1233           16 :     ret = setsockopt(connFd, IPPROTO_IP, IP_TOS, (void *)&tosLocal, sizeof(tosLocal));
    1234           16 :     if (ret) {
    1235            0 :         hccp_err("[client]setsockopt(IP_TOS) failed, connFd:%d, ret:%d, errno:%d", connFd, ret, errno);
    1236            0 :         goto err_socket_option;
    1237              :     }
    1238              : 
    1239           16 :     ret = setsockopt(connFd, IPPROTO_TCP, TCP_NODELAY, (void *)&tcpNodelayFlag, sizeof(int));
    1240           16 :     if (ret < 0) {
    1241            0 :         hccp_err("[client]setsockopt(TCP_NODELAY) failed, connFd:%d, ret:%d, errno:%d", connFd, ret, errno);
    1242            0 :         goto err_socket_option;
    1243              :     }
    1244              : 
    1245              :     // should set tcp socket send/recv timeout when ssl is disabled
    1246           16 :     if (sslEnable == RS_SSL_DISABLE) {
    1247           16 :         ret = RsSocketSetFdTimeoutUsec(connFd, RS_SOCKET_CONNECT_TIMEOUT_USECS);
    1248           16 :         if (ret != 0) {
    1249            0 :             goto err_connect_reset;
    1250              :         }
    1251              :     }
    1252              : 
    1253           16 :     conn->connfd = connFd;
    1254           16 :     conn->state = RS_CONN_STATE_INIT;
    1255              :     /*
    1256              :      * ssl will connect again and again, HCCL get socke timeout after period time,
    1257              :      * so there is no log info to prevent over log
    1258              :      */
    1259           16 :     ret = RsSocketStateInit(chipId, conn, sslEnable, rscb);
    1260           16 :     if (ret) {
    1261            0 :         return ret;
    1262              :     }
    1263              : 
    1264           16 :     return 0;
    1265              : 
    1266            0 : err_socket_option:
    1267            0 :     ret = -errno;
    1268            0 : err_connect_reset:
    1269            0 :     RS_CLOSE_RETRY_FOR_EINTR(retClose, connFd);
    1270            0 : err_socket_create:
    1271            0 :     RsSocketSaveErrInfo(RS_CONN_STATE_RESET, ret, &conn->errInfo);
    1272            0 :     return -ESYSFUNC;
    1273              : }
    1274              : 
    1275           21 : int RsSocketConnectAsync(struct RsConnInfo *conn, struct rs_cb *rscb)
    1276              : {
    1277           21 :     uint32_t sslEnable = rscb->sslEnable;
    1278           21 :     unsigned int chipId = rscb->chipId;
    1279           21 :     int ret = 0;
    1280              : 
    1281           21 :     RS_CHECK_POINTER_NULL_WITH_RET(conn);
    1282           21 :     switch (conn->state) {
    1283           16 :         case RS_CONN_STATE_RESET:
    1284              :             /* create socket for client */
    1285           16 :             ret = RsSocketStateReset(chipId, conn, sslEnable, rscb);
    1286           16 :             break;
    1287              : 
    1288            0 :         case RS_CONN_STATE_INIT:
    1289            0 :             ret = RsSocketStateInit(chipId, conn, sslEnable, rscb);
    1290            0 :             break;
    1291              : 
    1292            0 :         case RS_CONN_STATE_CONNECTED:
    1293            0 :             ret = RsSocketStateConnected(conn, sslEnable, rscb);
    1294            0 :             break;
    1295              : 
    1296            0 :         case RS_CONN_STATE_SSL_BIND_FD:
    1297            0 :             ret = RsSocketStateSslFdBind(conn, sslEnable, rscb);
    1298            0 :             break;
    1299              : 
    1300            0 :         case RS_CONN_STATE_SSL_CONNECTED:
    1301            0 :             hccp_info("[client]IP(%s) connect port %d, fd:%d OK!", conn->serverIp.readAddr, conn->port, conn->connfd);
    1302            0 :             RsSocketTagSync(conn);
    1303            0 :             break;
    1304              : 
    1305            4 :         case RS_CONN_STATE_TAG_SYNC:
    1306            4 :             if (gRsCb->connCb.wlistEnable == 1) {
    1307            0 :                 RsSocketClientValidSync(conn);
    1308              :             }
    1309            4 :             break;
    1310              : 
    1311            0 :         case RS_CONN_STATE_TIMEOUT:
    1312            0 :             hccp_info("[client]!send tag again! local_ip:%s server_ip:%s server_port:%u, tag:%s, fd:%d!",
    1313              :                 conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag, conn->connfd);
    1314            0 :             RsSocketTagSync(conn);
    1315            0 :             break;
    1316              : 
    1317            0 :         case RS_CONN_STATE_VALID_SYNC:
    1318            0 :             break;
    1319              : 
    1320            1 :         case RS_CONN_STATE_TX_TO_HCCL:
    1321            1 :             break;
    1322              : 
    1323            0 :         case RS_CONN_STATE_ERR:
    1324            0 :             break;
    1325              : 
    1326            0 :         default:
    1327            0 :             hccp_err("[client]Unknown state:%u, localIp:%s serverIp:%s serverPort:%u, tag:%s, fd:%d", conn->state,
    1328              :                 conn->clientIp.readAddr, conn->serverIp.readAddr, conn->port, conn->tag, conn->connfd);
    1329            0 :             return -EINVAL;
    1330              :     }
    1331              : 
    1332           21 :     return ret;
    1333              : }
    1334              : 
    1335              : // 获取socket connect状态;返回值 0:connect中,1:connect完成
    1336           21 : int RsGetSocketConnectState(struct RsConnInfo *conn)
    1337              : {
    1338           21 :     if ((conn->state == RS_CONN_STATE_TX_TO_HCCL) ||
    1339           20 :         ((gRsCb->connCb.wlistEnable == 1) && (conn->state == RS_CONN_STATE_VALID_SYNC)) ||
    1340           20 :         ((gRsCb->connCb.wlistEnable == 0) && (conn->state == RS_CONN_STATE_TAG_SYNC))) {
    1341           21 :         return 1;
    1342              :     } else {
    1343            0 :         return 0;
    1344              :     }
    1345              : }
    1346              : 
    1347           15 : STATIC void RsSocketsIpAddrConverter(struct SocketConnectInfo conn[], int num)
    1348              : {
    1349              :     int j;
    1350              : 
    1351           31 :     for (j = 0; j < num; j++) {
    1352           16 :         if (conn[j].family == AF_INET) {
    1353           16 :             conn[j].localIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].localIp.addr.s_addr);
    1354           16 :             conn[j].remoteIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].remoteIp.addr.s_addr);
    1355              :         }
    1356              :     }
    1357           15 : }
    1358              : 
    1359            1 : static void RsSocketHandleConnNodeErr(uint32_t i, struct RsConnCb *connCb, struct SocketConnectInfo conn[],
    1360              :     uint32_t serverPort)
    1361              : {
    1362            1 :     struct RsConnInfo *connInfo = NULL;
    1363              :     uint32_t j;
    1364              :     int ret;
    1365              : 
    1366            1 :     for (j = 0; j < i; j++) {
    1367            0 :         ret = RsGetConnInfo(connCb, conn + j, &connInfo, serverPort);
    1368            0 :         if (ret) {
    1369            0 :             hccp_dbg("not find conn node, ret %d", ret);
    1370              :         } else {
    1371            0 :             RS_PTHREAD_MUTEX_LOCK(&connCb->rscb->mutex);
    1372            0 :             RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    1373            0 :             RsListDel(&connInfo->list);
    1374            0 :             free(connInfo);
    1375            0 :             connInfo = NULL;
    1376            0 :             RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    1377            0 :             RS_PTHREAD_MUTEX_ULOCK(&connCb->rscb->mutex);
    1378              :         }
    1379              :     }
    1380              : 
    1381            1 :     return;
    1382              : }
    1383              : 
    1384           17 : STATIC int RsSocketConnectCheckPara(struct SocketConnectInfo *connInfo)
    1385              : {
    1386           17 :     if (((connInfo->family != AF_INET) && (connInfo->family != AF_INET6)) || connInfo->phyId >= RS_MAX_DEV_NUM ||
    1387           17 :         strlen(connInfo->tag) >= SOCK_CONN_TAG_SIZE) {
    1388            0 :         hccp_err("family[%d] invalid, or phyId[%u] invalid, or conn tag len:%u more than max len:%d", connInfo->family,
    1389              :             connInfo->phyId, strlen(connInfo->tag), SOCK_CONN_TAG_SIZE);
    1390            0 :         return -EINVAL;
    1391              :     }
    1392              : 
    1393           17 :     return 0;
    1394              : }
    1395              : 
    1396           17 : STATIC int rs_socket_IP_convert(struct SocketConnectInfo *connInfo, struct RsIpAddrInfo *remoteIp,
    1397              :     struct RsIpAddrInfo *localIp)
    1398              : {
    1399           17 :     int retVal = 0;
    1400           17 :     int ret = 0;
    1401              : 
    1402           17 :     if (connInfo->family == AF_INET) {
    1403           16 :         uint32_t *remoteIpTmp = &(connInfo->remoteIp.addr.s_addr);
    1404           16 :         uint32_t *localIpTmp = &(connInfo->localIp.addr.s_addr);
    1405           16 :         retVal = RsSocketNodeid2vnic(*remoteIpTmp, remoteIpTmp);
    1406           16 :         ret = RsSocketNodeid2vnic(*localIpTmp, localIpTmp);
    1407           16 :         hccp_info("local IP[0x%llx], ret:%d, remote IP[0x%llx], ret:%d", *localIpTmp, ret, *remoteIpTmp, retVal);
    1408              :     }
    1409              : 
    1410           17 :     ret = RsConvertIpAddr(connInfo->family, &connInfo->remoteIp, remoteIp);
    1411           17 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) remote ip failed, ret:%d", ret), ret);
    1412              : 
    1413           17 :     ret = RsConvertIpAddr(connInfo->family, &connInfo->localIp, localIp);
    1414           17 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) local ip failed, ret:%d", ret), ret);
    1415              : 
    1416           17 :     hccp_info("local IP[%s], ret:%d, remote IP[%s], ret:%d", localIp->readAddr, ret, remoteIp->readAddr, retVal);
    1417           17 :     return 0;
    1418              : }
    1419              : 
    1420              : RS_ATTRI_VISI_DEF int RsSocketBatchConnect(struct SocketConnectInfo conn[], uint32_t num)
    1421              : {
    1422           16 :     struct RsConnInfo *connInfo = NULL;
    1423           16 :     struct RsConnCb *connCb = NULL;
    1424              :     unsigned int chipId, serverPort;
    1425              :     struct RsIpAddrInfo remoteIp;
    1426              :     struct RsIpAddrInfo localIp;
    1427              :     unsigned int i;
    1428              :     int ret;
    1429              : 
    1430           16 :     RS_SOCKET_PARA_CHECK(num, conn);
    1431           32 :     for (i = 0; i < num; i++) {
    1432           17 :         serverPort = conn[i].port;
    1433           17 :         ret = RsSocketConnectCheckPara(&conn[i]);
    1434           17 :         if (ret) {
    1435            0 :             hccp_err("rs_socket_connect_check_para for failed, ret:%d, i:%u", ret, i);
    1436            0 :             goto conn_node_err_handle;
    1437              :         }
    1438              : 
    1439           17 :         ret = rs_socket_IP_convert(&conn[i], &remoteIp, &localIp);
    1440           17 :         if (ret) {
    1441            0 :             hccp_err("convert ip invalid, ret %d", ret);
    1442            0 :             goto conn_node_err_handle;
    1443              :         }
    1444           17 :         ret = rsGetLocalDevIDByHostDevID(conn[i].phyId, &chipId);
    1445           17 :         if (ret) {
    1446            0 :             hccp_err("phyId invalid, ret %d", ret);
    1447            0 :             goto conn_node_err_handle;
    1448              :         }
    1449              : 
    1450           17 :         ret = RsDev2conncb(chipId, &connCb);
    1451           17 :         if (ret) {
    1452            0 :             hccp_err("get conncb from dev failed(%d)!", ret);
    1453            0 :             goto conn_node_err_handle;
    1454              :         }
    1455              : 
    1456           17 :         if (conn[i].family == AF_INET6) {
    1457            1 :             connCb->scopeId = RsGetIpv6ScopeId(conn[i].localIp.addr6);
    1458            1 :             if (connCb->scopeId < 0) {
    1459            1 :                 hccp_err("scope_id[%d] is invalid", connCb->scopeId);
    1460            1 :                 connCb->scopeId = 0;
    1461            1 :                 goto conn_node_err_handle;
    1462              :             }
    1463              :         }
    1464              : 
    1465           16 :         ret = RsGetConnInfo(connCb, conn + i, &connInfo, serverPort);
    1466           16 :         if (ret) {
    1467           16 :             ret = RsAllocClientConnNode(connCb, RS_CONN_ROLE_CLIENT, &connInfo, &conn[i], &localIp, &remoteIp,
    1468              :                 serverPort);
    1469           16 :             if (ret) {
    1470            0 :                 hccp_err("rs_alloc_client_conn_node failed, ret:%d, role:%d, localIp:%s, remoteIp:%s, serverPort:%u,"
    1471              :                          " tag:%s",
    1472              :                     ret, RS_CONN_ROLE_CLIENT, localIp.readAddr, remoteIp.readAddr, serverPort, conn[i].tag);
    1473            0 :                 goto conn_node_err_handle;
    1474              :             }
    1475              : 
    1476           16 :             hccp_info("create conn node for {remote_ip(%s), serverPort(%u), tag(%s)}!", remoteIp.readAddr, serverPort,
    1477              :                 connInfo->tag);
    1478              :         } else {
    1479            0 :             hccp_info("conn node for {remote_ip(%s), serverPort(%u), tag(%s)} exist! state:%u", remoteIp.readAddr,
    1480              :                 serverPort, connInfo->tag, connInfo->state);
    1481              :         }
    1482              :     }
    1483           15 :     sem_post(&gRsCb->connectTrigSem);
    1484           15 :     RsSocketsIpAddrConverter(conn, num);
    1485           15 :     return 0;
    1486              : 
    1487            1 : conn_node_err_handle:
    1488            1 :     RsSocketHandleConnNodeErr(i, connCb, conn, serverPort);
    1489            1 :     return ret;
    1490              : }
    1491              : 
    1492           30 : STATIC int RsSocketCloseFd(int fd)
    1493              : {
    1494           30 :     int errNo = -1;
    1495              :     int ret;
    1496              : 
    1497              :     do {
    1498           30 :         ret = close(fd);
    1499           30 :         if (ret < 0) {
    1500            0 :             errNo = errno;
    1501            0 :             CHK_PRT_RETURN(errNo != EINTR, hccp_err("close fd[%d] failed, ret:%d, errNo[%d]", fd, ret, errNo), -errNo);
    1502              :         }
    1503           30 :     } while ((ret < 0) && (errNo == EINTR));
    1504              : 
    1505           30 :     return 0;
    1506              : }
    1507              : 
    1508              : RS_ATTRI_VISI_DEF int RsSocketBatchClose(int disuseLinger, struct RsSocketCloseInfoT conn[], uint32_t num)
    1509              : {
    1510           34 :     struct RsConnInfo *connInfo = NULL;
    1511              :     struct linger soLinger;
    1512           34 :     int fd = RS_FD_INVALID;
    1513           34 :     int retVal = 0;
    1514              :     unsigned int i;
    1515              :     int ret;
    1516              : 
    1517           34 :     RS_SOCKET_PARA_CHECK(num, conn);
    1518              : 
    1519           62 :     for (i = 0; i < num; i++) {
    1520           32 :         fd = conn[i].fd;
    1521           32 :         CHK_PRT_RETURN(fd < 0, hccp_err("param error ! fd:%d, i:%d, num:%d", fd, i, num), -EINVAL);
    1522              : 
    1523              :         // strict mutex lock before find to make sure conn_info is valid on concurrent scenario
    1524           31 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1525           31 :         ret = RsFd2conn(fd, &connInfo);
    1526           31 :         if (ret != 0) {
    1527            1 :             hccp_err("get conn failed! ret:%d", ret);
    1528            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1529            1 :             return ret;
    1530              :         }
    1531              : 
    1532           30 :         hccp_info("conn node of IP(%s) fd:%d, state:%d", connInfo->serverIp.readAddr, connInfo->connfd,
    1533              :             connInfo->state);
    1534              : 
    1535           30 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->connCb.connMutex);
    1536           30 :         RsListDel(&connInfo->list);
    1537           30 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->connCb.connMutex);
    1538           30 :         if (gRsCb->sslEnable == RS_SSL_ENABLE) {
    1539            0 :             ssl_adp_shutdown(connInfo->ssl);
    1540            0 :             ssl_adp_free(connInfo->ssl);
    1541            0 :             connInfo->ssl = NULL;
    1542              :         }
    1543           30 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1544              : 
    1545           30 :         if (connInfo->state > RS_CONN_STATE_RESET) {
    1546           30 :             soLinger.l_onoff = 1;
    1547           30 :             soLinger.l_linger = disuseLinger == 0 ? RS_CLOSE_TIMEOUT : 0;
    1548           30 :             ret = setsockopt(connInfo->connfd, SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger));
    1549           30 :             if (ret) {
    1550            0 :                 hccp_err("setsockopt l_onoff:%d l_linger:%d failed err:%d", soLinger.l_onoff, soLinger.l_linger, errno);
    1551            0 :                 retVal = ret;
    1552              :             }
    1553              : 
    1554           30 :             ret = RsSocketCloseFd(connInfo->connfd);
    1555           30 :             if (ret) {
    1556            0 :                 hccp_err("rs_socket_close_fd for fd[%d] failed, ret[%d]", connInfo->connfd, ret);
    1557            0 :                 retVal = ret;
    1558              :             }
    1559              :         }
    1560              : 
    1561           30 :         free(connInfo);
    1562           30 :         connInfo = NULL;
    1563              :     }
    1564              : 
    1565           30 :     return retVal;
    1566              : }
    1567              : 
    1568              : RS_ATTRI_VISI_DEF int RsSocketBatchAbort(struct SocketConnectInfo conn[], uint32_t num)
    1569              : {
    1570            2 :     struct RsConnInfo *connInfo = NULL;
    1571            2 :     struct linger soLinger = {0};
    1572            2 :     int retVal = 0;
    1573              :     unsigned int i;
    1574              :     int ret;
    1575              : 
    1576            2 :     RS_SOCKET_PARA_CHECK(num, conn);
    1577              : 
    1578            3 :     for (i = 0; i < num; i++) {
    1579              :         // strict mutex lock before find to make sure conn_info is valid on concurrent scenario
    1580            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1581            2 :         ret = RsGetConnInfo(&gRsCb->connCb, &conn[i], &connInfo, conn[i].port);
    1582            2 :         if (ret != 0) {
    1583            1 :             hccp_err("rs_get_conn_info conn:%u failed! ret:%d", i, ret);
    1584            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1585            1 :             return ret;
    1586              :         }
    1587              : 
    1588            1 :         hccp_info("abort conn node of IP(%s) fd:%d, state:%d", connInfo->serverIp.readAddr, connInfo->connfd,
    1589              :             connInfo->state);
    1590              : 
    1591            1 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->connCb.connMutex);
    1592            1 :         RsListDel(&connInfo->list);
    1593            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->connCb.connMutex);
    1594            1 :         if (gRsCb->sslEnable == RS_SSL_ENABLE && connInfo->ssl != NULL) {
    1595            0 :             ssl_adp_shutdown(connInfo->ssl);
    1596            0 :             ssl_adp_free(connInfo->ssl);
    1597            0 :             connInfo->ssl = NULL;
    1598            0 :             ssl_adp_clear_error();
    1599              :         }
    1600            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1601              : 
    1602            1 :         if (connInfo->state > RS_CONN_STATE_RESET && connInfo->connfd != RS_FD_INVALID) {
    1603              :             // force to close fd
    1604            1 :             soLinger.l_onoff = 1;
    1605            1 :             ret = setsockopt(connInfo->connfd, SOL_SOCKET, SO_LINGER, &soLinger, sizeof(soLinger));
    1606            1 :             if (ret) {
    1607            1 :                 hccp_err("setsockopt l_onoff:%d l_linger:%d failed err:%d", soLinger.l_onoff, soLinger.l_linger, errno);
    1608            1 :                 retVal = ret;
    1609              :             }
    1610              : 
    1611            1 :             ret = RsSocketCloseFd(connInfo->connfd);
    1612            1 :             if (ret) {
    1613            1 :                 hccp_err("rs_socket_close_fd for fd[%d] failed, ret[%d]", connInfo->connfd, ret);
    1614            1 :                 retVal = ret;
    1615              :             }
    1616              :         }
    1617              : 
    1618            1 :         free(connInfo);
    1619            1 :         connInfo = NULL;
    1620              :     }
    1621              : 
    1622            1 :     return retVal;
    1623              : }
    1624              : 
    1625           30 : STATIC void RsSocketsBackfill(struct SocketFdData conn[], int sockNum, struct RsConnInfo *connTmp,
    1626              :     struct RsVnicInfo vnicInfo)
    1627              : {
    1628           30 :     conn[sockNum].fd = connTmp->connfd;
    1629              : 
    1630           30 :     if (vnicInfo.role == RS_CONN_ROLE_SERVER) {
    1631           14 :         conn[sockNum].remoteIp = connTmp->clientIp.binAddr;
    1632              :     } else {
    1633           16 :         conn[sockNum].remoteIp = connTmp->serverIp.binAddr;
    1634              :     }
    1635              : 
    1636           30 :     conn[sockNum].status = RS_SOCK_STATUS_OK;
    1637           30 :     connTmp->state = RS_CONN_STATE_TX_TO_HCCL;
    1638           30 :     connTmp->isGot = true;
    1639           30 : }
    1640              : 
    1641           30 : STATIC void RsSocketsServeripConverter(struct SocketFdData conn[], int num, uint32_t vnicFlag)
    1642              : {
    1643              :     int j;
    1644              : 
    1645           30 :     if (vnicFlag) {
    1646            0 :         for (j = 0; j < num; j++) {
    1647            0 :             if (conn[j].family == AF_INET) {
    1648            0 :                 conn[j].localIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].localIp.addr.s_addr);
    1649            0 :                 conn[j].remoteIp.addr.s_addr = RsSocketVnic2nodeid(conn[j].remoteIp.addr.s_addr);
    1650              :             }
    1651              :         }
    1652              :     }
    1653           30 : }
    1654              : 
    1655           30 : STATIC int RsFindSockets(struct RsConnInfo *connTmp, struct SocketFdData conn[], int num, int role)
    1656              : {
    1657              :     int ret, i;
    1658              : 
    1659              :     /* normal process, no record log */
    1660           30 :     if (gRsCb->connCb.wlistEnable == 1) {
    1661            0 :         if (connTmp->state != RS_CONN_STATE_VALID_SYNC) {
    1662            0 :             return -EINVAL;
    1663              :         }
    1664              :     } else {
    1665           30 :         if (connTmp->state != RS_CONN_STATE_TAG_SYNC) {
    1666            0 :             return -EINVAL;
    1667              :         }
    1668              :     }
    1669              : 
    1670              :     // server skip to get current socket once socket already been got
    1671           30 :     if (role == RS_CONN_ROLE_SERVER && connTmp->isGot) {
    1672            0 :         return -EINVAL;
    1673              :     }
    1674              : 
    1675           30 :     if (role == RS_CONN_ROLE_SERVER) {
    1676           14 :         i = 0;
    1677              :         struct RsIpAddrInfo localIp;
    1678           14 :         ret = RsConvertIpAddr(conn->family, &conn->localIp, &localIp);
    1679           14 :         CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    1680              : 
    1681           14 :         CHK_PRT_RETURN(RsCompareIpAddr(&connTmp->serverIp, &localIp),
    1682              :             hccp_warn("server_ip[%s] != local_ip[%s]", connTmp->serverIp.readAddr, localIp.readAddr), -EINVAL);
    1683              :     } else {
    1684           16 :         for (i = 0; i < num; i++) {
    1685           16 :             if (conn[i].status == RS_SOCK_STATUS_OK) {
    1686            0 :                 continue;
    1687              :             }
    1688              : 
    1689              :             struct RsIpAddrInfo remoteIp;
    1690           16 :             remoteIp.family = (uint32_t)conn[i].family;
    1691           16 :             remoteIp.binAddr = conn[i].remoteIp;
    1692              :             struct RsIpAddrInfo localIp;
    1693           16 :             localIp.family = (uint32_t)conn[i].family;
    1694           16 :             localIp.binAddr = conn[i].localIp;
    1695           16 :             if ((!RsCompareIpAddr(&connTmp->serverIp, &remoteIp)) && (!RsCompareIpAddr(&connTmp->clientIp, &localIp))) {
    1696           16 :                 break;
    1697              :             }
    1698              :         }
    1699              :     }
    1700              : 
    1701           30 :     CHK_PRT_RETURN(i == num, hccp_warn("i == num %d, not find serverIp[%s]", num, connTmp->serverIp.readAddr), -EINVAL);
    1702              : 
    1703           30 :     conn[i].tag[SOCK_CONN_TAG_SIZE - 1] = '\0';
    1704           30 :     ret = strcmp(conn[i].tag, connTmp->tag);
    1705           30 :     CHK_PRT_RETURN(ret,
    1706              :         hccp_warn("The %dth conn tag[%s] is different from conn_tmp_tag [%s]", i, conn[i].tag, connTmp->tag), -EINVAL);
    1707              : 
    1708           30 :     return i;
    1709              : }
    1710              : 
    1711              : /* find it */
    1712           30 : STATIC int RsSocketsCompare(struct RsListHead *listHead, struct SocketFdData conn[], uint32_t num,
    1713              :     struct RsVnicInfo vnicInfo, struct RsConnCb *connCb)
    1714              : {
    1715           30 :     struct RsConnInfo *connTmp = NULL;
    1716           30 :     struct RsConnInfo *connTmp2 = NULL;
    1717           30 :     int sockNum = 0;
    1718              :     int i;
    1719              :     int sockIndex;
    1720              : 
    1721           30 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    1722           30 :     connTmp = list_entry((listHead)->next, struct RsConnInfo, list);
    1723           30 :     connTmp2 = list_entry(connTmp->list.next, struct RsConnInfo, list);
    1724           30 :     for (; &connTmp->list != (listHead);) {
    1725           30 :         i = RsFindSockets(connTmp, conn, num, vnicInfo.role);
    1726           30 :         if (i < 0) {
    1727            0 :             goto renew_conn;
    1728              :         }
    1729           30 :         sockIndex = (vnicInfo.role == RS_CONN_ROLE_SERVER) ? sockNum : i;
    1730           30 :         RsSocketsBackfill(conn, sockIndex, connTmp, vnicInfo);
    1731              : 
    1732           30 :         sockNum++;
    1733           30 :         if ((unsigned int)sockNum >= num) {
    1734           30 :             break;
    1735              :         }
    1736            0 :     renew_conn:
    1737            0 :         connTmp = connTmp2;
    1738            0 :         connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list);
    1739              :     }
    1740           30 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    1741           30 :     RsSocketsServeripConverter(conn, num, vnicInfo.vnicFlag);
    1742           30 :     return sockNum;
    1743              : }
    1744              : 
    1745           31 : STATIC int RsGetVnicFlag(uint32_t role, uint32_t *localIp, uint32_t *remoteIp)
    1746              : {
    1747           31 :     int vnicFlag = 0;
    1748              : 
    1749           31 :     if (role == RS_CONN_ROLE_SERVER) {
    1750           14 :         if (RsSocketNodeid2vnic(*localIp, localIp) == RS_VNIC_FLAG) {
    1751            0 :             vnicFlag = 1;
    1752              :         }
    1753              :     } else {
    1754           17 :         if ((RsSocketNodeid2vnic(*remoteIp, remoteIp) == RS_VNIC_FLAG) &&
    1755            0 :             (RsSocketNodeid2vnic(*localIp, localIp) == RS_VNIC_FLAG)) {
    1756            0 :             vnicFlag = 1;
    1757              :         }
    1758              :     }
    1759           31 :     return vnicFlag;
    1760              : }
    1761              : 
    1762              : RS_ATTRI_VISI_DEF int RsGetSockets(uint32_t role, struct SocketFdData conn[], uint32_t num)
    1763              : {
    1764           31 :     struct RsListHead *listHead = NULL;
    1765           31 :     struct RsVnicInfo vnicInfo = {0};
    1766           31 :     struct RsConnCb *connCb = NULL;
    1767              :     unsigned int chipId;
    1768              :     uint32_t j;
    1769              :     int ret;
    1770              : 
    1771           31 :     vnicInfo.role = role;
    1772              : 
    1773           31 :     RS_SOCKET_PARA_CHECK(num, conn);
    1774           31 :     CHK_PRT_RETURN(role > RS_CONN_ROLE_CLIENT, hccp_err("para invalid. role[%u]", role), -EINVAL);
    1775              : 
    1776              :     /* set conn status to NA */
    1777           62 :     for (j = 0; j < num; j++) {
    1778           32 :         conn[j].status = 0;
    1779           32 :         CHK_PRT_RETURN(((conn[j].family != AF_INET) && (conn[j].family != AF_INET6)) || conn[j].phyId >= RS_MAX_DEV_NUM,
    1780              :             hccp_err("family[%d] invalid, or phyId[%u] invalid, j:%u", conn[j].family, conn[j].phyId, j), -EINVAL);
    1781              : 
    1782           31 :         CHK_PRT_RETURN(strlen(conn[j].tag) >= SOCK_CONN_TAG_SIZE,
    1783              :             hccp_err("conn tag len:%u more than max len:%d", strlen(conn[j].tag), SOCK_CONN_TAG_SIZE), -EINVAL);
    1784              : 
    1785           31 :         if (conn[j].family == AF_INET) {
    1786           31 :             uint32_t *localIp = &(conn[j].localIp.addr.s_addr);
    1787           31 :             uint32_t *remoteIp = &(conn[j].remoteIp.addr.s_addr);
    1788           31 :             vnicInfo.vnicFlag = (uint32_t)RsGetVnicFlag(role, localIp, remoteIp);
    1789              :         }
    1790              :     }
    1791              : 
    1792           30 :     ret = rsGetLocalDevIDByHostDevID(conn->phyId, &chipId);
    1793           30 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    1794              : 
    1795           30 :     ret = RsDev2conncb(chipId, &connCb);
    1796           30 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed! ret(%d)", ret), -ENODEV);
    1797              : 
    1798           30 :     listHead = (role == RS_CONN_ROLE_SERVER) ? (&connCb->serverConnList) : (&connCb->clientConnList);
    1799           30 :     return RsSocketsCompare(listHead, conn, num, vnicInfo, connCb);
    1800              : }
    1801              : 
    1802              : RS_ATTRI_VISI_DEF int RsGetSslEnable(uint32_t *sslEnable)
    1803              : {
    1804            0 :     CHK_PRT_RETURN(gRsCb == NULL, hccp_err("param error, gRsCb is NULL"), -ENODEV);
    1805            0 :     CHK_PRT_RETURN(sslEnable == NULL, hccp_err("param error, sslEnable is NULL"), -EINVAL);
    1806              : 
    1807            0 :     *sslEnable = gRsCb->sslEnable;
    1808            0 :     return 0;
    1809              : }
    1810              : 
    1811              : RS_ATTRI_VISI_DEF int RsSocketSend(int fd, const void *data, uint64_t size)
    1812              : {
    1813              :     int ret;
    1814              : 
    1815           83 :     ret = RsDrvSocketSend(fd, data, size, MSG_DONTWAIT | MSG_NOSIGNAL);
    1816              : 
    1817           83 :     hccp_dbg("send fd:%d, size:%llu, send %dB", fd, size, ret);
    1818           83 :     return ret;
    1819              : }
    1820              : 
    1821              : RS_ATTRI_VISI_DEF int RsHdcSocketSend(int fd, const void *data, uint64_t size)
    1822              : {
    1823              :     static __thread char buf[RS_BUF_SIZE] = {0};
    1824            0 :     const void *sendData = data;
    1825            0 :     uint64_t sendSize = size;
    1826              :     int ret;
    1827              : 
    1828            0 :     if (gRsCb->sslEnable == RS_SSL_ENABLE) {
    1829              :         // reuse buf to fix SSL_write retry issue
    1830            0 :         sendSize = (size > RS_BUF_SIZE) ? RS_BUF_SIZE : size;
    1831            0 :         (void)memcpy_s(buf, sendSize, data, sendSize);
    1832            0 :         sendData = buf;
    1833              :     }
    1834              : 
    1835            0 :     ret = RsDrvSocketSend(fd, sendData, sendSize, MSG_DONTWAIT | MSG_NOSIGNAL);
    1836              : 
    1837            0 :     hccp_dbg("send fd:%d, sendSize:%llu, send %dB", fd, sendSize, ret);
    1838            0 :     return ret;
    1839              : }
    1840              : 
    1841              : RS_ATTRI_VISI_DEF int RsPeerSocketSend(uint32_t sslEnable, int fd, const void *data, uint64_t size)
    1842              : {
    1843            4 :     struct RsConnInfo *conn = NULL;
    1844            4 :     int ret = 0;
    1845              :     int errNo;
    1846              : 
    1847            4 :     CHK_PRT_RETURN(fd < 0 || size == 0 || data == NULL,
    1848              :         hccp_err("param error ! fd:%d < 0, size:%llu or data is NULL", fd, size), -EINVAL);
    1849            2 :     if (sslEnable != RS_SSL_DISABLE) {
    1850            1 :         ret = RsFd2conn(fd, &conn);
    1851            1 :         CHK_PRT_RETURN(ret, hccp_err("fd to conn failed, ret:%d", ret), ret);
    1852            0 :         ret = ssl_adp_write(conn->ssl, data, (int)size);
    1853            0 :         if (ret <= 0) {
    1854            0 :             ret = RsSslWriteInnerCheck(conn, ret, size);
    1855              :         }
    1856              :     } else {
    1857            1 :         ret = (int)send(fd, data, size, MSG_DONTWAIT | MSG_NOSIGNAL);
    1858            1 :         if (ret < 0) {
    1859            1 :             errNo = errno;
    1860            1 :             if (errNo == EAGAIN || errNo == EINTR) {
    1861            0 :                 hccp_dbg("send to fd:%d need retry, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
    1862            0 :                 ret = -EAGAIN;
    1863              :             } else {
    1864            1 :                 hccp_run_info("send to fd:%d not success, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
    1865            1 :                 ret = -EFILEOPER;
    1866              :             }
    1867              :         }
    1868              :     }
    1869              : 
    1870            1 :     return ret;
    1871              : }
    1872              : 
    1873              : RS_ATTRI_VISI_DEF int RsSocketRecv(int fd, void *data, uint64_t size)
    1874              : {
    1875              :     int ret;
    1876              : 
    1877           28 :     ret = RsDrvSocketRecv(fd, data, size, MSG_DONTWAIT);
    1878              : 
    1879           28 :     return ret;
    1880              : }
    1881              : 
    1882              : RS_ATTRI_VISI_DEF int RsPeerSocketRecv(uint32_t sslEnable, int fd, void *data, uint64_t size)
    1883              : {
    1884            4 :     struct RsConnInfo *conn = NULL;
    1885            4 :     int ret = 0;
    1886              :     int errNo;
    1887              : 
    1888            4 :     CHK_PRT_RETURN(fd < 0 || data == NULL || size == 0,
    1889              :         hccp_err("param error ! fd:%d < 0 or data is NULL, size:%llu", fd, size), -EINVAL);
    1890            2 :     if (sslEnable != RS_SSL_DISABLE) {
    1891            1 :         ret = RsFd2conn(fd, &conn);
    1892            1 :         CHK_PRT_RETURN(ret,
    1893              :             hccp_warn("can not find conn for fd[%d], ret:%d, the local fd may have been closed ", fd, ret), ret);
    1894            0 :         ret = ssl_adp_read(conn->ssl, data, (int)size);
    1895            0 :         if (ret <= 0) {
    1896            0 :             ret = RsSslReadInnerCheck(conn, ret, size);
    1897              :         }
    1898              :     } else {
    1899            1 :         ret = (int)recv(fd, data, size, MSG_DONTWAIT);
    1900            1 :         if (ret < 0) {
    1901            1 :             errNo = errno;
    1902              :             // not to print to avoid log flush
    1903            1 :             if (errNo == EAGAIN || errNo == EINTR) {
    1904            0 :                 ret = -EAGAIN;
    1905              :             } else {
    1906            1 :                 hccp_run_info("recv for fd:%d not success, recv size:%llu, ret:%d, errNo:%d", fd, size, ret, errNo);
    1907            1 :                 ret = -EFILEOPER;
    1908              :             }
    1909              :         }
    1910              :     }
    1911              : 
    1912            1 :     return ret;
    1913              : }
    1914              : 
    1915              : RS_ATTRI_VISI_DEF int RsSocketGetClientSocketErrInfo(struct SocketConnectInfo conn[], struct SocketErrInfo err[],
    1916              :     unsigned int num)
    1917              : {
    1918            2 :     struct RsConnInfo *connInfo = NULL;
    1919              :     unsigned int i, serverPort;
    1920              :     int ret;
    1921              : 
    1922            2 :     RS_SOCKET_PARA_CHECK(num, conn);
    1923            2 :     RS_CHECK_POINTER_NULL_WITH_RET(err);
    1924            3 :     for (i = 0; i < num; i++) {
    1925            2 :         serverPort = conn[i].port;
    1926            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1927            2 :         ret = RsGetConnInfo(&gRsCb->connCb, &conn[i], &connInfo, serverPort);
    1928            2 :         if (ret != 0) {
    1929            1 :             hccp_err("rs_get_conn_info failed, i:%u ret:%d", i, ret);
    1930            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1931            1 :             return ret;
    1932              :         }
    1933              : 
    1934            1 :         (void)memcpy_s(&err[i], sizeof(struct SocketErrInfo), &connInfo->errInfo, sizeof(struct SocketErrInfo));
    1935              : 
    1936              :         // clear the singer socket connect err info
    1937            1 :         (void)memset_s(&connInfo->errInfo, sizeof(struct SocketErrInfo), 0, sizeof(struct SocketErrInfo));
    1938            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1939              :     }
    1940              : 
    1941            1 :     return 0;
    1942              : }
    1943              : 
    1944              : RS_ATTRI_VISI_DEF int RsSocketGetServerSocketErrInfo(struct SocketListenInfo conn[], struct ServerSocketErrInfo err[],
    1945              :     unsigned int num)
    1946              : {
    1947            2 :     struct RsListenInfo *listenInfo = NULL;
    1948            2 :     struct RsIpAddrInfo ipInfo = {0};
    1949            2 :     struct RsConnCb *connCb = NULL;
    1950              :     unsigned int i, serverPort;
    1951              :     int ret;
    1952              : 
    1953            2 :     RS_SOCKET_PARA_CHECK(num, conn);
    1954            2 :     RS_CHECK_POINTER_NULL_WITH_RET(err);
    1955            3 :     for (i = 0; i < num; i++) {
    1956            2 :         ret = RsConvertIpAddr(conn[i].family, &conn[i].localIp, &ipInfo);
    1957            2 :         CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, i:%u, ret:%d", i, ret), ret);
    1958              : 
    1959            2 :         serverPort = conn[i].port;
    1960            2 :         RS_PTHREAD_MUTEX_LOCK(&gRsCb->mutex);
    1961            2 :         connCb = &gRsCb->connCb;
    1962            2 :         ret = RsFindListenNode(connCb, &ipInfo, serverPort, &listenInfo);
    1963            2 :         if (ret != 0) {
    1964            1 :             hccp_err("rs_find_listen_node failed, i:%u, ip:%s, serverPort:%u, ret:%d", i, ipInfo.readAddr, serverPort,
    1965              :                 ret);
    1966            1 :             RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1967            1 :             return ret;
    1968              :         }
    1969              : 
    1970            1 :         (void)memcpy_s(&err[i].epollWait, sizeof(struct SocketErrInfo), &connCb->epollErrInfo,
    1971              :             sizeof(struct SocketErrInfo));
    1972            1 :         (void)memcpy_s(&err[i].accept, sizeof(struct SocketErrInfo), &listenInfo->errInfo,
    1973              :             sizeof(struct SocketErrInfo));
    1974              : 
    1975              :         // clear the single socket listen err info
    1976            1 :         (void)memset_s(&listenInfo->errInfo, sizeof(struct SocketErrInfo), 0, sizeof(struct SocketErrInfo));
    1977            1 :         RS_PTHREAD_MUTEX_ULOCK(&gRsCb->mutex);
    1978              :     }
    1979              : 
    1980            1 :     return 0;
    1981              : }
    1982              : 
    1983           13 : static void RsSocketGetIpInfo(unsigned int *serverIp, unsigned int *clientIp)
    1984              : {
    1985           13 :     uint32_t serverNodeId = *serverIp;
    1986           13 :     uint32_t clientNodeId = *clientIp;
    1987              :     int ret;
    1988              : 
    1989           13 :     ret = RsSocketNodeid2vnic(serverNodeId, serverIp);
    1990           13 :     hccp_info("white list listen IP 0x%llx, ret_vnic %d", *serverIp, ret);
    1991              : 
    1992           13 :     ret = RsSocketNodeid2vnic(clientNodeId, clientIp);
    1993           13 :     hccp_info("white list client IP 0x%llx, ret_vnic %d", *clientIp, ret);
    1994              : 
    1995           13 :     return;
    1996              : }
    1997              : 
    1998           13 : STATIC int RsSocketWhiteListAlloc(struct RsConnCb *connCb, struct SocketWlistInfoT *whiteList,
    1999              :     struct RsIpAddrInfo *serverIp)
    2000              : {
    2001              :     int ret;
    2002              :     /*lint -e429*/
    2003           13 :     struct RsWhiteListInfo *whiteListNodeTmp = NULL;
    2004           13 :     struct RsWhiteList *whiteListTmp = NULL;
    2005              :     struct SocketWlistInfoT wlist;
    2006              :     struct RsIpAddrInfo clientIp;
    2007           13 :     ret = memcpy_s(&wlist, sizeof(struct SocketWlistInfoT), whiteList, sizeof(struct SocketWlistInfoT));
    2008           13 :     CHK_PRT_RETURN(ret, hccp_err("memcpy socket_wlist_info_t wlist failed, ret[%d]!", ret), -ESAFEFUNC);
    2009              : 
    2010           13 :     if (serverIp->family == AF_INET) {
    2011           13 :         RsSocketGetIpInfo(&serverIp->binAddr.addr.s_addr, &(wlist.remoteIp.addr.s_addr));
    2012           13 :         RsInetNtop(serverIp->family, &serverIp->binAddr, (char *)&serverIp->readAddr, sizeof(serverIp->readAddr));
    2013              :     }
    2014              : 
    2015           13 :     ret = RsConvertIpAddr(serverIp->family, &wlist.remoteIp, &clientIp);
    2016           13 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2017              : 
    2018           13 :     ret = RsFindWhiteList(connCb, serverIp, &whiteListTmp);
    2019           13 :     if (ret) {
    2020           11 :         whiteListTmp = calloc(1, sizeof(struct RsWhiteList));
    2021           11 :         CHK_PRT_RETURN(whiteListTmp == NULL, hccp_err("alloc mem for rs_white_list failed!"), -ENOMEM);
    2022           11 :         whiteListTmp->serverIp = *serverIp;
    2023           11 :         RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2024           11 :         RS_INIT_LIST_HEAD(&whiteListTmp->whiteList);
    2025           11 :         RsListAddTail(&whiteListTmp->list, &connCb->whiteList);
    2026           11 :         RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2027              :     }
    2028              : 
    2029           13 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2030           13 :     ret = RsFindWhiteListNode(whiteListTmp, &wlist, (int)serverIp->family, &whiteListNodeTmp);
    2031           13 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2032           13 :     if (ret == 0) {
    2033            0 :         whiteListNodeTmp->connLimit += wlist.connLimit;
    2034            0 :         return 0;
    2035              :     }
    2036              : 
    2037           13 :     whiteListNodeTmp = calloc(1, sizeof(struct RsWhiteListInfo));
    2038           13 :     CHK_PRT_RETURN(whiteListNodeTmp == NULL, hccp_err("alloc mem for socket_wlist_info_t failed!"), -ENOMEM);
    2039              : 
    2040           13 :     whiteListNodeTmp->clientIp = clientIp;
    2041           13 :     whiteListNodeTmp->connLimit = wlist.connLimit;
    2042           13 :     ret = memcpy_s(whiteListNodeTmp->tag, SOCK_CONN_TAG_SIZE, wlist.tag, sizeof(wlist.tag));
    2043           13 :     if (ret) {
    2044            0 :         hccp_err("memcpy_s failed, ret[%d]. ", ret);
    2045            0 :         free(whiteListNodeTmp);
    2046            0 :         whiteListNodeTmp = NULL;
    2047            0 :         return -ESAFEFUNC;
    2048              :     }
    2049              : 
    2050           13 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2051           13 :     RsListAddTail(&whiteListNodeTmp->list, &whiteListTmp->whiteList);
    2052           13 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2053           13 :     return 0;
    2054              :     /*lint +e429*/
    2055              : }
    2056              : 
    2057              : RS_ATTRI_VISI_DEF int RsSocketWhiteListSwitch(unsigned int phyId, unsigned int enable)
    2058              : {
    2059            0 :     struct RsConnCb *connCb = NULL;
    2060              :     int ret;
    2061              : 
    2062            0 :     ret = RsDev2conncb(phyId, &connCb);
    2063            0 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed, ret:%d", ret), -1);
    2064            0 :     connCb->wlistEnable = enable;
    2065            0 :     return 0;
    2066              : }
    2067              : 
    2068              : RS_ATTRI_VISI_DEF int RsSocketWhiteListAdd(struct rdev rdevInfo, struct SocketWlistInfoT whiteList[], unsigned int num)
    2069              : {
    2070           13 :     struct RsConnCb *connCb = &(gRsCb->connCb);
    2071              :     struct RsIpAddrInfo serverIp;
    2072              :     unsigned int i, chipId;
    2073              :     int ret;
    2074              : 
    2075           13 :     ret = RsConvertIpAddr(rdevInfo.family, &rdevInfo.localIp, &serverIp);
    2076           13 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), -EINVAL);
    2077              : 
    2078           13 :     CHK_PRT_RETURN(num <= 0 || whiteList == NULL || num > RS_MAX_WLIST_NUM ||
    2079              :                        ((rdevInfo.family != AF_INET) && (rdevInfo.family != AF_INET6)) ||
    2080              :                        rdevInfo.phyId >= RS_MAX_DEV_NUM,
    2081              :         hccp_err("white list add param error, phyId[%u], server ip[%s], num[%u], family[%d]", rdevInfo.phyId,
    2082              :             serverIp.readAddr, num, rdevInfo.family),
    2083              :         -EINVAL);
    2084              : 
    2085           13 :     ret = rsGetLocalDevIDByHostDevID(rdevInfo.phyId, &chipId);
    2086           13 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    2087              : 
    2088           26 :     for (i = 0; i < num; ++i) {
    2089           13 :         CHK_PRT_RETURN(strnlen(whiteList[i].tag, SOCK_CONN_TAG_SIZE) >= SOCK_CONN_TAG_SIZE,
    2090              :             hccp_err("white_list tag len:%u more than max len:%d", strlen(whiteList[i].tag), SOCK_CONN_TAG_SIZE),
    2091              :             -EINVAL);
    2092           13 :         ret = RsSocketWhiteListAlloc(connCb, &whiteList[i], &serverIp);
    2093           13 :         if (ret) {
    2094              :             struct RsIpAddrInfo clientIp;
    2095            0 :             ret = RsConvertIpAddr(serverIp.family, &whiteList->remoteIp, &clientIp);
    2096            0 :             CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2097            0 :             hccp_err("add white list node failed, server ip[%s], client ip[%s], tag[%s], ret:%d", serverIp.readAddr,
    2098              :                 clientIp.readAddr, whiteList[i].tag, ret);
    2099              :         }
    2100              :     }
    2101           13 :     return 0;
    2102              : }
    2103              : 
    2104            2 : STATIC int RsSocketWhiteListNodeDestroy(struct RsConnCb *connCb, struct SocketWlistInfoT *whiteList,
    2105              :     struct RsIpAddrInfo *serverIp)
    2106              : {
    2107            2 :     struct RsWhiteListInfo *whiteListNodeTmp = NULL;
    2108            2 :     struct RsWhiteList *whiteListTmp = NULL;
    2109              :     struct SocketWlistInfoT wlist;
    2110              :     struct RsIpAddrInfo clientIp;
    2111              :     int ret;
    2112              : 
    2113            2 :     ret = RsConvertIpAddr((int)serverIp->family, &whiteList->remoteIp, &clientIp);
    2114            2 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2115              : 
    2116            2 :     ret = memset_s(&wlist, sizeof(struct SocketWlistInfoT), 0, sizeof(struct SocketWlistInfoT));
    2117            2 :     CHK_PRT_RETURN(ret, hccp_err("memset_s socket_wlist_info_t wlist failed, ret:%d", ret), -ESAFEFUNC);
    2118            2 :     ret = memcpy_s(&wlist, sizeof(struct SocketWlistInfoT), whiteList, sizeof(struct SocketWlistInfoT));
    2119            2 :     CHK_PRT_RETURN(ret, hccp_err("memcpy socket_wlist_info_t wlist failed!"), -ESAFEFUNC);
    2120              : 
    2121            2 :     if (serverIp->family == AF_INET) {
    2122            2 :         ret = RsSocketNodeid2vnic(serverIp->binAddr.addr.s_addr, &serverIp->binAddr.addr.s_addr);
    2123            2 :         hccp_info("listen IP 0x%llx, ret_vnic %d", serverIp->binAddr.addr.s_addr, ret);
    2124            2 :         ret = RsSocketNodeid2vnic(wlist.remoteIp.addr.s_addr, &(wlist.remoteIp.addr.s_addr));
    2125            2 :         hccp_info("client IP 0x%llx, ret_vnic %d", wlist.remoteIp.addr.s_addr, ret);
    2126              :     }
    2127              : 
    2128            2 :     ret = RsFindWhiteList(connCb, serverIp, &whiteListTmp);
    2129            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("white list for IP(%s) doesn't exist! state:%d", serverIp->readAddr, ret), ret);
    2130            2 :     RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
    2131            2 :     ret = RsFindWhiteListNode(whiteListTmp, &wlist, (int)serverIp->family, &whiteListNodeTmp);
    2132            2 :     if (ret == 0) {
    2133            2 :         RsListDel(&whiteListNodeTmp->list);
    2134            2 :         free(whiteListNodeTmp);
    2135            2 :         whiteListNodeTmp = NULL;
    2136            2 :         RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2137            2 :         return 0;
    2138              :     }
    2139            0 :     RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
    2140            0 :     hccp_info("can not find white list node: client ip[%s], tag[%s], ret:%d", clientIp.readAddr, wlist.tag, ret);
    2141            0 :     return ret;
    2142              : }
    2143              : 
    2144              : RS_ATTRI_VISI_DEF int RsSocketWhiteListDel(struct rdev rdevInfo, struct SocketWlistInfoT whiteList[], unsigned int num)
    2145              : {
    2146            2 :     struct RsConnCb *connCb = &(gRsCb->connCb);
    2147              :     unsigned int i, chipId;
    2148              :     struct RsIpAddrInfo serverIp;
    2149              :     int ret;
    2150              : 
    2151            2 :     ret = RsConvertIpAddr(rdevInfo.family, &rdevInfo.localIp, &serverIp);
    2152            2 :     CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2153              : 
    2154            2 :     CHK_PRT_RETURN(num <= 0 || whiteList == NULL || num > RS_MAX_WLIST_NUM ||
    2155              :                        ((rdevInfo.family != AF_INET) && (rdevInfo.family != AF_INET6)) ||
    2156              :                        rdevInfo.phyId >= RS_MAX_DEV_NUM,
    2157              :         hccp_err("white list del param error, phyId[%u], server ip[%s], num[%u] family[%d]", rdevInfo.phyId,
    2158              :             serverIp.readAddr, num, rdevInfo.family),
    2159              :         -EINVAL);
    2160              : 
    2161            2 :     ret = rsGetLocalDevIDByHostDevID(rdevInfo.phyId, &chipId);
    2162            2 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    2163              : 
    2164            4 :     for (i = 0; i < num; ++i) {
    2165            2 :         CHK_PRT_RETURN(strlen(whiteList[i].tag) >= SOCK_CONN_TAG_SIZE,
    2166              :             hccp_err("white_list tag len:%u more than"
    2167              :                      "max len:%d",
    2168              :                 strlen(whiteList[i].tag), SOCK_CONN_TAG_SIZE),
    2169              :             -EINVAL);
    2170            2 :         ret = RsSocketWhiteListNodeDestroy(connCb, &whiteList[i], &serverIp);
    2171            2 :         if (ret) {
    2172              :             struct RsIpAddrInfo clientIp;
    2173            0 :             ret = RsConvertIpAddr(serverIp.family, &whiteList->remoteIp, &clientIp);
    2174            0 :             CHK_PRT_RETURN(ret, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
    2175            0 :             hccp_info("white list node wait to delete, server ip[%s], client ip[%s], tag[%s], ret:%d",
    2176              :                 serverIp.readAddr, clientIp.readAddr, whiteList[i].tag, ret);
    2177              :         }
    2178              :     }
    2179            2 :     return 0;
    2180              : }
    2181              : 
    2182              : // 获取device网卡信息,当前device网卡只支持IPv4
    2183            0 : STATIC int RsFillIfaddrInfos(struct IfaddrInfo ifaddrInfos[], unsigned int *num, unsigned int phyId)
    2184              : {
    2185            0 :     struct ifaddrs *ifaddr = NULL;
    2186            0 :     struct ifaddrs *ifa = NULL;
    2187              :     int family, ret;
    2188            0 :     unsigned int numBak = *num;
    2189            0 :     *num = 0;
    2190              :     enum RsHardwareType type;
    2191              : 
    2192            0 :     type = RsGetDeviceType(phyId);
    2193            0 :     CHK_PRT_RETURN(type == RS_HARDWARE_UNKNOWN, hccp_err("rs_get_device_type failed, type[%d]", type), -EINVAL);
    2194            0 :     ret = getifaddrs(&ifaddr);
    2195            0 :     CHK_PRT_RETURN(ret == -1, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
    2196              :     /* Walk through linked list, maintaining head pointer so we can free list later */
    2197            0 :     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    2198            0 :         if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
    2199            0 :             continue;
    2200              :         }
    2201            0 :         family = ifa->ifa_addr->sa_family;
    2202              :         /* If not an AF_INET/AF_INET6 interface address, continue */
    2203            0 :         if (family != AF_INET) {
    2204            0 :             continue;
    2205              :         }
    2206            0 :         ret = RsCheckDstInterface(phyId, ifa->ifa_name, type, false);
    2207            0 :         if (ret < 0) {
    2208            0 :             hccp_err("rs_check_dst_interface failed, ret[%d]", ret);
    2209            0 :             goto out;
    2210              :         }
    2211            0 :         if (ret) {
    2212            0 :             (*num)++;
    2213            0 :             if ((*num) > numBak) {
    2214            0 :                 hccp_err("num of interfaces found is more than expect, expect[%u], actual[%u]", numBak, *num);
    2215            0 :                 goto out;
    2216              :             }
    2217            0 :             ifaddrInfos[*num - 1].ip.addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
    2218            0 :             ifaddrInfos[*num - 1].mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
    2219              :         }
    2220              :     }
    2221              : 
    2222            0 :     freeifaddrs(ifaddr);
    2223            0 :     ifaddr = NULL;
    2224            0 :     return 0;
    2225            0 : out:
    2226            0 :     freeifaddrs(ifaddr);
    2227            0 :     ifaddr = NULL;
    2228            0 :     return -EAGAIN;
    2229              : }
    2230              : 
    2231              : // 获取device网卡信息,支持IPv4/IPV6
    2232            0 : STATIC int RsFillIfaddrInfosV2(struct InterfaceInfo interfaceInfos[], unsigned int *num, unsigned int phyId, bool isAll)
    2233              : {
    2234            0 :     struct ifaddrs *ifaddr = NULL;
    2235            0 :     struct ifaddrs *ifa = NULL;
    2236              :     enum RsHardwareType type;
    2237              :     unsigned int numBak;
    2238              :     int family, ret;
    2239              : 
    2240            0 :     numBak = *num;
    2241            0 :     *num = 0;
    2242            0 :     type = RsGetDeviceType(phyId);
    2243            0 :     CHK_PRT_RETURN(type == RS_HARDWARE_UNKNOWN, hccp_err("rs_get_device_type failed, type[%d]", type), -EINVAL);
    2244            0 :     ret = getifaddrs(&ifaddr);
    2245            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
    2246              :     /* Walk through linked list, maintaining head pointer so we can free list later */
    2247            0 :     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    2248            0 :         if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
    2249            0 :             continue;
    2250              :         }
    2251              : 
    2252              :         /* If not an AF_INET/AF_INET6 interface address, continue */
    2253            0 :         family = ifa->ifa_addr->sa_family;
    2254            0 :         if ((family != AF_INET) && (family != AF_INET6)) {
    2255            0 :             continue;
    2256              :         }
    2257              : 
    2258            0 :         ret = RsCheckDstInterface(phyId, ifa->ifa_name, type, isAll);
    2259            0 :         if (ret < 0) {
    2260            0 :             hccp_err("rs_check_dst_interface failed, ret[%d]", ret);
    2261            0 :             ret = -EAGAIN;
    2262            0 :             break;
    2263              :         }
    2264            0 :         if (ret) {
    2265            0 :             (*num)++;
    2266            0 :             if ((*num) > numBak) {
    2267            0 :                 hccp_err("num of interfaces found is more than expect, expect[%u], actual[%u]", numBak, *num);
    2268            0 :                 ret = -EAGAIN;
    2269            0 :                 break;
    2270              :             }
    2271              : 
    2272            0 :             ret = strcpy_s(interfaceInfos[*num - 1].ifname, MAX_INTERFACE_NAME_LEN, ifa->ifa_name);
    2273            0 :             if (ret) {
    2274            0 :                 hccp_err("strcpy interface name failed, ret[%d]", ret);
    2275            0 :                 ret = -EAGAIN;
    2276            0 :                 break;
    2277              :             }
    2278            0 :             interfaceInfos[*num - 1].scopeId = 0;
    2279            0 :             if (family == AF_INET) {
    2280            0 :                 interfaceInfos[*num - 1].ifaddr.ip.addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
    2281            0 :                 interfaceInfos[*num - 1].ifaddr.mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
    2282              :             } else {
    2283            0 :                 interfaceInfos[*num - 1].ifaddr.ip.addr6 = ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
    2284            0 :                 interfaceInfos[*num - 1].scopeId = (int)((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id;
    2285              :             }
    2286            0 :             interfaceInfos[*num - 1].family = family;
    2287              :         }
    2288              :     }
    2289              : 
    2290            0 :     freeifaddrs(ifaddr);
    2291            0 :     ifaddr = NULL;
    2292            0 :     return ret;
    2293              : }
    2294              : 
    2295            3 : STATIC int RsFillIfnum(unsigned int phyId, bool isAll, unsigned int *num, unsigned int isPeer)
    2296              : {
    2297            3 :     struct ifaddrs *ifaddr = NULL;
    2298            3 :     struct ifaddrs *ifa = NULL;
    2299            3 :     enum RsHardwareType type = RS_HARDWARE_UNKNOWN;
    2300              :     int family, ret;
    2301            3 :     *num = 0;
    2302              : 
    2303            3 :     if (isPeer == 0) {
    2304            2 :         type = RsGetDeviceType(phyId);
    2305            2 :         CHK_PRT_RETURN(type == RS_HARDWARE_UNKNOWN, hccp_err("rs_get_device_type failed, type[%d]", type), -EINVAL);
    2306              :     }
    2307            3 :     ret = getifaddrs(&ifaddr);
    2308            3 :     CHK_PRT_RETURN(ret == -1, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
    2309              :     /* Walk through linked list, maintaining head pointer so we can free list later */
    2310            8 :     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
    2311            7 :         if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
    2312            4 :             continue;
    2313              :         }
    2314            3 :         family = ifa->ifa_addr->sa_family;
    2315              :         /* If not an AF_INET/AF_INET6 interface address, continue */
    2316            3 :         if ((family != AF_INET) && (family != AF_INET6)) {
    2317            0 :             continue;
    2318              :         }
    2319            3 :         if (isPeer == 0) {
    2320            3 :             ret = RsCheckDstInterface(phyId, ifa->ifa_name, type, isAll);
    2321            3 :             if (ret < 0) {
    2322            1 :                 hccp_err("rs_check_dst_interface failed, ret[%d]", ret);
    2323            1 :                 goto out;
    2324              :             }
    2325            2 :             if (ret) {
    2326            1 :                 (*num)++;
    2327              :             }
    2328              :         } else {
    2329            0 :             (*num)++;
    2330              :         }
    2331              :     }
    2332              : 
    2333            1 :     freeifaddrs(ifaddr);
    2334            1 :     ifaddr = NULL;
    2335            1 :     return 0;
    2336            1 : out:
    2337            1 :     freeifaddrs(ifaddr);
    2338            1 :     ifaddr = NULL;
    2339            1 :     return -EAGAIN;
    2340              : }
    2341              : 
    2342              : RS_ATTRI_VISI_DEF int RsPeerGetIfnum(unsigned int phyId, unsigned int *num)
    2343              : {
    2344              :     int ret;
    2345            1 :     CHK_PRT_RETURN(num == NULL, hccp_err("param error, num is NULL"), -EINVAL);
    2346            1 :     CHK_PRT_RETURN(gRsCb == NULL, hccp_err("param error, gRsCb is NULL"), -EINVAL);
    2347            1 :     ret = RsPeerFillIfnum(phyId, num, gRsCb->ifaddrList);
    2348            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_peer_fill_ifnum failed, ret[%d]", ret), ret);
    2349            1 :     return ret;
    2350              : }
    2351              : 
    2352              : RS_ATTRI_VISI_DEF int RsGetIfnum(unsigned int phyId, bool isAll, unsigned int *num)
    2353              : {
    2354              :     int ret;
    2355            3 :     CHK_PRT_RETURN(num == NULL, hccp_err("rs_get_ifaddrs param error, num is NULL"), -EINVAL);
    2356            2 :     ret = RsFillIfnum(phyId, isAll, num, 0);
    2357            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_fill_ifnum failed, ret[%d]", ret), ret);
    2358            1 :     return ret;
    2359              : }
    2360              : 
    2361              : RS_ATTRI_VISI_DEF int RsPeerGetIfaddrs(struct InterfaceInfo interfaceInfos[], unsigned int *num, unsigned int phyId)
    2362              : {
    2363              :     int ret;
    2364            1 :     CHK_PRT_RETURN(interfaceInfos == NULL || num == NULL, hccp_err("param error, interfaceInfos or num is NULL"),
    2365              :         -EINVAL);
    2366            1 :     CHK_PRT_RETURN(gRsCb == NULL, hccp_err("param error, gRsCb is NULL"), -EINVAL);
    2367            1 :     ret = RsPeerFillIfaddrInfos(interfaceInfos, num, phyId, gRsCb->ifaddrList);
    2368            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_peer_fill_ifaddr_infos failed, ret[%d]", ret), ret);
    2369            1 :     return ret;
    2370              : }
    2371              : 
    2372              : RS_ATTRI_VISI_DEF int RsGetIfaddrs(struct IfaddrInfo ifaddrInfos[], unsigned int *num, unsigned int phyId)
    2373              : {
    2374              :     int ret;
    2375              : 
    2376            0 :     CHK_PRT_RETURN(ifaddrInfos == NULL || num == NULL,
    2377              :         hccp_err("rs_get_ifaddrs param error,"
    2378              :                  "ifaddrInfos or num is NULL"),
    2379              :         -EINVAL);
    2380              : 
    2381            0 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM || *num > MAX_INTERFACE_NUM,
    2382              :         hccp_err("rs_get_ifaddrs param error,"
    2383              :                  "phyId[%u], num[%u]",
    2384              :             phyId, *num),
    2385              :         -EINVAL);
    2386              : 
    2387            0 :     ret = RsFillIfaddrInfos(ifaddrInfos, num, phyId);
    2388            0 :     CHK_PRT_RETURN(ret, hccp_err("rs_fill_ifaddr_infos failed, ret[%d]", ret), ret);
    2389              : 
    2390            0 :     return 0;
    2391              : }
    2392              : 
    2393              : RS_ATTRI_VISI_DEF int RsGetIfaddrsV2(struct InterfaceInfo interfaceInfos[], unsigned int *num, unsigned int phyId,
    2394              :     bool isAll)
    2395              : {
    2396              :     int ret;
    2397              : 
    2398            0 :     CHK_PRT_RETURN(interfaceInfos == NULL || num == NULL,
    2399              :         hccp_err("rs_get_ifaddrs_v2 param error,"
    2400              :                  "interfaceInfos or num is NULL"),
    2401              :         -EINVAL);
    2402              : 
    2403            0 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM || *num > MAX_INTERFACE_NUM,
    2404              :         hccp_err("rs_get_ifaddrs_v2 param error,"
    2405              :                  "phyId[%u], num[%u]",
    2406              :             phyId, *num),
    2407              :         -EINVAL);
    2408              : 
    2409            0 :     ret = RsFillIfaddrInfosV2(interfaceInfos, num, phyId, isAll);
    2410            0 :     CHK_PRT_RETURN(ret, hccp_err("rs_fill_ifaddr_infos_v2 failed, ret[%d]", ret), ret);
    2411              : 
    2412            0 :     return 0;
    2413              : }
    2414              : 
    2415              : RS_ATTRI_VISI_DEF int RsSocketSetScopeId(unsigned int devId, int scopeId)
    2416              : {
    2417              :     int ret;
    2418              :     unsigned int chipId;
    2419            1 :     struct RsConnCb *connCb = NULL;
    2420            1 :     ret = rsGetLocalDevIDByHostDevID(devId, &chipId);
    2421            1 :     CHK_PRT_RETURN(ret, hccp_err("phyId invalid, ret %d", ret), ret);
    2422              : 
    2423            1 :     ret = RsDev2conncb(chipId, &connCb);
    2424            1 :     CHK_PRT_RETURN(ret, hccp_err("get conncb from dev failed, ret:%d", ret), ret);
    2425              : 
    2426            1 :     connCb->scopeId = scopeId;
    2427            1 :     return 0;
    2428              : }
        

Generated by: LCOV version 2.0-1