• 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 <securec.h>
17 #include <stdint.h>
18 #include <stdio.h>
19 #include <string.h>
20 
21 #include "anonymizer.h"
22 #include "auth_interface.h"
23 #include "bus_center_adapter.h"
24 #include "bus_center_event.h"
25 #include "bus_center_info_key.h"
26 #include "bus_center_manager.h"
27 #include "conn_log.h"
28 #include "disc_interface.h"
29 #include "g_enhance_lnn_func.h"
30 #include "g_enhance_lnn_func_pack.h"
31 #include "g_enhance_conn_func.h"
32 #include "g_enhance_conn_func_pack.h"
33 #include "lnn_async_callback_utils.h"
34 #include "lnn_common_utils.h"
35 #include "lnn_discovery_manager.h"
36 #include "lnn_ip_utils_adapter.h"
37 #include "lnn_linkwatch.h"
38 #include "lnn_log.h"
39 #include "lnn_net_builder.h"
40 #include "lnn_network_manager.h"
41 #include "lnn_physical_subnet_manager.h"
42 #include "lnn_connection_fsm.h"
43 #include "message_handler.h"
44 #include "softbus_adapter_mem.h"
45 #include "softbus_adapter_thread.h"
46 #include "softbus_adapter_timer.h"
47 #include "softbus_common.h"
48 #include "softbus_def.h"
49 #include "softbus_error_code.h"
50 #include "softbus_init_common.h"
51 #include "softbus_feature_config.h"
52 #include "softbus_protocol_def.h"
53 #include "trans_tcp_direct_listener.h"
54 
55 #define IP_DEFAULT_PORT 0
56 #define LNN_LOOPBACK_IP "127.0.0.1"
57 #define WLAN_IFNAME "wlan0"
58 
59 static bool g_wifiConnected = false;
60 static bool g_apEnabled = false;
61 static bool g_heartbeatEnable = false;
62 
63 #define GET_IP_RETRY_TIMES 10
64 #define GET_IP_INTERVAL_TIME 500 // uint:ms
65 
GetWifiServiceIpAddr(const char * ifName,char * ip,uint32_t size)66 static int32_t GetWifiServiceIpAddr(const char *ifName, char *ip, uint32_t size)
67 {
68     if (ifName == NULL || ip == NULL || size == 0) {
69         LNN_LOGE(LNN_BUILDER, "invalid parameter");
70         return SOFTBUS_INVALID_PARAM;
71     }
72     if (strcmp(ifName, WLAN_IFNAME) != 0) {
73         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
74     }
75     if (GetWlanIpv4Addr(ip, size) != SOFTBUS_OK) {
76         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
77     }
78     if (strnlen(ip, size) == 0 || strnlen(ip, size) == size) {
79         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
80     }
81     if (strcmp(ip, LNN_LOOPBACK_IP) == 0 || strcmp(ip, "") == 0 || strcmp(ip, "0.0.0.0") == 0) {
82         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
83     }
84     return SOFTBUS_OK;
85 }
86 
GetIpAddrFromNetlink(const char * ifName,char * ip,uint32_t size)87 static int32_t GetIpAddrFromNetlink(const char *ifName, char *ip, uint32_t size)
88 {
89     if (GetNetworkIpByIfName(ifName, ip, NULL, size) != SOFTBUS_OK) {
90         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
91     }
92 
93     if (strcmp(ip, LNN_LOOPBACK_IP) == 0 || strcmp(ip, "") == 0 || strcmp(ip, "0.0.0.0") == 0) {
94         LNN_LOGE(LNN_BUILDER, "invalid ip addr");
95         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
96     }
97     return SOFTBUS_OK;
98 }
99 
GetIpProcess(const char * ifName,char * ip,uint32_t size)100 static bool GetIpProcess(const char *ifName, char *ip, uint32_t size)
101 {
102     if (GetIpAddrFromNetlink(ifName, ip, size) != SOFTBUS_OK &&
103         GetWifiServiceIpAddr(ifName, ip, size) != SOFTBUS_OK) {
104         LNN_LOGD(LNN_BUILDER, "get network IP by ifName fail");
105         return false;
106     }
107     return true;
108 }
109 
NotifyWlanAddressChanged(const LnnNetIfMgr * netifManager,void * data)110 static VisitNextChoice NotifyWlanAddressChanged(const LnnNetIfMgr *netifManager, void *data)
111 {
112     if (netifManager->type == LNN_NETIF_TYPE_WLAN) {
113         LNN_LOGI(LNN_BUILDER, "notify wlan changed at %{public}" PRIu64, SoftBusGetSysTimeMs());
114         LnnNotifyPhysicalSubnetStatusChanged(netifManager->ifName, LNN_PROTOCOL_IP, data);
115     }
116     return CHOICE_VISIT_NEXT;
117 }
118 
RetryGetAvailableIpAddr(void * para)119 static void RetryGetAvailableIpAddr(void *para)
120 {
121     (void)para;
122     (void)LnnVisitNetif(NotifyWlanAddressChanged, NULL);
123 }
124 
GetAvailableIpAddr(const char * ifName,char * ip,uint32_t size)125 static int32_t GetAvailableIpAddr(const char *ifName, char *ip, uint32_t size)
126 {
127     static int32_t retryTime = GET_IP_RETRY_TIMES;
128     if (strcmp(ifName, WLAN_IFNAME) != 0) {
129         retryTime = 0;
130     }
131     if (GetIpProcess(ifName, ip, size)) {
132         retryTime = GET_IP_RETRY_TIMES;
133         return SOFTBUS_OK;
134     }
135     LNN_LOGD(LNN_BUILDER, "get ip retry time=%{public}d", retryTime);
136     if (--retryTime > 0 && LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), RetryGetAvailableIpAddr,
137         NULL, GET_IP_INTERVAL_TIME) != SOFTBUS_OK) {
138         LNN_LOGE(LNN_BUILDER, "LnnAsyncCallbackDelayHelper get available ip fail");
139         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
140     }
141     if (retryTime <= 0) {
142         retryTime = GET_IP_RETRY_TIMES;
143     }
144     return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
145 }
146 
OpenAuthPort(void)147 static int32_t OpenAuthPort(void)
148 {
149     char localIp[MAX_ADDR_LEN] = {0};
150 
151     int32_t authPort;
152     if (LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, &authPort, WLAN_IF) != SOFTBUS_OK) {
153         LNN_LOGE(LNN_BUILDER, "get port failed");
154         authPort = 0;
155     }
156 
157     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, localIp, MAX_ADDR_LEN, WLAN_IF) != SOFTBUS_OK) {
158         LNN_LOGE(LNN_BUILDER, "get local ip failed");
159         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
160     }
161     int32_t port = AuthStartListening(AUTH_LINK_TYPE_WIFI, localIp, authPort);
162     if (port < 0) {
163         LNN_LOGE(LNN_BUILDER, "AuthStartListening failed");
164         return SOFTBUS_INVALID_PORT;
165     }
166     char *anonyIp = NULL;
167     Anonymize(localIp, &anonyIp);
168     LNN_LOGI(LNN_BUILDER, "open auth port listening on ip=%{public}s", AnonymizeWrapper(anonyIp));
169     AnonymizeFree(anonyIp);
170     if (authPort == 0) {
171         return LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, port, WLAN_IF);
172     }
173     return SOFTBUS_OK;
174 }
175 
CloseAuthPort(void)176 static void CloseAuthPort(void)
177 {
178     AuthStopListening(AUTH_LINK_TYPE_WIFI);
179     (void)LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, IP_DEFAULT_PORT, WLAN_IF);
180 }
181 
OpenSessionPort(void)182 static int32_t OpenSessionPort(void)
183 {
184     int32_t sessionPort;
185     if (LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_SESSION_PORT, &sessionPort, WLAN_IF) != SOFTBUS_OK) {
186         LNN_LOGE(LNN_BUILDER, "get port failed");
187         sessionPort = 0;
188     }
189 
190     int32_t port;
191     LocalListenerInfo info = {
192         .type = CONNECT_TCP,
193         .socketOption = {
194             .addr = "",
195             .port = sessionPort,
196             .moduleId = DIRECT_CHANNEL_SERVER_WIFI,
197             .protocol = LNN_PROTOCOL_IP,
198         }
199     };
200     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, info.socketOption.addr,
201         sizeof(info.socketOption.addr), WLAN_IF) != SOFTBUS_OK) {
202         LNN_LOGE(LNN_BUILDER, "get local ip failed");
203         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
204     }
205     port = TransTdcStartSessionListener(DIRECT_CHANNEL_SERVER_WIFI, &info);
206     if (port < 0) {
207         LNN_LOGE(LNN_BUILDER, "open session server failed");
208         return SOFTBUS_INVALID_PORT;
209     }
210     if (sessionPort == 0) {
211         return LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_SESSION_PORT, port, WLAN_IF);
212     }
213 
214     return SOFTBUS_OK;
215 }
216 
CloseSessionPort(void)217 static void CloseSessionPort(void)
218 {
219     TransTdcStopSessionListener(DIRECT_CHANNEL_SERVER_WIFI);
220     (void)LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_SESSION_PORT, IP_DEFAULT_PORT, WLAN_IF);
221 }
222 
OpenProxyPort(void)223 static void OpenProxyPort(void)
224 {
225     int32_t proxyPort;
226     if (LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_PROXY_PORT, &proxyPort, WLAN_IF) != SOFTBUS_OK) {
227         LNN_LOGE(LNN_BUILDER, "get port failed");
228         proxyPort = 0;
229     }
230 
231     LocalListenerInfo listenerInfo = {
232         .type = CONNECT_TCP,
233         .socketOption = {
234             .addr = "",
235             .port = proxyPort,
236             .moduleId = PROXY,
237             .protocol = LNN_PROTOCOL_IP,
238         }
239     };
240     int32_t ret = LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, listenerInfo.socketOption.addr,
241         sizeof(listenerInfo.socketOption.addr), WLAN_IF);
242     if (ret != SOFTBUS_OK) {
243         LNN_LOGE(LNN_BUILDER, "get local ip failed");
244         return;
245     }
246     int32_t port = ConnStartLocalListening(&listenerInfo);
247     if (port < 0) {
248         LNN_LOGE(LNN_BUILDER, "open proxy server failed");
249         return;
250     }
251     if (proxyPort == 0) {
252         (void)LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_PROXY_PORT, port, WLAN_IF);
253     }
254 }
255 
CloseProxyPort(void)256 static void CloseProxyPort(void)
257 {
258     LocalListenerInfo listenerInfo = {
259         .type = CONNECT_TCP,
260         .socketOption = {
261             .addr = "",
262             .port = 0,
263             .moduleId = PROXY,
264             .protocol = LNN_PROTOCOL_IP,
265         }
266     };
267     if (ConnStopLocalListening(&listenerInfo) != SOFTBUS_OK) {
268         LNN_LOGE(LNN_BUILDER, "ConnStopLocalListening fail");
269     }
270     (void)LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_PROXY_PORT, IP_DEFAULT_PORT, WLAN_IF);
271 }
272 
OpenIpLink(void)273 static int32_t OpenIpLink(void)
274 {
275     int32_t ret = OpenAuthPort();
276     if (ret != SOFTBUS_OK) {
277         LNN_LOGE(LNN_BUILDER, "OpenAuthPort fail");
278         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
279     }
280     ret = OpenSessionPort();
281     if (ret != SOFTBUS_OK) {
282         LNN_LOGE(LNN_BUILDER, "OpenSessionPort fail");
283         CloseAuthPort();
284         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
285     }
286     OpenProxyPort();
287     return SOFTBUS_OK;
288 }
289 
CloseIpLink(void)290 static void CloseIpLink(void)
291 {
292     CloseAuthPort();
293     CloseSessionPort();
294     CloseProxyPort();
295     LNN_LOGI(LNN_BUILDER, "close port success");
296 }
297 
GetLocalIpInfo(char * ipAddr,uint32_t ipAddrLen,char * ifName,uint32_t ifNameLen)298 static int32_t GetLocalIpInfo(char *ipAddr, uint32_t ipAddrLen, char *ifName, uint32_t ifNameLen)
299 {
300     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, ipAddr, ipAddrLen, WLAN_IF) != SOFTBUS_OK) {
301         LNN_LOGE(LNN_BUILDER, "get local ip error");
302         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
303     }
304     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, ifName, ifNameLen, WLAN_IF) != SOFTBUS_OK) {
305         LNN_LOGE(LNN_BUILDER, "get local ifName error");
306         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
307     }
308     return SOFTBUS_OK;
309 }
310 
SetLocalIpInfo(const char * ipAddr,const char * ifName)311 static int32_t SetLocalIpInfo(const char *ipAddr, const char *ifName)
312 {
313     if (LnnSetLocalStrInfoByIfnameIdx(STRING_KEY_IP, ipAddr, WLAN_IF) != SOFTBUS_OK) {
314         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
315     }
316     if (LnnSetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, ifName, WLAN_IF) != SOFTBUS_OK) {
317         LNN_LOGE(LNN_BUILDER, "set local ifName error");
318         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
319     }
320     return SOFTBUS_OK;
321 }
322 
LeaveOldIpNetwork(const char * ifCurrentName)323 static void LeaveOldIpNetwork(const char *ifCurrentName)
324 {
325     ConnectionAddrType type = CONNECTION_ADDR_MAX;
326     bool addrType[CONNECTION_ADDR_MAX] = {false};
327 
328     if (LnnGetAddrTypeByIfName(ifCurrentName, &type) != SOFTBUS_OK) {
329         LNN_LOGE(LNN_BUILDER, "LnnGetAddrTypeByIfName failed ifName=%{public}s", ifCurrentName);
330         return;
331     }
332     if (type == CONNECTION_ADDR_MAX) {
333         addrType[CONNECTION_ADDR_WLAN] = true;
334         addrType[CONNECTION_ADDR_ETH] = true;
335     } else {
336         addrType[type] = true;
337     }
338     LNN_LOGI(LNN_BUILDER, "LNN start leave ip network");
339     if (LnnRequestLeaveByAddrType(addrType, CONNECTION_ADDR_MAX) != SOFTBUS_OK) {
340         LNN_LOGE(LNN_BUILDER, "LNN leave ip network fail");
341     }
342 }
343 
ReleaseMainPort(const char * ifName)344 static int32_t ReleaseMainPort(const char *ifName)
345 {
346     char oldMainIf[NET_IF_NAME_LEN] = {0};
347     do {
348         if (LnnGetLocalStrInfoByIfnameIdx(
349             STRING_KEY_NET_IF_NAME, oldMainIf, sizeof(oldMainIf), WLAN_IF) != SOFTBUS_OK) {
350             LNN_LOGE(LNN_BUILDER, "get local ifName error!");
351             break;
352         }
353         if (strcmp(ifName, oldMainIf) != 0) {
354             LNN_LOGE(LNN_BUILDER, "if is not main port! ifName=%{public}s", ifName);
355             return SOFTBUS_CMP_FAIL;
356         }
357     } while (false);
358     if (SetLocalIpInfo(LNN_LOOPBACK_IP, LNN_LOOPBACK_IFNAME) != SOFTBUS_OK) {
359         LNN_LOGE(LNN_BUILDER, "set local ip info failed");
360         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
361     }
362     return SOFTBUS_OK;
363 }
364 
RequestMainPort(const char * ifName,const char * address)365 static int32_t RequestMainPort(const char *ifName, const char *address)
366 {
367     if (strcmp(ifName, LNN_LOOPBACK_IFNAME) == 0) {
368         LNN_LOGE(LNN_BUILDER, "loopback ifName not allowed");
369         return SOFTBUS_CMP_FAIL;
370     }
371     if (strcmp(address, LNN_LOOPBACK_IP) == 0) {
372         LNN_LOGE(LNN_BUILDER, "loopback ip not allowed");
373         return SOFTBUS_CMP_FAIL;
374     }
375     LNN_LOGI(LNN_BUILDER, "get local ifName begin");
376     char oldMainIf[NET_IF_NAME_LEN] = {0};
377     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, oldMainIf, sizeof(oldMainIf), WLAN_IF) != SOFTBUS_OK) {
378         LNN_LOGE(LNN_BUILDER, "get local ifName error");
379         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
380     }
381     LNN_LOGD(LNN_BUILDER, "get local ifName end");
382     if (strcmp(oldMainIf, ifName) != 0 && strcmp(oldMainIf, LNN_LOOPBACK_IFNAME) != 0) {
383         LNN_LOGE(LNN_BUILDER, "Only 1 local subnet is allowed");
384         return SOFTBUS_CMP_FAIL;
385     }
386     if (SetLocalIpInfo(address, ifName) != SOFTBUS_OK) {
387         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
388     }
389     return SOFTBUS_OK;
390 }
391 
EnableIpSubnet(LnnPhysicalSubnet * subnet)392 static int32_t EnableIpSubnet(LnnPhysicalSubnet *subnet)
393 {
394     char address[IP_LEN] = {0};
395 
396     int32_t ret = GetAvailableIpAddr(subnet->ifName, address, sizeof(address));
397     if (ret != SOFTBUS_OK) {
398         LNN_LOGE(LNN_BUILDER, "get available Ip failed! ifName=%{public}s, ret=%{public}d", subnet->ifName, ret);
399         return ret;
400     }
401     if (RequestMainPort(subnet->ifName, address)) {
402         LNN_LOGE(LNN_BUILDER, "request main port failed! ifName=%{public}s", subnet->ifName);
403         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
404     }
405     LNN_LOGI(LNN_BUILDER, "open ip link and start discovery");
406     if (OpenIpLink() != SOFTBUS_OK) {
407         LNN_LOGE(LNN_BUILDER, "open ip link failed");
408         return SOFTBUS_CONN_AUTH_START_LISTEN_FAIL;
409     }
410     if (ConnCoapStartServerListenPacked() != SOFTBUS_OK) {
411         LNN_LOGE(LNN_BUILDER, "start coap conn server failed");
412     }
413     if (!LnnIsAutoNetWorkingEnabled()) {
414         LNN_LOGI(LNN_BUILDER, "auto network disable");
415         return SOFTBUS_OK;
416     }
417     DiscLinkStatusChanged(LINK_STATUS_UP, COAP, WLAN_IF);
418     if (LnnStartPublish() != SOFTBUS_OK) {
419         LNN_LOGE(LNN_BUILDER, "start publish failed");
420     }
421     if (LnnStartDiscovery() != SOFTBUS_OK) {
422         LNN_LOGE(LNN_BUILDER, "start discovery failed");
423     }
424     return SOFTBUS_OK;
425 }
426 
DisableIpSubnet(LnnPhysicalSubnet * subnet)427 static int32_t DisableIpSubnet(LnnPhysicalSubnet *subnet)
428 {
429     if (subnet->status == LNN_SUBNET_RUNNING) {
430         LnnIpAddrChangeEventHandlerPacked();
431         CloseIpLink();
432         LnnStopPublish();
433         LnnStopDiscovery();
434         ConnCoapStopServerListenPacked();
435         DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP, WLAN_IF);
436         LeaveOldIpNetwork(subnet->ifName);
437         ReleaseMainPort(subnet->ifName);
438     }
439     return SOFTBUS_OK;
440 }
441 
ChangeIpSubnetAddress(LnnPhysicalSubnet * subnet)442 static int32_t ChangeIpSubnetAddress(LnnPhysicalSubnet *subnet)
443 {
444     CloseIpLink();
445     LnnStopPublish();
446     LnnStopDiscovery();
447     ConnCoapStopServerListenPacked();
448     DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP, WLAN_IF);
449     LeaveOldIpNetwork(subnet->ifName);
450     return SOFTBUS_OK;
451 }
452 
DestroyIpSubnetManager(LnnPhysicalSubnet * subnet)453 static void DestroyIpSubnetManager(LnnPhysicalSubnet *subnet)
454 {
455     LNN_CHECK_AND_RETURN_LOGE(subnet != NULL, LNN_BUILDER, "invalid param");
456     if (subnet->status == LNN_SUBNET_RUNNING) {
457         DisableIpSubnet(subnet);
458     }
459     SoftBusFree(subnet);
460 }
461 
462 typedef enum {
463     IP_SUBNET_MANAGER_EVENT_IF_READY,
464     IP_SUBNET_MANAGER_EVENT_IF_DOWN,    // addr change from available to
465     IP_SUBNET_MANAGER_EVENT_IF_CHANGED, // addr changed
466     IP_SUBNET_MANAGER_EVENT_MAX
467 } IpSubnetManagerEvent;
468 
469 typedef enum {
470     IP_EVENT_RESULT_ACCEPTED = 0,
471     IP_EVENT_RESULT_REJECTED,
472     IP_EVENT_RESULT_OPTION_COUNT
473 } IpSubnetManagerEventResultOptions;
474 
TransactIpSubnetState(LnnPhysicalSubnet * subnet,IpSubnetManagerEvent event,bool isAccepted)475 static void TransactIpSubnetState(LnnPhysicalSubnet *subnet, IpSubnetManagerEvent event, bool isAccepted)
476 {
477     LnnPhysicalSubnetStatus transactMap[][IP_EVENT_RESULT_OPTION_COUNT] = {
478         [IP_SUBNET_MANAGER_EVENT_IF_READY] = {LNN_SUBNET_RUNNING, LNN_SUBNET_IDLE},
479         [IP_SUBNET_MANAGER_EVENT_IF_DOWN] = {LNN_SUBNET_SHUTDOWN, subnet->status},
480         [IP_SUBNET_MANAGER_EVENT_IF_CHANGED] = {LNN_SUBNET_RESETTING, subnet->status}
481     };
482     subnet->status = transactMap[event][isAccepted ? IP_EVENT_RESULT_ACCEPTED : IP_EVENT_RESULT_REJECTED];
483     LNN_LOGD(LNN_BUILDER, "subnet state change. ifName=%{public}s, protocolId=%{public}u, status=%{public}d",
484         subnet->ifName, subnet->protocol->id, subnet->status);
485 }
486 
GetIpEventInOther(LnnPhysicalSubnet * subnet)487 static IpSubnetManagerEvent GetIpEventInOther(LnnPhysicalSubnet *subnet)
488 {
489     char currentIfAddress[IP_LEN] = {0};
490     int32_t ret = GetAvailableIpAddr(subnet->ifName, currentIfAddress, sizeof(currentIfAddress));
491     if (ret == SOFTBUS_OK) {
492         return IP_SUBNET_MANAGER_EVENT_IF_READY;
493     }
494     return subnet->status == LNN_SUBNET_SHUTDOWN ? IP_SUBNET_MANAGER_EVENT_IF_DOWN : IP_SUBNET_MANAGER_EVENT_MAX;
495 }
496 
GetIpEventInRunning(LnnPhysicalSubnet * subnet)497 static IpSubnetManagerEvent GetIpEventInRunning(LnnPhysicalSubnet *subnet)
498 {
499     char currentIfAddress[IP_LEN] = {0};
500     int32_t ret = GetAvailableIpAddr(subnet->ifName, currentIfAddress, sizeof(currentIfAddress));
501     if (ret != SOFTBUS_OK) {
502         return IP_SUBNET_MANAGER_EVENT_IF_DOWN;
503     }
504 
505     char localIpAddr[IP_LEN] = {0};
506     char localNetifName[NET_IF_NAME_LEN] = {0};
507     if (GetLocalIpInfo(localIpAddr, sizeof(localIpAddr), localNetifName, sizeof(localNetifName)) != SOFTBUS_OK) {
508         LNN_LOGE(LNN_BUILDER, "get main ip info failed");
509         return IP_SUBNET_MANAGER_EVENT_IF_READY;
510     }
511     if (strcmp(localNetifName, subnet->ifName) != 0) {
512         return IP_SUBNET_MANAGER_EVENT_IF_READY;
513     }
514     if (strcmp(localIpAddr, currentIfAddress) == 0) {
515         return IP_SUBNET_MANAGER_EVENT_MAX;
516     } else {
517         return IP_SUBNET_MANAGER_EVENT_IF_CHANGED;
518     }
519 }
520 
OnSoftbusIpNetworkDisconnected(LnnPhysicalSubnet * subnet)521 static void OnSoftbusIpNetworkDisconnected(LnnPhysicalSubnet *subnet)
522 {
523     LNN_CHECK_AND_RETURN_LOGE(subnet != NULL, LNN_BUILDER, "invalid param");
524     if (subnet->status == LNN_SUBNET_RESETTING || subnet->status == LNN_SUBNET_IDLE) {
525         int32_t ret = EnableIpSubnet(subnet);
526         TransactIpSubnetState(subnet, IP_SUBNET_MANAGER_EVENT_IF_READY, (ret == SOFTBUS_OK));
527     }
528 }
529 
OnIpNetifStatusChanged(LnnPhysicalSubnet * subnet,void * status)530 static void OnIpNetifStatusChanged(LnnPhysicalSubnet *subnet, void *status)
531 {
532     if (subnet == NULL) {
533         LNN_LOGE(LNN_BUILDER, "invaild subnet paramter");
534         if (status != NULL) {
535             SoftBusFree(status);
536         }
537         return;
538     }
539 
540     IpSubnetManagerEvent event = IP_SUBNET_MANAGER_EVENT_MAX;
541     if (status == NULL) {
542         if (subnet->status == LNN_SUBNET_RUNNING) {
543             event = GetIpEventInRunning(subnet);
544         } else {
545             event = GetIpEventInOther(subnet);
546         }
547     } else {
548         event = *(IpSubnetManagerEvent *)status;
549         LNN_LOGI(LNN_BUILDER, "want to enter event=%{public}d", event);
550         SoftBusFree(status);
551         if (event < IP_SUBNET_MANAGER_EVENT_IF_READY || event > IP_SUBNET_MANAGER_EVENT_MAX) {
552             LNN_LOGW(LNN_BUILDER, "is not right event=%{public}d", event);
553             return;
554         }
555     }
556 
557     int32_t ret = SOFTBUS_NETWORK_NETIF_STATUS_CHANGED;
558     switch (event) {
559         case IP_SUBNET_MANAGER_EVENT_IF_READY: {
560             ret = EnableIpSubnet(subnet);
561             break;
562         }
563         case IP_SUBNET_MANAGER_EVENT_IF_DOWN: {
564             ret = DisableIpSubnet(subnet);
565             break;
566         }
567         case IP_SUBNET_MANAGER_EVENT_IF_CHANGED: {
568             ret = ChangeIpSubnetAddress(subnet);
569             break;
570         }
571         default:
572             return;
573     }
574 
575     TransactIpSubnetState(subnet, event, (ret == SOFTBUS_OK));
576 }
577 
CreateIpSubnetManager(const struct LnnProtocolManager * self,const char * ifName)578 static LnnPhysicalSubnet *CreateIpSubnetManager(const struct LnnProtocolManager *self, const char *ifName)
579 {
580     LnnPhysicalSubnet *subnet = (LnnPhysicalSubnet *)SoftBusCalloc(sizeof(LnnPhysicalSubnet));
581     if (subnet == NULL) {
582         LNN_LOGE(LNN_BUILDER, "malloc subnet fail");
583         return NULL;
584     }
585 
586     do {
587         subnet->destroy = DestroyIpSubnetManager;
588         subnet->protocol = self;
589         subnet->status = LNN_SUBNET_IDLE;
590         subnet->onNetifStatusChanged = OnIpNetifStatusChanged;
591         subnet->onSoftbusNetworkDisconnected = OnSoftbusIpNetworkDisconnected;
592 
593         int32_t ret = strcpy_s(subnet->ifName, sizeof(subnet->ifName), ifName);
594         if (ret != EOK) {
595             LNN_LOGE(LNN_BUILDER, "copy ifName failed ret=%{public}d", ret);
596             break;
597         }
598         return subnet;
599     } while (false);
600 
601     subnet->destroy((LnnPhysicalSubnet *)subnet);
602     return NULL;
603 }
604 
IpAddrChangeEventHandler(const LnnEventBasicInfo * info)605 static void IpAddrChangeEventHandler(const LnnEventBasicInfo *info)
606 {
607     if (info == NULL || info->event != LNN_EVENT_IP_ADDR_CHANGED) {
608         LNN_LOGE(LNN_BUILDER, "not interest event");
609         return;
610     }
611     const LnnMonitorAddressChangedEvent *event = (const LnnMonitorAddressChangedEvent *)info;
612     if (strlen(event->ifName) != 0) {
613         LnnNotifyPhysicalSubnetStatusChanged(event->ifName, LNN_PROTOCOL_IP, NULL);
614         DfxRecordTriggerTime(WIFI_IP_ADDR_CHANGED, EVENT_STAGE_LNN_WIFI_TRIGGER);
615     }
616 }
617 
WifiStateChangeWifiOrAp(const SoftBusWifiState wifiState)618 static bool WifiStateChangeWifiOrAp(const SoftBusWifiState wifiState)
619 {
620     switch (wifiState) {
621         case SOFTBUS_WIFI_CONNECTED:
622             g_wifiConnected = true;
623             return true;
624         case SOFTBUS_WIFI_DISCONNECTED:
625             g_wifiConnected = false;
626             return true;
627         case SOFTBUS_AP_ENABLED:
628             g_apEnabled = true;
629             return true;
630         case SOFTBUS_AP_DISABLED:
631             g_apEnabled = false;
632             return true;
633         default:
634             return false;
635     }
636 }
637 
IsValidLocalIp(void)638 static bool IsValidLocalIp(void)
639 {
640     char localIp[MAX_ADDR_LEN] = {0};
641     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, localIp, MAX_ADDR_LEN, WLAN_IF) != SOFTBUS_OK) {
642         LNN_LOGE(LNN_BUILDER, "get local ip failed");
643         return false;
644     }
645     if (strcmp(localIp, LNN_LOOPBACK_IP) == 0 || strcmp(localIp, "") == 0 || strcmp(localIp, "0.0.0.0") == 0) {
646         return false;
647     }
648     return true;
649 }
650 
WifiStateChangeEventHandler(const LnnEventBasicInfo * info)651 static void WifiStateChangeEventHandler(const LnnEventBasicInfo *info)
652 {
653     if (info == NULL || info->event != LNN_EVENT_WIFI_STATE_CHANGED) {
654         LNN_LOGE(LNN_BUILDER, "not interest event");
655         return;
656     }
657     if (!g_heartbeatEnable) {
658         LNN_LOGI(LNN_BUILDER, "g_heartbeatEnable not enable");
659         return;
660     }
661     const LnnMonitorWlanStateChangedEvent *event = (const LnnMonitorWlanStateChangedEvent *)info;
662     SoftBusWifiState wifiState = (SoftBusWifiState)event->status;
663     LNN_LOGI(LNN_BUILDER, "wifi state change. wifiState=%{public}d", wifiState);
664     bool beforeConnected = g_apEnabled || g_wifiConnected;
665     if (!WifiStateChangeWifiOrAp(wifiState)) {
666         LNN_LOGI(LNN_BUILDER, "not interest wifi event");
667         return;
668     }
669     bool currentConnected = g_apEnabled || g_wifiConnected;
670     bool isValidIp = IsValidLocalIp();
671     LNN_LOGI(LNN_BUILDER,
672         "wifi or ap wifiConnected=%{public}d, apEnabled=%{public}d, beforeConnected=%{public}d, "
673         "currentConnected=%{public}d, isValidIp=%{public}d",
674         g_wifiConnected, g_apEnabled, beforeConnected, currentConnected, isValidIp);
675     IpSubnetManagerEvent *status = (IpSubnetManagerEvent *)SoftBusCalloc(sizeof(IpSubnetManagerEvent));
676     if (status == NULL) {
677         LNN_LOGE(LNN_BUILDER, "wifi start calloc fail");
678         return;
679     }
680     if ((beforeConnected != currentConnected) || (currentConnected && !isValidIp)) {
681         LNN_LOGI(LNN_BUILDER, "wifi start to subnet change!");
682         if (currentConnected) {
683             SoftBusFree(status);
684             (void)LnnVisitNetif(NotifyWlanAddressChanged, NULL);
685         } else {
686             *status = IP_SUBNET_MANAGER_EVENT_IF_DOWN;
687             (void)LnnVisitNetif(NotifyWlanAddressChanged, status);
688         }
689         return;
690     }
691     SoftBusFree(status);
692 }
693 
LnnInitIpProtocol(struct LnnProtocolManager * self)694 int32_t LnnInitIpProtocol(struct LnnProtocolManager *self)
695 {
696     (void)self;
697     int32_t ret = SOFTBUS_OK;
698     if (LnnRegisterEventHandler(LNN_EVENT_IP_ADDR_CHANGED, IpAddrChangeEventHandler) != SOFTBUS_OK) {
699         LNN_LOGE(LNN_INIT, "register ip addr change event handler failed");
700         return SOFTBUS_NETWORK_REG_EVENT_HANDLER_ERR;
701     }
702     if (SetLocalIpInfo(LNN_LOOPBACK_IP, LNN_LOOPBACK_IFNAME) != SOFTBUS_OK) {
703         LNN_LOGE(LNN_INIT, "init local ip as loopback failed!");
704         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
705     }
706     DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP, WLAN_IF);
707     g_heartbeatEnable = IsEnableSoftBusHeartbeat();
708     LNN_LOGI(LNN_INIT, "init IP protocol g_heartbeatEnable=%{public}d", g_heartbeatEnable);
709     return ret;
710 }
711 
LnnEnableIpProtocol(struct LnnProtocolManager * self,LnnNetIfMgr * netifMgr)712 int32_t LnnEnableIpProtocol(struct LnnProtocolManager *self, LnnNetIfMgr *netifMgr)
713 {
714     (void)self;
715     if (netifMgr == NULL) {
716         LNN_LOGE(LNN_BUILDER, "netif mgr is null");
717         return SOFTBUS_INVALID_PARAM;
718     }
719     LnnPhysicalSubnet *manager = CreateIpSubnetManager(self, netifMgr->ifName);
720     if (manager == NULL) {
721         LNN_LOGE(LNN_BUILDER, "malloc subnet mgr fail");
722         return SOFTBUS_MALLOC_ERR;
723     }
724     int ret = LnnRegistPhysicalSubnet(manager);
725     if (ret != SOFTBUS_OK) {
726         LNN_LOGE(LNN_BUILDER, "regist subnet manager failed! ret=%{public}d", ret);
727         manager->destroy(manager);
728         return ret;
729     }
730     return SOFTBUS_OK;
731 }
732 
LnnGetIpListenerModule(ListenerMode mode)733 static ListenerModule LnnGetIpListenerModule(ListenerMode mode)
734 {
735     if (mode == LNN_LISTENER_MODE_PROXY) {
736         return PROXY;
737     } else if (mode == LNN_LISTENER_MODE_DIRECT) {
738         return DIRECT_CHANNEL_SERVER_WIFI;
739     } else {
740         return UNUSE_BUTT;
741     }
742 }
743 
LnnDeinitIpNetwork(struct LnnProtocolManager * self)744 void LnnDeinitIpNetwork(struct LnnProtocolManager *self)
745 {
746     (void)self;
747     LnnUnregisterEventHandler(LNN_EVENT_IP_ADDR_CHANGED, IpAddrChangeEventHandler);
748     LnnUnregisterEventHandler(LNN_EVENT_WIFI_STATE_CHANGED, WifiStateChangeEventHandler);
749     LnnUnregistPhysicalSubnetByType(LNN_PROTOCOL_IP);
750     LNN_LOGW(LNN_INIT, "ip network deinited");
751 }
752 
753 static LnnProtocolManager g_ipProtocol = {
754     .init = LnnInitIpProtocol,
755     .deinit = LnnDeinitIpNetwork,
756     .enable = LnnEnableIpProtocol,
757     .disable = NULL,
758     .getListenerModule = LnnGetIpListenerModule,
759     .id = LNN_PROTOCOL_IP,
760     .supportedNetif = LNN_NETIF_TYPE_ETH | LNN_NETIF_TYPE_WLAN,
761     .pri = 10,
762 };
763 
RegistIPProtocolManager(void)764 int32_t RegistIPProtocolManager(void)
765 {
766     return LnnRegistProtocol(&g_ipProtocol);
767 }
768