Skip to content

Commit 4742a70

Browse files
larseggertdjc
authored andcommitted
refactor(quinn-udp): extract ControlMetadata helper
1 parent 42de9dd commit 4742a70

File tree

1 file changed

+40
-24
lines changed

1 file changed

+40
-24
lines changed

quinn-udp/src/unix.rs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -707,17 +707,42 @@ fn decode_recv<M: cmsg::MsgHdr<ControlMessage = libc::cmsghdr>>(
707707
len: usize,
708708
) -> io::Result<RecvMeta> {
709709
let name = unsafe { name.assume_init() };
710-
let mut ecn_bits = 0;
711-
let mut dst_ip = None;
712-
let mut interface_index = None;
713-
#[allow(unused_mut)] // only mutable on Linux
714-
let mut stride = len;
710+
let mut ctrl = ControlMetadata {
711+
ecn_bits: 0,
712+
dst_ip: None,
713+
interface_index: None,
714+
stride: len,
715+
};
715716

716717
let cmsg_iter = unsafe { cmsg::Iter::new(hdr) };
717718
for cmsg in cmsg_iter {
719+
ctrl.decode(cmsg);
720+
}
721+
722+
Ok(RecvMeta {
723+
len,
724+
stride: ctrl.stride,
725+
addr: decode_socket_addr(&name)?,
726+
ecn: EcnCodepoint::from_bits(ctrl.ecn_bits),
727+
dst_ip: ctrl.dst_ip,
728+
interface_index: ctrl.interface_index,
729+
})
730+
}
731+
732+
/// Metadata decoded from control messages
733+
struct ControlMetadata {
734+
ecn_bits: u8,
735+
dst_ip: Option<IpAddr>,
736+
interface_index: Option<u32>,
737+
stride: usize,
738+
}
739+
740+
impl ControlMetadata {
741+
/// Decodes a control message and updates the metadata state
742+
fn decode(&mut self, cmsg: &libc::cmsghdr) {
718743
match (cmsg.cmsg_level, cmsg.cmsg_type) {
719744
(libc::IPPROTO_IP, libc::IP_TOS) => unsafe {
720-
ecn_bits = cmsg::decode::<u8, libc::cmsghdr>(cmsg);
745+
self.ecn_bits = cmsg::decode::<u8, libc::cmsghdr>(cmsg);
721746
},
722747
// FreeBSD uses IP_RECVTOS here, and we can be liberal because cmsgs are opt-in.
723748
#[cfg(not(any(
@@ -727,7 +752,7 @@ fn decode_recv<M: cmsg::MsgHdr<ControlMessage = libc::cmsghdr>>(
727752
solarish
728753
)))]
729754
(libc::IPPROTO_IP, libc::IP_RECVTOS) => unsafe {
730-
ecn_bits = cmsg::decode::<u8, libc::cmsghdr>(cmsg);
755+
self.ecn_bits = cmsg::decode::<u8, libc::cmsghdr>(cmsg);
731756
},
732757
(libc::IPPROTO_IPV6, libc::IPV6_TCLASS) => unsafe {
733758
// Temporary hack around broken macos ABI. Remove once upstream fixes it.
@@ -736,45 +761,36 @@ fn decode_recv<M: cmsg::MsgHdr<ControlMessage = libc::cmsghdr>>(
736761
if cfg!(apple)
737762
&& cmsg.cmsg_len as usize == libc::CMSG_LEN(mem::size_of::<u8>() as _) as usize
738763
{
739-
ecn_bits = cmsg::decode::<u8, libc::cmsghdr>(cmsg);
764+
self.ecn_bits = cmsg::decode::<u8, libc::cmsghdr>(cmsg);
740765
} else {
741-
ecn_bits = cmsg::decode::<libc::c_int, libc::cmsghdr>(cmsg) as u8;
766+
self.ecn_bits = cmsg::decode::<libc::c_int, libc::cmsghdr>(cmsg) as u8;
742767
}
743768
},
744769
#[cfg(any(target_os = "linux", target_os = "android"))]
745770
(libc::IPPROTO_IP, libc::IP_PKTINFO) => {
746771
let pktinfo = unsafe { cmsg::decode::<libc::in_pktinfo, libc::cmsghdr>(cmsg) };
747-
dst_ip = Some(IpAddr::V4(Ipv4Addr::from(
772+
self.dst_ip = Some(IpAddr::V4(Ipv4Addr::from(
748773
pktinfo.ipi_addr.s_addr.to_ne_bytes(),
749774
)));
750-
interface_index = Some(pktinfo.ipi_ifindex as u32);
775+
self.interface_index = Some(pktinfo.ipi_ifindex as u32);
751776
}
752777
#[cfg(any(bsd, apple))]
753778
(libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => {
754779
let in_addr = unsafe { cmsg::decode::<libc::in_addr, libc::cmsghdr>(cmsg) };
755-
dst_ip = Some(IpAddr::V4(Ipv4Addr::from(in_addr.s_addr.to_ne_bytes())));
780+
self.dst_ip = Some(IpAddr::V4(Ipv4Addr::from(in_addr.s_addr.to_ne_bytes())));
756781
}
757782
(libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => {
758783
let pktinfo = unsafe { cmsg::decode::<libc::in6_pktinfo, libc::cmsghdr>(cmsg) };
759-
dst_ip = Some(IpAddr::V6(Ipv6Addr::from(pktinfo.ipi6_addr.s6_addr)));
760-
interface_index = Some(pktinfo.ipi6_ifindex as u32);
784+
self.dst_ip = Some(IpAddr::V6(Ipv6Addr::from(pktinfo.ipi6_addr.s6_addr)));
785+
self.interface_index = Some(pktinfo.ipi6_ifindex as u32);
761786
}
762787
#[cfg(any(target_os = "linux", target_os = "android"))]
763788
(libc::SOL_UDP, libc::UDP_GRO) => unsafe {
764-
stride = cmsg::decode::<libc::c_int, libc::cmsghdr>(cmsg) as usize;
789+
self.stride = cmsg::decode::<libc::c_int, libc::cmsghdr>(cmsg) as usize;
765790
},
766791
_ => {}
767792
}
768793
}
769-
770-
Ok(RecvMeta {
771-
len,
772-
stride,
773-
addr: decode_socket_addr(&name)?,
774-
ecn: EcnCodepoint::from_bits(ecn_bits),
775-
dst_ip,
776-
interface_index,
777-
})
778794
}
779795

780796
/// Decodes a `sockaddr_storage` into a `SocketAddr`

0 commit comments

Comments
 (0)