close TCP connections on DHCP/SLAAC IP address changes

This commit is contained in:
Sergio R. Caprile committed 2026-05-22 11:14:45 -03:00
1 parent d4013e47f9
commit 7a74f5ada1
4 files changed
+40 -2

No files matched your search

+18 -1
View File
@@ -6846,6 +6846,13 @@ static void onstatechange(struct mg_tcpip_if *ifp) {
MG_INFO((" MAC: %M", mg_print_mac, ifp->mac));
if (ifp->l2type == MG_TCPIP_L2_ETH)
mg_tcpip_arp_request(ifp, ifp->ip, ifp->mac); // gratuitous ARP annc
if (ifp->is_ip_changed) {
struct mg_connection *c;
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
if (!c->is_listening && !c->is_udp) c->is_closing = 1;
}
ifp->is_ip_changed = false;
}
} else if (ifp->state == MG_TCPIP_STATE_IP) {
if (ifp->gw != 0 && ifp->l2type == MG_TCPIP_L2_ETH)
mg_tcpip_arp_request(ifp, ifp->gw, NULL); // unsolicited GW ARP request
@@ -7155,6 +7162,7 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
// assume DHCP server = router until ARP resolves
memcpy(ifp->gwmac, mg_l2_getaddr(ifp, pkt->l2), sizeof(ifp->gwmac));
ifp->gw_ready = true; // NOTE(): actual gw ARP won't retry now
if (ifp->ip != ip) ifp->is_ip_changed = true;
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
mg_random(&rand, sizeof(rand));
@@ -7410,7 +7418,7 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
struct ndp_ra *ra = (struct ndp_ra *) (pkt->icmp6 + 1);
uint8_t *opts = (uint8_t *) (ra + 1);
size_t opt_left = pkt->pay.len - 12;
bool gotl2addr = false, gotprefix = false;
bool gotl2addr = false, gotprefix = false, changed = false;
uint8_t l2[sizeof(struct mg_l2addr)];
uint32_t mtu = 0;
uint8_t *prefix, prefix_len;
@@ -7443,6 +7451,8 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
(void) pref_lifetime;
gotprefix = true;
if (prefix_len != ifp->prefix || !match_prefix(prefix, ifp->prefix, ifp->prefix_len))
changed = true;
}
opts += length;
opt_left -= length;
@@ -7450,6 +7460,7 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
// fill prefix and global
if (gotprefix && !fill_global(ifp, prefix, prefix_len)) return;
if (changed) ifp->is_ip6_changed = true;
ifp->gw6[0] = pkt->ip6->src[0], ifp->gw6[1] = pkt->ip6->src[1];
if (gotl2addr) memcpy(ifp->gw6mac, l2, sizeof(ifp->gw6mac));
if (gotl2addr || ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) {
@@ -7528,6 +7539,12 @@ static void onstate6change(struct mg_tcpip_if *ifp) {
(struct mg_addr *) &ip6_allrouters),
ifp->ip6, (uint64_t *) ip6_allrouters.addr.ip6, false,
ifp->mac);
if (ifp->is_ip6_changed) {
struct mg_connection *c;
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
if (!c->is_listening && !c->is_udp) c->is_closing = 1;
}
ifp->is_ip6_changed = false;
}
} else if (ifp->state6 == MG_TCPIP_STATE_IP) {
if ((ifp->gw6[0] != 0 || ifp->gw6[1] != 0) && (ifp->l2type != MG_TCPIP_L2_PPP && ifp->l2type != MG_TCPIP_L2_PPPoE))
+2
View File
@@ -3452,6 +3452,7 @@ struct mg_tcpip_if {
bool enable_fcs_check; // Do a FCS check on RX frames and strip it
bool enable_mac_check; // Do a hw addr check on RX frames
bool update_mac_hash_table; // Signal drivers to update MAC controller
bool is_ip_changed; // IP address changed, close/restart conns
struct mg_tcpip_driver *driver; // Low level driver
void *driver_data; // Driver-specific data
mg_tcpip_event_handler_t pfn; // Driver-specific event handler function
@@ -3468,6 +3469,7 @@ struct mg_tcpip_if {
uint64_t gw6[2]; // default gateway.
bool enable_slaac; // Enable IPv6 address autoconfiguration
bool enable_dhcp6_client; // Enable DCHPv6 client TODO()
bool is_ip6_changed; // IPv6 address changed, close/restart conns
#endif
// Internal state, user can use it but should not change it
+18 -1
View File
@@ -391,6 +391,13 @@ static void onstatechange(struct mg_tcpip_if *ifp) {
MG_INFO((" MAC: %M", mg_print_mac, ifp->mac));
if (ifp->l2type == MG_TCPIP_L2_ETH)
mg_tcpip_arp_request(ifp, ifp->ip, ifp->mac); // gratuitous ARP annc
if (ifp->is_ip_changed) {
struct mg_connection *c;
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
if (!c->is_listening && !c->is_udp) c->is_closing = 1;
}
ifp->is_ip_changed = false;
}
} else if (ifp->state == MG_TCPIP_STATE_IP) {
if (ifp->gw != 0 && ifp->l2type == MG_TCPIP_L2_ETH)
mg_tcpip_arp_request(ifp, ifp->gw, NULL); // unsolicited GW ARP request
@@ -700,6 +707,7 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
// assume DHCP server = router until ARP resolves
memcpy(ifp->gwmac, mg_l2_getaddr(ifp, pkt->l2), sizeof(ifp->gwmac));
ifp->gw_ready = true; // NOTE(): actual gw ARP won't retry now
if (ifp->ip != ip) ifp->is_ip_changed = true;
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
mg_random(&rand, sizeof(rand));
@@ -955,7 +963,7 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
struct ndp_ra *ra = (struct ndp_ra *) (pkt->icmp6 + 1);
uint8_t *opts = (uint8_t *) (ra + 1);
size_t opt_left = pkt->pay.len - 12;
bool gotl2addr = false, gotprefix = false;
bool gotl2addr = false, gotprefix = false, changed = false;
uint8_t l2[sizeof(struct mg_l2addr)];
uint32_t mtu = 0;
uint8_t *prefix, prefix_len;
@@ -988,6 +996,8 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
(void) pref_lifetime;
gotprefix = true;
if (prefix_len != ifp->prefix || !match_prefix(prefix, ifp->prefix, ifp->prefix_len))
changed = true;
}
opts += length;
opt_left -= length;
@@ -995,6 +1005,7 @@ static void rx_ndp_ra(struct mg_tcpip_if *ifp, struct pkt *pkt) {
// fill prefix and global
if (gotprefix && !fill_global(ifp, prefix, prefix_len)) return;
if (changed) ifp->is_ip6_changed = true;
ifp->gw6[0] = pkt->ip6->src[0], ifp->gw6[1] = pkt->ip6->src[1];
if (gotl2addr) memcpy(ifp->gw6mac, l2, sizeof(ifp->gw6mac));
if (gotl2addr || ifp->l2type == MG_TCPIP_L2_PPP || ifp->l2type == MG_TCPIP_L2_PPPoE) {
@@ -1073,6 +1084,12 @@ static void onstate6change(struct mg_tcpip_if *ifp) {
(struct mg_addr *) &ip6_allrouters),
ifp->ip6, (uint64_t *) ip6_allrouters.addr.ip6, false,
ifp->mac);
if (ifp->is_ip6_changed) {
struct mg_connection *c;
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
if (!c->is_listening && !c->is_udp) c->is_closing = 1;
}
ifp->is_ip6_changed = false;
}
} else if (ifp->state6 == MG_TCPIP_STATE_IP) {
if ((ifp->gw6[0] != 0 || ifp->gw6[1] != 0) && (ifp->l2type != MG_TCPIP_L2_PPP && ifp->l2type != MG_TCPIP_L2_PPPoE))
+2
View File
@@ -50,6 +50,7 @@ struct mg_tcpip_if {
bool enable_fcs_check; // Do a FCS check on RX frames and strip it
bool enable_mac_check; // Do a hw addr check on RX frames
bool update_mac_hash_table; // Signal drivers to update MAC controller
bool is_ip_changed; // IP address changed, close/restart conns
struct mg_tcpip_driver *driver; // Low level driver
void *driver_data; // Driver-specific data
mg_tcpip_event_handler_t pfn; // Driver-specific event handler function
@@ -66,6 +67,7 @@ struct mg_tcpip_if {
uint64_t gw6[2]; // default gateway.
bool enable_slaac; // Enable IPv6 address autoconfiguration
bool enable_dhcp6_client; // Enable DCHPv6 client TODO()
bool is_ip6_changed; // IPv6 address changed, close/restart conns
#endif
// Internal state, user can use it but should not change it