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