diff --git a/src/esp_wireguard.c b/src/esp_wireguard.c index da2664c..e6b3170 100644 --- a/src/esp_wireguard.c +++ b/src/esp_wireguard.c @@ -299,6 +299,10 @@ esp_err_t esp_wireguard_disconnect(wireguard_ctx_t *ctx) goto fail; } + // Clear the IP address to gracefully disconnect any clients while the + // peers are still valid + netif_set_ipaddr(ctx->netif, IP4_ADDR_ANY4); + lwip_err = wireguardif_disconnect(ctx->netif, wireguard_peer_index); if (lwip_err != ERR_OK) { ESP_LOGW(TAG, "wireguardif_disconnect: peer_index: %" PRIu8 " err: %i", wireguard_peer_index, lwip_err); @@ -312,6 +316,7 @@ esp_err_t esp_wireguard_disconnect(wireguard_ctx_t *ctx) wireguard_peer_index = WIREGUARDIF_INVALID_INDEX; wireguardif_shutdown(ctx->netif); netif_remove(ctx->netif); + wireguardif_fini(ctx->netif); netif_set_default(ctx->netif_default); ctx->netif = NULL; diff --git a/src/wireguardif.c b/src/wireguardif.c index 2be9c45..52ea926 100644 --- a/src/wireguardif.c +++ b/src/wireguardif.c @@ -198,8 +198,14 @@ static err_t wireguardif_output_to_peer(struct netif *netif, struct pbuf *q, con // The ipaddr here is the one inside the VPN which we use to lookup the correct peer/endpoint static err_t wireguardif_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ip4addr) { struct wireguard_device *device = (struct wireguard_device *)netif->state; - // Send to peer that matches dest IP ip_addr_t ipaddr; + + if (!device) { + ESP_LOGE(TAG, "wireguardif_output NULL device"); + return ERR_RTE; + } + + // Send to peer that matches dest IP ip_addr_copy_from_ip4(ipaddr, *ip4addr); struct wireguard_peer *peer = peer_lookup_by_allowed_ip(device, &ipaddr); if (peer) { @@ -1037,6 +1043,14 @@ void wireguardif_shutdown(struct netif *netif) { udp_remove(device->udp_pcb); device->udp_pcb = NULL; } +} + +void wireguardif_fini(struct netif *netif) { + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("state != NULL", (netif->state != NULL)); + + struct wireguard_device *device = (struct wireguard_device *)netif->state; + // remove device context. free(device); netif->state = NULL; diff --git a/src/wireguardif.h b/src/wireguardif.h index 489244d..3d1864f 100644 --- a/src/wireguardif.h +++ b/src/wireguardif.h @@ -131,6 +131,9 @@ err_t wireguardif_disconnect(struct netif *netif, u8_t peer_index); // Shutdown the WireGuard interface void wireguardif_shutdown(struct netif *netif); +// Finalize the WireGuard interface after the netif is removed +void wireguardif_fini(struct netif *netif); + // Is the given peer "up"? A peer is up if it has a valid session key it can communicate with err_t wireguardif_peer_is_up(struct netif *netif, u8_t peer_index, ip_addr_t *current_ip, u16_t *current_port);