diff --git a/README.md b/README.md index ac7b283..2c4f4f4 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,11 @@ in ESPHome website. ## Compatibility -This code targets only ESPHome and has been tested on `esp32` boards (with both frameworks `esp-idf` and `Arduino`) -and on `esp8266` boards. +This code targets only ESPHome and has been tested on the following platforms: + +* ESP32 (with both frameworks) +* ESP8266 +* LibreTiny (with `bk72` microcontrollers only) ## References @@ -28,6 +31,10 @@ For additional information see: * the first pull-request [esphome/esphome#4256](https://github.com/esphome/esphome/pull/4256) +* `esp8266` support [esphome/esphome#6365](https://github.com/esphome/esphome/pull/6365) + +* LibreTiny support [droscy/esp_wireguard#4](https://github.com/droscy/esp_wireguard/pull/4) + ## License diff --git a/library.json b/library.json index 259fe6a..0868a74 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "esp_wireguard", - "version": "0.4.0", + "version": "0.4.1", "description": "WireGuard implementation for ESPHome", "keywords":[ "esphome", @@ -45,7 +45,8 @@ "license": "BSD-3-Clause", "platforms": [ "espressif32", - "espressif8266" + "espressif8266", + "libretiny" ], "frameworks":[ "espidf", @@ -60,7 +61,7 @@ { "owner": "droscy", "name": "esp_mbedtls_esp8266", - "version": "^2.23.0", + "version": "^2.22300.2", "platforms": "espressif8266", "frameworks": "arduino" } diff --git a/src/esp_wireguard.c b/src/esp_wireguard.c index d574b80..529e4ef 100644 --- a/src/esp_wireguard.c +++ b/src/esp_wireguard.c @@ -208,7 +208,11 @@ esp_err_t esp_wireguard_init(wireguard_config_t *config, wireguard_ctx_t *ctx) err = wireguard_platform_init(); if (err != ESP_OK) { +#if !defined(LIBRETINY) ESP_LOGE(TAG, "wireguard_platform_init: %s", esp_err_to_name(err)); +#else // !defined(LIBRETINY) + ESP_LOGE(TAG, "wireguard_platform_init: %d", err); +#endif // !defined(LIBRETINY) goto fail; } ctx->config = config; @@ -233,7 +237,11 @@ esp_err_t esp_wireguard_connect(wireguard_ctx_t *ctx) if (ctx->netif == NULL) { err = esp_wireguard_netif_create(ctx->config); if (err != ESP_OK) { +#if !defined(LIBRETINY) ESP_LOGE(TAG, "netif_create: %s", esp_err_to_name(err)); +#else // !defined(LIBRETINY) + ESP_LOGE(TAG, "netif_create: %d", err); +#endif // !defined(LIBRETINY) goto fail; } ctx->netif = wg_netif; @@ -271,7 +279,11 @@ esp_err_t esp_wireguard_connect(wireguard_ctx_t *ctx) /* Initialize the first WireGuard peer structure */ err = esp_wireguard_peer_init(ctx->config, &peer); if (err != ESP_OK) { +#if !defined(LIBRETINY) ESP_LOGE(TAG, "peer_init: %s", esp_err_to_name(err)); +#else // !defined(LIBRETINY) + ESP_LOGE(TAG, "peer_init: %d", err); +#endif // !defined(LIBRETINY) goto fail; } @@ -343,6 +355,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); @@ -356,6 +372,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/esp_wireguard_err.h b/src/esp_wireguard_err.h index 2f19b79..2a38308 100644 --- a/src/esp_wireguard_err.h +++ b/src/esp_wireguard_err.h @@ -31,7 +31,11 @@ #if !defined(__ESP_WIREGUARD_ERR__H__) #define __ESP_WIREGUARD_ERR__H__ -#if defined(ESP8266) && !defined(IDF_VER) +#if defined(LIBRETINY) +#undef esp_err_t +#endif + +#if defined(ESP8266) && !defined(IDF_VER) || defined(LIBRETINY) typedef int esp_err_t; #define ESP_OK 0 /*!< esp_err_t value indicating success (no error) */ diff --git a/src/esp_wireguard_log.h b/src/esp_wireguard_log.h index 7441ab1..f292b04 100644 --- a/src/esp_wireguard_log.h +++ b/src/esp_wireguard_log.h @@ -56,8 +56,10 @@ #define ESP_LOGV(tag, ...) _noop(tag, __VA_ARGS__) #endif -#else // defined(ESP8266) && !defined(IDF_VER) +#elif defined(LIBRETINY) +#include +#else // defined(LIBRETINY) #include -#endif // defined(ESP8266) && !defined(IDF_VER) +#endif // defined(ESP8266) && !defined(IDF_VER) #endif // __ESP_WIREGUARD_LOG__H__ diff --git a/src/wireguard-platform.c b/src/wireguard-platform.c index 43a9f65..aa4f05c 100644 --- a/src/wireguard-platform.c +++ b/src/wireguard-platform.c @@ -38,13 +38,17 @@ #include "lwip/sys.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" +#include "mbedtls/version.h" #if defined(ESP8266) && !defined(IDF_VER) #include #define esp_fill_random(out, size) os_get_random(out, size) -#else // defined(ESP8266) && !defined(IDF_VER) +#elif defined(LIBRETINY) +#include +#define esp_fill_random(out, size) lt_rand_bytes(out, size) +#else // defined(LIBRETINY) #include -#endif // defined(ESP8266) && !defined(IDF_VER) +#endif // defined(ESP8266) && !defined(IDF_VER) #include "esp_wireguard_err.h" #include "esp_wireguard_log.h" @@ -56,8 +60,13 @@ #define ENTROPY_CUSTOM_DATA_LENGTH (0) #define TAG "wireguard-platform" +#if MBEDTLS_VERSION_NUMBER >= 0x020D0000 static struct mbedtls_ctr_drbg_context random_context; static struct mbedtls_entropy_context entropy_context; +#else +static mbedtls_ctr_drbg_context random_context; +static mbedtls_entropy_context entropy_context; +#endif static int entropy_hw_random_source( void *data, unsigned char *output, size_t len, size_t *olen ) { esp_fill_random(output, len); diff --git a/src/wireguardif.c b/src/wireguardif.c index 0d50fc1..80c11d9 100644 --- a/src/wireguardif.c +++ b/src/wireguardif.c @@ -49,10 +49,10 @@ #include "esp_wireguard_log.h" #include "esp_wireguard_err.h" -#if !defined(ESP8266) || defined(IDF_VER) +#if (!defined(ESP8266) || defined(IDF_VER)) && !defined(LIBRETINY) #include #include "esp_netif.h" -#endif // !defined(ESP8266) || defined(IDF_VER) +#endif // (!defined(ESP8266) || defined(IDF_VER)) && !defined(LIBRETINY) #include "wireguard.h" #include "crypto.h" @@ -204,8 +204,14 @@ static err_t wireguardif_output(struct netif *netif, struct pbuf *q, const ip4_a return ERR_IF; } 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) { @@ -743,7 +749,7 @@ time_t wireguardif_latest_handshake(struct netif *netif, u8_t peer_index) { */ result = (peer->latest_handshake_millis / 1000) + (time(NULL) - (wireguard_sys_now() / 1000)); } else { - ESP_LOGD(TAG, "wireguardif_latest_handshake: valid=%d, lhs=%d", (int) peer->valid, peer->latest_handshake_millis); + ESP_LOGD(TAG, "wireguardif_latest_handshake: valid=%ld, lhs=%ld", (long) peer->valid, (long) peer->latest_handshake_millis); } } return result; @@ -948,7 +954,7 @@ err_t wireguardif_init(struct netif *netif) { struct netif* underlying_netif = NULL; -#if !defined(ESP8266) || defined(IDF_VER) +#if (!defined(ESP8266) || defined(IDF_VER)) && !defined(LIBRETINY) char lwip_netif_name[8] = {0,}; // list of interfaces to try to bind wireguard to @@ -970,15 +976,21 @@ err_t wireguardif_init(struct netif *netif) { } underlying_netif = netif_find(lwip_netif_name); -#else // !defined(ESP8266) || defined(IDF_VER) - underlying_netif = netif_default; -#endif // !defined(ESP8266) || defined(IDF_VER) if (underlying_netif == NULL) { ESP_LOGE(TAG, "netif_find: cannot find %s (%s)", ifkey, lwip_netif_name); result = ERR_IF; goto fail; } +#else // (!defined(ESP8266) || defined(IDF_VER)) && !defined(LIBRETINY) + underlying_netif = netif_default; + + if (underlying_netif == NULL) { + ESP_LOGE(TAG, "netif_find: cannot find default netif"); + result = ERR_IF; + goto fail; + } +#endif // (!defined(ESP8266) || defined(IDF_VER)) && !defined(LIBRETINY) ESP_LOGV(TAG, "underlying_netif = %p", underlying_netif); @@ -1091,6 +1103,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 b011863..581c062 100644 --- a/src/wireguardif.h +++ b/src/wireguardif.h @@ -133,6 +133,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);