@@ -11,7 +11,6 @@ use crate::{
1111 message:: { InnerMessage , NetMessage , Transaction } ,
1212 node:: { NetworkBridge , OpManager , PeerId } ,
1313 ring:: { Location , PeerKeyLocation , RingError } ,
14- transport:: ObservedAddr ,
1514} ;
1615use freenet_stdlib:: {
1716 client_api:: { ContractResponse , ErrorKind , HostResponse } ,
@@ -275,7 +274,7 @@ async fn complete_local_subscription(
275274 key : ContractKey ,
276275) -> Result < ( ) , OpError > {
277276 let subscriber = op_manager. ring . connection_manager . own_location ( ) ;
278- // Local subscription - no upstream_addr needed since it's our own peer
277+ // Local subscription - no upstream NAT address
279278 if let Err ( err) = op_manager
280279 . ring
281280 . add_subscriber ( & key, subscriber. clone ( ) , None )
@@ -310,7 +309,7 @@ pub(crate) struct SubscribeOp {
310309 state : Option < SubscribeState > ,
311310 /// The address we received this operation's message from.
312311 /// Used for connection-based routing: responses are sent back to this address.
313- upstream_addr : Option < ObservedAddr > ,
312+ upstream_addr : Option < std :: net :: SocketAddr > ,
314313}
315314
316315impl SubscribeOp {
@@ -364,16 +363,11 @@ impl Operation for SubscribeOp {
364363 }
365364 Ok ( None ) => {
366365 // new request to subscribe to a contract, initialize the machine
367- tracing:: debug!(
368- tx = %id,
369- ?source_addr,
370- "subscribe: load_or_init creating new op with source_addr as upstream_addr"
371- ) ;
372366 Ok ( OpInitialization {
373367 op : Self {
374368 state : Some ( SubscribeState :: ReceivedRequest ) ,
375369 id,
376- upstream_addr : source_addr. map ( ObservedAddr :: new ) , // Connection-based routing: store who sent us this request
370+ upstream_addr : source_addr, // Connection-based routing: store who sent us this request
377371 } ,
378372 source_addr,
379373 } )
@@ -413,29 +407,31 @@ impl Operation for SubscribeOp {
413407 target : _,
414408 subscriber,
415409 } => {
416- // ALWAYS use the transport-level source address when available .
417- // This is critical for NAT peers: they may embed a "known" but wrong address
418- // (e.g., 127.0.0.1:31337 for loopback). The transport address is the only
419- // reliable way to route responses back through the NAT .
410+ // Fill in subscriber's external address from transport layer if unknown .
411+ // This is the key step where the first recipient (gateway) determines the
412+ // subscriber's external address from the actual packet source address.
413+ // IMPORTANT: Must fill address BEFORE any .peer() calls to avoid panic .
420414 let mut subscriber = subscriber. clone ( ) ;
421415
416+ if subscriber. peer_addr . is_unknown ( ) {
417+ if let Some ( addr) = source_addr {
418+ subscriber. set_addr ( addr) ;
419+ tracing:: debug!(
420+ tx = %id,
421+ %key,
422+ subscriber_addr = %addr,
423+ "subscribe: filled subscriber address from source_addr"
424+ ) ;
425+ }
426+ }
427+
422428 tracing:: debug!(
423429 tx = %id,
424430 %key,
425- subscriber_orig = %subscriber. peer( ) ,
431+ subscriber = %subscriber. peer( ) ,
426432 source_addr = ?source_addr,
427433 "subscribe: processing RequestSub"
428434 ) ;
429-
430- if let Some ( addr) = source_addr {
431- subscriber. set_addr ( addr) ;
432- tracing:: debug!(
433- tx = %id,
434- %key,
435- subscriber_updated = %subscriber. peer( ) ,
436- "subscribe: updated subscriber address from transport source"
437- ) ;
438- }
439435 let own_loc = op_manager. ring . connection_manager . own_location ( ) ;
440436
441437 if !matches ! (
@@ -462,10 +458,10 @@ impl Operation for SubscribeOp {
462458 "subscribe: handling RequestSub locally (contract available)"
463459 ) ;
464460
465- // Use upstream_addr for NAT routing - subscriber may embed wrong address
461+ // Local registration - no upstream NAT address
466462 if op_manager
467463 . ring
468- . add_subscriber ( key, subscriber. clone ( ) , self . upstream_addr )
464+ . add_subscriber ( key, subscriber. clone ( ) , None )
469465 . is_err ( )
470466 {
471467 tracing:: warn!(
@@ -532,13 +528,6 @@ impl Operation for SubscribeOp {
532528 subscribed : true ,
533529 } ;
534530
535- tracing:: debug!(
536- tx = %id,
537- %key,
538- upstream_addr = ?self . upstream_addr,
539- "subscribe: creating ReturnSub with upstream_addr"
540- ) ;
541-
542531 return build_op_result (
543532 self . id ,
544533 None ,
@@ -741,10 +730,7 @@ impl Operation for SubscribeOp {
741730 subscribers_before = ?before_direct,
742731 "subscribe: attempting to register direct subscriber"
743732 ) ;
744- // Pass None: subscriber address was already corrected by Gateway at the
745- // start of the subscribe flow. Using self.upstream_addr here would
746- // incorrectly overwrite with the forwarder's address instead of the
747- // original subscriber's Gateway-corrected address.
733+ // Local registration - no upstream NAT address
748734 if op_manager
749735 . ring
750736 . add_subscriber ( key, subscriber. clone ( ) , None )
@@ -895,7 +881,7 @@ impl Operation for SubscribeOp {
895881 subscribers_before = ?before_upstream,
896882 "subscribe: attempting to register upstream link"
897883 ) ;
898- // upstream_subscriber was stored in op state, no transport address available
884+ // Local registration - no upstream NAT address
899885 if op_manager
900886 . ring
901887 . add_subscriber ( key, upstream_subscriber. clone ( ) , None )
@@ -928,10 +914,7 @@ impl Operation for SubscribeOp {
928914 subscribers_before = ?before_provider,
929915 "subscribe: registering provider/subscription source"
930916 ) ;
931- // Pass None: sender was already looked up from source_addr (line ~866),
932- // so it has the correct transport address. Using self.upstream_addr
933- // would incorrectly use the original requester's address instead of
934- // the provider's address.
917+ // Local registration - no upstream NAT address
935918 if op_manager
936919 . ring
937920 . add_subscriber ( key, sender. clone ( ) , None )
@@ -993,26 +976,17 @@ fn build_op_result(
993976 id : Transaction ,
994977 state : Option < SubscribeState > ,
995978 msg : Option < SubscribeMsg > ,
996- upstream_addr : Option < ObservedAddr > ,
979+ upstream_addr : Option < std :: net :: SocketAddr > ,
997980) -> Result < OperationResult , OpError > {
998981 // For response messages (ReturnSub), use upstream_addr directly for routing.
999982 // This is more reliable than extracting from the message's target field, which
1000983 // may have been looked up from connection_manager (subject to race conditions).
1001984 // For forward messages (SeekNode, RequestSub, FetchRouting), use the message's target.
1002985 let target_addr = match & msg {
1003- // Convert ObservedAddr to SocketAddr at the transport boundary
1004- Some ( SubscribeMsg :: ReturnSub { .. } ) => upstream_addr. map ( |a| a. socket_addr ( ) ) ,
986+ Some ( SubscribeMsg :: ReturnSub { .. } ) => upstream_addr,
1005987 _ => msg. as_ref ( ) . and_then ( |m| m. target_addr ( ) ) ,
1006988 } ;
1007989
1008- tracing:: debug!(
1009- tx = %id,
1010- msg_type = ?msg. as_ref( ) . map( |m| std:: any:: type_name_of_val( m) ) ,
1011- ?upstream_addr,
1012- ?target_addr,
1013- "build_op_result: computed target_addr"
1014- ) ;
1015-
1016990 let output_op = state. map ( |state| SubscribeOp {
1017991 id,
1018992 state : Some ( state) ,
0 commit comments