@@ -100,37 +100,38 @@ async fn maybe_timeout<F: Future>(
100
100
101
101
/// Forward all complete datagrams in `buffer` to `udp_out`.
102
102
/// Returns the number of processed bytes.
103
- async fn forward_datagrams_in_buffer ( udp_out : & UdpSocket , buffer : & [ u8 ] ) -> io:: Result < usize > {
104
- let mut header_start = 0 ;
103
+ async fn forward_datagrams_in_buffer ( udp_out : & UdpSocket , mut buffer : & [ u8 ] ) -> io:: Result < usize > {
104
+ let original_buffer_len = buffer . len ( ) ;
105
105
loop {
106
- let header_end = header_start + HEADER_LEN ;
107
- // "parse" the header
108
- let header = match buffer. get ( header_start..header_end) {
109
- Some ( header) => <[ u8 ; HEADER_LEN ] >:: try_from ( header) . unwrap ( ) ,
110
- // Buffer does not contain entire header for next datagram
111
- None => break Ok ( header_start) ,
112
- } ;
113
- let datagram_len = usize:: from ( u16:: from_be_bytes ( header) ) ;
114
- let datagram_start = header_end;
115
- let datagram_end = datagram_start + datagram_len;
116
-
117
- let datagram_data = match buffer. get ( datagram_start..datagram_end) {
118
- Some ( datagram_data) => datagram_data,
106
+ let ( datagram_data, tail) = match split_first_datagram ( buffer) {
107
+ Some ( data_tuple) => data_tuple,
119
108
// The buffer does not contain the entire datagram
120
- None => break Ok ( header_start ) ,
109
+ None => break Ok ( original_buffer_len - buffer . len ( ) ) ,
121
110
} ;
122
111
123
112
let udp_write_len = udp_out. send ( datagram_data) . await ?;
124
113
assert_eq ! (
125
- udp_write_len, datagram_len,
114
+ udp_write_len,
115
+ datagram_data. len( ) ,
126
116
"Did not send entire UDP datagram"
127
117
) ;
128
- log:: trace!( "Forwarded {} byte TCP->UDP" , datagram_len ) ;
118
+ log:: trace!( "Forwarded {} byte TCP->UDP" , datagram_data . len ( ) ) ;
129
119
130
- header_start = datagram_end ;
120
+ buffer = tail ;
131
121
}
132
122
}
133
123
124
+ /// Parses the header at the beginning of the `buffer` and if it contains a full
125
+ /// `udp-to-tcp` datagram it splits the buffer and returns the datagram data and
126
+ /// buffer tail as two separate slices: `(datagram_data, tail)`
127
+ fn split_first_datagram ( buffer : & [ u8 ] ) -> Option < ( & [ u8 ] , & [ u8 ] ) > {
128
+ let ( header, tail) = buffer. split_first_chunk :: < HEADER_LEN > ( ) ?;
129
+ let datagram_len = usize:: from ( u16:: from_be_bytes ( * header) ) ;
130
+ let datagram_data = tail. get ( ..datagram_len) ?;
131
+ let tail = tail. get ( datagram_len..) ?;
132
+ Some ( ( datagram_data, tail) )
133
+ }
134
+
134
135
/// Reads datagrams from `udp_in` and writes them (with the 16 bit header containing the length)
135
136
/// to `tcp_out` indefinitely, or until an IO error happens on either socket.
136
137
async fn process_udp2tcp (
0 commit comments