Skip to content

Commit 46e2c18

Browse files
committed
Issue #12: roaming fix
1 parent eaa1f28 commit 46e2c18

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

src/userspace.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,11 @@ pub fn run(config: &crate::config::Config) -> crate::Result<()> {
12641264

12651265
// Lock-free shared WG peer address (client mode: egress writes, ingress reads)
12661266
let shared_wg_peer = Arc::new(SharedAddr::new());
1267+
// Endpoint roaming: ingress writes the actual source addr of the last authenticated
1268+
// packet from the peer; egress prefers this over the configured remote_peer_addr.
1269+
// This lets the server respond to the client's real (possibly ephemeral) port without
1270+
// requiring peer_ip=dynamic.
1271+
let shared_peer_ext = Arc::new(SharedAddr::new());
12671272

12681273
// Shared maps for dynamic_peer routing (egress reads client_map, ingress writes it; vice versa for session_map)
12691274
let client_map: Arc<Mutex<HashMap<u32, SocketAddr>>> = Arc::new(Mutex::new(HashMap::new()));
@@ -1280,6 +1285,7 @@ pub fn run(config: &crate::config::Config) -> crate::Result<()> {
12801285
let egress_session_map = Arc::clone(&session_map);
12811286
let egress_peer = peer.clone();
12821287
let egress_client_obfs = Arc::clone(&client_obfs);
1288+
let egress_peer_ext = Arc::clone(&shared_peer_ext);
12831289
let egress_handle = std::thread::Builder::new()
12841290
.name("gutd-egress".into())
12851291
.spawn(move || {
@@ -1360,7 +1366,9 @@ pub fn run(config: &crate::config::Config) -> crate::Result<()> {
13601366
}
13611367

13621368
let egress_dest = if !dynamic_peer {
1363-
remote_peer_addr
1369+
// Prefer the endpoint learned from the last authenticated inbound
1370+
// packet (roaming), fall back to the statically configured address.
1371+
egress_peer_ext.load().map(Some).unwrap_or(remote_peer_addr)
13641372
} else if size >= 4 {
13651373
let wg_type = buf[0] & 0x1F;
13661374
if wg_type == 1 {
@@ -1517,6 +1525,7 @@ pub fn run(config: &crate::config::Config) -> crate::Result<()> {
15171525
let ingress_client_map = Arc::clone(&client_map);
15181526
let ingress_session_map = Arc::clone(&session_map);
15191527
let ingress_client_obfs = Arc::clone(&client_obfs);
1528+
let ingress_peer_ext = Arc::clone(&shared_peer_ext);
15201529
let ingress_peer = peer.clone();
15211530

15221531
let ingress_handle = std::thread::Builder::new()
@@ -1725,6 +1734,11 @@ pub fn run(config: &crate::config::Config) -> crate::Result<()> {
17251734
if let Some((new_size, _wg_sport, _wg_dport)) =
17261735
obfs_decap(buf, size, &key_init, rounds, detected_obfs)
17271736
{
1737+
// Endpoint roaming: remember the actual source of every
1738+
// authenticated packet so the egress thread can respond
1739+
// to the peer's real (possibly ephemeral) port.
1740+
ingress_peer_ext.store(src);
1741+
17281742
if dynamic_peer && new_size >= 8 {
17291743
let wg_type = buf[0] & 0x1F;
17301744
if wg_type == 1 {

0 commit comments

Comments
 (0)