From e5b21535ab2edbf1a048de2da8547d2bd82b3aa6 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 4 Jan 2021 16:31:11 -0800 Subject: [PATCH] server: add EPICS_PVAS_IGNORE_ADDR_LIST --- documentation/server.rst | 5 +++++ src/config.cpp | 43 ++++++++++++++++++++-------------------- src/pvxs/server.h | 5 +++++ src/server.cpp | 19 ++++++++++++++++++ src/serverconn.h | 1 + 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/documentation/server.rst b/documentation/server.rst index 1904adb..3f87fcc 100644 --- a/documentation/server.rst +++ b/documentation/server.rst @@ -69,6 +69,11 @@ EPICS_PVAS_BROADCAST_PORT or EPICS_PVA_BROADCAST_PORT If already in use, then an exception is thrown. Sets `pvxs::server::Config::udp_port` +EPICS_PVAS_IGNORE_ADDR_LIST + Space seperated list of addresses with optional port. + Port zero is treated as a wildcard to match any port. + UDP traffic from matched addresses will be ignored with no further processing. + .. doxygenstruct:: pvxs::server::Config :members: diff --git a/src/config.cpp b/src/config.cpp index 7a5fab6..1af3766 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -182,6 +182,10 @@ void _fromDefs(Config& self, const std::map& defs, boo split_addr_into(pickone.name.c_str(), self.interfaces, pickone.val, self.tcp_port, true); } + if(pickone({"EPICS_PVAS_IGNORE_ADDR_LIST"})) { + split_addr_into(pickone.name.c_str(), self.ignoreAddrs, pickone.val, 0, true); + } + if(pickone({"EPICS_PVAS_BEACON_ADDR_LIST", "EPICS_PVA_ADDR_LIST"})) { split_addr_into(pickone.name.c_str(), self.beaconDestinations, pickone.val, self.udp_port); } @@ -223,6 +227,7 @@ void Config::updateDefs(defs_t& defs) const defs["EPICS_PVA_AUTO_ADDR_LIST"] = defs["EPICS_PVAS_AUTO_BEACON_ADDR_LIST"] = auto_beacon ? "YES" : "NO"; defs["EPICS_PVA_ADDR_LIST"] = defs["EPICS_PVAS_BEACON_ADDR_LIST"] = join_addr(beaconDestinations); defs["EPICS_PVA_INTF_ADDR_LIST"] = defs["EPICS_PVAS_INTF_ADDR_LIST"] = join_addr(interfaces); + defs["EPICS_PVAS_IGNORE_ADDR_LIST"] = join_addr(ignoreAddrs); } void Config::expand() @@ -240,33 +245,27 @@ void Config::expand() removeDups(interfaces); removeDups(beaconDestinations); + removeDups(ignoreAddrs); } std::ostream& operator<<(std::ostream& strm, const Config& conf) { - bool first; + auto showAddrs = [&strm](const char* var, const std::vector& addrs) { + strm< interfaces; + //! Ignore client requests originating from addresses in this list. + //! Entries must be IP addresses with optional port numbers. + //! Port number zero (default) is treated as a wildcard which matches any port. + //! @since UNRELEASED + std::vector ignoreAddrs; //! Addresses (**not** host names) to which (UDP) beacons message will be sent. //! May include broadcast and/or unicast addresses. //! Supplemented iif auto_beacon==true diff --git a/src/server.cpp b/src/server.cpp index 7baa12a..5de5379 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -364,6 +364,11 @@ Server::Pvt::Pvt(const Config &conf) #endif } + for(const auto& addr : effective.ignoreAddrs) { + SockAddr temp(AF_INET, addr.c_str()); + ignoreList.push_back(temp); + } + acceptor_loop.call([this](){ // from acceptor worker @@ -535,6 +540,20 @@ void Server::Pvt::onSearch(const UDPManager::Search& msg) { // on UDPManager worker + for(const auto& addr : ignoreList) { // expected to be a short list + if(msg.src.family()!=addr.family()) { + // skip + } else if(msg.src->in.sin_addr.s_addr != addr->in.sin_addr.s_addr) { + // skip + } else if(addr->in.sin_port==0) { + // ignore all ports + return; + } else if(msg.src->in.sin_port == addr->in.sin_port) { + // ignore specific sender port + return; + } + } + log_debug_printf(serverio, "%s searching\n", msg.src.tostring().c_str()); searchOp._names.resize(msg.names.size()); diff --git a/src/serverconn.h b/src/serverconn.h index 1dc3767..3635fc2 100644 --- a/src/serverconn.h +++ b/src/serverconn.h @@ -217,6 +217,7 @@ struct Server::Pvt std::list > listeners; std::vector beaconDest; + std::vector ignoreList; std::list interfaces; std::map > connections;