11//! Handles [`UdpRequest`]
22
33use crate :: {
4- find_mac, find_network ,
4+ find_mac,
55 state:: { State , UnitSelector } ,
66} ;
77use anyhow:: { ensure, Context , Result } ;
8+ use futures:: FutureExt ;
9+ use ipnet:: Ipv4Net ;
810use pixie_shared:: {
9- chunk_codec:: Encoder , ChunkHash , HintPacket , RegistrationInfo , UdpRequest , ACTION_PORT ,
10- CHUNKS_PORT , HINT_PORT , UDP_BODY_LEN ,
11+ chunk_codec:: Encoder , ChunkHash , HintPacket , InterfaceConfig , RegistrationInfo , UdpRequest ,
12+ ACTION_PORT , CHUNKS_PORT , HINT_PORT , UDP_BODY_LEN ,
1113} ;
1214use std:: {
1315 collections:: BTreeSet ,
14- net:: { Ipv4Addr , SocketAddrV4 } ,
16+ net:: { IpAddr , Ipv4Addr , SocketAddrV4 } ,
1517 ops:: Bound ,
1618 sync:: Arc ,
1719} ;
@@ -24,7 +26,7 @@ use tokio::{
2426async fn broadcast_chunks (
2527 state : & State ,
2628 socket : & UdpSocket ,
27- ip : Ipv4Addr ,
29+ iface : & InterfaceConfig ,
2830 mut rx : Receiver < ChunkHash > ,
2931) -> Result < ( ) > {
3032 let mut queue = BTreeSet :: < ChunkHash > :: new ( ) ;
@@ -75,8 +77,7 @@ async fn broadcast_chunks(
7577 continue ;
7678 } ;
7779
78- let hosts_cfg = & state. config . hosts ;
79- let chunks_addr = SocketAddrV4 :: new ( ip, CHUNKS_PORT ) ;
80+ let chunks_addr = SocketAddrV4 :: new ( iface. network . broadcast ( ) , CHUNKS_PORT ) ;
8081
8182 let mut encoder = Encoder :: new ( cdata) ;
8283 write_buf[ ..32 ] . clone_from_slice ( & index) ;
@@ -85,7 +86,7 @@ async fn broadcast_chunks(
8586
8687 let sent_len = socket. send_to ( & write_buf[ ..32 + len] , chunks_addr) . await ?;
8788 ensure ! ( sent_len == 32 + len, "Could not send packet" ) ;
88- wait_for += 8 * ( sent_len as u32 ) * Duration :: from_secs ( 1 ) / hosts_cfg . broadcast_speed ;
89+ wait_for += 8 * ( sent_len as u32 ) * Duration :: from_secs ( 1 ) / iface . broadcast_speed ;
8990 }
9091 }
9192
@@ -165,13 +166,24 @@ async fn broadcast_hint(state: &State, socket: &UdpSocket, ip: Ipv4Addr) -> Resu
165166 Ok ( ( ) )
166167}
167168
168- async fn handle_requests ( state : & State , socket : & UdpSocket , tx : Sender < [ u8 ; 32 ] > ) -> Result < ( ) > {
169+ async fn handle_requests (
170+ state : & State ,
171+ socket : & UdpSocket ,
172+ net_tx : Vec < ( Ipv4Net , Sender < [ u8 ; 32 ] > ) > ,
173+ ) -> Result < ( ) > {
169174 let mut buf = [ 0 ; UDP_BODY_LEN ] ;
170175 loop {
171176 let ( len, peer_addr) = tokio:: select! {
172177 x = socket. recv_from( & mut buf) => x?,
173178 _ = state. cancel_token. cancelled( ) => break ,
174179 } ;
180+ let peer_ip = match peer_addr. ip ( ) {
181+ IpAddr :: V4 ( ip) => ip,
182+ _ => panic ! ( ) ,
183+ } ;
184+ let Some ( ( _, tx) ) = net_tx. iter ( ) . find ( |( net, _) | net. contains ( & peer_ip) ) else {
185+ continue ;
186+ } ;
175187 let req: postcard:: Result < UdpRequest > = postcard:: from_bytes ( & buf[ ..len] ) ;
176188 match req {
177189 Ok ( UdpRequest :: Discover ) => {
@@ -201,18 +213,29 @@ async fn handle_requests(state: &State, socket: &UdpSocket, tx: Sender<[u8; 32]>
201213}
202214
203215pub async fn main ( state : Arc < State > ) -> Result < ( ) > {
204- let ( _, network) = find_network ( state. config . hosts . listen_on ) ?;
216+ let ( net_tx, net_rx) : ( _ , Vec < _ > ) = state
217+ . config
218+ . hosts
219+ . interfaces
220+ . iter ( )
221+ . map ( |iface| {
222+ let ( tx, rx) = mpsc:: channel ( 128 ) ;
223+ ( ( iface. network , tx) , ( iface, rx) )
224+ } )
225+ . unzip ( ) ;
205226
206- let ( tx, rx) = mpsc:: channel ( 128 ) ;
207227 let socket = UdpSocket :: bind ( ( Ipv4Addr :: UNSPECIFIED , ACTION_PORT ) ) . await ?;
208228 log:: info!( "Listening on {}" , socket. local_addr( ) ?) ;
209229 socket. set_broadcast ( true ) ?;
210230
211- tokio:: try_join!(
212- broadcast_chunks( & state, & socket, network. broadcast( ) , rx) ,
213- broadcast_hint( & state, & socket, network. broadcast( ) ) ,
214- handle_requests( & state, & socket, tx) ,
215- ) ?;
231+ let mut tasks = vec ! [ handle_requests( & state, & socket, net_tx) . boxed( ) ] ;
232+
233+ for ( iface, rx) in net_rx {
234+ tasks. push ( broadcast_chunks ( & state, & socket, iface, rx) . boxed ( ) ) ;
235+ tasks. push ( broadcast_hint ( & state, & socket, iface. network . broadcast ( ) ) . boxed ( ) ) ;
236+ }
237+
238+ futures:: future:: try_join_all ( tasks) . await ?;
216239
217240 Ok ( ( ) )
218241}
0 commit comments