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