13#include <esp_wireguard.h>
14#include <esp_wireguard_err.h>
19static const char *
const TAG =
"wireguard";
25#define LOGMSG_PEER_STATUS "Remote peer is %s (latest handshake %s)"
27static const char *
const LOGMSG_ONLINE =
"online";
28static const char *
const LOGMSG_OFFLINE =
"offline";
50 ESP_LOGI(TAG,
"Initialized");
61 ESP_LOGE(TAG,
"Cannot initialize: error code %d", this->
wg_initialized_);
72 ESP_LOGV(TAG,
"Local network connection has been lost, stopping");
82 ESP_LOGV(TAG,
"enabled=%d, connected=%d, peer_up=%d, handshake: current=%.0f latest=%.0f updated=%d",
87 this->latest_saved_handshake_ = lhs;
90 std::string latest_handshake =
91 (this->latest_saved_handshake_ > 0)
93 :
"timestamp not available";
97 ESP_LOGI(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
100 ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_ONLINE, latest_handshake.c_str());
104 ESP_LOGW(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
106 }
else if (this->enabled_) {
107 ESP_LOGD(TAG, LOGMSG_PEER_STATUS, LOGMSG_OFFLINE, latest_handshake.c_str());
114 ESP_LOGE(TAG,
"Remote peer is unreachable; rebooting");
120#ifdef USE_BINARY_SENSOR
134 ESP_LOGCONFIG(TAG,
"WireGuard:");
135 ESP_LOGCONFIG(TAG,
" Address: %s", this->
address_.c_str());
136 ESP_LOGCONFIG(TAG,
" Netmask: %s", this->
netmask_.c_str());
138 ESP_LOGCONFIG(TAG,
" Peer Endpoint: " LOG_SECRET(
"%s"), this->
peer_endpoint_.c_str());
139 ESP_LOGCONFIG(TAG,
" Peer Port: " LOG_SECRET(
"%d"), this->
peer_port_);
140 ESP_LOGCONFIG(TAG,
" Peer Public Key: " LOG_SECRET(
"%s"), this->
peer_public_key_.c_str());
141 ESP_LOGCONFIG(TAG,
" Peer Pre-shared Key: " LOG_SECRET(
"%s"),
143 ESP_LOGCONFIG(TAG,
" Peer Allowed IPs:");
145 ESP_LOGCONFIG(TAG,
" - %s/%s", std::get<0>(allowed_ip).c_str(), std::get<1>(allowed_ip).c_str());
147 ESP_LOGCONFIG(TAG,
" Peer Persistent Keepalive: %d%s", this->
keepalive_,
148 (this->
keepalive_ > 0 ?
"s" :
" (DISABLED)"));
149 ESP_LOGCONFIG(TAG,
" Reboot Timeout: %" PRIu32
"%s", (this->
reboot_timeout_ / 1000),
152 ESP_LOGCONFIG(TAG,
" Require Connection to Proceed: %s", (this->
proceed_allowed_ ?
"NO" :
"YES"));
153 LOG_UPDATE_INTERVAL(
this);
162 (esp_wireguardif_peer_is_up(&(this->
wg_ctx_)) == ESP_OK);
167 if (esp_wireguard_latest_handshake(&(this->
wg_ctx_), &result) != ESP_OK) {
189#ifdef USE_BINARY_SENSOR
198#ifdef USE_TEXT_SENSOR
206 ESP_LOGI(TAG,
"Enabled");
213 ESP_LOGI(TAG,
"Disabled");
218#ifdef USE_BINARY_SENSOR
229 ESP_LOGV(TAG,
"Disabled, cannot start connection");
239 ESP_LOGD(TAG,
"Waiting for local network connection to be available");
244 ESP_LOGD(TAG,
"Waiting for system time to be synchronized");
249 ESP_LOGV(TAG,
"Connection already started");
253 ESP_LOGD(TAG,
"Starting connection");
260 ESP_LOGI(TAG,
"Connection started");
262 ESP_LOGD(TAG,
"Waiting for endpoint IP address to be available");
265 ESP_LOGW(TAG,
"Cannot start connection, error code %d", this->
wg_connected_);
269 ESP_LOGD(TAG,
"Configuring allowed IPs list");
270 bool allowed_ips_ok =
true;
271 for (std::tuple<std::string, std::string> ip : this->
allowed_ips_) {
273 (esp_wireguard_add_allowed_ip(&(this->
wg_ctx_), std::get<0>(ip).c_str(), std::get<1>(ip).c_str()) == ESP_OK);
276 if (allowed_ips_ok) {
277 ESP_LOGD(TAG,
"Allowed IPs list configured correctly");
279 ESP_LOGE(TAG,
"Cannot configure allowed IPs list, aborting");
287 ESP_LOGD(TAG,
"Stopping connection");
290 esp_wireguard_disconnect(&(this->
wg_ctx_));
296std::string
mask_key(
const std::string &key) {
return (key.substr(0, 5) +
"[...]="); }
virtual void mark_failed()
Mark this component as failed.
void defer(const std::string &name, std::function< void()> &&f)
Defer a callback to the next loop() call.
Helper class to lock the lwIP TCPIP core when making lwIP API calls from non-TCPIP threads.
Base class for all binary_sensor-type classes.
void publish_state(bool new_state)
Publish a new state to the front-end.
Base-class for all sensors.
void publish_state(float state)
Publish a new state to the front-end.
void publish_state(const std::string &state)
The RealTimeClock class exposes common timekeeping functions via the device's local real-time clock.
void add_on_time_sync_callback(std::function< void()> &&callback)
ESPTime now()
Get the time in the currently defined timezone.
binary_sensor::BinarySensor * enabled_sensor_
void set_keepalive(uint16_t seconds)
bool enabled_
When false the wireguard link will not be established.
binary_sensor::BinarySensor * status_sensor_
void set_peer_public_key(const std::string &key)
void set_status_sensor(binary_sensor::BinarySensor *sensor)
std::string peer_public_key_
void set_srctime(time::RealTimeClock *srctime)
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
void add_allowed_ip(const std::string &ip, const std::string &netmask)
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
std::vector< std::tuple< std::string, std::string > > allowed_ips_
void set_reboot_timeout(uint32_t seconds)
void set_peer_endpoint(const std::string &endpoint)
void set_private_key(const std::string &key)
void disable_auto_proceed()
Block the setup step until peer is connected.
bool can_proceed() override
std::string peer_endpoint_
void set_preshared_key(const std::string &key)
void set_address_sensor(text_sensor::TextSensor *sensor)
std::string preshared_key_
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.
void set_enabled_sensor(binary_sensor::BinarySensor *sensor)
void set_handshake_sensor(sensor::Sensor *sensor)
void set_address(const std::string &address)
esp_err_t wg_initialized_
bool is_enabled()
Return if the WireGuard component is or is not enabled.
void enable()
Enable the WireGuard component.
void set_peer_port(uint16_t port)
void set_netmask(const std::string &netmask)
time_t latest_saved_handshake_
The latest saved handshake.
wireguard_config_t wg_config_
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
std::string mask_key(const std::string &key)
Strip most part of the key only for secure printing.
Providing packet encoding functions for exchanging data with a remote host.
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() const
Check if this ESPTime is valid (all fields in range and year is greater than 2018)