@@ -222,7 +222,7 @@ pub(crate) struct MagicSock {
222
222
/// Nearest relay node ID; 0 means none/unknown.
223
223
my_relay : Watchable < Option < RelayUrl > > ,
224
224
/// Tracks the networkmap node entity for each node discovery key.
225
- node_map : NodeMap ,
225
+ node_map : Arc < NodeMap > ,
226
226
/// Tracks the mapped IP addresses
227
227
ip_mapped_addrs : IpMappedAddresses ,
228
228
/// NetReport client
@@ -1737,7 +1737,7 @@ impl Handle {
1737
1737
my_relay : Default :: default ( ) ,
1738
1738
net_reporter : net_reporter. addr ( ) ,
1739
1739
disco_secrets : DiscoSecrets :: default ( ) ,
1740
- node_map,
1740
+ node_map : Arc :: new ( node_map ) ,
1741
1741
ip_mapped_addrs,
1742
1742
udp_disco_sender,
1743
1743
discovery,
@@ -2129,7 +2129,7 @@ impl RelayDatagramRecvQueue {
2129
2129
}
2130
2130
2131
2131
impl 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 > > {
2133
2133
// To do this properly the MagicSock would need a registry of pollers. For each
2134
2134
// node we would look up the poller or create one. Then on each try_send we can
2135
2135
// look up the correct poller and configure it to poll the paths it needs.
@@ -2150,6 +2150,10 @@ impl AsyncUdpSocket for MagicSock {
2150
2150
let ipv6_poller = self . sockets . v6 . as_ref ( ) . map ( |sock| sock. create_io_poller ( ) ) ;
2151
2151
let relay_sender = self . relay_datagram_send_channel . clone ( ) ;
2152
2152
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 ( ) ,
2153
2157
#[ cfg( not( wasm_browser) ) ]
2154
2158
ipv4_poller,
2155
2159
#[ cfg( not( wasm_browser) ) ]
@@ -2248,6 +2252,10 @@ impl AsyncUdpSocket for MagicSock {
2248
2252
2249
2253
#[ derive( Debug ) ]
2250
2254
struct IoPoller {
2255
+ mapped_addr : MappedAddr ,
2256
+ node_map : Arc < NodeMap > ,
2257
+ ip_mapped_addrs : IpMappedAddresses ,
2258
+ ipv6_reported : Arc < AtomicBool > ,
2251
2259
#[ cfg( not( wasm_browser) ) ]
2252
2260
ipv4_poller : Pin < Box < dyn quinn:: UdpPoller > > ,
2253
2261
#[ cfg( not( wasm_browser) ) ]
@@ -2257,21 +2265,60 @@ struct IoPoller {
2257
2265
2258
2266
impl quinn:: UdpPoller for IoPoller {
2259
2267
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.
2261
2268
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 ;
2272
2275
}
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)
2275
2322
}
2276
2323
}
2277
2324
0 commit comments