Implements recvmmsg() for UDP packets (#1161)
* Implemented recvmmsg() for UDP packets - This change implements binding between libc API for recvmmsg() - The function can receive multiple packets using one system call Fixes #1141 * Added unit tests for recvmmsg() * Added recv_mmsg() wrapper for non Linux OS * Address review comments for recvmmsg() * Remove unnecessary imports * Moved target specific dependencies to the function
This commit is contained in:
@ -3,6 +3,7 @@ use bincode::{deserialize, serialize};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use counter::Counter;
|
||||
use log::Level;
|
||||
use recvmmsg::{recv_mmsg, NUM_RCVMMSGS};
|
||||
use result::{Error, Result};
|
||||
use serde::Serialize;
|
||||
use signature::Pubkey;
|
||||
@ -251,31 +252,30 @@ impl Packets {
|
||||
// * read until it fails
|
||||
// * set it back to blocking before returning
|
||||
socket.set_nonblocking(false)?;
|
||||
for p in &mut self.packets {
|
||||
p.meta.size = 0;
|
||||
trace!("receiving on {}", socket.local_addr().unwrap());
|
||||
match socket.recv_from(&mut p.data) {
|
||||
trace!("receiving on {}", socket.local_addr().unwrap());
|
||||
loop {
|
||||
match recv_mmsg(socket, &mut self.packets[i..]) {
|
||||
Err(_) if i > 0 => {
|
||||
inc_new_counter_info!("packets-recv_count", i);
|
||||
debug!("got {:?} messages on {}", i, socket.local_addr().unwrap());
|
||||
break;
|
||||
socket.set_nonblocking(true)?;
|
||||
return Ok(i);
|
||||
}
|
||||
Err(e) => {
|
||||
trace!("recv_from err {:?}", e);
|
||||
return Err(Error::IO(e));
|
||||
}
|
||||
Ok((nrecv, from)) => {
|
||||
p.meta.size = nrecv;
|
||||
p.meta.set_addr(&from);
|
||||
trace!("got {} bytes from {}", nrecv, from);
|
||||
if i == 0 {
|
||||
Ok(npkts) => {
|
||||
trace!("got {} packets", npkts);
|
||||
i += npkts;
|
||||
if npkts != NUM_RCVMMSGS {
|
||||
socket.set_nonblocking(true)?;
|
||||
inc_new_counter_info!("packets-recv_count", i);
|
||||
return Ok(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
Ok(i)
|
||||
}
|
||||
pub fn recv_from(&mut self, socket: &UdpSocket) -> Result<()> {
|
||||
let sz = self.run_read_from(socket)?;
|
||||
|
Reference in New Issue
Block a user