initial dual tcp/udp

This commit is contained in:
Richard Holland
2025-07-07 15:52:53 +10:00
parent 1233694b6c
commit 2c04ed91e5
6 changed files with 62 additions and 1 deletions

View File

@@ -365,8 +365,27 @@ void
ServerHandlerImp::onUDPMessage(
std::string const& message,
boost::asio::ip::tcp::endpoint const& remoteEndpoint,
Port const& p,
std::function<void(std::string const&)> sendResponse)
{
uint8_t static is_peer[65536] = {};
auto const port = p.port;
if (is_peer[port] == 0 /* not yet known */)
{
is_peer[port] = p.has_peer() ? 1 : 2;
std::cout << "set port " << port << " to " << ('0' + is_peer[port]) << "\n";
}
if (is_peer[port] == 1)
{
// offload to peer processing
// RHUPTO udp peer processing here
std::cout << "offload to peer processing\n";
}
Json::Value jv;
if (message.size() > RPC::Tuning::maxRequestSize ||
!Json::Reader{}.parse(message, jv) || !jv.isObject())

View File

@@ -169,6 +169,7 @@ public:
onUDPMessage(
std::string const& message,
boost::asio::ip::tcp::endpoint const& remoteEndpoint,
Port const& port,
std::function<void(std::string const&)> sendResponse);
void

View File

@@ -93,6 +93,12 @@ struct Port
return protocol.count("udp") > 0;
}
bool
has_peer() const
{
return protocol.count("peer") > 0;
}
// Maximum UDP packet size (default 64KB)
std::size_t udp_packet_size = 65536;
};

View File

@@ -192,6 +192,17 @@ ServerImpl<Handler>::ports(std::vector<Port> const& ports)
eps.push_back(sp->get_endpoint());
sp->run();
}
if (port.has_peer())
{
// peer ports run dual tcp/udp stack
if (auto sp = ios_.emplace<UDPDoor<Handler>>(
handler_, io_service_, ports_.back(), j_))
{
eps.push_back(sp->get_endpoint());
sp->run();
}
}
}
}
return eps;

View File

@@ -97,6 +97,25 @@ public:
return;
}
std::cout << "UDP Door created on port " << port.port << "\n";
// Port reuse means we can support dual udp/tcp on the same port
// used for peer upgrades to lightweight udp protocol
/*
RHNOTE: in boost 1.70 apparently SO_REUSEPORT is included with reuse_address,
there's no actual option without modifying the native socket handle
despite the obvious need for one.
*/
/*
socket_.set_option(boost::asio::socket_base::reuse_port(true), ec);
if (ec)
{
JLOG(j_.debug())
<< "UDP set reuse_port failed: " << ec.message();
// Not fatal - some platforms don't support it
}
*/
socket_.bind(udp_endpoint, ec);
if (ec)
{
@@ -104,7 +123,7 @@ public:
return;
}
JLOG(j_.info()) << "UDP-RPC listening on " << udp_endpoint;
JLOG(j_.info()) << "UDP listening on " << udp_endpoint;
}
endpoint_type
@@ -133,6 +152,8 @@ private:
void
do_receive()
{
std::cout << "UDP Door receive on " << port_.port << "\n";
if (!socket_.is_open())
return;
@@ -169,6 +190,7 @@ private:
handler_.onUDPMessage(
std::string(recv_buffer_.data(), bytes_transferred),
tcp_endpoint,
port_,
[this, tcp_endpoint](std::string const& response) {
do_send(response, tcp_endpoint);
});

View File

@@ -148,6 +148,7 @@ public:
onUDPMessage(
std::string const& message,
boost::asio::ip::tcp::endpoint const& remoteEndpoint,
Port const& port,
std::function<void(std::string const&)> sendResponse)
{
}
@@ -361,6 +362,7 @@ public:
onUDPMessage(
std::string const& message,
boost::asio::ip::tcp::endpoint const& remoteEndpoint,
Port const& port,
std::function<void(std::string const&)> sendResponse)
{
}