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