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 <netdb.h>
15 : #include <netinet/in.h>
16 : #include <arpa/inet.h>
17 : #include <sys/types.h>
18 : #include <sys/epoll.h>
19 : #include <sys/eventfd.h>
20 : #include <sys/socket.h>
21 :
22 : #include "securec.h"
23 : #include "dl_hal_function.h"
24 : #include "ssl_adp.h"
25 : #include "ra_rs_comm.h"
26 : #include "ra_rs_err.h"
27 : #include "rs.h"
28 : #include "rs_inner.h"
29 : #include "rs_epoll.h"
30 : #include "rs_tls.h"
31 : #include "rs_drv_socket.h"
32 :
33 230 : int RsInetNtop(int family, union HccpIpAddr *ip, char readAddr[], unsigned int len)
34 : {
35 : // IPv4/IPv6 二进制转字符串
36 230 : const char *str = NULL;
37 230 : str = inet_ntop(family, ip, readAddr, len);
38 230 : CHK_PRT_RETURN(str == NULL, hccp_err("[rs][inet_ntop]ip is a invalid, err(%d), family %d", errno, family), -EINVAL);
39 230 : return 0;
40 : }
41 :
42 171 : int RsConvertIpAddr(int family, union HccpIpAddr *ipAddr, struct RsIpAddrInfo *ip)
43 : {
44 : // IPv4/IPv6 二进制转内部IP数据格式(含二进制、字符串)
45 171 : ip->family = (uint32_t)family;
46 171 : ip->binAddr = *ipAddr;
47 171 : return RsInetNtop((int)ip->family, &ip->binAddr, (char*)&ip->readAddr, sizeof(ip->readAddr));
48 : }
49 :
50 87 : bool RsCompareIpAddr(struct RsIpAddrInfo *a, struct RsIpAddrInfo *b)
51 : {
52 : // return: true(IP不同), false(IP相同)
53 87 : if (a->family != b->family) {
54 0 : return true;
55 : }
56 87 : if (a->family == AF_INET) {
57 87 : return (a->binAddr.addr.s_addr != b->binAddr.addr.s_addr);
58 : } else {
59 0 : return memcmp(&a->binAddr.addr6, &b->binAddr.addr6, sizeof(b->binAddr.addr6));
60 : }
61 : }
62 :
63 3 : int RsGetIpv6ScopeId(struct in6_addr localIp)
64 : {
65 3 : struct in6_addr ipv6Addr = {0};
66 3 : struct ifaddrs *ifaddr = NULL;
67 3 : struct ifaddrs *ifa = NULL;
68 3 : int scopeId = 0;
69 : int ret, i;
70 :
71 3 : ret = getifaddrs(&ifaddr);
72 3 : CHK_PRT_RETURN(ret == -1, hccp_err("get ifaddrs failed, ret[%d]", ret), -ESYSFUNC);
73 : /* Walk through linked list, maintaining head pointer so we can free list later */
74 10 : for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
75 8 : if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6) {
76 8 : continue;
77 : }
78 0 : ipv6Addr = ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
79 0 : for (i = 0; i < IPV6_S6_ADDR_SIZE; i++) {
80 0 : if (ipv6Addr.s6_addr[i] != localIp.s6_addr[i]) {
81 0 : break;
82 : }
83 : }
84 0 : if (i == IPV6_S6_ADDR_SIZE) { /* all 16 u6_addr8 in ipv6 are equal */
85 0 : scopeId = (int)((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id;
86 0 : freeifaddrs(ifaddr);
87 0 : ifaddr = NULL;
88 0 : return scopeId;
89 : }
90 : }
91 :
92 2 : hccp_err("get scope id failed");
93 2 : freeifaddrs(ifaddr);
94 2 : ifaddr = NULL;
95 2 : return -EINVAL;
96 : }
97 :
98 2 : enum RsHardwareType RsGetDeviceType(unsigned int phyId)
99 : {
100 2 : int64_t deviceInfo = 0;
101 : unsigned int boardType;
102 : unsigned int logicId;
103 : unsigned int chipId;
104 : int64_t boardId;
105 : int ret;
106 :
107 2 : CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("invalid param phy_id[%u]", phyId), RS_HARDWARE_UNKNOWN);
108 2 : ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
109 2 : CHK_PRT_RETURN(ret != 0, hccp_err("phy_id[%u] invalid, ret %d", phyId, ret), RS_HARDWARE_UNKNOWN);
110 2 : ret = DlDrvDeviceGetIndexByPhyId(chipId, &logicId);
111 2 : CHK_PRT_RETURN(ret != 0, hccp_err("dl_drv_device_get_index_by_phy_id failed, ret(%d), chipId(%u)",
112 : ret, chipId), RS_HARDWARE_UNKNOWN);
113 :
114 2 : ret = DlHalGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_BOARD_ID, &boardId);
115 2 : CHK_PRT_RETURN(ret != 0, hccp_err("dl_hal_get_device_info board_id failed, ret[%d]", ret), RS_HARDWARE_UNKNOWN);
116 2 : hccp_info("board_id is (0x%llx)", boardId);
117 2 : boardType = (unsigned int)((uint64_t)boardId & (0xfff0));
118 2 : ret = DlHalGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &deviceInfo);
119 2 : CHK_PRT_RETURN(ret != 0, hccp_err("dl_hal_get_device_info device_info failed, ret(%d), phyId(%u)", ret, phyId),
120 : RS_HARDWARE_UNKNOWN);
121 :
122 : // 910A场景判断逻辑
123 2 : if (DlHalPlatGetChip((uint64_t)deviceInfo) == CHIP_TYPE_910A) {
124 0 : if (((boardType & RS_BOARDID_PCIE_CARD_MASK) == RS_BOARDID_PCIE_CARD_MASK_VALUE) &&
125 0 : (boardType != RS_BOARDID_AI_SERVER_MODULE) && (boardType != RS_BOARDID_ARM_SERVER_AG)) {
126 0 : return RS_HARDWARE_PCIE;
127 : }
128 0 : return RS_HARDWARE_SERVER;
129 : }
130 :
131 2 : if (((boardType & RS_BOARDID_PCIE_CARD_MASK) == RS_BOARDID_PCIE_CARD_MASK_VALUE) &&
132 0 : (boardType != RS_BOARDID_AI_SERVER_MODULE) && (boardType != RS_BOARDID_ARM_SERVER_AG) &&
133 0 : (boardType != RS_BOARDID_ARM_POD) && (boardType != RS_BOARDID_X86_16P) &&
134 : (boardType != RS_BOARDID_ARM_SERVER_2DIE)) {
135 0 : return RS_HARDWARE_PCIE;
136 : }
137 :
138 2 : if ((boardType == RS_BOARDID_ARM_SERVER_2DIE)) {
139 0 : return RS_HARDWARE_2DIE;
140 : }
141 2 : return RS_HARDWARE_SERVER;
142 : }
143 :
144 2 : int RsCheckDstInterface(unsigned int phyId, const char *ifaName, enum RsHardwareType type, bool isAll)
145 : {
146 2 : char dstIfaBondName[RS_INTERFACE_BOND_LEN + 1] = {0};
147 2 : char dstIfaName[RS_INTERFACE_LEN + 1] = {0};
148 : int ret, bondRet;
149 :
150 2 : if (isAll) {
151 : /* get information of all device with eth or bond prefix */
152 0 : if (strncmp("eth", ifaName, RS_INTERFACE_ETH_PREFIX_LEN) != 0 &&
153 0 : strncmp("bond", ifaName, RS_INTERFACE_BOND_PREFIX_LEN) != 0) {
154 0 : return 0;
155 : }
156 0 : return 1;
157 : }
158 :
159 : // 标卡场景910B和910A device网卡固定为eth0,处理标卡场景
160 2 : if (type == RS_HARDWARE_PCIE) {
161 0 : if (strncmp("eth0", ifaName, RS_INTERFACE_LEN) && strncmp("eth1", ifaName, RS_INTERFACE_LEN)) {
162 0 : return 0;
163 : }
164 0 : return 1;
165 2 : } else if (type == RS_HARDWARE_2DIE) {
166 : /* 1. For RoH mode, only "bondx" port is supported when binding groups,
167 : * and "ethx" port is used when unbinding ;
168 : * 2. For eth mode, only the eth port is supported
169 : */
170 0 : ret = snprintf_s(dstIfaName, RS_INTERFACE_LEN + 1, RS_INTERFACE_LEN, "eth%u", phyId);
171 0 : bondRet = snprintf_s(dstIfaBondName, RS_INTERFACE_BOND_LEN + 1, RS_INTERFACE_BOND_LEN, "bond%u", phyId);
172 0 : if (ret <= 0 || bondRet <= 0) {
173 0 : hccp_err("copy eth or bond name failed, ret(%d), bondRet(%d)", ret, bondRet);
174 0 : return -EAGAIN;
175 : }
176 :
177 0 : if (strncmp(dstIfaName, ifaName, RS_INTERFACE_LEN) &&
178 0 : strncmp(dstIfaBondName, ifaName, RS_INTERFACE_BOND_LEN)) {
179 0 : return 0;
180 : }
181 : } else {
182 2 : ret = snprintf_s(dstIfaName, RS_INTERFACE_LEN + 1, RS_INTERFACE_LEN, "eth%u", phyId);
183 2 : CHK_PRT_RETURN(ret <= 0, hccp_err("copy eth name failed, %d", ret), -EAGAIN);
184 :
185 2 : if (strncmp(dstIfaName, ifaName, RS_INTERFACE_LEN)) {
186 1 : return 0;
187 : }
188 : }
189 1 : return 1;
190 : }
191 :
192 1 : int RsPeerFillIfnum(unsigned int phyId, unsigned int *num, struct ifaddrs *ifaddrList)
193 : {
194 1 : struct ifaddrs *ifaddr = ifaddrList;
195 1 : struct ifaddrs *ifa = NULL;
196 : int family;
197 :
198 1 : *num = 0;
199 5 : for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
200 4 : if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
201 2 : continue;
202 : }
203 2 : family = ifa->ifa_addr->sa_family;
204 : /* If not an AF_INET/AF_INET6 interface address, continue */
205 2 : if ((family != AF_INET) && (family != AF_INET6)) {
206 0 : continue;
207 : }
208 2 : (*num)++;
209 : }
210 :
211 1 : hccp_dbg("phy_id:%u got interface num:%u", phyId, *num);
212 1 : return 0;
213 : }
214 :
215 1 : int RsPeerFillIfaddrInfos(struct InterfaceInfo interfaceInfos[], unsigned int *num,
216 : unsigned int phyId, struct ifaddrs *ifaddrList)
217 : {
218 1 : struct ifaddrs *ifaddr = ifaddrList;
219 1 : unsigned int numBak = *num;
220 1 : struct ifaddrs *ifa = NULL;
221 : int family, ret;
222 1 : *num = 0;
223 :
224 : /* Walk through linked list, maintaining head pointer so we can free list later */
225 5 : for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
226 4 : if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
227 2 : continue;
228 : }
229 2 : family = ifa->ifa_addr->sa_family;
230 : // /* If not an AF_INET/AF_INET6 interface address, continue */
231 2 : if ((family != AF_INET) && (family != AF_INET6)) {
232 0 : continue;
233 : }
234 :
235 2 : (*num)++;
236 2 : if ((*num) > numBak) {
237 0 : hccp_err("num of interfaces found is more than expect, expect[%u], actual[%u]", numBak, *num);
238 0 : goto out;
239 : }
240 2 : ret = strcpy_s(interfaceInfos[*num - 1].ifname, MAX_INTERFACE_NAME_LEN, ifa->ifa_name);
241 2 : if (ret != 0) {
242 0 : hccp_err("strcpy interface name failed, ret[%d]", ret);
243 0 : goto out;
244 : }
245 2 : interfaceInfos[*num - 1].scopeId = 0;
246 2 : if (family == AF_INET) {
247 2 : interfaceInfos[*num - 1].ifaddr.ip.addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
248 2 : interfaceInfos[*num - 1].ifaddr.mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
249 2 : hccp_info("ifname[%s] addr[0x%08x]", ifa->ifa_name, ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr);
250 : } else {
251 0 : interfaceInfos[*num - 1].ifaddr.ip.addr6 = ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
252 0 : interfaceInfos[*num - 1].scopeId = (int)((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id;
253 0 : hccp_info("ifname[%s] scope_id[%u] flowinfo[%u]", ifa->ifa_name,
254 : ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id,
255 : ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_flowinfo);
256 0 : for (unsigned long i = 0; i < sizeof(struct in6_addr); i++) {
257 0 : hccp_info("addr[%lu] 0x%02x", i, ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr.s6_addr[i]);
258 : }
259 : }
260 2 : interfaceInfos[*num - 1].family = family;
261 : }
262 :
263 1 : hccp_dbg("phy_id:%u got interface num:%u", phyId, *num);
264 1 : return 0;
265 0 : out:
266 0 : hccp_dbg("phy_id:%u got interface num:%u", phyId, *num);
267 0 : return -EAGAIN;
268 : }
269 :
270 0 : int RsDrvSslBindFd(struct RsConnInfo *conn, int fd)
271 : {
272 : int ret;
273 0 : if (conn->ssl == NULL) {
274 0 : conn->ssl = ssl_adp_new(gRsCb->clientSslCtx);
275 0 : CHK_PRT_RETURN(conn->ssl == NULL, hccp_err("server ssl ctx alloc failed"), -ENOMEM);
276 : }
277 :
278 0 : ssl_adp_set_mode(conn->ssl, SSL_MODE_AUTO_RETRY);
279 0 : ret = ssl_adp_set_fd(conn->ssl, fd);
280 0 : if (ret != 1) {
281 0 : hccp_err("bind connfd and ssl failed, ret %d", ret);
282 0 : goto out;
283 : }
284 :
285 0 : ssl_adp_set_connect_state(conn->ssl);
286 :
287 0 : return 0;
288 0 : out:
289 0 : ssl_adp_shutdown(conn->ssl);
290 0 : ssl_adp_free(conn->ssl);
291 0 : conn->ssl = NULL;
292 0 : return -EINVAL;
293 : }
294 :
295 16 : int RsDrvConnect(int fd, struct RsIpAddrInfo *serverIp, struct RsIpAddrInfo *clientIp, uint16_t port)
296 : {
297 16 : union RsSocketaddr clientAddr = { 0 };
298 16 : socklen_t clientAddrLen = 0;
299 16 : uint16_t clientPort = 0;
300 : int errNo;
301 : int ret;
302 :
303 16 : hccp_info("IP(%s) port %d family %d fd:%d begin", serverIp->readAddr, port, clientIp->family, fd);
304 16 : if (clientIp->family == AF_INET) {
305 16 : struct sockaddr_in addr = {0};
306 16 : addr.sin_family = clientIp->family;
307 16 : addr.sin_port = htons(port);
308 16 : addr.sin_addr = serverIp->binAddr.addr;
309 16 : ret = connect(fd, &addr, sizeof(addr));
310 : } else {
311 0 : struct sockaddr_in6 addr = {0};
312 0 : addr.sin6_family = clientIp->family;
313 0 : addr.sin6_port = htons(port);
314 0 : addr.sin6_addr = serverIp->binAddr.addr6;
315 0 : ret = connect(fd, &addr, sizeof(addr));
316 : }
317 :
318 16 : if (ret) {
319 0 : errNo = errno;
320 0 : if (errNo == -EISCONN) {
321 0 : goto out;
322 : }
323 :
324 : /*
325 : * if the errno is EINTR, it can not retry directly,
326 : * otherwise it will directly return an error
327 : */
328 0 : hccp_warn("connect not success, need to try again! server IP:%s, port:%d, fd:%d, ret:%d, errNo:%d",
329 : serverIp->readAddr, port, fd, ret, errNo);
330 :
331 0 : return -errNo;
332 : }
333 :
334 16 : out:
335 16 : clientAddrLen = (clientIp->family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
336 16 : getsockname(fd, (struct sockaddr *)&clientAddr, &clientAddrLen);
337 32 : clientPort =
338 16 : (clientIp->family == AF_INET) ? ntohs(clientAddr.sAddr.sin_port) : ntohs(clientAddr.sAddr6.sin6_port);
339 :
340 16 : if ((clientPort < 60000) || (clientPort > 60015)) { // HCCL默认监听60000-60015端口,如client使用该端口,记录EVENT日志
341 16 : hccp_info("client connect success. client family %d addr %s:%u, server addr %s:%u, fd:%d", clientIp->family,
342 : clientIp->readAddr, clientPort, serverIp->readAddr, port, fd);
343 : } else {
344 0 : hccp_run_info("client connect success. client family %d addr %s:%u, server addr %s:%u, fd:%d",
345 : clientIp->family, clientIp->readAddr, clientPort, serverIp->readAddr, port, fd);
346 : }
347 :
348 16 : return 0;
349 : }
350 :
351 62 : int RsFd2conn(int fd, struct RsConnInfo **conn)
352 : {
353 62 : struct RsConnInfo *connTmp = NULL;
354 62 : struct RsConnInfo *connTmp2 = NULL;
355 62 : struct RsListHead *head = NULL;
356 62 : struct rs_cb *rsCb = NULL;
357 :
358 62 : if (gRsCb != NULL) {
359 61 : rsCb = gRsCb;
360 : } else {
361 1 : hccp_err("g_rs_cb is NULL");
362 1 : return -ENODEV;
363 : }
364 :
365 61 : RS_PTHREAD_MUTEX_LOCK(&rsCb->connCb.connMutex);
366 61 : head = &rsCb->connCb.serverConnList;
367 61 : RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, head, list, struct RsConnInfo);
368 100 : for (; &connTmp->list != head;
369 39 : connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
370 66 : if (connTmp->connfd == fd) {
371 27 : *conn = connTmp;
372 27 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
373 27 : return 0;
374 : }
375 : }
376 :
377 34 : head = &rsCb->connCb.clientConnList;
378 34 : RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, head, list, struct RsConnInfo);
379 36 : for (; &connTmp->list != head;
380 2 : connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
381 33 : if (connTmp->connfd == fd) {
382 31 : *conn = connTmp;
383 31 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
384 31 : return 0;
385 : }
386 : }
387 :
388 3 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
389 :
390 3 : hccp_warn("cannot find conn node for fd:%d!", fd);
391 3 : *conn = NULL;
392 :
393 3 : return -ENODEV;
394 : }
395 :
396 0 : int RsSslWriteInnerCheck(struct RsConnInfo *conn, int sslRet, uint64_t size)
397 : {
398 0 : int err = ssl_adp_get_error(conn->ssl, sslRet);
399 0 : int fd = conn->connfd;
400 0 : int errNo = errno;
401 :
402 0 : rs_ssl_err_string(fd, err);
403 0 : CHK_PRT_RETURN((err == SSL_ERROR_WANT_WRITE) || (err == SSL_ERROR_WANT_READ),
404 : hccp_info("ssl_adp_write fd:%d need to retry, err:%d errno:%d", fd, err, errNo), -EAGAIN);
405 0 : CHK_PRT_RETURN((err == SSL_ERROR_SYSCALL) && (errNo == EAGAIN || errNo == EWOULDBLOCK || errNo == EINTR),
406 : hccp_info("ssl_adp_write fd:%d need to retry, err:%d errno:%d", fd, err, errNo), -EAGAIN);
407 :
408 : // degrade log level to prevent false alarms and log flooding in heartbeat monitor scenario
409 0 : hccp_warn("ssl_adp_write fd:%d ret:%d, size:%llu err:%d errno:%d", fd, sslRet, size, err, errNo);
410 0 : return sslRet;
411 : }
412 :
413 99 : int RsDrvSocketSend(int fd, const void *data, uint64_t size, int flags)
414 : {
415 99 : struct RsConnInfo *conn = NULL;
416 99 : int ret = 0;
417 : int errNo;
418 :
419 99 : CHK_PRT_RETURN(fd < 0 || size == 0 || data == NULL, hccp_err("param error ! fd:%d < 0, size:%llu or data is NULL",
420 : fd, size), -EINVAL);
421 :
422 98 : if (gRsCb->sslEnable == RS_SSL_ENABLE) {
423 0 : ret = RsFd2conn(fd, &conn);
424 0 : CHK_PRT_RETURN(ret != 0, hccp_err("fd:%d to conn failed, ret:%d", fd, ret), ret);
425 0 : ret = ssl_adp_write(conn->ssl, data, size);
426 0 : if (ret <= 0) {
427 0 : ret = RsSslWriteInnerCheck(conn, ret, size);
428 : }
429 : } else {
430 98 : ret = send(fd, data, size, flags);
431 98 : if (ret < 0) {
432 3 : errNo = errno;
433 3 : if (errNo == EAGAIN || errNo == EINTR) {
434 0 : hccp_dbg("send to fd:%d need retry, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
435 0 : ret = -EAGAIN;
436 : } else {
437 3 : hccp_warn("send to fd:%d not success, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
438 3 : ret = -EFILEOPER;
439 : }
440 : }
441 : }
442 :
443 98 : return ret;
444 : }
445 :
446 0 : int RsSslReadInnerCheck(struct RsConnInfo *conn, int sslRet, uint64_t size)
447 : {
448 0 : int err = ssl_adp_get_error(conn->ssl, sslRet);
449 0 : int fd = conn->connfd;
450 0 : int errNo = errno;
451 :
452 0 : rs_ssl_err_string(fd, err);
453 0 : CHK_PRT_RETURN((err == SSL_ERROR_WANT_WRITE) || (err == SSL_ERROR_WANT_READ),
454 : hccp_dbg("ssl_adp_read fd:%d need to retry, err:%d errno:%d", fd, err, errNo), -EAGAIN);
455 0 : CHK_PRT_RETURN((err == SSL_ERROR_SYSCALL) && (errNo == EAGAIN || errNo == EWOULDBLOCK || errNo == EINTR),
456 : hccp_dbg("ssl_adp_read fd:%d need to retry, err:%d errno:%d", fd, err, errNo), -EAGAIN);
457 :
458 : // degrade log level to prevent false alarms and log flooding in heartbeat monitor scenario
459 0 : hccp_warn("ssl_adp_read fd:%d ret:%d, size:%llu err:%d errno:%d", fd, sslRet, size, err, errNo);
460 0 : return sslRet;
461 : }
462 :
463 28 : int RsDrvSocketRecv(int fd, void *data, uint64_t size, int flags)
464 : {
465 28 : struct RsConnInfo *conn = NULL;
466 28 : int ret = 0;
467 : int errNo;
468 :
469 28 : CHK_PRT_RETURN(fd < 0 || data == NULL || size == 0, hccp_err("param error ! fd:%d < 0 or data is NULL, size:%llu",
470 : fd, size), -EINVAL);
471 :
472 27 : if (gRsCb->sslEnable == RS_SSL_ENABLE) {
473 0 : ret = RsFd2conn(fd, &conn);
474 0 : CHK_PRT_RETURN(ret, hccp_warn("can not find conn for fd[%d], ret:%d, the local fd may have been closed ",
475 : fd, ret), ret);
476 0 : ret = ssl_adp_read(conn->ssl, data, size);
477 0 : if (ret <= 0) {
478 0 : ret = RsSslReadInnerCheck(conn, ret, size);
479 : }
480 : } else {
481 27 : ret = recv(fd, data, size, flags);
482 27 : if (ret < 0) {
483 14 : errNo = errno;
484 : // not to print to avoid log flush
485 14 : if (errNo == EAGAIN || errNo == EINTR) {
486 14 : ret = -EAGAIN;
487 : } else {
488 0 : hccp_warn("recv for fd:%d not success, recv size:%llu, ret:%d, errNo:%d", fd, size, ret, errNo);
489 0 : ret = -EFILEOPER;
490 : }
491 : }
492 : }
493 :
494 27 : return ret;
495 : }
496 :
497 16 : void ShowConnNode(struct RsListHead *listHead)
498 : {
499 16 : struct RsConnInfo *connTmp2 = NULL;
500 16 : struct RsConnInfo *connTmp = NULL;
501 :
502 16 : RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, listHead, list, struct RsConnInfo);
503 33 : for (; (&connTmp->list) != listHead;
504 17 : connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
505 17 : hccp_info("current server ip: %s, client ip:%s, fd:%d, state:%d, tag:%s", connTmp->serverIp.readAddr,
506 : connTmp->clientIp.readAddr, connTmp->connfd, connTmp->state, connTmp->tag);
507 : }
508 16 : }
509 :
510 16 : int RsGetConnInfo(struct RsConnCb *connCb, struct SocketConnectInfo *conn,
511 : struct RsConnInfo **connInfo, unsigned int serverPort)
512 : {
513 16 : struct RsConnInfo *connTmp2 = NULL;
514 16 : struct RsConnInfo *connTmp = NULL;
515 : struct RsIpAddrInfo ipAddr;
516 : int ret;
517 :
518 16 : RS_CHECK_POINTER_NULL_RETURN_INT(connCb);
519 16 : RS_CHECK_POINTER_NULL_RETURN_INT(conn);
520 :
521 16 : ret = RsConvertIpAddr(conn->family, &conn->remoteIp, &ipAddr);
522 16 : CHK_PRT_RETURN(ret != 0, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
523 :
524 16 : RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
525 16 : RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, &connCb->clientConnList, list, struct RsConnInfo);
526 17 : for (; (&connTmp->list) != &connCb->clientConnList;
527 1 : connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
528 1 : if ((!RsCompareIpAddr(&connTmp->serverIp, &ipAddr)) && connTmp->port == serverPort) {
529 1 : ret = strcmp(connTmp->tag, conn->tag);
530 1 : if (ret == 0) {
531 0 : *connInfo = connTmp;
532 0 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
533 0 : return 0;
534 : }
535 : }
536 : }
537 16 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
538 :
539 16 : conn->tag[SOCK_CONN_TAG_SIZE - 1] = '\0';
540 16 : hccp_warn("conn node for IP(%s) server_port(%u) tag(%s) not found", ipAddr.readAddr, serverPort, conn->tag);
541 16 : return -ENODEV;
542 : }
543 :
544 71 : int RsFindListenNode(struct RsConnCb *connCb, struct RsIpAddrInfo *ipAddr, uint32_t serverPort,
545 : struct RsListenInfo **listenInfo)
546 : {
547 71 : struct RsListenInfo *listenTmp2 = NULL;
548 71 : struct RsListenInfo *listenTmp = NULL;
549 :
550 71 : RS_CHECK_POINTER_NULL_WITH_RET(connCb);
551 71 : RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
552 71 : RS_LIST_GET_HEAD_ENTRY(listenTmp, listenTmp2, &connCb->listenList, list, struct RsListenInfo);
553 73 : for (; (&listenTmp->list) != &connCb->listenList;
554 2 : listenTmp = listenTmp2, listenTmp2 = list_entry(listenTmp2->list.next, struct RsListenInfo, list)) {
555 21 : if ((!RsCompareIpAddr(&listenTmp->serverIpAddr, ipAddr)) && (listenTmp->sockPort == serverPort)) {
556 19 : *listenInfo = listenTmp;
557 19 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
558 19 : return 0;
559 : }
560 : }
561 52 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
562 :
563 52 : hccp_info("listen node for IP(%s), serverPort(%u) is not listen!", ipAddr->readAddr, serverPort);
564 52 : return -ENODEV;
565 : }
566 :
567 1 : int RsSocketListenAddToEpoll(struct RsConnCb *connCb, struct RsListenInfo *listenInfo)
568 : {
569 1 : int ret = 0;
570 :
571 1 : RS_PTHREAD_MUTEX_LOCK(&listenInfo->acceptCreditMutex);
572 1 : if (listenInfo->fdState == LISTEN_FD_STATE_ADDED) {
573 0 : goto out;
574 : }
575 :
576 : // should ctl_add to make sure epoll event can be triggered
577 1 : hccp_run_info("IP:%s server_port:%u listen_fd:%d add to epoll:%d", listenInfo->serverIpAddr.readAddr,
578 : listenInfo->sockPort, listenInfo->listenFd, connCb->epollfd);
579 1 : ret = RsEpollCtl(connCb->epollfd, EPOLL_CTL_ADD, listenInfo->listenFd, EPOLLIN);
580 1 : if (ret != 0) {
581 0 : hccp_err("IP:%s server_port:%u listen_fd:%d rs_epoll_ctl failed, ret:%d errno:%d",
582 : listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, listenInfo->listenFd, ret, errno);
583 0 : goto out;
584 : }
585 :
586 1 : listenInfo->fdState = LISTEN_FD_STATE_ADDED;
587 :
588 1 : out:
589 1 : RS_PTHREAD_MUTEX_ULOCK(&listenInfo->acceptCreditMutex);
590 1 : return ret;
591 : }
592 :
593 24 : STATIC int RsListenCreditLimitInit(struct RsListenInfo *listenInfo)
594 : {
595 : int ret;
596 :
597 24 : ret = pthread_mutex_init(&listenInfo->acceptCreditMutex, NULL);
598 24 : CHK_PRT_RETURN(ret != 0, hccp_err("mutex_init accept_credit_mutex failed, ret:%d", ret), -ESYSFUNC);
599 24 : return 0;
600 : }
601 :
602 23 : STATIC void RsListenCreditLimitDeinit(struct RsListenInfo *listenInfo)
603 : {
604 23 : (void)pthread_mutex_destroy(&listenInfo->acceptCreditMutex);
605 23 : }
606 :
607 25 : int RsListenNodeAlloc(struct RsConnCb *connCb, struct RsIpAddrInfo *ipAddr, uint32_t serverPort,
608 : struct RsListenInfo **node)
609 : {
610 25 : struct RsListenInfo *listenInfo = NULL;
611 : int ret;
612 :
613 25 : ret = RsFindListenNode(connCb, ipAddr, serverPort, &listenInfo);
614 25 : CHK_PRT_RETURN(ret == 0,
615 : hccp_info("listen node for IP(%s) exist! state:%u", ipAddr->readAddr, listenInfo->state), -EEXIST);
616 :
617 25 : listenInfo = calloc(1, sizeof(struct RsListenInfo));
618 25 : CHK_PRT_RETURN(listenInfo == NULL, hccp_err("alloc mem for socket listen info failed!"), -ENOMEM);
619 :
620 24 : hccp_info("create listen node for IP(%s)!", ipAddr->readAddr);
621 24 : listenInfo->serverIpAddr = *ipAddr;
622 24 : listenInfo->state = RS_CONN_STATE_RESET;
623 24 : ret = RsListenCreditLimitInit(listenInfo);
624 24 : if (ret != 0) {
625 0 : hccp_err("rs_listen_credit_limit_init failed, ret:%d", ret);
626 0 : free(listenInfo);
627 0 : listenInfo = NULL;
628 0 : return ret;
629 : }
630 :
631 24 : RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
632 24 : RsListAddTail(&listenInfo->list, &connCb->listenList);
633 24 : (void)__sync_fetch_and_add(&(listenInfo->counter), 1);
634 24 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
635 :
636 24 : *node = listenInfo;
637 :
638 24 : return 0;
639 : }
640 :
641 19 : int RsSocketListenDelFromEpoll(struct RsConnCb *connCb, struct RsListenInfo *listenInfo)
642 : {
643 19 : int ret = 0;
644 :
645 19 : RS_PTHREAD_MUTEX_LOCK(&listenInfo->acceptCreditMutex);
646 19 : if (listenInfo->fdState == LISTEN_FD_STATE_DELETED) {
647 1 : goto out;
648 : }
649 :
650 18 : hccp_run_info("IP:%s server_port:%u listen_fd:%d del from epoll:%d", listenInfo->serverIpAddr.readAddr,
651 : listenInfo->sockPort, listenInfo->listenFd, connCb->epollfd);
652 18 : ret = RsEpollCtl(connCb->epollfd, EPOLL_CTL_DEL, listenInfo->listenFd, EPOLLIN);
653 18 : if (ret != 0) {
654 1 : hccp_err("IP:%s server_port:%u listen_fd:%d rs_epoll_ctl failed, ret:%d errno:%d",
655 : listenInfo->serverIpAddr.readAddr, listenInfo->sockPort, listenInfo->listenFd, ret, errno);
656 1 : goto out;
657 : }
658 :
659 17 : listenInfo->fdState = LISTEN_FD_STATE_DELETED;
660 :
661 19 : out:
662 19 : RS_PTHREAD_MUTEX_ULOCK(&listenInfo->acceptCreditMutex);
663 19 : return ret;
664 : }
665 :
666 23 : void RsListenNodeFree(struct RsConnCb *connCb, struct RsListenInfo *node)
667 : {
668 23 : RS_CHECK_POINTER_NULL_RETURN_VOID(connCb);
669 23 : RS_CHECK_POINTER_NULL_RETURN_VOID(node);
670 :
671 23 : hccp_dbg("delete listen node for (IP %s : port %u)!", node->serverIpAddr.readAddr, node->sockPort);
672 :
673 23 : RS_PTHREAD_MUTEX_LOCK(&connCb->rscb->mutex);
674 23 : RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
675 23 : RsListDel(&node->list);
676 23 : RsListenCreditLimitDeinit(node);
677 23 : free(node);
678 23 : node = NULL;
679 23 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
680 23 : RS_PTHREAD_MUTEX_ULOCK(&connCb->rscb->mutex);
681 :
682 23 : return;
683 : }
684 :
685 16 : int RsAllocConnNode(struct RsConnInfo **conn, unsigned short serverPort)
686 : {
687 : struct RsConnInfo *connInfo;
688 :
689 16 : connInfo = calloc(1, sizeof(struct RsConnInfo));
690 16 : CHK_PRT_RETURN(connInfo == NULL, hccp_err("alloc mem for socket conn info failed!"), -ENOMEM);
691 :
692 16 : connInfo->port = serverPort;
693 16 : connInfo->connfd = RS_FD_INVALID;
694 16 : connInfo->state = RS_CONN_STATE_RESET;
695 :
696 16 : *conn = connInfo;
697 :
698 16 : return 0;
699 : }
700 :
701 15 : int RsFindWhiteListNode(struct RsWhiteList *rsSocketWhiteList,
702 : struct SocketWlistInfoT *whiteListExpect, int family, struct RsWhiteListInfo **whiteListNode)
703 : {
704 15 : struct RsWhiteListInfo *whiteListTmp2 = NULL;
705 15 : struct RsWhiteListInfo *whiteListTmp = NULL;
706 : struct RsIpAddrInfo expectIp;
707 : int ret;
708 :
709 15 : ret = RsConvertIpAddr(family, &whiteListExpect->remoteIp, &expectIp);
710 15 : CHK_PRT_RETURN(ret != 0, hccp_err("convert(ntop) ip failed, ret:%d", ret), ret);
711 :
712 15 : RS_CHECK_POINTER_NULL_WITH_RET(rsSocketWhiteList);
713 15 : RS_LIST_GET_HEAD_ENTRY(whiteListTmp, whiteListTmp2, &rsSocketWhiteList->whiteList, list,
714 : struct RsWhiteListInfo);
715 17 : for (; (&whiteListTmp->list) != &rsSocketWhiteList->whiteList;
716 2 : whiteListTmp = whiteListTmp2, whiteListTmp2 = list_entry(whiteListTmp2->list.next,
717 : struct RsWhiteListInfo, list)) {
718 4 : hccp_info("client_ip %s 0x%08x, expectIp %s 0x%08x",
719 : whiteListTmp->clientIp.readAddr, whiteListTmp->clientIp.binAddr.addr.s_addr,
720 : expectIp.readAddr, expectIp.binAddr.addr.s_addr);
721 4 : if ((!RsCompareIpAddr(&whiteListTmp->clientIp, &expectIp)) &&
722 4 : (strncmp(whiteListTmp->tag, whiteListExpect->tag, SOCK_CONN_TAG_SIZE) == 0)) {
723 2 : *whiteListNode = whiteListTmp;
724 2 : return 0;
725 : }
726 : }
727 :
728 13 : whiteListExpect->tag[SOCK_CONN_TAG_SIZE - 1] = '\0';
729 13 : hccp_info("white list node for IP(%s), tag(%s) doesn't exist!", expectIp.readAddr, whiteListExpect->tag);
730 13 : return -ENODEV;
731 : }
732 :
733 15 : int RsFindWhiteList(struct RsConnCb *connCb, struct RsIpAddrInfo *serverIp,
734 : struct RsWhiteList **whiteList)
735 : {
736 15 : struct RsWhiteList *whiteListTmp2 = NULL;
737 15 : struct RsWhiteList *whiteListTmp = NULL;
738 :
739 15 : RS_CHECK_POINTER_NULL_WITH_RET(connCb);
740 15 : RS_PTHREAD_MUTEX_LOCK(&connCb->connMutex);
741 15 : RS_LIST_GET_HEAD_ENTRY(whiteListTmp, whiteListTmp2, &connCb->whiteList, list, struct RsWhiteList);
742 15 : for (; (&whiteListTmp->list) != &connCb->whiteList;
743 0 : whiteListTmp = whiteListTmp2, whiteListTmp2 = list_entry(whiteListTmp2->list.next,
744 : struct RsWhiteList, list)) {
745 4 : if (!RsCompareIpAddr(serverIp, &whiteListTmp->serverIp)) {
746 4 : *whiteList = whiteListTmp;
747 4 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
748 4 : return 0;
749 : }
750 : }
751 11 : RS_PTHREAD_MUTEX_ULOCK(&connCb->connMutex);
752 :
753 11 : hccp_info("white list for IP(%s) doesn't exist!", serverIp->readAddr);
754 11 : return -ENODEV;
755 : }
756 :
757 19 : void RsSocketGetBindByChip(unsigned int chipId, bool *bindIp)
758 : {
759 : #define CHIP_NAME_910_93 "910_93"
760 19 : halChipInfo chipInfo = { 0 };
761 19 : int64_t deviceInfo = 0;
762 : unsigned int logicId;
763 : int ret;
764 :
765 : // get chip info failed, return directly to avoid exit from batch connect
766 19 : ret = DlDrvDeviceGetIndexByPhyId(chipId, &logicId);
767 19 : if (ret != 0) {
768 1 : hccp_warn("dl_drv_device_get_index_by_phy_id unsuccessful, ret(%d), chipId(%u)", ret, chipId);
769 1 : return;
770 : }
771 18 : ret = DlHalGetDeviceInfo(logicId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &deviceInfo);
772 18 : if (ret != 0) {
773 1 : hccp_warn("dl_hal_get_device_info unsuccessful, ret(%d), logicId(%u)", ret, logicId);
774 1 : return;
775 : }
776 :
777 : // chip force to bind: 310P & 910_93
778 34 : if ((DlHalPlatGetChip((uint64_t)deviceInfo) == CHIP_TYPE_310P) ||
779 17 : ((DlHalPlatGetChip((uint64_t)deviceInfo) == CHIP_TYPE_910B_910_93) &&
780 0 : (DlHalPlatGetVer((uint64_t)deviceInfo) >= VER_BIN5) &&
781 0 : (DlHalPlatGetVer((uint64_t)deviceInfo) <= VER_BIN8))) {
782 0 : *bindIp = true;
783 0 : return;
784 : }
785 :
786 : // get chip info, chip force to bind: 910_93
787 17 : ret = DlHalGetChipInfo(logicId, &chipInfo);
788 17 : if (ret != 0) {
789 1 : hccp_warn("dl_hal_get_chip_info unsuccessful, ret(%d), logicId(%u)", ret, logicId);
790 1 : return;
791 : }
792 16 : if (strncmp((char *)chipInfo.name, CHIP_NAME_910_93, sizeof(CHIP_NAME_910_93) - 1) == 0) {
793 1 : *bindIp = true;
794 : }
795 :
796 16 : return;
797 : }
798 :
799 16 : bool RsSocketIsVnicIp(unsigned int chipId, unsigned int ipAddr)
800 : {
801 16 : unsigned int vnicIp = 0;
802 16 : int64_t deviceInfo = 0;
803 16 : unsigned int phyId = 0;
804 16 : bool bindIp = false;
805 : int hccpMode;
806 : int ret;
807 :
808 : // no need to handle other mode, only need to handle HDC mode
809 16 : hccpMode = RsGetHccpMode(chipId);
810 16 : if (hccpMode != NETWORK_OFFLINE) {
811 1 : return false;
812 : }
813 :
814 : // check chip info: 310P & 910_93 will force to bind, no need to compare ip_addr with vnic ip
815 15 : RsSocketGetBindByChip(chipId, &bindIp);
816 15 : if (bindIp) {
817 0 : return false;
818 : }
819 :
820 : // compare ip_addr with current vnic_ip
821 15 : ret = rsGetDevIDByLocalDevID(chipId, &phyId);
822 15 : if (ret != 0) {
823 0 : hccp_warn("rsGetDevIDByLocalDevID unsuccessful, ret(%d), chipId(%u)", ret, chipId);
824 0 : return false;
825 : }
826 :
827 15 : ret = DlHalGetDeviceInfo(phyId, MODULE_TYPE_SYSTEM, INFO_TYPE_VNIC_IP, &deviceInfo);
828 15 : if (ret != 0) {
829 0 : hccp_warn("dl_hal_get_device_info unsuccessful, ret(%d), chipId(%u), phyId(%u)", ret, chipId, phyId);
830 0 : return false;
831 : }
832 :
833 15 : vnicIp = (unsigned int)deviceInfo;
834 15 : hccp_dbg("chip_id:%u phy_id:%u vnic_ip:%u ip_addr:%u", chipId, phyId, vnicIp, ipAddr);
835 15 : if (vnicIp == ipAddr) {
836 0 : return true;
837 : }
838 :
839 15 : return false;
840 : }
841 :
842 16 : void RsConnCostTime(struct RsConnInfo *conn)
843 : {
844 16 : float timeCost = 0.0;
845 :
846 16 : RsGetCurTime(&conn->endTime);
847 16 : HccpTimeInterval(&conn->endTime, &conn->startTime, &timeCost);
848 16 : if (timeCost > RS_EXPECT_TIME_MAX) {
849 0 : hccp_warn("socket [%d] connect success cost [%f] ms more than[%f]ms!", conn->connfd, timeCost,
850 : RS_EXPECT_TIME_MAX);
851 : } else {
852 16 : hccp_info("socket [%d] connect success! cost [%f] ms", conn->connfd, timeCost);
853 : }
854 :
855 16 : return;
856 : }
|