@@ -53,24 +53,6 @@ impl UdpServer {
5353 socket. set_send_buffer_size ( actual_send_buffer) . map_err ( tokio:: io:: Error :: other) ?;
5454 socket. set_reuse_address ( reuse_address) . map_err ( tokio:: io:: Error :: other) ?;
5555
56- // Enable SO_REUSEPORT for better load distribution across threads
57- #[ cfg( target_os = "linux" ) ]
58- {
59- let reuse_port = 1i32 ;
60- unsafe {
61- let optval = & reuse_port as * const i32 as * const libc:: c_void ;
62- if libc:: setsockopt (
63- socket. as_raw_fd ( ) ,
64- libc:: SOL_SOCKET ,
65- libc:: SO_REUSEPORT ,
66- optval,
67- std:: mem:: size_of :: < i32 > ( ) as libc:: socklen_t ,
68- ) != 0 {
69- log:: warn!( "Failed to set SO_REUSEPORT - continuing without it" ) ;
70- }
71- }
72- }
73-
7456 socket. bind ( & bind_address. into ( ) ) . map_err ( tokio:: io:: Error :: other) ?;
7557 socket. set_nonblocking ( true ) . map_err ( tokio:: io:: Error :: other) ?;
7658
@@ -174,9 +156,18 @@ impl UdpServer {
174156 let position = cursor. position ( ) as usize ;
175157 debug ! ( "Response bytes: {:?}" , & buffer[ ..position] ) ;
176158
177- // Get batch manager for this socket and queue the response
178- let batch_manager = ResponseBatchManager :: get_for_socket ( socket) . await ;
179- batch_manager. queue_response ( remote_addr, buffer[ ..position] . to_vec ( ) ) ;
159+ // For immediate response (bypassing batching for better latency)
160+ match socket. send_to ( & buffer[ ..position] , & remote_addr) . await {
161+ Ok ( bytes_sent) => {
162+ debug ! ( "Direct send successful: {} bytes to {}" , bytes_sent, remote_addr) ;
163+ }
164+ Err ( e) => {
165+ // If direct send fails, fall back to batched approach
166+ log:: warn!( "Direct send failed ({}), using batch queue" , e) ;
167+ let batch_manager = ResponseBatchManager :: get_for_socket ( socket) . await ;
168+ batch_manager. queue_response ( remote_addr, buffer[ ..position] . to_vec ( ) ) ;
169+ }
170+ }
180171 }
181172 Err ( error) => {
182173 sentry:: capture_error ( & error) ;
0 commit comments