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