Skip to content

Commit c6663d9

Browse files
authored
Merge pull request #107 from bevenky/fix/registration-contact-nat-401
fix: rebuild Contact from public_address after 401 NAT challenge
2 parents c9b2507 + 1feecc5 commit c6663d9

2 files changed

Lines changed: 22 additions & 3 deletions

File tree

src/dialog/authenticate.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,9 @@ pub async fn handle_client_authenticate(
253253
let params = &mut via_header.params;
254254
params.retain(|p| !matches!(p, rsip::Param::Branch(_)));
255255
params.push(make_via_branch());
256-
params.push(Param::Other("rport".into(), None));
256+
if !params.iter().any(|p| matches!(p, Param::Other(key, _) if key.value().eq_ignore_ascii_case("rport"))) {
257+
params.push(Param::Other("rport".into(), None));
258+
}
257259
new_req.headers_mut().unique_push(via_header.into());
258260

259261
new_req.headers_mut().retain(|h| {

src/dialog/registration.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ impl Registration {
405405
);
406406

407407
// Thanks to https://github.com/restsend/rsipstack/issues/32
408+
let contact_for_retry = contact.clone();
408409
request.headers.unique_push(self.call_id.clone().into());
409410
request.headers.unique_push(contact.into());
410411
request.headers.unique_push(self.allow.clone().into());
@@ -446,10 +447,26 @@ impl Registration {
446447
if let Some(cred) = &self.credential {
447448
self.last_seq += 1;
448449

449-
// Handle authentication with the existing transaction
450-
// The contact will be updated in the next registration cycle if needed
451450
tx = handle_client_authenticate(self.last_seq, &tx, resp, cred).await?;
452451

452+
// Update Contact in the retry request to use the discovered
453+
// public address (rport/received from 401 Via header).
454+
// handle_client_authenticate clones tx.original which has
455+
// the stale Contact from the initial REGISTER.
456+
if let Some(ref pa) = self.public_address {
457+
let new_contact_uri = rsip::Uri {
458+
auth: contact_for_retry.uri.auth.clone(),
459+
scheme: Some(rsip::Scheme::Sip),
460+
host_with_port: pa.clone(),
461+
params: vec![],
462+
headers: vec![],
463+
};
464+
let mut new_contact = contact_for_retry.clone();
465+
new_contact.uri = new_contact_uri;
466+
tx.original.headers.retain(|h| !matches!(h, rsip::Header::Contact(_)));
467+
tx.original.headers.unique_push(new_contact.into());
468+
}
469+
453470
tx.send().await?;
454471
auth_sent = true;
455472
continue;

0 commit comments

Comments
 (0)