From f0a713adc308dc2246ff75c42cea8c3f2ba8415c Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 16:29:49 +1000 Subject: [PATCH 1/8] [dhcpmon]: Bound packet callback work Limit each raw-socket callback to 64 packets and reset the recvfrom address length before every receive so the event loop remains responsive. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/packet_handler.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/packet_handler.cpp b/src/packet_handler.cpp index 7ec5d07a3..9f38ed5b2 100644 --- a/src/packet_handler.cpp +++ b/src/packet_handler.cpp @@ -16,6 +16,8 @@ #include "dhcp_check_profile.h" /** to get dhcp/v6 check profile */ #include "util.h" +static constexpr int MAX_PACKETS_PER_CALLBACK = 64; + /** * @code _increase_cache_counter(ifname, sock, type); * @brief helper function to increase cache counter. Simple increase of counter, no complications. In the event of @@ -864,8 +866,13 @@ void callback_common(int fd, short event, void *arg) socklen_t slen = sizeof(sll); sock_info_t &sock_info = sock_mgr_get_sock_info(fd); - while ((buffer_sz = recvfrom(fd, sock_info.buffer, sock_info.snaplen, MSG_DONTWAIT, (struct sockaddr *)&sll, &slen)) > 0) - { + for (int packet_count = 0; packet_count < MAX_PACKETS_PER_CALLBACK; packet_count++) { + slen = sizeof(sll); + buffer_sz = recvfrom(fd, sock_info.buffer, sock_info.snaplen, MSG_DONTWAIT, + (struct sockaddr *)&sll, &slen); + if (buffer_sz <= 0) { + break; + } char ifname_buf[IF_NAMESIZE]; if (if_indextoname(sll.sll_ifindex, ifname_buf) == NULL) { syslog_debug(LOG_WARNING, "if_indextoname: invalid input interface index %d %s", sll.sll_ifindex, strerror(errno)); From b03bcec028c8c900e202b831a98dc383af36f2b6 Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 16:33:48 +1000 Subject: [PATCH 2/8] [dhcpmon]: Synchronize counter state access Use writer-priority shared/exclusive guards so packet callbacks cannot race health sampling, snapshot, counter-clear, or COUNTERS_DB synchronization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/dhcp_mon.cpp | 27 ++++++++++-- src/packet_handler.cpp | 4 ++ src/sock_mgr.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++ src/sock_mgr.h | 29 +++++++++++++ 4 files changed, 150 insertions(+), 3 deletions(-) diff --git a/src/dhcp_mon.cpp b/src/dhcp_mon.cpp index ef4f6623d..3504737a8 100644 --- a/src/dhcp_mon.cpp +++ b/src/dhcp_mon.cpp @@ -212,9 +212,14 @@ static void cleanup_stale_db_counters() static void signal_callback(evutil_socket_t fd, short event, void *arg) { syslog(LOG_INFO, "Received signal: %s", strsignal(fd)); - - dhcp_devman_print_all_status(DHCP_COUNTERS_CURRENT); - dhcp_devman_print_all_status(DHCP_COUNTERS_CURRENT_V6); + + { + counter_state_write_lock counter_lock; + if (counter_lock.owns_lock()) { + dhcp_devman_print_all_status(DHCP_COUNTERS_CURRENT); + dhcp_devman_print_all_status(DHCP_COUNTERS_CURRENT_V6); + } + } if ((fd == SIGTERM) || (fd == SIGINT)) { syslog(LOG_INFO, "Received signal to stop dhcpmon"); @@ -223,6 +228,10 @@ static void signal_callback(evutil_socket_t fd, short event, void *arg) if (fd == SIGUSR1) { // we need to sync cache counter from COUNTERS_DB syslog(LOG_INFO, "Received signal to stop writing to DB counter"); + counter_state_write_lock counter_lock; + if (!counter_lock.owns_lock()) { + return; + } std::lock_guard lock(db_sync_mutex); sock_mgr_pause_write_cache_to_db(); syslog(LOG_INFO, "Stopped writing to DB counter"); @@ -260,6 +269,10 @@ static void update_cache_counter_callback(evutil_socket_t fd, short event, void syslog(LOG_INFO, "Start updating %s cache counter from DB counter", sock_info.name); + counter_state_write_lock counter_lock; + if (!counter_lock.owns_lock()) { + return; + } std::lock_guard lock(db_sync_mutex); // can only sync db to cache counter and db updater is paused, otherwise its unexpected @@ -392,6 +405,10 @@ static void update_cache_counter_callback(evutil_socket_t fd, short event, void static void timeout_callback(evutil_socket_t fd, short event, void *arg) { syslog_debug(LOG_INFO, "Received timeout signal for DHCP relay health check"); + counter_state_write_lock counter_lock; + if (!counter_lock.owns_lock()) { + return; + } dhcp_devman_print_all_status_debug(DHCP_COUNTERS_CURRENT); dhcp_devman_print_all_status_debug(DHCP_COUNTERS_SNAPSHOT); @@ -418,6 +435,10 @@ static void db_update_callback(evutil_socket_t fd, short event, void *arg) { syslog_debug(LOG_INFO, "Received db update signal"); syslog_debug(LOG_INFO, "Sync cache counter to DB counter"); + counter_state_write_lock counter_lock; + if (!counter_lock.owns_lock()) { + return; + } std::lock_guard lock(db_sync_mutex); // If there is clear counter going on and its been longer than expected // consider the clear counter operation failed so we don't block db update forever diff --git a/src/packet_handler.cpp b/src/packet_handler.cpp index 9f38ed5b2..aa564c1a0 100644 --- a/src/packet_handler.cpp +++ b/src/packet_handler.cpp @@ -861,6 +861,10 @@ void packet_handler_v6(int sock, const std::string &ifname, const dhcp_device_co void callback_common(int fd, short event, void *arg) { + counter_state_read_lock counter_lock; + if (!counter_lock.owns_lock()) { + return; + } ssize_t buffer_sz; struct sockaddr_ll sll; socklen_t slen = sizeof(sll); diff --git a/src/sock_mgr.cpp b/src/sock_mgr.cpp index 8d3e48d81..114d2cfa3 100644 --- a/src/sock_mgr.cpp +++ b/src/sock_mgr.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include #include "sock_mgr.h" @@ -40,10 +43,100 @@ static const char cache_counter_updater_tag[] = "CacheCounterUpdater"; /* sock fd to sock_info mapping */ std::unordered_map sock_map; +std::shared_mutex counter_state_mutex; +std::atomic counter_state_writers_pending{0}; +static std::mutex counter_state_wait_mutex; +static std::condition_variable counter_state_wait_cv; + extern std::shared_ptr mCountersDbPtr; extern std::string downstream_ifname; +counter_state_write_lock::counter_state_write_lock() +{ + { + std::lock_guard wait_lock(counter_state_wait_mutex); + counter_state_writers_pending.fetch_add(1, std::memory_order_acq_rel); + } + try { + lock = std::unique_lock(counter_state_mutex); + } catch (const std::system_error &e) { + bool notify = false; + { + std::lock_guard wait_lock(counter_state_wait_mutex); + notify = counter_state_writers_pending.fetch_sub(1, std::memory_order_acq_rel) == 1; + } + if (notify) { + counter_state_wait_cv.notify_all(); + } + syslog(LOG_ALERT, "Failed to lock DHCP counter state: %s", e.what()); + } +} + +counter_state_write_lock::~counter_state_write_lock() +{ + if (!lock.owns_lock()) { + return; + } + lock.unlock(); + bool notify = false; + { + std::lock_guard wait_lock(counter_state_wait_mutex); + notify = counter_state_writers_pending.fetch_sub(1, std::memory_order_acq_rel) == 1; + } + if (notify) { + counter_state_wait_cv.notify_all(); + } +} + +bool counter_state_write_lock::owns_lock() const +{ + return lock.owns_lock(); +} + +counter_state_read_lock::counter_state_read_lock() +{ + if (counter_state_writers_pending.load(std::memory_order_acquire) == 0) { + try { + lock = std::shared_lock(counter_state_mutex, std::try_to_lock); + } catch (const std::system_error &e) { + syslog(LOG_ALERT, "Failed to lock DHCP counter state for packet handling: %s", e.what()); + return; + } + if (lock.owns_lock() && + counter_state_writers_pending.load(std::memory_order_acquire) == 0) { + return; + } + if (lock.owns_lock()) { + lock.unlock(); + } + } + + while (true) { + { + std::unique_lock wait_lock(counter_state_wait_mutex); + counter_state_wait_cv.wait(wait_lock, [] { + return counter_state_writers_pending.load(std::memory_order_acquire) == 0; + }); + } + try { + lock = std::shared_lock(counter_state_mutex); + } catch (const std::system_error &e) { + syslog(LOG_ALERT, "Failed to lock DHCP counter state for packet handling: %s", e.what()); + return; + } + if (counter_state_writers_pending.load(std::memory_order_acquire) == 0) { + return; + } + lock.unlock(); + } +} + +bool counter_state_read_lock::owns_lock() const +{ + return lock.owns_lock(); +} + /** * @code opensocket(); * diff --git a/src/sock_mgr.h b/src/sock_mgr.h index 9619a9526..8d17b56c2 100644 --- a/src/sock_mgr.h +++ b/src/sock_mgr.h @@ -9,7 +9,10 @@ #ifndef SOCKET_MANAGER_H_ #define SOCKET_MANAGER_H_ +#include +#include #include +#include #include #include #include @@ -41,6 +44,32 @@ typedef struct { /** sock file descriptors, serve as the identifier of all related information described in sock_info_t */ extern int rx_sock, tx_sock, rx_sock_v6, tx_sock_v6; +extern std::shared_mutex counter_state_mutex; +extern std::atomic counter_state_writers_pending; + +class counter_state_write_lock +{ + public: + counter_state_write_lock(); + ~counter_state_write_lock(); + bool owns_lock() const; + counter_state_write_lock(const counter_state_write_lock &) = delete; + counter_state_write_lock &operator=(const counter_state_write_lock &) = delete; + + private: + std::unique_lock lock; +}; + +class counter_state_read_lock +{ + public: + counter_state_read_lock(); + bool owns_lock() const; + + private: + std::shared_lock lock; +}; + /** Initialize socket manager with given snaplen */ int sock_mgr_init(uint32_t snaplen); From f4f6b70a8e1574a736dbe5dd560d07ebbba6c3c3 Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 18:13:22 +1000 Subject: [PATCH 3/8] [dhcpmon]: Explain packet callback batch bound Document that the 64-packet batch keeps periodic health and DB events responsive during bursts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/packet_handler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packet_handler.cpp b/src/packet_handler.cpp index aa564c1a0..10409ca0b 100644 --- a/src/packet_handler.cpp +++ b/src/packet_handler.cpp @@ -16,6 +16,7 @@ #include "dhcp_check_profile.h" /** to get dhcp/v6 check profile */ #include "util.h" +// Bound one callback to keep health/DB events responsive during packet bursts. static constexpr int MAX_PACKETS_PER_CALLBACK = 64; /** From bdbdae814a06e7f74611418978a344921bfd765c Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 18:42:10 +1000 Subject: [PATCH 4/8] [dhcpmon]: Use C++14 shared timed mutex Use std::shared_timed_mutex for counter-state guards so the synchronization primitive does not depend on an implicit C++17 compiler default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/sock_mgr.cpp | 8 ++++---- src/sock_mgr.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sock_mgr.cpp b/src/sock_mgr.cpp index 114d2cfa3..dade6121b 100644 --- a/src/sock_mgr.cpp +++ b/src/sock_mgr.cpp @@ -43,7 +43,7 @@ static const char cache_counter_updater_tag[] = "CacheCounterUpdater"; /* sock fd to sock_info mapping */ std::unordered_map sock_map; -std::shared_mutex counter_state_mutex; +std::shared_timed_mutex counter_state_mutex; std::atomic counter_state_writers_pending{0}; static std::mutex counter_state_wait_mutex; static std::condition_variable counter_state_wait_cv; @@ -59,7 +59,7 @@ counter_state_write_lock::counter_state_write_lock() counter_state_writers_pending.fetch_add(1, std::memory_order_acq_rel); } try { - lock = std::unique_lock(counter_state_mutex); + lock = std::unique_lock(counter_state_mutex); } catch (const std::system_error &e) { bool notify = false; { @@ -98,7 +98,7 @@ counter_state_read_lock::counter_state_read_lock() { if (counter_state_writers_pending.load(std::memory_order_acquire) == 0) { try { - lock = std::shared_lock(counter_state_mutex, std::try_to_lock); + lock = std::shared_lock(counter_state_mutex, std::try_to_lock); } catch (const std::system_error &e) { syslog(LOG_ALERT, "Failed to lock DHCP counter state for packet handling: %s", e.what()); return; @@ -120,7 +120,7 @@ counter_state_read_lock::counter_state_read_lock() }); } try { - lock = std::shared_lock(counter_state_mutex); + lock = std::shared_lock(counter_state_mutex); } catch (const std::system_error &e) { syslog(LOG_ALERT, "Failed to lock DHCP counter state for packet handling: %s", e.what()); return; diff --git a/src/sock_mgr.h b/src/sock_mgr.h index 8d17b56c2..0b625701b 100644 --- a/src/sock_mgr.h +++ b/src/sock_mgr.h @@ -44,7 +44,7 @@ typedef struct { /** sock file descriptors, serve as the identifier of all related information described in sock_info_t */ extern int rx_sock, tx_sock, rx_sock_v6, tx_sock_v6; -extern std::shared_mutex counter_state_mutex; +extern std::shared_timed_mutex counter_state_mutex; extern std::atomic counter_state_writers_pending; class counter_state_write_lock @@ -57,7 +57,7 @@ class counter_state_write_lock counter_state_write_lock &operator=(const counter_state_write_lock &) = delete; private: - std::unique_lock lock; + std::unique_lock lock; }; class counter_state_read_lock @@ -67,7 +67,7 @@ class counter_state_read_lock bool owns_lock() const; private: - std::shared_lock lock; + std::shared_lock lock; }; /** Initialize socket manager with given snaplen */ From 28b6c66d462d80c273fb0cff814b1b06ecf8c517 Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 18:59:18 +1000 Subject: [PATCH 5/8] [dhcpmon]: Keep signal status printing best effort Hide raw counter synchronization state behind RAII guards and use a nonblocking writer guard for signal-triggered status output so shutdown signals are never delayed by counter work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/dhcp_mon.cpp | 2 +- src/sock_mgr.cpp | 18 ++++++++++++++++-- src/sock_mgr.h | 5 ++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/dhcp_mon.cpp b/src/dhcp_mon.cpp index 3504737a8..2796ff64a 100644 --- a/src/dhcp_mon.cpp +++ b/src/dhcp_mon.cpp @@ -214,7 +214,7 @@ static void signal_callback(evutil_socket_t fd, short event, void *arg) syslog(LOG_INFO, "Received signal: %s", strsignal(fd)); { - counter_state_write_lock counter_lock; + counter_state_write_lock counter_lock(std::try_to_lock); if (counter_lock.owns_lock()) { dhcp_devman_print_all_status(DHCP_COUNTERS_CURRENT); dhcp_devman_print_all_status(DHCP_COUNTERS_CURRENT_V6); diff --git a/src/sock_mgr.cpp b/src/sock_mgr.cpp index dade6121b..b51a23eaf 100644 --- a/src/sock_mgr.cpp +++ b/src/sock_mgr.cpp @@ -43,8 +43,8 @@ static const char cache_counter_updater_tag[] = "CacheCounterUpdater"; /* sock fd to sock_info mapping */ std::unordered_map sock_map; -std::shared_timed_mutex counter_state_mutex; -std::atomic counter_state_writers_pending{0}; +static std::shared_timed_mutex counter_state_mutex; +static std::atomic counter_state_writers_pending{0}; static std::mutex counter_state_wait_mutex; static std::condition_variable counter_state_wait_cv; @@ -57,6 +57,7 @@ counter_state_write_lock::counter_state_write_lock() { std::lock_guard wait_lock(counter_state_wait_mutex); counter_state_writers_pending.fetch_add(1, std::memory_order_acq_rel); + registered_writer = true; } try { lock = std::unique_lock(counter_state_mutex); @@ -69,16 +70,29 @@ counter_state_write_lock::counter_state_write_lock() if (notify) { counter_state_wait_cv.notify_all(); } + registered_writer = false; syslog(LOG_ALERT, "Failed to lock DHCP counter state: %s", e.what()); } } +counter_state_write_lock::counter_state_write_lock(std::try_to_lock_t) +{ + try { + lock = std::unique_lock(counter_state_mutex, std::try_to_lock); + } catch (const std::system_error &e) { + syslog(LOG_ALERT, "Failed to try-lock DHCP counter state: %s", e.what()); + } +} + counter_state_write_lock::~counter_state_write_lock() { if (!lock.owns_lock()) { return; } lock.unlock(); + if (!registered_writer) { + return; + } bool notify = false; { std::lock_guard wait_lock(counter_state_wait_mutex); diff --git a/src/sock_mgr.h b/src/sock_mgr.h index 0b625701b..cd81359b8 100644 --- a/src/sock_mgr.h +++ b/src/sock_mgr.h @@ -44,13 +44,11 @@ typedef struct { /** sock file descriptors, serve as the identifier of all related information described in sock_info_t */ extern int rx_sock, tx_sock, rx_sock_v6, tx_sock_v6; -extern std::shared_timed_mutex counter_state_mutex; -extern std::atomic counter_state_writers_pending; - class counter_state_write_lock { public: counter_state_write_lock(); + explicit counter_state_write_lock(std::try_to_lock_t); ~counter_state_write_lock(); bool owns_lock() const; counter_state_write_lock(const counter_state_write_lock &) = delete; @@ -58,6 +56,7 @@ class counter_state_write_lock private: std::unique_lock lock; + bool registered_writer = false; }; class counter_state_read_lock From 4c005f76710f5e3cd07595325dc05268611e01bf Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 19:17:58 +1000 Subject: [PATCH 6/8] [dhcpmon]: Make counter guard teardown fail-safe Require C++14 explicitly and catch shared-mutex unlock failures so RAII destruction cannot terminate the daemon or corrupt the pending-writer count. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/sock_mgr.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sock_mgr.cpp b/src/sock_mgr.cpp index b51a23eaf..1ea67fc0b 100644 --- a/src/sock_mgr.cpp +++ b/src/sock_mgr.cpp @@ -16,6 +16,10 @@ #include #include +#if __cplusplus < 201402L +#error "dhcpmon counter synchronization requires C++14 or newer" +#endif + #include "sock_mgr.h" #include "packet_handler.h" /** for attaching packet handler */ @@ -89,7 +93,12 @@ counter_state_write_lock::~counter_state_write_lock() if (!lock.owns_lock()) { return; } - lock.unlock(); + try { + lock.unlock(); + } catch (const std::system_error &e) { + syslog(LOG_ALERT, "Failed to unlock DHCP counter state: %s", e.what()); + return; + } if (!registered_writer) { return; } From a1f54721f7b29c9ee20af4f89492cc1a16604ae8 Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 19:49:22 +1000 Subject: [PATCH 7/8] [dhcpmon]: Keep counter unlocks RAII-owned Let unique/shared lock destructors release mutex ownership and use local candidate read locks, avoiding manual unlock exception paths while preserving writer priority. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/sock_mgr.cpp | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/sock_mgr.cpp b/src/sock_mgr.cpp index 1ea67fc0b..c7130321e 100644 --- a/src/sock_mgr.cpp +++ b/src/sock_mgr.cpp @@ -16,8 +16,8 @@ #include #include -#if __cplusplus < 201402L -#error "dhcpmon counter synchronization requires C++14 or newer" +#if __cplusplus < 201703L +#error "dhcpmon counter synchronization requires C++17 or newer" #endif #include "sock_mgr.h" @@ -93,17 +93,8 @@ counter_state_write_lock::~counter_state_write_lock() if (!lock.owns_lock()) { return; } - try { - lock.unlock(); - } catch (const std::system_error &e) { - syslog(LOG_ALERT, "Failed to unlock DHCP counter state: %s", e.what()); - return; - } - if (!registered_writer) { - return; - } bool notify = false; - { + if (registered_writer) { std::lock_guard wait_lock(counter_state_wait_mutex); notify = counter_state_writers_pending.fetch_sub(1, std::memory_order_acq_rel) == 1; } @@ -121,18 +112,17 @@ counter_state_read_lock::counter_state_read_lock() { if (counter_state_writers_pending.load(std::memory_order_acquire) == 0) { try { - lock = std::shared_lock(counter_state_mutex, std::try_to_lock); + std::shared_lock candidate(counter_state_mutex, + std::try_to_lock); + if (candidate.owns_lock() && + counter_state_writers_pending.load(std::memory_order_acquire) == 0) { + lock = std::move(candidate); + return; + } } catch (const std::system_error &e) { syslog(LOG_ALERT, "Failed to lock DHCP counter state for packet handling: %s", e.what()); return; } - if (lock.owns_lock() && - counter_state_writers_pending.load(std::memory_order_acquire) == 0) { - return; - } - if (lock.owns_lock()) { - lock.unlock(); - } } while (true) { @@ -143,15 +133,15 @@ counter_state_read_lock::counter_state_read_lock() }); } try { - lock = std::shared_lock(counter_state_mutex); + std::shared_lock candidate(counter_state_mutex); + if (counter_state_writers_pending.load(std::memory_order_acquire) == 0) { + lock = std::move(candidate); + return; + } } catch (const std::system_error &e) { syslog(LOG_ALERT, "Failed to lock DHCP counter state for packet handling: %s", e.what()); return; } - if (counter_state_writers_pending.load(std::memory_order_acquire) == 0) { - return; - } - lock.unlock(); } } From ad9595054814b161e67c0cc3c1792f1d8188b1ad Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Sun, 26 Jul 2026 20:12:20 +1000 Subject: [PATCH 8/8] [dhcpmon]: Pin the C++17 build standard Compile C++ sources explicitly as gnu++17 and include utility directly for std::move, making the counter guard build requirements deterministic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 --- src/sock_mgr.cpp | 1 + src/subdir.mk | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sock_mgr.cpp b/src/sock_mgr.cpp index c7130321e..9cd5743b1 100644 --- a/src/sock_mgr.cpp +++ b/src/sock_mgr.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #if __cplusplus < 201703L #error "dhcpmon counter synchronization requires C++17 or newer" diff --git a/src/subdir.mk b/src/subdir.mk index 4708a6fa5..e44d3f471 100644 --- a/src/subdir.mk +++ b/src/subdir.mk @@ -42,6 +42,6 @@ C_DEPS += \ src/%.o: src/%.cpp @echo 'Building file: $<' @echo 'Invoking: GCC C Compiler' - $(CC) -O3 -g3 -Wall -I/usr/include/swss -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + $(CC) -std=gnu++17 -O3 -g3 -Wall -I/usr/include/swss -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" @echo 'Finished building: $<' @echo ' '