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 : }
|