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