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 a invalid, err(%d), family %d", errno, family), -EINVAL);
39 231 : 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)", ret, chipId),
112 : 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) && strncmp(dstIfaBondName, ifaName, RS_INTERFACE_BOND_LEN)) {
178 0 : return 0;
179 : }
180 : } else {
181 2 : ret = snprintf_s(dstIfaName, RS_INTERFACE_LEN + 1, RS_INTERFACE_LEN, "eth%u", phyId);
182 2 : CHK_PRT_RETURN(ret <= 0, hccp_err("copy eth name failed, %d", ret), -EAGAIN);
183 :
184 2 : if (strncmp(dstIfaName, ifaName, RS_INTERFACE_LEN)) {
185 1 : return 0;
186 : }
187 : }
188 1 : return 1;
189 : }
190 :
191 1 : int RsPeerFillIfnum(unsigned int phyId, unsigned int *num, struct ifaddrs *ifaddrList)
192 : {
193 1 : struct ifaddrs *ifaddr = ifaddrList;
194 1 : struct ifaddrs *ifa = NULL;
195 : int family;
196 :
197 1 : *num = 0;
198 5 : for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
199 4 : if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
200 2 : continue;
201 : }
202 2 : family = ifa->ifa_addr->sa_family;
203 : /* If not an AF_INET/AF_INET6 interface address, continue */
204 2 : if ((family != AF_INET) && (family != AF_INET6)) {
205 0 : continue;
206 : }
207 2 : (*num)++;
208 : }
209 :
210 1 : hccp_dbg("phy_id:%u got interface num:%u", phyId, *num);
211 1 : return 0;
212 : }
213 :
214 1 : int RsPeerFillIfaddrInfos(struct InterfaceInfo interfaceInfos[], unsigned int *num, unsigned int phyId,
215 : struct ifaddrs *ifaddrList)
216 : {
217 1 : struct ifaddrs *ifaddr = ifaddrList;
218 1 : unsigned int numBak = *num;
219 1 : struct ifaddrs *ifa = NULL;
220 : int family, ret;
221 1 : *num = 0;
222 :
223 : /* Walk through linked list, maintaining head pointer so we can free list later */
224 5 : for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
225 4 : if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL) {
226 2 : continue;
227 : }
228 2 : family = ifa->ifa_addr->sa_family;
229 : // /* If not an AF_INET/AF_INET6 interface address, continue */
230 2 : if ((family != AF_INET) && (family != AF_INET6)) {
231 0 : continue;
232 : }
233 :
234 2 : (*num)++;
235 2 : if ((*num) > numBak) {
236 0 : hccp_err("num of interfaces found is more than expect, expect[%u], actual[%u]", numBak, *num);
237 0 : goto out;
238 : }
239 2 : ret = strcpy_s(interfaceInfos[*num - 1].ifname, MAX_INTERFACE_NAME_LEN, ifa->ifa_name);
240 2 : if (ret != 0) {
241 0 : hccp_err("strcpy interface name failed, ret[%d]", ret);
242 0 : goto out;
243 : }
244 2 : interfaceInfos[*num - 1].scopeId = 0;
245 2 : if (family == AF_INET) {
246 2 : interfaceInfos[*num - 1].ifaddr.ip.addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
247 2 : interfaceInfos[*num - 1].ifaddr.mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
248 2 : hccp_info("ifname[%s] addr[0x%08x]", ifa->ifa_name, ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr);
249 : } else {
250 0 : interfaceInfos[*num - 1].ifaddr.ip.addr6 = ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
251 0 : interfaceInfos[*num - 1].scopeId = (int)((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id;
252 0 : hccp_info("ifname[%s] scope_id[%u] flowinfo[%u]", ifa->ifa_name,
253 : ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id,
254 : ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_flowinfo);
255 0 : for (unsigned long i = 0; i < sizeof(struct in6_addr); i++) {
256 0 : hccp_info("addr[%lu] 0x%02x", i, ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr.s6_addr[i]);
257 : }
258 : }
259 2 : interfaceInfos[*num - 1].family = family;
260 : }
261 :
262 1 : hccp_dbg("phy_id:%u got interface num:%u", phyId, *num);
263 1 : return 0;
264 0 : out:
265 0 : hccp_dbg("phy_id:%u got interface num:%u", phyId, *num);
266 0 : return -EAGAIN;
267 : }
268 :
269 0 : int RsDrvSslBindFd(struct RsConnInfo *conn, int fd)
270 : {
271 : int ret;
272 0 : if (conn->ssl == NULL) {
273 0 : conn->ssl = ssl_adp_new(gRsCb->clientSslCtx);
274 0 : CHK_PRT_RETURN(conn->ssl == NULL, hccp_err("server ssl ctx alloc failed"), -ENOMEM);
275 : }
276 :
277 0 : ssl_adp_set_mode(conn->ssl, SSL_MODE_AUTO_RETRY);
278 0 : ret = ssl_adp_set_fd(conn->ssl, fd);
279 0 : if (ret != 1) {
280 0 : hccp_err("bind connfd and ssl failed, ret %d", ret);
281 0 : goto out;
282 : }
283 :
284 0 : ssl_adp_set_connect_state(conn->ssl);
285 :
286 0 : return 0;
287 0 : out:
288 0 : ssl_adp_shutdown(conn->ssl);
289 0 : ssl_adp_free(conn->ssl);
290 0 : conn->ssl = NULL;
291 0 : return -EINVAL;
292 : }
293 :
294 16 : int RsDrvConnect(int fd, struct RsIpAddrInfo *serverIp, struct RsIpAddrInfo *clientIp, uint16_t port)
295 : {
296 16 : union RsSocketaddr clientAddr = {0};
297 16 : socklen_t clientAddrLen = 0;
298 16 : uint16_t clientPort = 0;
299 : int errNo;
300 : int ret;
301 :
302 16 : hccp_info("IP(%s) port %d family %d fd:%d begin", serverIp->readAddr, port, clientIp->family, fd);
303 16 : if (clientIp->family == AF_INET) {
304 16 : struct sockaddr_in addr = {0};
305 16 : addr.sin_family = clientIp->family;
306 16 : addr.sin_port = htons(port);
307 16 : addr.sin_addr = serverIp->binAddr.addr;
308 16 : ret = connect(fd, &addr, sizeof(addr));
309 : } else {
310 0 : struct sockaddr_in6 addr = {0};
311 0 : addr.sin6_family = clientIp->family;
312 0 : addr.sin6_port = htons(port);
313 0 : addr.sin6_addr = serverIp->binAddr.addr6;
314 0 : ret = connect(fd, &addr, sizeof(addr));
315 : }
316 :
317 16 : if (ret) {
318 0 : errNo = errno;
319 0 : if (errNo == -EISCONN) {
320 0 : goto out;
321 : }
322 :
323 : /*
324 : * if the errno is EINTR, it can not retry directly,
325 : * otherwise it will directly return an error
326 : */
327 0 : hccp_warn("connect not success, need to try again! server IP:%s, port:%d, fd:%d, ret:%d, errNo:%d",
328 : serverIp->readAddr, port, fd, ret, errNo);
329 :
330 0 : return -errNo;
331 : }
332 :
333 16 : out:
334 16 : clientAddrLen = (clientIp->family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
335 16 : getsockname(fd, (struct sockaddr *)&clientAddr, &clientAddrLen);
336 16 : clientPort = (clientIp->family == AF_INET) ? ntohs(clientAddr.sAddr.sin_port) : ntohs(clientAddr.sAddr6.sin6_port);
337 :
338 16 : if ((clientPort < 60000) || (clientPort > 60015)) { // HCCL默认监听60000-60015端口,如client使用该端口,记录EVENT日志
339 16 : hccp_info("client connect success. client family %d addr %s:%u, server addr %s:%u, fd:%d", clientIp->family,
340 : clientIp->readAddr, clientPort, serverIp->readAddr, port, fd);
341 : } else {
342 0 : hccp_run_info("client connect success. client family %d addr %s:%u, server addr %s:%u, fd:%d", clientIp->family,
343 : clientIp->readAddr, clientPort, serverIp->readAddr, port, fd);
344 : }
345 :
346 16 : return 0;
347 : }
348 :
349 62 : int RsFd2conn(int fd, struct RsConnInfo **conn)
350 : {
351 62 : struct RsConnInfo *connTmp = NULL;
352 62 : struct RsConnInfo *connTmp2 = NULL;
353 62 : struct RsListHead *head = NULL;
354 62 : struct rs_cb *rsCb = NULL;
355 :
356 62 : if (gRsCb != NULL) {
357 61 : rsCb = gRsCb;
358 : } else {
359 1 : hccp_err("g_rs_cb is NULL");
360 1 : return -ENODEV;
361 : }
362 :
363 61 : RS_PTHREAD_MUTEX_LOCK(&rsCb->connCb.connMutex);
364 61 : head = &rsCb->connCb.serverConnList;
365 61 : RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, head, list, struct RsConnInfo);
366 100 : for (; &connTmp->list != head;
367 39 : connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
368 66 : if (connTmp->connfd == fd) {
369 27 : *conn = connTmp;
370 27 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
371 27 : return 0;
372 : }
373 : }
374 :
375 34 : head = &rsCb->connCb.clientConnList;
376 34 : RS_LIST_GET_HEAD_ENTRY(connTmp, connTmp2, head, list, struct RsConnInfo);
377 36 : for (; &connTmp->list != head;
378 2 : connTmp = connTmp2, connTmp2 = list_entry(connTmp2->list.next, struct RsConnInfo, list)) {
379 33 : if (connTmp->connfd == fd) {
380 31 : *conn = connTmp;
381 31 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
382 31 : return 0;
383 : }
384 : }
385 :
386 3 : RS_PTHREAD_MUTEX_ULOCK(&rsCb->connCb.connMutex);
387 :
388 3 : hccp_warn("cannot find conn node for fd:%d!", fd);
389 3 : *conn = NULL;
390 :
391 3 : return -ENODEV;
392 : }
393 :
394 0 : int RsSslWriteInnerCheck(struct RsConnInfo *conn, int sslRet, uint64_t size)
395 : {
396 0 : int err = ssl_adp_get_error(conn->ssl, sslRet);
397 0 : int fd = conn->connfd;
398 0 : int errNo = errno;
399 :
400 0 : rs_ssl_err_string(fd, err);
401 0 : CHK_PRT_RETURN((err == SSL_ERROR_WANT_WRITE) || (err == SSL_ERROR_WANT_READ),
402 : hccp_info("ssl_adp_write fd:%d need to retry, err:%d errno:%d", fd, err, errNo), -EAGAIN);
403 0 : CHK_PRT_RETURN((err == SSL_ERROR_SYSCALL) && (errNo == EAGAIN || errNo == EWOULDBLOCK || errNo == EINTR),
404 : hccp_info("ssl_adp_write fd:%d need to retry, err:%d errno:%d", fd, err, errNo), -EAGAIN);
405 :
406 : // degrade log level to prevent false alarms and log flooding in heartbeat monitor scenario
407 0 : hccp_warn("ssl_adp_write fd:%d ret:%d, size:%llu err:%d errno:%d", fd, sslRet, size, err, errNo);
408 0 : return sslRet;
409 : }
410 :
411 99 : int RsDrvSocketSend(int fd, const void *data, uint64_t size, int flags)
412 : {
413 99 : struct RsConnInfo *conn = NULL;
414 99 : int ret = 0;
415 : int errNo;
416 :
417 99 : CHK_PRT_RETURN(fd < 0 || size == 0 || data == NULL,
418 : hccp_err("param error ! fd:%d < 0, size:%llu or data is NULL", fd, size), -EINVAL);
419 :
420 98 : if (gRsCb->sslEnable == RS_SSL_ENABLE) {
421 0 : ret = RsFd2conn(fd, &conn);
422 0 : CHK_PRT_RETURN(ret != 0, hccp_err("fd:%d to conn failed, ret:%d", fd, ret), ret);
423 0 : ret = ssl_adp_write(conn->ssl, data, size);
424 0 : if (ret <= 0) {
425 0 : ret = RsSslWriteInnerCheck(conn, ret, size);
426 : }
427 : } else {
428 98 : ret = send(fd, data, size, flags);
429 98 : if (ret < 0) {
430 3 : errNo = errno;
431 3 : if (errNo == EAGAIN || errNo == EINTR) {
432 0 : hccp_dbg("send to fd:%d need retry, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
433 0 : ret = -EAGAIN;
434 : } else {
435 3 : hccp_warn("send to fd:%d not success, send size:%llu, ret:%d, errno:%d", fd, size, ret, errNo);
436 3 : ret = -EFILEOPER;
437 : }
438 : }
439 : }
440 :
441 98 : return ret;
442 : }
443 :
444 0 : int RsSslReadInnerCheck(struct RsConnInfo *conn, int sslRet, uint64_t size)
445 : {
446 0 : int err = ssl_adp_get_error(conn->ssl, sslRet);
447 0 : int fd = conn->connfd;
448 0 : int errNo = errno;
449 :
450 0 : rs_ssl_err_string(fd, err);
451 0 : 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 0 : 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 0 : hccp_warn("ssl_adp_read fd:%d ret:%d, size:%llu err:%d errno:%d", fd, sslRet, size, err, errNo);
458 0 : 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, 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 : }
|