@@ -222,7 +222,7 @@ pub(crate) struct MagicSock {
222222 /// Nearest relay node ID; 0 means none/unknown.
223223 my_relay : Watchable < Option < RelayUrl > > ,
224224 /// Tracks the networkmap node entity for each node discovery key.
225- node_map : NodeMap ,
225+ node_map : Arc < NodeMap > ,
226226 /// Tracks the mapped IP addresses
227227 ip_mapped_addrs : IpMappedAddresses ,
228228 /// NetReport client
@@ -1737,7 +1737,7 @@ impl Handle {
17371737 my_relay : Default :: default ( ) ,
17381738 net_reporter : net_reporter. addr ( ) ,
17391739 disco_secrets : DiscoSecrets :: default ( ) ,
1740- node_map,
1740+ node_map : Arc :: new ( node_map ) ,
17411741 ip_mapped_addrs,
17421742 udp_disco_sender,
17431743 discovery,
@@ -2129,7 +2129,7 @@ impl RelayDatagramRecvQueue {
21292129}
21302130
21312131impl AsyncUdpSocket for MagicSock {
2132- fn create_io_poller ( self : Arc < Self > ) -> Pin < Box < dyn quinn:: UdpPoller > > {
2132+ fn create_io_poller ( self : Arc < Self > , remote : SocketAddr ) -> Pin < Box < dyn quinn:: UdpPoller > > {
21332133 // To do this properly the MagicSock would need a registry of pollers. For each
21342134 // node we would look up the poller or create one. Then on each try_send we can
21352135 // look up the correct poller and configure it to poll the paths it needs.
@@ -2150,6 +2150,10 @@ impl AsyncUdpSocket for MagicSock {
21502150 let ipv6_poller = self . sockets . v6 . as_ref ( ) . map ( |sock| sock. create_io_poller ( ) ) ;
21512151 let relay_sender = self . relay_datagram_send_channel . clone ( ) ;
21522152 Box :: pin ( IoPoller {
2153+ mapped_addr : MappedAddr :: from ( remote) ,
2154+ node_map : self . node_map . clone ( ) ,
2155+ ip_mapped_addrs : self . ip_mapped_addrs . clone ( ) ,
2156+ ipv6_reported : self . ipv6_reported . clone ( ) ,
21532157 #[ cfg( not( wasm_browser) ) ]
21542158 ipv4_poller,
21552159 #[ cfg( not( wasm_browser) ) ]
@@ -2248,6 +2252,10 @@ impl AsyncUdpSocket for MagicSock {
22482252
22492253#[ derive( Debug ) ]
22502254struct IoPoller {
2255+ mapped_addr : MappedAddr ,
2256+ node_map : Arc < NodeMap > ,
2257+ ip_mapped_addrs : IpMappedAddresses ,
2258+ ipv6_reported : Arc < AtomicBool > ,
22512259 #[ cfg( not( wasm_browser) ) ]
22522260 ipv4_poller : Pin < Box < dyn quinn:: UdpPoller > > ,
22532261 #[ cfg( not( wasm_browser) ) ]
@@ -2257,21 +2265,60 @@ struct IoPoller {
22572265
22582266impl quinn:: UdpPoller for IoPoller {
22592267 fn poll_writable ( mut self : Pin < & mut Self > , cx : & mut Context ) -> Poll < io:: Result < ( ) > > {
2260- // This version returns Ready as soon as any of them are ready.
22612268 let this = & mut * self ;
2262- #[ cfg( not( wasm_browser) ) ]
2263- match this. ipv4_poller . as_mut ( ) . poll_writable ( cx) {
2264- Poll :: Ready ( _) => return Poll :: Ready ( Ok ( ( ) ) ) ,
2265- Poll :: Pending => ( ) ,
2266- }
2267- #[ cfg( not( wasm_browser) ) ]
2268- if let Some ( ref mut ipv6_poller) = this. ipv6_poller {
2269- match ipv6_poller. as_mut ( ) . poll_writable ( cx) {
2270- Poll :: Ready ( _) => return Poll :: Ready ( Ok ( ( ) ) ) ,
2271- Poll :: Pending => ( ) ,
2269+ let udp_addr = match & this. mapped_addr {
2270+ MappedAddr :: None ( dest) => {
2271+ error ! ( %dest, "Cannot convert to a mapped address, voiding transmit." ) ;
2272+ // Because we can't send these, we just stall whatever endpoint driver got into this state
2273+ // TODO: Maybe we shoulde error out instead? Since there's no way this recovers, right?
2274+ return Poll :: Pending ;
22722275 }
2273- }
2274- this. relay_sender . poll_writable ( cx)
2276+ MappedAddr :: NodeId ( dest) => {
2277+ trace ! ( %dest, "polling writable" ) ;
2278+
2279+ // Get the node's relay address and best direct address, as well
2280+ // as any pings that need to be sent for hole-punching purposes.
2281+ match this
2282+ . node_map
2283+ . addr_for_send ( * dest, this. ipv6_reported . load ( Ordering :: Relaxed ) )
2284+ {
2285+ Some ( ( _, None , Some ( _relay_url) ) ) => {
2286+ return this. relay_sender . poll_writable ( cx)
2287+ }
2288+ Some ( ( _, Some ( udp_addr) , None ) ) => udp_addr,
2289+ Some ( ( _, Some ( udp_addr) , Some ( _relay_url) ) ) => {
2290+ // If we're in mixed connection mode, then wait for anything to be ready.
2291+ if let Poll :: Ready ( r) = this. relay_sender . poll_writable ( cx) {
2292+ return Poll :: Ready ( r) ;
2293+ }
2294+ udp_addr
2295+ }
2296+ _ => {
2297+ // TODO ensure this is correct
2298+ return Poll :: Pending ;
2299+ }
2300+ }
2301+ }
2302+ MappedAddr :: Ip ( mapped_addr) => {
2303+ let Some ( udp_addr) = this. ip_mapped_addrs . get_ip_addr ( mapped_addr) else {
2304+ // TODO idk
2305+ return Poll :: Pending ;
2306+ } ;
2307+ udp_addr
2308+ }
2309+ } ;
2310+
2311+ let poller = match udp_addr {
2312+ SocketAddr :: V4 ( _) => this. ipv4_poller . as_mut ( ) ,
2313+ SocketAddr :: V6 ( _) => {
2314+ let Some ( poller) = this. ipv6_poller . as_mut ( ) else {
2315+ // TODO error? Trace?
2316+ return Poll :: Pending ;
2317+ } ;
2318+ poller. as_mut ( )
2319+ }
2320+ } ;
2321+ poller. poll_writable ( cx)
22752322 }
22762323}
22772324
0 commit comments