Skip to content

Commit c40286b

Browse files
committed
Improve DNS server selection logic
Add `.dns` to the ip_info struct Update DNS server according to highest priority active connection: Ethernet, WiFi, PPP. Signed-off-by: Deomid "rojer" Ryabkov <[email protected]>
1 parent a79dcbb commit c40286b

File tree

5 files changed

+94
-32
lines changed

5 files changed

+94
-32
lines changed

include/mgos_net.h

+4-12
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
* is lost, established, etc.
2424
*/
2525

26-
#ifndef CS_FW_INCLUDE_MGOS_NET_H_
27-
#define CS_FW_INCLUDE_MGOS_NET_H_
26+
#pragma once
2827

2928
#include <stdbool.h>
3029

@@ -35,7 +34,7 @@
3534

3635
#ifdef __cplusplus
3736
extern "C" {
38-
#endif /* __cplusplus */
37+
#endif
3938

4039
/*
4140
* Event group which should be given to `mgos_event_add_group_handler()`
@@ -85,6 +84,7 @@ struct mgos_net_ip_info {
8584
struct sockaddr_in ip;
8685
struct sockaddr_in netmask;
8786
struct sockaddr_in gw;
87+
struct sockaddr_in dns;
8888
};
8989

9090
struct mgos_net_event_data {
@@ -118,14 +118,6 @@ bool mgos_net_str_to_ip(const char *ips, struct sockaddr_in *sin);
118118
*/
119119
bool mgos_net_str_to_ip_n(const struct mg_str ips, struct sockaddr_in *sin);
120120

121-
/*
122-
* Returns nameserver address. The caller should `free()` it. Returns NULL
123-
* in case of no DNS.
124-
*/
125-
char *mgos_get_nameserver(void);
126-
127121
#ifdef __cplusplus
128122
}
129-
#endif /* __cplusplus */
130-
131-
#endif /* CS_FW_INCLUDE_MGOS_NET_H_ */
123+
#endif

platforms/esp32/sdk.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
docker.io/mgos/esp32-build:4.2-r1
1+
docker.io/mgos/esp32-build:4.2-r2

src/mgos_net.c

+32-19
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ struct net_ev_info {
3838
enum mgos_net_event ev;
3939
};
4040

41+
static void mgos_update_nameserver(void);
42+
4143
static const char *get_if_name(enum mgos_net_if_type if_type, int if_instance) {
4244
const char *name = "";
4345
switch (if_type) {
@@ -80,6 +82,7 @@ static void mgos_net_on_change_cb(void *arg) {
8082
switch (ei->ev) {
8183
case MGOS_NET_EV_DISCONNECTED: {
8284
LOG(LL_INFO, ("%s: disconnected", if_name));
85+
mgos_update_nameserver();
8386
break;
8487
}
8588
case MGOS_NET_EV_CONNECTING: {
@@ -92,17 +95,13 @@ static void mgos_net_on_change_cb(void *arg) {
9295
}
9396
case MGOS_NET_EV_IP_ACQUIRED: {
9497
if (mgos_net_get_ip_info(ei->if_type, ei->if_instance, &evd.ip_info)) {
95-
char ip[16], gw[16];
96-
char *nameserver = mgos_get_nameserver();
97-
memset(ip, 0, sizeof(ip));
98-
memset(gw, 0, sizeof(gw));
98+
char ip[16], gw[16], dns[16];
9999
mgos_net_ip_to_str(&evd.ip_info.ip, ip);
100100
mgos_net_ip_to_str(&evd.ip_info.gw, gw);
101-
LOG(LL_INFO, ("%s: ready, IP %s, GW %s, DNS %s", if_name, ip, gw,
102-
nameserver ? nameserver : "default"));
103-
mg_set_nameserver(mgos_get_mgr(), nameserver);
104-
free(nameserver);
101+
mgos_net_ip_to_str(&evd.ip_info.dns, dns);
102+
LOG(LL_INFO, ("%s: ready, IP %s, GW %s, DNS %s", if_name, ip, gw, dns));
105103
}
104+
mgos_update_nameserver();
106105
break;
107106
}
108107
}
@@ -179,18 +178,32 @@ bool mgos_net_str_to_ip_n(struct mg_str ips, struct sockaddr_in *sin) {
179178
return res;
180179
}
181180

182-
char *mgos_get_nameserver() {
183-
#ifdef MGOS_HAVE_WIFI
184-
char *dns = NULL;
185-
if (mgos_sys_config_get_wifi_sta_nameserver() != NULL) {
186-
dns = strdup(mgos_sys_config_get_wifi_sta_nameserver());
187-
} else {
188-
dns = mgos_wifi_get_sta_default_dns();
181+
static void mgos_update_nameserver(void) {
182+
char nameserver[16];
183+
struct mgos_net_ip_info ip_info;
184+
memset(&ip_info, 0, sizeof(ip_info));
185+
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_ETHERNET, 0, &ip_info) &&
186+
ip_info.ip.sin_addr.s_addr != 0 && ip_info.dns.sin_addr.s_addr != 0) {
187+
goto out;
189188
}
190-
return dns;
191-
#else
192-
return NULL;
193-
#endif
189+
memset(&ip_info, 0, sizeof(ip_info));
190+
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, 0, &ip_info) &&
191+
ip_info.ip.sin_addr.s_addr != 0 && ip_info.dns.sin_addr.s_addr != 0) {
192+
goto out;
193+
}
194+
memset(&ip_info, 0, sizeof(ip_info));
195+
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_PPP, 0, &ip_info) &&
196+
ip_info.ip.sin_addr.s_addr != 0 && ip_info.dns.sin_addr.s_addr != 0) {
197+
goto out;
198+
}
199+
mgos_net_str_to_ip(MGOS_DEFAULT_NAMESERVER, &ip_info.dns);
200+
out:
201+
mgos_net_ip_to_str(&ip_info.dns, nameserver);
202+
struct mg_mgr *mgr = mgos_get_mgr();
203+
if (mgr->nameserver != NULL && strcmp(mgr->nameserver, nameserver) == 0)
204+
return;
205+
LOG(LL_DEBUG, ("Setting DNS server to %s", nameserver));
206+
mg_set_nameserver(mgr, nameserver);
194207
}
195208

196209
enum mgos_init_result mgos_net_init(void) {

tools/docker/esp32/Dockerfile-esp32-build

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ RUN git clone -j 8 --branch $DOCKER_TAG --depth 1 --recursive --shallow-submodul
4141
RUN cd /opt/Espressif/esp-idf && git tag v$DOCKER_TAG
4242
ENV IDF_PATH=/opt/Espressif/esp-idf
4343

44+
ADD lwip_dns.patch /opt/Espressif/esp-idf/components/lwip/lwip
45+
RUN cd /opt/Espressif/esp-idf/components/lwip/lwip && patch -p 1 < lwip_dns.patch
46+
4447
# Pre-build configuration tools
4548
RUN cd $IDF_PATH/tools/kconfig && make conf-idf
4649

tools/docker/esp32/lwip_dns.patch

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c
2+
index b519ae909..96de64423 100644
3+
--- a/src/core/ipv4/dhcp.c
4+
+++ b/src/core/ipv4/dhcp.c
5+
@@ -703,6 +703,10 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
6+
dns_setserver(n, &dns_addr);
7+
}
8+
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
9+
+ ip4_addr_set_zero(&dhcp->offered_dns_addr);
10+
+ if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER)) {
11+
+ ip4_addr_set_u32(&dhcp->offered_dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER)));
12+
+ }
13+
}
14+
15+
/**
16+
diff --git a/src/include/lwip/dhcp.h b/src/include/lwip/dhcp.h
17+
index 962cc2ee2..752db1f67 100644
18+
--- a/src/include/lwip/dhcp.h
19+
+++ b/src/include/lwip/dhcp.h
20+
@@ -103,6 +103,7 @@ struct dhcp
21+
ip4_addr_t offered_ip_addr;
22+
ip4_addr_t offered_sn_mask;
23+
ip4_addr_t offered_gw_addr;
24+
+ ip4_addr_t offered_dns_addr;
25+
26+
u32_t offered_t0_lease; /* lease period (in seconds) */
27+
u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
28+
diff --git a/src/include/netif/ppp/ppp.h b/src/include/netif/ppp/ppp.h
29+
index 3d73c3657..2f1e1e9e3 100644
30+
--- a/src/include/netif/ppp/ppp.h
31+
+++ b/src/include/netif/ppp/ppp.h
32+
@@ -421,6 +421,8 @@ struct ppp_pcb_s {
33+
ipv6cp_options ipv6cp_allowoptions; /* Options we allow peer to request */
34+
ipv6cp_options ipv6cp_hisoptions; /* Options that we ack'd */
35+
#endif /* PPP_IPV6_SUPPORT */
36+
+
37+
+ u32_t dns_server;
38+
};
39+
40+
/************************
41+
diff --git a/src/netif/ppp/ipcp.c b/src/netif/ppp/ipcp.c
42+
index b7c766eb0..2d33f97c2 100644
43+
--- a/src/netif/ppp/ipcp.c
44+
+++ b/src/netif/ppp/ipcp.c
45+
@@ -1930,7 +1930,9 @@ static void ipcp_up(fsm *f) {
46+
if (go->dnsaddr[1])
47+
script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
48+
#endif /* UNUSED */
49+
+ pcb->dns_server = 0;
50+
if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
51+
+ pcb->dns_server = go->dnsaddr[0];
52+
sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]);
53+
#if 0 /* UNUSED */
54+
script_setenv("USEPEERDNS", "1", 0);

0 commit comments

Comments
 (0)