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