Skip to content

Commit 82e8cab

Browse files
committed
feat(dialog): get via from orignal request
1 parent 7c6bc86 commit 82e8cab

File tree

6 files changed

+146
-23
lines changed

6 files changed

+146
-23
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rsipstack"
3-
version = "0.2.35"
3+
version = "0.2.36"
44
edition = "2021"
55
description = "SIP Stack Rust library for building SIP applications"
66
license = "MIT"

src/dialog/dialog.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ use crate::{
1010
transaction::{
1111
endpoint::EndpointInnerRef,
1212
key::{TransactionKey, TransactionRole},
13+
make_via_branch,
1314
transaction::{Transaction, TransactionEventSender},
1415
},
1516
Result,
1617
};
1718
use rsip::{
1819
headers::Route,
1920
prelude::{HeadersExt, ToTypedHeader, UntypedHeader},
20-
typed::{CSeq, Contact},
21+
typed::{CSeq, Contact, Via},
2122
Header, Param, Request, Response, SipMessage, StatusCode,
2223
};
2324
use std::sync::{
@@ -289,12 +290,31 @@ impl DialogInner {
289290
Ok(())
290291
}
291292

292-
pub(super) fn make_request(
293+
pub(super) fn build_vias_from_request(&self) -> Result<Vec<Via>> {
294+
let mut vias = vec![];
295+
for header in self.initial_request.headers.iter() {
296+
if let Header::Via(via) = header {
297+
if let Ok(mut typed_via) = via.typed() {
298+
for param in typed_via.params.iter_mut() {
299+
if let Param::Branch(_) = param {
300+
*param = make_via_branch();
301+
}
302+
}
303+
vias.push(typed_via);
304+
return Ok(vias);
305+
}
306+
}
307+
}
308+
let via = self.endpoint_inner.get_via(None, None)?;
309+
vias.push(via);
310+
Ok(vias)
311+
}
312+
313+
pub(super) fn make_request_with_vias(
293314
&self,
294315
method: rsip::Method,
295316
cseq: Option<u32>,
296-
addr: Option<crate::transport::SipAddr>,
297-
branch: Option<Param>,
317+
vias: Vec<rsip::headers::typed::Via>,
298318
headers: Option<Vec<rsip::Header>>,
299319
body: Option<Vec<u8>>,
300320
) -> Result<rsip::Request> {
@@ -304,8 +324,9 @@ impl DialogInner {
304324
method,
305325
};
306326

307-
let via = self.endpoint_inner.get_via(addr, branch)?;
308-
headers.push(via.into());
327+
for via in vias {
328+
headers.push(Header::Via(via.into()));
329+
}
309330
headers.push(Header::CallId(
310331
self.id.lock().unwrap().call_id.clone().into(),
311332
));
@@ -339,6 +360,19 @@ impl DialogInner {
339360
Ok(req)
340361
}
341362

363+
pub(super) fn make_request(
364+
&self,
365+
method: rsip::Method,
366+
cseq: Option<u32>,
367+
addr: Option<crate::transport::SipAddr>,
368+
branch: Option<Param>,
369+
headers: Option<Vec<rsip::Header>>,
370+
body: Option<Vec<u8>>,
371+
) -> Result<rsip::Request> {
372+
let via = self.endpoint_inner.get_via(addr, branch)?;
373+
self.make_request_with_vias(method, cseq, vec![via], headers, body)
374+
}
375+
342376
pub(super) fn make_response(
343377
&self,
344378
request: &Request,

src/dialog/server_dialog.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,14 @@ impl ServerInviteDialog {
331331
return Ok(());
332332
}
333333
info!(id=%self.id(), "sending bye request");
334-
let request = self
335-
.inner
336-
.make_request(rsip::Method::Bye, None, None, None, None, None)?;
334+
335+
let request = self.inner.make_request_with_vias(
336+
rsip::Method::Bye,
337+
None,
338+
self.inner.build_vias_from_request()?,
339+
None,
340+
None,
341+
)?;
337342

338343
match self.inner.do_request(request).await {
339344
Ok(_) => {}
@@ -383,9 +388,13 @@ impl ServerInviteDialog {
383388
return Ok(None);
384389
}
385390
info!(id=%self.id(), "sending re-invite request, body: \n{:?}", body);
386-
let request =
387-
self.inner
388-
.make_request(rsip::Method::Invite, None, None, None, headers, body)?;
391+
let request = self.inner.make_request_with_vias(
392+
rsip::Method::Invite,
393+
None,
394+
self.inner.build_vias_from_request()?,
395+
headers,
396+
body,
397+
)?;
389398
let resp = self.inner.do_request(request.clone()).await;
390399
match resp {
391400
Ok(Some(ref resp)) => {
@@ -436,9 +445,13 @@ impl ServerInviteDialog {
436445
return Ok(None);
437446
}
438447
info!(id=%self.id(), "sending update request, body: \n{:?}", body);
439-
let request =
440-
self.inner
441-
.make_request(rsip::Method::Update, None, None, None, headers, body)?;
448+
let request = self.inner.make_request_with_vias(
449+
rsip::Method::Update,
450+
None,
451+
self.inner.build_vias_from_request()?,
452+
headers,
453+
body,
454+
)?;
442455
self.inner.do_request(request.clone()).await
443456
}
444457

@@ -483,9 +496,13 @@ impl ServerInviteDialog {
483496
return Ok(None);
484497
}
485498
info!(id=%self.id(), "sending info request, body: \n{:?}", body);
486-
let request =
487-
self.inner
488-
.make_request(rsip::Method::Info, None, None, None, headers, body)?;
499+
let request = self.inner.make_request_with_vias(
500+
rsip::Method::Info,
501+
None,
502+
self.inner.build_vias_from_request()?,
503+
headers,
504+
body,
505+
)?;
489506
self.inner.do_request(request.clone()).await
490507
}
491508

@@ -608,7 +625,7 @@ impl ServerInviteDialog {
608625

609626
async fn handle_invite(&mut self, tx: &mut Transaction) -> Result<()> {
610627
let handle_loop = async {
611-
if !self.inner.is_confirmed() {
628+
if !self.inner.is_confirmed() && matches!(tx.original.method, rsip::Method::Invite) {
612629
match self.inner.transition(DialogState::Calling(self.id())) {
613630
Ok(_) => {
614631
tx.send_trying().await.ok();

src/dialog/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
mod test_client_dialog;
22
mod test_dialog_layer;
33
mod test_dialog_states;
4+
mod test_server_dialog;

src/dialog/tests/test_dialog_states.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ use tokio::sync::mpsc::unbounded_channel;
1414
use tokio_util::sync::CancellationToken;
1515

1616
/// Test helper to create a mock INVITE request
17-
fn create_invite_request(from_tag: &str, to_tag: &str, call_id: &str) -> Request {
17+
pub(super) fn create_invite_request(from_tag: &str, to_tag: &str, call_id: &str) -> Request {
1818
Request {
1919
method: rsip::Method::Invite,
2020
uri: rsip::Uri::try_from("sip:[email protected]:5060").unwrap(),
2121
headers: vec![
22-
Via::new("SIP/2.0/UDP alice.example.com:5060;branch=z9hG4bKnashds").into(),
22+
Via::new("SIP/2.0/UDP alice.example.com:5060;branch=z9hG4bKnashds;received=172.0.0.1")
23+
.into(),
2324
CSeq::new("1 INVITE").into(),
2425
From::new(&format!("Alice <sip:[email protected]>;tag={}", from_tag)).into(),
2526
To::new(&format!("Bob <sip:[email protected]>;tag={}", to_tag)).into(),
@@ -57,7 +58,8 @@ fn create_response(status: StatusCode, from_tag: &str, to_tag: &str, call_id: &s
5758
}
5859
}
5960

60-
async fn create_test_endpoint() -> crate::Result<crate::transaction::endpoint::Endpoint> {
61+
pub(super) async fn create_test_endpoint() -> crate::Result<crate::transaction::endpoint::Endpoint>
62+
{
6163
let token = CancellationToken::new();
6264
let tl = TransportLayer::new(token.child_token());
6365
let endpoint = EndpointBuilder::new()
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use rsip::prelude::{HeadersExt, ToTypedHeader};
2+
use tokio::sync::mpsc::unbounded_channel;
3+
4+
use crate::{
5+
dialog::{
6+
dialog::DialogInner,
7+
tests::test_dialog_states::{create_invite_request, create_test_endpoint},
8+
DialogId,
9+
},
10+
transaction::key::TransactionRole,
11+
};
12+
13+
#[tokio::test]
14+
async fn test_dialog_make_request() -> crate::Result<()> {
15+
// Create dialog ID
16+
let dialog_id = DialogId {
17+
call_id: "test-call-id-123".to_string(),
18+
from_tag: "alice-tag-456".to_string(),
19+
to_tag: "bob-tag-789".to_string(),
20+
};
21+
22+
let endpoint = create_test_endpoint().await?;
23+
let (tu_sender, _tu_receiver) = unbounded_channel();
24+
let (state_sender, _state_receiver) = unbounded_channel();
25+
// Create INVITE request
26+
let invite_req = create_invite_request("alice-tag-456", "", "test-call-id-123");
27+
// Create dialog inner
28+
let dialog_inner = DialogInner::new(
29+
TransactionRole::Client,
30+
dialog_id.clone(),
31+
invite_req.clone(),
32+
endpoint.inner.clone(),
33+
state_sender,
34+
None,
35+
Some(rsip::Uri::try_from("sip:[email protected]:5060")?),
36+
tu_sender,
37+
)
38+
.expect("Failed to create dialog inner");
39+
40+
let bye = dialog_inner
41+
.make_request_with_vias(
42+
rsip::Method::Bye,
43+
None,
44+
dialog_inner
45+
.build_vias_from_request()
46+
.expect("Failed to build vias"),
47+
None,
48+
None,
49+
)
50+
.expect("Failed to make request");
51+
assert_eq!(bye.method, rsip::Method::Bye);
52+
53+
assert_eq!(
54+
bye.via_header()
55+
.expect("not via header")
56+
.typed()?
57+
.received()?,
58+
"172.0.0.1".parse().ok()
59+
);
60+
assert!(
61+
bye.via_header().expect("not via header").typed()?.branch()
62+
!= invite_req
63+
.via_header()
64+
.expect("not via header")
65+
.typed()?
66+
.branch()
67+
);
68+
Ok(())
69+
}

0 commit comments

Comments
 (0)