12#include <esp_wireguard.h>
13#include <esp_wireguard_err.h>
23#define LOGMSG_PEER_STATUS "Remote peer is %s (latest handshake %s)"
25static const char *
const LOGMSG_ONLINE =
"online";
26static const char *
const LOGMSG_OFFLINE =
"offline";
48 ESP_LOGI(TAG,
"Initialized");
59 ESP_LOGE(TAG,
"Cannot initialize: error code %d", this->
wg_initialized_);
70 ESP_LOGV(TAG,
"Local network connection has been lost, stopping");
80 ESP_LOGV(TAG,
"enabled=%d, connected=%d, peer_up=%d, handshake: current=%.0f latest=%.0f updated=%d",
85 this->latest_saved_handshake_ = lhs;
88 std::string latest_handshake =
89 (this->latest_saved_handshake_ > 0)
91 :
"timestamp not available";
95 ESP_LOGI(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
98 ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
102 ESP_LOGW(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
105 }
else if (this->enabled_) {
106 ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
117 ESP_LOGE(TAG,
"Remote peer is unreachable; rebooting");
123#ifdef USE_BINARY_SENSOR
137 char private_key_masked[MASK_KEY_BUFFER_SIZE];
138 char preshared_key_masked[MASK_KEY_BUFFER_SIZE];
147 " Private Key: " LOG_SECRET(
"%s")
"\n"
148 " Peer Endpoint: " LOG_SECRET(
"%s")
"\n"
149 " Peer Port: " LOG_SECRET(
"%d")
"\n"
150 " Peer Public Key: " LOG_SECRET(
"%s")
"\n"
151 " Peer Pre-shared Key: " LOG_SECRET(
"%s"),
154 (this->
preshared_key_ !=
nullptr ? preshared_key_masked : LOG_STR_LITERAL(
"NOT IN USE")));
156 ESP_LOGCONFIG(TAG,
" Peer Allowed IPs:");
158 ESP_LOGCONFIG(TAG,
" - %s/%s", it->ip, it->netmask);
160 ESP_LOGCONFIG(TAG,
" Peer Persistent Keepalive: %d%s", this->
keepalive_,
161 (this->
keepalive_ > 0 ? LOG_STR_LITERAL(
"s") : LOG_STR_LITERAL(
" (DISABLED)")));
162 ESP_LOGCONFIG(TAG,
" Reboot Timeout: %" PRIu32
"%s", (this->
reboot_timeout_ / 1000),
163 (this->
reboot_timeout_ != 0 ? LOG_STR_LITERAL(
"s") : LOG_STR_LITERAL(
" (DISABLED)")));
165 ESP_LOGCONFIG(TAG,
" Require Connection to Proceed: %s",
167 LOG_UPDATE_INTERVAL(
this);
176 (esp_wireguardif_peer_is_up(&(this->
wg_ctx_)) == ESP_OK);
181 if (esp_wireguard_latest_handshake(&(this->
wg_ctx_), &result) != ESP_OK) {
189 ESP_LOGI(TAG,
"Enabled");
196 ESP_LOGI(TAG,
"Disabled");
201#ifdef USE_BINARY_SENSOR
210 ESP_LOGV(TAG,
"Disabled, cannot start connection");
220 ESP_LOGD(TAG,
"Waiting for local network connection to be available");
225 ESP_LOGD(TAG,
"Waiting for system time to be synchronized");
230 ESP_LOGV(TAG,
"Connection already started");
234 ESP_LOGD(TAG,
"Starting connection");
241 ESP_LOGI(TAG,
"Connection started");
243 ESP_LOGD(TAG,
"Waiting for endpoint IP address to be available");
246 ESP_LOGW(TAG,
"Cannot start connection, error code %d", this->
wg_connected_);
250 ESP_LOGD(TAG,
"Configuring allowed IPs list");
251 bool allowed_ips_ok =
true;
253 allowed_ips_ok &= (esp_wireguard_add_allowed_ip(&(this->
wg_ctx_), it->ip, it->netmask) == ESP_OK);
256 if (allowed_ips_ok) {
257 ESP_LOGD(TAG,
"Allowed IPs list configured correctly");
259 ESP_LOGE(TAG,
"Cannot configure allowed IPs list, aborting");
267 ESP_LOGD(TAG,
"Stopping connection");
270 esp_wireguard_disconnect(&(this->
wg_ctx_));
278 if (
len < MASK_KEY_BUFFER_SIZE ||
key ==
nullptr) {
285 for (; i < 5 &&
key[i] !=
'\0'; ++i) {
289 const char *suffix =
"[...]=";
290 for (
size_t j = 0; suffix[j] !=
'\0' && (i + j) <
len - 1; ++j) {
291 buffer[i + j] = suffix[j];
void mark_failed()
Mark this component as failed.
void defer(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call with a const char* name.
Helper class to lock the lwIP TCPIP core when making lwIP API calls from non-TCPIP threads.
void publish_state(bool new_state)
Publish a new state to the front-end.
void publish_state(float state)
Publish a new state to the front-end.
void publish_state(const std::string &state)
ESPTime now()
Get the time in the currently defined timezone.
void add_on_time_sync_callback(F &&callback)
binary_sensor::BinarySensor * enabled_sensor_
bool enabled_
When false the wireguard link will not be established.
binary_sensor::BinarySensor * status_sensor_
void publish_enabled_state()
Publish the enabled state if the enabled binary sensor is configured.
time_t get_latest_handshake() const
void on_shutdown() override
sensor::Sensor * handshake_sensor_
time::RealTimeClock * srctime_
bool proceed_allowed_
Set to false to block the setup step until peer is connected.
void dump_config() override
const char * private_key_
bool can_proceed() override
text_sensor::TextSensor * address_sensor_
uint32_t wg_peer_offline_time_
The last time the remote peer become offline.
void disable()
Stop any running connection and disable the WireGuard component.
uint32_t wg_reconnect_time_
esp_err_t wg_initialized_
const char * peer_public_key_
void enable()
Enable the WireGuard component.
const char * preshared_key_
const AllowedIP * allowed_ips_
const char * peer_endpoint_
time_t latest_saved_handshake_
The latest saved handshake.
wireguard_config_t wg_config_
ESPHOME_ALWAYS_INLINE bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
void mask_key_to(char *buffer, size_t len, const char *key)
Strip most part of the key only for secure printing.
ESPHOME_LOG_TAG(TAG, "wireguard")
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
static ESPTime from_epoch_local(time_t epoch)
Convert an UTC epoch timestamp to a local time ESPTime instance.
size_t strftime(char *buffer, size_t buffer_len, const char *format)
Convert this ESPTime struct to a null-terminated c string buffer as specified by the format argument.
bool is_valid(bool check_day_of_week=true, bool check_day_of_year=true) const
Check if this ESPTime is valid (year >= 2019 and the requested fields are in range).
Allowed IP entry for WireGuard peer configuration.