From 634c5ee38fc116866d91faed5044dd75972a82f6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 3 Apr 2025 14:22:38 +0000 Subject: [PATCH] refactor(eBPF): reuse `CdHdr` struct (#8635) Instead of passing just a 4-byte array, we can pass a `CdHdr` struct that we have already defined. This is more type-safe and correctly captures the invariant of the order of fields in the header. --- rust/relay/ebpf-turn-router/src/main.rs | 30 ++++++++++--------- .../ebpf-turn-router/src/move_headers.rs | 8 ++--- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/rust/relay/ebpf-turn-router/src/main.rs b/rust/relay/ebpf-turn-router/src/main.rs index 39c669df0..8825e35f1 100644 --- a/rust/relay/ebpf-turn-router/src/main.rs +++ b/rust/relay/ebpf-turn-router/src/main.rs @@ -223,7 +223,7 @@ fn try_handle_ipv4_udp_to_channel_data( let new_udp_len = udp_len + CdHdr::LEN as u16; let channel_number = client_and_channel.channel(); - let channel_data_length = udp_len - UdpHdr::LEN as u16; + let channel_data_length = udp_len - UdpHdr::LEN as u16; // The `length` field in the UDP header includes the header itself. For the channel-data field, we only want the length of the payload. udp.update( pseudo_header, @@ -234,12 +234,13 @@ fn try_handle_ipv4_udp_to_channel_data( channel_data_length, ); - let cd_num = channel_number.to_be_bytes(); - let cd_len = channel_data_length.to_be_bytes(); // The `length` field in the UDP header includes the header itself. For the channel-data field, we only want the length of the payload. - - let channel_data_header = [cd_num[0], cd_num[1], cd_len[0], cd_len[1]]; - - add_channel_data_header_ipv4(ctx, channel_data_header)?; + add_channel_data_header_ipv4( + ctx, + CdHdr { + number: channel_number.to_be_bytes(), + length: channel_data_length.to_be_bytes(), + }, + )?; Ok(()) } @@ -313,7 +314,7 @@ fn try_handle_ipv6_udp_to_channel_data( let new_udp_len = udp_len + CdHdr::LEN as u16; let channel_number = client_and_channel.channel(); - let channel_data_length = udp_len - UdpHdr::LEN as u16; + let channel_data_length = udp_len - UdpHdr::LEN as u16; // The `length` field in the UDP header includes the header itself. For the channel-data field, we only want the length of the payload. udp.update( pseudo_header, @@ -324,12 +325,13 @@ fn try_handle_ipv6_udp_to_channel_data( channel_data_length, ); - let cd_num = channel_number.to_be_bytes(); - let cd_len = channel_data_length.to_be_bytes(); // The `length` field in the UDP header includes the header itself. For the channel-data field, we only want the length of the payload. - - let channel_data_header = [cd_num[0], cd_num[1], cd_len[0], cd_len[1]]; - - add_channel_data_header_ipv6(ctx, channel_data_header)?; + add_channel_data_header_ipv6( + ctx, + CdHdr { + number: channel_number.to_be_bytes(), + length: channel_data_length.to_be_bytes(), + }, + )?; Ok(()) } diff --git a/rust/relay/ebpf-turn-router/src/move_headers.rs b/rust/relay/ebpf-turn-router/src/move_headers.rs index 93017e71f..7c98472a5 100644 --- a/rust/relay/ebpf-turn-router/src/move_headers.rs +++ b/rust/relay/ebpf-turn-router/src/move_headers.rs @@ -17,12 +17,12 @@ pub fn remove_channel_data_header_ipv4(ctx: &XdpContext) -> Result<(), Error> { } #[inline(always)] -pub fn add_channel_data_header_ipv4(ctx: &XdpContext, mut header: [u8; 4]) -> Result<(), Error> { +pub fn add_channel_data_header_ipv4(ctx: &XdpContext, mut header: CdHdr) -> Result<(), Error> { move_headers::<{ -(CdHdr::LEN as i32) }, { Ipv4Hdr::LEN }>(ctx)?; let offset = (EthHdr::LEN + Ipv4Hdr::LEN + UdpHdr::LEN) as u32; let header_ptr = &mut header as *mut _ as *mut c_void; - let header_len = CdHdr::LEN as u32; + let header_len = core::mem::size_of_val(&header) as u32; let ret = unsafe { bpf_xdp_store_bytes(ctx.ctx, offset, header_ptr, header_len) }; if ret < 0 { @@ -38,12 +38,12 @@ pub fn remove_channel_data_header_ipv6(ctx: &XdpContext) -> Result<(), Error> { } #[inline(always)] -pub fn add_channel_data_header_ipv6(ctx: &XdpContext, mut header: [u8; 4]) -> Result<(), Error> { +pub fn add_channel_data_header_ipv6(ctx: &XdpContext, mut header: CdHdr) -> Result<(), Error> { move_headers::<{ -(CdHdr::LEN as i32) }, { Ipv6Hdr::LEN }>(ctx)?; let offset = (EthHdr::LEN + Ipv6Hdr::LEN + UdpHdr::LEN) as u32; let header_ptr = &mut header as *mut _ as *mut c_void; - let header_len = CdHdr::LEN as u32; + let header_len = core::mem::size_of_val(&header) as u32; let ret = unsafe { bpf_xdp_store_bytes(ctx.ctx, offset, header_ptr, header_len) }; if ret < 0 {