Get or create a socket bound to local_port.
If a socket for this port already exists, increments ref_count and returns it. Otherwise binds a new socket and starts the async receive loop.
269{
271
274 it->second->ref_count++;
275 return it->second.get();
276 }
277
278 auto state = std::make_unique<SocketState>(
m_context);
279 state->local_port = local_port;
280 state->ref_count = 1;
281
282 asio::error_code ec;
283 if (state->socket.open(asio::ip::udp::v4(), ec)) {
285 "Failed to open UDP socket: {}", ec.message());
286 return nullptr;
287 }
288
289 if (state->socket.set_option(asio::socket_base::reuse_address(true), ec)) {
291 "Failed to set SO_REUSEADDR on UDP socket: {}", ec.message());
292 return nullptr;
293 }
294
295 if (local_port > 0) {
296 if (
297 state->socket.bind(
298 asio::ip::udp::endpoint(asio::ip::udp::v4(), local_port), ec)) {
300 "Failed to bind UDP socket to port {}: {}", local_port, ec.message());
301 return nullptr;
302 }
303 }
304
306 if (state->socket.set_option(
307 asio::socket_base::receive_buffer_size(
309 ec)) {
311 "Failed to set receive buffer size on UDP socket: {}", ec.message());
312 }
313 }
314
315 auto* raw = state.get();
316 m_sockets[local_port] = std::move(state);
317
319
321 "UDP socket bound to port {}", local_port);
322
323 return raw;
324}
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::unordered_map< uint16_t, std::unique_ptr< SocketState > > m_sockets
void start_receive_loop(SocketState &state)
Post the first async_receive_from for a newly bound socket.
asio::io_context & m_context
std::shared_mutex m_sockets_mutex
@ NetworkBackend
Network transport backend (UDP, TCP, SHM)
@ Core
Core engine, backend, subsystems.
size_t receive_buffer_size