natpmp: pass shared pointer to timer to avoid crash
Change-Id: I1fbf84f8fb10b14390abb951b8ed312716047936
diff --git a/src/upnp/protocol/natpmp/nat_pmp.cpp b/src/upnp/protocol/natpmp/nat_pmp.cpp
index c5e8ce6..48e010a 100644
--- a/src/upnp/protocol/natpmp/nat_pmp.cpp
+++ b/src/upnp/protocol/natpmp/nat_pmp.cpp
@@ -186,9 +186,11 @@
// Cancel the current timer (if any) and re-schedule.
searchForIgdTimer_.expires_after(NATPMP_SEARCH_RETRY_UNIT * igdSearchCounter_);
- searchForIgdTimer_.async_wait([this](const asio::error_code& ec) {
- if (!ec)
- searchForIgd();
+ searchForIgdTimer_.async_wait([w=weak()](const asio::error_code& ec) {
+ if (!ec) {
+ if (auto shared = w.lock())
+ shared->searchForIgd();
+ }
});
} else {
if (logger_) logger_->warn("NAT-PMP: Setup failed after {} trials. NAT-PMP will be disabled!",
diff --git a/src/upnp/protocol/natpmp/nat_pmp.h b/src/upnp/protocol/natpmp/nat_pmp.h
index fbc2fc0..1545399 100644
--- a/src/upnp/protocol/natpmp/nat_pmp.h
+++ b/src/upnp/protocol/natpmp/nat_pmp.h
@@ -149,6 +149,13 @@
// Shutdown synchronization
bool shutdownComplete_ {false};
+
+ // Asio :(
+ // https://stackoverflow.com/questions/35507956/is-it-safe-to-destroy-boostasio-timer-from-its-handler-or-handler-dtor
+ std::weak_ptr<NatPmp> weak()
+ {
+ return std::static_pointer_cast<NatPmp>(shared_from_this());
+ }
};
} // namespace upnp