diff --git a/crates/scion/src/udp_socket.rs b/crates/scion/src/udp_socket.rs index a959316..4e1f0fe 100644 --- a/crates/scion/src/udp_socket.rs +++ b/crates/scion/src/udp_socket.rs @@ -102,39 +102,51 @@ impl UdpSocket { self.local_address } - /// Receive a SCION UDP packet from a remote endpoint. + /// Receive a SCION UDP packet. /// /// The UDP payload is written into the provided buffer. If there is insufficient space, excess /// data is dropped. The returned number of bytes always refers to the amount of data in the UDP /// payload. + pub async fn recv(&self, buffer: &mut [u8]) -> Result { + let (packet_len, _) = self.inner.recv_from(buffer).await?; + Ok(packet_len) + } + + /// Receive a SCION UDP packet from a remote endpoint. /// - /// Additionally returns + /// This behaves like [`Self::recv`] but additionally returns the remote SCION socket address. + pub async fn recv_from(&self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), ReceiveError> { + self.inner.recv_from(buffer).await + } + + /// Receive a SCION UDP packet from a remote endpoint with path information. + /// + /// This behaves like [`Self::recv`] but additionally returns /// - the remote SCION socket address and /// - the path over which the packet was received. For supported path types, this path is /// already reversed such that it can be used directly to send reply packets; for unsupported /// path types, the path is unmodified. /// /// Note that copying/reversing the path requires allocating memory; if you do not need the path - /// information, consider using the method [`Self::recv_from_without_path`] instead. - pub async fn recv_from( + /// information, consider using the method [`Self::recv_from`] instead. + pub async fn recv_with_path_from( &self, buffer: &mut [u8], ) -> Result<(usize, SocketAddr, Path), ReceiveError> { - self.inner.recv_from(buffer).await + self.inner.recv_with_path_from(buffer).await } - /// Receive a SCION UDP packet from a remote endpoint. + /// Receive a SCION UDP packet with path information. /// - /// The UDP payload is written into the provided buffer. If there is insufficient space, excess - /// data is dropped. The returned number of bytes always refers to the amount of data in the UDP - /// payload. + /// This behaves like [`Self::recv`] but additionally returns the path over which the packet was + /// received. For supported path types, this path is already reversed such that it can be used + /// directly to send reply packets; for unsupported path types, the path is unmodified. /// - /// Additionally returns the remote SCION socket address. - pub async fn recv_from_without_path( - &self, - buffer: &mut [u8], - ) -> Result<(usize, SocketAddr), ReceiveError> { - self.inner.recv_from_without_path(buffer).await + /// Note that copying/reversing the path requires allocating memory; if you do not need the path + /// information, consider using the method [`Self::recv`] instead. + pub async fn recv_with_path(&self, buffer: &mut [u8]) -> Result<(usize, Path), ReceiveError> { + let (packet_len, _, path) = self.inner.recv_with_path_from(buffer).await?; + Ok((packet_len, path)) } /// Returns the remote SCION address set for this socket, if any. @@ -274,8 +286,11 @@ impl UdpSocketInner { Ok(()) } - async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr, Path), ReceiveError> { - let (packet_len, sender, last_host, scion_packet) = self.recv_from_loop(buf).await?; + async fn recv_with_path_from( + &self, + buf: &mut [u8], + ) -> Result<(usize, SocketAddr, Path), ReceiveError> { + let (packet_len, sender, last_host, scion_packet) = self.recv_loop(buf).await?; let path = { // Explicit match here in case we add other errors to the `reverse` method at some point let dataplane_path = match scion_packet.headers.path.reverse() { @@ -291,15 +306,12 @@ impl UdpSocketInner { Ok((packet_len, sender, path)) } - async fn recv_from_without_path( - &self, - buf: &mut [u8], - ) -> Result<(usize, SocketAddr), ReceiveError> { - let (packet_len, sender, ..) = self.recv_from_loop(buf).await?; + async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr), ReceiveError> { + let (packet_len, sender, ..) = self.recv_loop(buf).await?; Ok((packet_len, sender)) } - async fn recv_from_loop( + async fn recv_loop( &self, buf: &mut [u8], ) -> Result< diff --git a/crates/scion/tests/test_udp_socket.rs b/crates/scion/tests/test_udp_socket.rs index 5e9257a..050b6c9 100644 --- a/crates/scion/tests/test_udp_socket.rs +++ b/crates/scion/tests/test_udp_socket.rs @@ -57,11 +57,9 @@ macro_rules! test_send_receive_reply { socket_source.send(MESSAGE.clone()).await?; let mut buffer = [0_u8; 100]; - let (length, sender) = tokio::time::timeout( - TIMEOUT, - socket_destination.recv_from_without_path(&mut buffer), - ) - .await??; + let (length, sender) = + tokio::time::timeout(TIMEOUT, socket_destination.recv_from(&mut buffer)) + .await??; assert_eq!(sender, socket_source.local_addr()); assert_eq!(buffer[..length], MESSAGE[..]); Ok(()) @@ -76,9 +74,11 @@ macro_rules! test_send_receive_reply { socket_source.send(MESSAGE.clone()).await?; let mut buffer = [0_u8; 100]; - let (length, sender, path) = - tokio::time::timeout(TIMEOUT, socket_destination.recv_from(&mut buffer)) - .await??; + let (length, sender, path) = tokio::time::timeout( + TIMEOUT, + socket_destination.recv_with_path_from(&mut buffer), + ) + .await??; assert_eq!(sender, socket_source.local_addr()); assert_eq!(buffer[..length], MESSAGE[..]); @@ -87,8 +87,9 @@ macro_rules! test_send_receive_reply { .send_to_with(MESSAGE.clone(), sender, &path) .await?; - let (_, _, path_return) = - tokio::time::timeout(TIMEOUT, socket_source.recv_from(&mut buffer)).await??; + let (_, path_return) = + tokio::time::timeout(TIMEOUT, socket_source.recv_with_path(&mut buffer)) + .await??; assert_eq!(path_return.isd_asn, path_forward.isd_asn); assert_eq!(path_return.dataplane_path, path_forward.dataplane_path);