• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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