1 /*
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "softbus_socket.h"
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <ifaddrs.h>
21 #include <securec.h>
22
23 #include "conn_log.h"
24 #include "softbus_adapter_socket.h"
25 #include "softbus_conn_common.h"
26 #include "softbus_def.h"
27 #include "softbus_error_code.h"
28 #include "softbus_mintp_socket.h"
29 #include "softbus_htp_socket.h"
30 #include "softbus_tcp_socket.h"
31 #include "softbus_usb_tcp_socket.h"
32 #include "softbus_watch_event_interface.h"
33
34 #define HML_IPV4_ADDR_PREFIX "172.30."
35
36 #define MAX_SOCKET_TYPE 5
37 #define SEND_BUF_SIZE 0x200000 // 2M
38 #define RECV_BUF_SIZE 0x100000 // 1M
39 #define USER_TIMEOUT_US 5000000 // 5000000us
40
41 static const SocketInterface *g_socketInterfaces[MAX_SOCKET_TYPE] = { 0 };
42 static SoftBusMutex g_socketsMutex;
43
RegistSocketProtocol(const SocketInterface * interface)44 int32_t RegistSocketProtocol(const SocketInterface *interface)
45 {
46 if (interface == NULL || interface->GetSockPort == NULL || interface->OpenClientSocket == NULL ||
47 interface->OpenServerSocket == NULL || interface->AcceptClient == NULL) {
48 CONN_LOGW(CONN_COMMON, "Bad socket interface!");
49 return SOFTBUS_INVALID_PARAM;
50 }
51 int ret = SoftBusMutexLock(&g_socketsMutex);
52 if (ret != SOFTBUS_OK) {
53 CONN_LOGE(CONN_COMMON, "get lock fail! ret=%{public}" PRId32, ret);
54 return ret;
55 }
56
57 ret = SOFTBUS_CONN_SOCKET_INTERNAL_ERR;
58 for (uint8_t i = 0; i < MAX_SOCKET_TYPE; i++) {
59 if (g_socketInterfaces[i] == NULL) {
60 g_socketInterfaces[i] = interface;
61 ret = SOFTBUS_OK;
62 break;
63 }
64 }
65 (void)SoftBusMutexUnlock(&g_socketsMutex);
66 if (ret != SOFTBUS_OK) {
67 CONN_LOGE(CONN_COMMON, "socket type list is full!");
68 }
69 return ret;
70 }
71
GetSocketInterface(ProtocolType protocolType)72 const SocketInterface *GetSocketInterface(ProtocolType protocolType)
73 {
74 int ret = SoftBusMutexLock(&g_socketsMutex);
75 if (ret != SOFTBUS_OK) {
76 CONN_LOGE(CONN_COMMON, "get lock fail! ret=%{public}" PRId32, ret);
77 return NULL;
78 }
79 const SocketInterface *result = NULL;
80 for (uint8_t i = 0; i < MAX_SOCKET_TYPE; i++) {
81 if (g_socketInterfaces[i] != NULL && g_socketInterfaces[i]->type == protocolType) {
82 CONN_LOGI(CONN_COMMON, "protocolType=%{public}d", protocolType);
83 result = g_socketInterfaces[i];
84 break;
85 }
86 }
87 (void)SoftBusMutexUnlock(&g_socketsMutex);
88 return result;
89 }
90
RegistNewIpSocket(void)91 int32_t __attribute__((weak)) RegistNewIpSocket(void)
92 {
93 CONN_LOGD(CONN_COMMON, "newip not deployed");
94 return SOFTBUS_OK;
95 }
96
ConnInitSockets(void)97 int32_t ConnInitSockets(void)
98 {
99 int32_t ret = SoftBusMutexInit(&g_socketsMutex, NULL);
100 if (ret != SOFTBUS_OK) {
101 CONN_LOGE(CONN_INIT, "init mutex fail! ret=%{public}" PRId32, ret);
102 return ret;
103 }
104
105 (void)memset_s(g_socketInterfaces, sizeof(g_socketInterfaces), 0, sizeof(g_socketInterfaces));
106
107 ret = RegistSocketProtocol(GetTcpProtocol());
108 if (ret != SOFTBUS_OK) {
109 CONN_LOGE(CONN_INIT, "regist tcp fail!! ret=%{public}" PRId32, ret);
110 (void)SoftBusMutexDestroy(&g_socketsMutex);
111 return ret;
112 }
113 CONN_LOGD(CONN_INIT, "tcp registed!");
114
115 ret = RegistNewIpSocket();
116 if (ret != SOFTBUS_OK) {
117 CONN_LOGE(CONN_INIT, "regist newip fail!! ret=%{public}" PRId32, ret);
118 (void)SoftBusMutexDestroy(&g_socketsMutex);
119 return ret;
120 }
121
122 ret = RegistSocketProtocol(GetUsbProtocol());
123 if (ret != SOFTBUS_OK) {
124 CONN_LOGE(CONN_INIT, "regist usb fail!! ret=%{public}" PRId32, ret);
125 (void)SoftBusMutexDestroy(&g_socketsMutex);
126 return ret;
127 }
128 CONN_LOGD(CONN_INIT, "usb registed!");
129
130 ret = RegistSocketProtocol(GetMintpProtocol());
131 if (ret != SOFTBUS_OK) {
132 CONN_LOGE(CONN_INIT, "regist mintp fail!! ret=%{public}" PRId32, ret);
133 (void)SoftBusMutexDestroy(&g_socketsMutex);
134 return ret;
135 }
136 CONN_LOGD(CONN_INIT, "mintp registed!");
137
138 ret = RegistSocketProtocol(GetHtpProtocol());
139 if (ret != SOFTBUS_OK) {
140 CONN_LOGE(CONN_INIT, "regist htp fail!! ret=%{public}" PRId32, ret);
141 (void)SoftBusMutexDestroy(&g_socketsMutex);
142 return ret;
143 }
144 return ret;
145 }
146
ConnDeinitSockets(void)147 void ConnDeinitSockets(void)
148 {
149 (void)memset_s(g_socketInterfaces, sizeof(g_socketInterfaces), 0, sizeof(g_socketInterfaces));
150 (void)SoftBusMutexDestroy(&g_socketsMutex);
151 }
152
ConnOpenClientSocket(const ConnectOption * option,const char * bindAddr,bool isNonBlock)153 int32_t ConnOpenClientSocket(const ConnectOption *option, const char *bindAddr, bool isNonBlock)
154 {
155 if (option == NULL) {
156 return SOFTBUS_INVALID_PARAM;
157 }
158 const SocketInterface *socketInterface = GetSocketInterface(option->socketOption.protocol);
159 if (socketInterface == NULL) {
160 CONN_LOGE(CONN_COMMON, "protocol not supported! protocol=%{public}d", option->socketOption.protocol);
161 return SOFTBUS_CONN_SOCKET_GET_INTERFACE_ERR;
162 }
163 return socketInterface->OpenClientSocket(option, bindAddr, isNonBlock);
164 }
165
ConnToggleNonBlockMode(int32_t fd,bool isNonBlock)166 int32_t ConnToggleNonBlockMode(int32_t fd, bool isNonBlock)
167 {
168 if (fd < 0) {
169 return SOFTBUS_INVALID_PARAM;
170 }
171 int32_t flags = fcntl(fd, F_GETFL, 0);
172 if (flags < 0) {
173 CONN_LOGE(CONN_COMMON, "fcntl get flag fail, fd=%{public}d, errno=%{public}d(%{public}s)",
174 fd, errno, strerror(errno));
175 return SOFTBUS_CONN_SOCKET_FCNTL_ERR;
176 }
177 if (isNonBlock && ((uint32_t)flags & O_NONBLOCK) == 0) {
178 flags = (int32_t)((uint32_t)flags | O_NONBLOCK);
179 CONN_LOGI(CONN_COMMON, "set to nonblock. fd=%{public}d", fd);
180 } else if (!isNonBlock && ((uint32_t)flags & O_NONBLOCK) != 0) {
181 flags = (int32_t)((uint32_t)flags & ~O_NONBLOCK);
182 CONN_LOGI(CONN_COMMON, "set to block. fd=%{public}d", fd);
183 } else {
184 CONN_LOGI(CONN_COMMON, "nonblock state is already ok. fd=%{public}d", fd);
185 return SOFTBUS_OK;
186 }
187 return fcntl(fd, F_SETFL, flags);
188 }
189
ConnSendSocketData(int32_t fd,const char * buf,size_t len,int32_t timeout)190 ssize_t ConnSendSocketData(int32_t fd, const char *buf, size_t len, int32_t timeout)
191 {
192 if (fd < 0 || buf == NULL || len == 0) {
193 CONN_LOGE(CONN_COMMON, "invalid params. fd=%{public}d", fd);
194 return -1;
195 }
196
197 if (timeout == 0) {
198 timeout = USER_TIMEOUT_US;
199 }
200
201 int err = WaitEvent(fd, SOFTBUS_SOCKET_OUT, USER_TIMEOUT_US);
202 if (err <= 0) {
203 CONN_LOGE(CONN_COMMON, "wait event error. err=%{public}d", err);
204 return err;
205 }
206 ssize_t bytes = 0;
207 while (1) {
208 ssize_t rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketSend(fd, &buf[bytes], len - bytes, 0));
209 if (rc == SOFTBUS_ADAPTER_SOCKET_EAGAIN) {
210 continue;
211 } else if (rc <= 0) {
212 if (bytes == 0) {
213 bytes = -1;
214 }
215 CONN_LOGE(CONN_COMMON, "tcp send fail. rc=%{public}zd, errno=%{public}d(%{public}s)",
216 rc, errno, strerror(errno));
217 break;
218 }
219 bytes += rc;
220 if (bytes == (ssize_t)(len)) {
221 break;
222 }
223
224 err = WaitEvent(fd, SOFTBUS_SOCKET_OUT, timeout);
225 if (err == 0) {
226 continue;
227 } else if (err < 0) {
228 if (bytes == 0) {
229 CONN_LOGE(CONN_COMMON, "send data wait event fail. err=%{public}d", err);
230 bytes = err;
231 }
232 break;
233 }
234 }
235 return bytes;
236 }
237
OnRecvData(int32_t fd,char * buf,size_t len,int timeout,int flags)238 static ssize_t OnRecvData(int32_t fd, char *buf, size_t len, int timeout, int flags)
239 {
240 if (fd < 0 || buf == NULL || len == 0) {
241 CONN_LOGE(CONN_COMMON, "invalid params. fd=%{public}d, len=%{public}zu", fd, len);
242 return -1;
243 }
244
245 if (timeout != 0) {
246 int err = WaitEvent(fd, SOFTBUS_SOCKET_IN, timeout);
247 if (err < 0) {
248 CONN_LOGE(CONN_COMMON, "recv data wait event err=%{public}d", err);
249 return err;
250 }
251 }
252
253 ssize_t rc = SOFTBUS_TEMP_FAILURE_RETRY(SoftBusSocketRecv(fd, buf, len, flags));
254 if (rc == SOFTBUS_ADAPTER_SOCKET_EAGAIN) {
255 CONN_LOGW(CONN_COMMON, "recv data socket EAGAIN");
256 rc = 0;
257 } else if (rc == 0) {
258 CONN_LOGE(CONN_COMMON, "recv data fail, peer close connection, fd=%{public}d", fd);
259 rc = -1;
260 } else if (rc < 0) {
261 CONN_LOGE(CONN_COMMON, "recv data fail fd=%{public}d, errno=%{public}d(%{public}s), rc=%{public}zd",
262 fd, errno, strerror(errno), rc);
263 rc = -1;
264 }
265 return rc;
266 }
267
ConnRecvSocketData(int32_t fd,char * buf,size_t len,int32_t timeout)268 ssize_t ConnRecvSocketData(int32_t fd, char *buf, size_t len, int32_t timeout)
269 {
270 return OnRecvData(fd, buf, len, timeout, 0);
271 }
272
ConnCloseSocket(int32_t fd)273 void ConnCloseSocket(int32_t fd)
274 {
275 if (fd >= 0) {
276 CONN_LOGI(CONN_COMMON, "close fd=%{public}d", fd);
277 SoftBusSocketClose(fd);
278 }
279 }
280
ConnShutdownSocket(int32_t fd)281 void ConnShutdownSocket(int32_t fd)
282 {
283 if (fd >= 0) {
284 CONN_LOGI(CONN_COMMON, "shutdown fd=%{public}d", fd);
285 SoftBusSocketShutDown(fd, SOFTBUS_SHUT_RDWR);
286 SoftBusSocketClose(fd);
287 }
288 }
289
ConnGetSocketError(int32_t fd)290 int32_t ConnGetSocketError(int32_t fd)
291 {
292 return SoftBusSocketGetError(fd);
293 }
294
ConnGetLocalSocketPort(int32_t fd)295 int32_t ConnGetLocalSocketPort(int32_t fd)
296 {
297 const SocketInterface *socketInterface = GetSocketInterface(LNN_PROTOCOL_IP);
298 if (socketInterface == NULL) {
299 CONN_LOGW(CONN_COMMON, "LNN_PROTOCOL_IP not supported!");
300 return SOFTBUS_CONN_SOCKET_GET_INTERFACE_ERR;
301 }
302 return socketInterface->GetSockPort(fd);
303 }
304
ConnGetPeerSocketAddr6(int32_t fd,SocketAddr * socketAddr)305 int32_t ConnGetPeerSocketAddr6(int32_t fd, SocketAddr *socketAddr)
306 {
307 SoftBusSockAddr addr;
308 if (socketAddr == NULL) {
309 CONN_LOGW(CONN_COMMON, "invalid param");
310 return SOFTBUS_INVALID_PARAM;
311 }
312 int rc = SoftBusSocketGetPeerName(fd, &addr);
313 if (rc != 0) {
314 CONN_LOGE(CONN_COMMON, "GetPeerName fd=%{public}d, rc=%{public}d", fd, rc);
315 return SOFTBUS_TCP_SOCKET_ERR;
316 }
317 if (addr.saFamily == SOFTBUS_AF_INET6) {
318 if (SoftBusInetNtoP(SOFTBUS_AF_INET6, (void *)&((SoftBusSockAddrIn6 *)&addr)->sin6Addr,
319 socketAddr->addr, sizeof(socketAddr->addr)) == NULL) {
320 CONN_LOGE(CONN_COMMON, "Get ipv6 fail. fd=%{public}d", fd);
321 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
322 }
323 socketAddr->port = SoftBusNtoHs(((SoftBusSockAddrIn6 *)&addr)->sin6Port);
324 return SOFTBUS_OK;
325 }
326 socketAddr->port = SoftBusNtoHs(((SoftBusSockAddrIn *)&addr)->sinPort);
327 if (SoftBusInetNtoP(SOFTBUS_AF_INET, (void *)&((SoftBusSockAddrIn *)&addr)->sinAddr,
328 socketAddr->addr, sizeof(socketAddr->addr)) == NULL) {
329 CONN_LOGE(CONN_COMMON, "InetNtoP fail. fd=%{public}d", fd);
330 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
331 }
332 return SOFTBUS_OK;
333 }
334
ConnGetPeerSocketAddr(int32_t fd,SocketAddr * socketAddr)335 int32_t ConnGetPeerSocketAddr(int32_t fd, SocketAddr *socketAddr)
336 {
337 SoftBusSockAddr addr;
338 if (socketAddr == NULL) {
339 CONN_LOGW(CONN_COMMON, "invalid param");
340 return SOFTBUS_INVALID_PARAM;
341 }
342 int rc = SoftBusSocketGetPeerName(fd, &addr);
343 if (rc != 0) {
344 CONN_LOGE(CONN_COMMON, "GetPeerName fd=%{public}d, rc=%{public}d", fd, rc);
345 return SOFTBUS_TCP_SOCKET_ERR;
346 }
347 if (addr.saFamily == SOFTBUS_AF_INET6) {
348 rc = Ipv6AddrInToAddr((SoftBusSockAddrIn6 *)&addr, socketAddr->addr, sizeof(socketAddr->addr));
349 socketAddr->port = SoftBusNtoHs(((SoftBusSockAddrIn6 *)&addr)->sin6Port);
350 if (rc < 0) {
351 CONN_LOGE(CONN_COMMON, "Ipv6AddrInToAddr fail. fd=%{public}d", fd);
352 return SOFTBUS_SOCKET_ADDR_ERR;
353 }
354 return SOFTBUS_OK;
355 }
356 socketAddr->port = SoftBusNtoHs(((SoftBusSockAddrIn *)&addr)->sinPort);
357 if (SoftBusInetNtoP(SOFTBUS_AF_INET, (void *)&((SoftBusSockAddrIn *)&addr)->sinAddr,
358 socketAddr->addr, sizeof(socketAddr->addr)) == NULL) {
359 CONN_LOGE(CONN_COMMON, "InetNtoP fail. fd=%{public}d", fd);
360 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
361 }
362 return SOFTBUS_OK;
363 }
364
ConnPreAssignPortBind(int32_t socketFd,int32_t domain)365 static int32_t ConnPreAssignPortBind(int32_t socketFd, int32_t domain)
366 {
367 int ret = SOFTBUS_TCPCONNECTION_SOCKET_ERR;
368 if (domain == SOFTBUS_AF_INET6) {
369 SoftBusSockAddrIn6 addrIn6 = {0};
370 ret = Ipv6AddrToAddrIn(&addrIn6, "::", 0);
371 if (ret != SOFTBUS_ADAPTER_OK) {
372 CONN_LOGE(CONN_COMMON, "convert address to net order fail");
373 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
374 }
375 return SoftBusSocketBind(socketFd, (SoftBusSockAddr *)&addrIn6, sizeof(SoftBusSockAddrIn6));
376 }
377 SoftBusSockAddrIn addrIn = {0};
378 ret = Ipv4AddrToAddrIn(&addrIn, "0.0.0.0", 0);
379 if (ret != SOFTBUS_ADAPTER_OK) {
380 CONN_LOGE(CONN_COMMON, "convert address to net order fail");
381 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
382 }
383 return SoftBusSocketBind(socketFd, (SoftBusSockAddr *)&addrIn, sizeof(SoftBusSockAddrIn));
384 }
385
ConnPreAssignPort(int32_t domain)386 int32_t ConnPreAssignPort(int32_t domain)
387 {
388 int socketFd = -1;
389 int ret = SoftBusSocketCreate(domain, SOFTBUS_SOCK_STREAM, 0, &socketFd);
390 if (ret < 0) {
391 CONN_LOGE(CONN_COMMON, "create socket fail, ret=%{public}d", ret);
392 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
393 }
394 int reuse = 1;
395 ret = SoftBusSocketSetOpt(socketFd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse));
396 if (ret != SOFTBUS_OK) {
397 CONN_LOGE(CONN_COMMON, "set reuse port option fail");
398 SoftBusSocketClose(socketFd);
399 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
400 }
401 ret = ConnPreAssignPortBind(socketFd, domain);
402 if (ret != SOFTBUS_ADAPTER_OK) {
403 SoftBusSocketClose(socketFd);
404 CONN_LOGE(CONN_COMMON, "bind address fail");
405 return SOFTBUS_TCPCONNECTION_SOCKET_ERR;
406 }
407 return socketFd;
408 }
409
GetDomainByAddr(const char * addr)410 int32_t GetDomainByAddr(const char *addr)
411 {
412 CONN_CHECK_AND_RETURN_RET_LOGE(addr != NULL,
413 SOFTBUS_INVALID_PARAM, CONN_COMMON, "invalid param!");
414 if (strchr(addr, ADDR_FEATURE_IPV6) != NULL) {
415 return SOFTBUS_AF_INET6;
416 }
417 return SOFTBUS_AF_INET;
418 }
419
Ipv6AddrInToAddr(SoftBusSockAddrIn6 * addrIn6,char * addr,int32_t addrLen)420 int32_t Ipv6AddrInToAddr(SoftBusSockAddrIn6 *addrIn6, char *addr, int32_t addrLen)
421 {
422 CONN_CHECK_AND_RETURN_RET_LOGE(addrIn6 != NULL && addr != NULL && addrLen > 0,
423 SOFTBUS_INVALID_PARAM, CONN_COMMON, "invalid param!");
424 char ip[IP_LEN] = {0};
425 if (SoftBusInetNtoP(SOFTBUS_AF_INET6, &addrIn6->sin6Addr, ip, addrLen) == NULL) {
426 CONN_LOGE(CONN_COMMON, "InetNtoP faild!");
427 return SOFTBUS_SOCKET_ADDR_ERR;
428 }
429 char ifname[IF_NAME_SIZE] = { 0 };
430 int32_t rc = SoftBusIndexToIfName(addrIn6->sin6ScopeId, ifname, IF_NAME_SIZE);
431 if (rc < 0) {
432 if (strcpy_s(addr, IP_LEN, ip) != SOFTBUS_OK) {
433 CONN_LOGE(CONN_COMMON, "strcpy faild!");
434 return SOFTBUS_STRCPY_ERR;
435 }
436 CONN_LOGW(CONN_COMMON, "no ifname or global addr");
437 return SOFTBUS_OK;
438 }
439 rc = sprintf_s(addr, addrLen, "%s%s%s", ip, ADDR_SPLIT_IPV6, ifname);
440 if (rc < 0) {
441 COMM_LOGE(CONN_COMMON, "sprintf_s addr fail");
442 return SOFTBUS_SOCKET_ADDR_ERR;
443 }
444 return SOFTBUS_OK;
445 }
446
Ipv6AddrToAddrIn(SoftBusSockAddrIn6 * addrIn6,const char * ip,uint16_t port)447 int32_t Ipv6AddrToAddrIn(SoftBusSockAddrIn6 *addrIn6, const char *ip, uint16_t port)
448 {
449 CONN_CHECK_AND_RETURN_RET_LOGE(addrIn6 != NULL && ip != NULL, SOFTBUS_INVALID_PARAM,
450 CONN_COMMON, "invalid param!");
451 (void)memset_s(addrIn6, sizeof(*addrIn6), 0, sizeof(*addrIn6));
452 addrIn6->sin6Family = SOFTBUS_AF_INET6;
453 char *addr = NULL;
454 char *ifName = NULL;
455 char *nextToken = NULL;
456 char tmpIp[IP_LEN] = { 0 };
457 if (strcpy_s(tmpIp, sizeof(tmpIp), ip) != EOK) {
458 CONN_LOGE(CONN_COMMON, "copy local id fail");
459 return SOFTBUS_MEM_ERR;
460 }
461 addr = strtok_s(tmpIp, ADDR_SPLIT_IPV6, &nextToken);
462 if (addr == NULL) {
463 addr = "";
464 }
465 ifName = strtok_s(NULL, ADDR_SPLIT_IPV6, &nextToken);
466 if (ifName != NULL) {
467 addrIn6->sin6ScopeId = SoftBusIfNameToIndex(ifName);
468 if (addrIn6->sin6ScopeId == 0) {
469 CONN_LOGE(CONN_WIFI_DIRECT, "nameToIndex fail, errno=%{public}d(%{public}s)", errno, strerror(errno));
470 return SOFTBUS_SOCKET_ADDR_ERR;
471 }
472 }
473 int32_t rc = SoftBusInetPtoN(SOFTBUS_AF_INET6, addr, &addrIn6->sin6Addr);
474 if (rc != SOFTBUS_OK) {
475 CONN_LOGE(CONN_COMMON, "ipv6 SoftBusInetPtoN rc=%{public}d", rc);
476 return SOFTBUS_SOCKET_ADDR_ERR;
477 }
478 addrIn6->sin6Port = SoftBusHtoNs(port);
479 return SOFTBUS_OK;
480 }
481
Ipv4AddrToAddrIn(SoftBusSockAddrIn * addrIn,const char * ip,uint16_t port)482 int32_t Ipv4AddrToAddrIn(SoftBusSockAddrIn *addrIn, const char *ip, uint16_t port)
483 {
484 CONN_CHECK_AND_RETURN_RET_LOGE(addrIn != NULL && ip != NULL, SOFTBUS_INVALID_PARAM,
485 CONN_COMMON, "invalid param!");
486 (void)memset_s(addrIn, sizeof(*addrIn), 0, sizeof(*addrIn));
487 addrIn->sinFamily = SOFTBUS_AF_INET;
488 int32_t rc = SoftBusInetPtoN(SOFTBUS_AF_INET, ip, &addrIn->sinAddr);
489 if (rc != SOFTBUS_OK) {
490 CONN_LOGE(CONN_COMMON, "ipv4 SoftBusInetPtoN rc=%{public}d", rc);
491 return SOFTBUS_SOCKET_ADDR_ERR;
492 }
493 addrIn->sinPort = SoftBusHtoNs(port);
494 return SOFTBUS_OK;
495 }
496
IsHmlIpAddr(const char * ip)497 bool IsHmlIpAddr(const char *ip)
498 {
499 CONN_CHECK_AND_RETURN_RET_LOGE(ip != NULL, false, CONN_COMMON, "invalid param!");
500 if (GetDomainByAddr(ip) == SOFTBUS_AF_INET6) {
501 return true;
502 }
503
504 return strncmp(ip, HML_IPV4_ADDR_PREFIX, strlen(HML_IPV4_ADDR_PREFIX)) == 0;
505 }
506
GetIfNameByIp(const char * myIp,int32_t domain,char * ifName,int32_t ifNameMaxLen)507 static int32_t GetIfNameByIp(const char *myIp, int32_t domain, char *ifName, int32_t ifNameMaxLen)
508 {
509 if (myIp == NULL || ifName == NULL || strcmp(myIp, BIND_ADDR_ALL) == 0) {
510 COMM_LOGE(CONN_COMMON, "Invalid param.");
511 return SOFTBUS_INVALID_PARAM;
512 }
513
514 struct ifaddrs *ifa = NULL;
515 struct ifaddrs *ifList = NULL;
516 struct in_addr inAddr = { 0 };
517 char animizedIp[IP_LEN] = { 0 };
518 ConvertAnonymizeIpAddress(animizedIp, IP_LEN, myIp, IP_LEN);
519
520 int32_t ret = getifaddrs(&ifList);
521 if (ret != 0) {
522 COMM_LOGE(CONN_COMMON, "ip=%{public}s getifaddrs ifList fail, ret=%{public}d, errno=%{public}d(%{public}s)",
523 animizedIp, ret, errno, strerror(errno));
524 return SOFTBUS_SOCKET_ADDR_ERR;
525 }
526 if (inet_aton(myIp, &inAddr) == 0) {
527 COMM_LOGE(CONN_COMMON, "inet_aton ip=%{public}s fail.", animizedIp);
528 freeifaddrs(ifList);
529 return SOFTBUS_TCP_SOCKET_ERR;
530 }
531 for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next) {
532 if (ifa->ifa_addr == NULL) {
533 continue;
534 }
535 (void)memset_s(ifName, ifNameMaxLen, 0, ifNameMaxLen);
536 if (memcmp(&inAddr, &(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr), sizeof(struct in_addr)) == 0) {
537 if (memcpy_s(ifName, ifNameMaxLen - 1, ifa->ifa_name, strlen(ifa->ifa_name)) != EOK) {
538 COMM_LOGE(CONN_COMMON, "fail to memcpy_s ifName by ip=%{public}s", animizedIp);
539 freeifaddrs(ifList);
540 return SOFTBUS_MEM_ERR;
541 }
542 freeifaddrs(ifList);
543 return SOFTBUS_OK;
544 }
545 }
546 COMM_LOGW(CONN_COMMON, "not found ifName by ip=%{public}s", animizedIp);
547 freeifaddrs(ifList);
548 return SOFTBUS_CONN_NOT_FOUND_FAILED;
549 }
550
551 // prevent the scenario of using VPN to produce virtual network cards.
BindToInterface(const char * myIp,int32_t domain,int fd,char * ifName,int32_t ifNameMaxLen)552 void BindToInterface(const char *myIp, int32_t domain, int fd, char *ifName, int32_t ifNameMaxLen)
553 {
554 // The IPv6 socket has already been bound to the network card, there is no need to bind it again.
555 CONN_CHECK_AND_RETURN_LOGW(domain != SOFTBUS_AF_INET6, CONN_COMMON, "Ipv6 addr no need to get ifName.");
556
557 int32_t ret = GetIfNameByIp(myIp, domain, ifName, ifNameMaxLen);
558 CONN_CHECK_AND_RETURN_LOGW(ret == SOFTBUS_OK, CONN_COMMON, "cannot bind to interface.");
559
560 ret = SoftBusSocketSetOpt(fd, SOFTBUS_SOL_SOCKET, SOFTBUS_SO_BINDTODEVICE, ifName, strlen(ifName));
561 if (ret < 0) {
562 COMM_LOGE(
563 CONN_COMMON, "socketSetOpt fail, fd=%{public}d, ifName=%{public}s, errno=%{public}d", fd, ifName, ret);
564 return;
565 }
566 return;
567 }
568