Skip to content

Commit e7fcf3a

Browse files
committed
bump version to 0.4.4 and refactor request handling in dialog and subscription modules
1 parent 7d66ad2 commit e7fcf3a

8 files changed

Lines changed: 148 additions & 105 deletions

File tree

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.4.3"
3+
version = "0.4.4"
44
edition = "2021"
55
description = "SIP Stack Rust library for building SIP applications"
66
license = "MIT"

src/dialog/dialog.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::{
1111
transaction::{
1212
endpoint::EndpointInnerRef,
1313
key::{TransactionKey, TransactionRole},
14-
make_via_branch,
1514
transaction::{Transaction, TransactionEventSender},
1615
},
1716
transport::SipAddr,
@@ -22,7 +21,7 @@ use rsip::{
2221
headers::Route,
2322
message::HasHeaders,
2423
prelude::{HeadersExt, ToTypedHeader, UntypedHeader},
25-
typed::{CSeq, Contact, Via},
24+
typed::{CSeq, Contact},
2625
Header, Method, Param, Request, Response, SipMessage, StatusCode, StatusCodeKind,
2726
};
2827
use std::sync::{
@@ -696,30 +695,6 @@ impl DialogInner {
696695
*self.route_set.lock().unwrap() = new_route_set;
697696
}
698697

699-
pub(super) fn build_vias_from_request(&self) -> Result<Vec<Via>> {
700-
let mut vias = vec![];
701-
let initial_request = self
702-
.initial_request
703-
.lock()
704-
.expect("build vias from request poisoned mutex");
705-
for header in initial_request.headers.iter() {
706-
if let Header::Via(via) = header {
707-
if let Ok(mut typed_via) = via.typed() {
708-
for param in typed_via.params.iter_mut() {
709-
if let Param::Branch(_) = param {
710-
*param = make_via_branch();
711-
}
712-
}
713-
vias.push(typed_via);
714-
return Ok(vias);
715-
}
716-
}
717-
}
718-
let via = self.endpoint_inner.get_via(None, None)?;
719-
vias.push(via);
720-
Ok(vias)
721-
}
722-
723698
pub(super) fn make_request_with_vias(
724699
&self,
725700
method: rsip::Method,

src/dialog/publication.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,9 @@ impl ServerPublicationDialog {
200200
if !self.inner.is_confirmed() {
201201
return Ok(None);
202202
}
203-
let request = self.inner.make_request_with_vias(
204-
method,
205-
None,
206-
self.inner.build_vias_from_request()?,
207-
headers,
208-
body,
209-
)?;
203+
let request = self
204+
.inner
205+
.make_request(method, None, None, None, headers, body)?;
210206
self.inner.do_request(request).await
211207
}
212208

src/dialog/server_dialog.rs

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -355,21 +355,13 @@ impl ServerInviteDialog {
355355
return Ok(());
356356
}
357357

358-
let request = self.inner.make_request_with_vias(
359-
rsip::Method::Bye,
360-
None,
361-
self.inner.build_vias_from_request()?,
362-
headers,
363-
None,
364-
)?;
365-
366-
if let Err(e) = self.inner.do_request(request).await {
367-
debug!(id = %self.id(), error = %e, "bye error");
368-
}
358+
let request =
359+
self.inner
360+
.make_request(rsip::Method::Bye, None, None, None, headers, None)?;
369361

370362
self.inner
371363
.transition(DialogState::Terminated(self.id(), TerminatedReason::UasBye))?;
372-
Ok(())
364+
self.inner.do_request(request).await.map(|_| ())
373365
}
374366

375367
/// Send a BYE request with a SIP `Reason` header.
@@ -427,13 +419,9 @@ impl ServerInviteDialog {
427419
return Ok(None);
428420
}
429421
debug!(id = %self.id(), ?body, "sending re-invite request");
430-
let request = self.inner.make_request_with_vias(
431-
rsip::Method::Invite,
432-
None,
433-
self.inner.build_vias_from_request()?,
434-
headers,
435-
body,
436-
)?;
422+
let request =
423+
self.inner
424+
.make_request(rsip::Method::Invite, None, None, None, headers, body)?;
437425
let resp = self.inner.do_request(request.clone()).await;
438426
match resp {
439427
Ok(Some(ref resp)) => {
@@ -485,13 +473,9 @@ impl ServerInviteDialog {
485473
return Ok(None);
486474
}
487475
debug!(id = %self.id(), ?body, "sending update request");
488-
let request = self.inner.make_request_with_vias(
489-
rsip::Method::Update,
490-
None,
491-
self.inner.build_vias_from_request()?,
492-
headers,
493-
body,
494-
)?;
476+
let request =
477+
self.inner
478+
.make_request(rsip::Method::Update, None, None, None, headers, body)?;
495479
self.inner.do_request(request.clone()).await
496480
}
497481

@@ -536,13 +520,9 @@ impl ServerInviteDialog {
536520
return Ok(None);
537521
}
538522
debug!(id = %self.id(), ?body, "sending info request");
539-
let request = self.inner.make_request_with_vias(
540-
rsip::Method::Info,
541-
None,
542-
self.inner.build_vias_from_request()?,
543-
headers,
544-
body,
545-
)?;
523+
let request =
524+
self.inner
525+
.make_request(rsip::Method::Info, None, None, None, headers, body)?;
546526
self.inner.do_request(request.clone()).await
547527
}
548528

@@ -557,13 +537,9 @@ impl ServerInviteDialog {
557537
return Ok(None);
558538
}
559539
debug!(id = %self.id(), %method, "sending request");
560-
let request = self.inner.make_request_with_vias(
561-
method,
562-
None,
563-
self.inner.build_vias_from_request()?,
564-
headers,
565-
body,
566-
)?;
540+
let request = self
541+
.inner
542+
.make_request(method, None, None, None, headers, body)?;
567543
self.inner.do_request(request).await
568544
}
569545

src/dialog/subscription.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,9 @@ impl ServerSubscriptionDialog {
151151
if !self.inner.is_confirmed() {
152152
return Ok(None);
153153
}
154-
let request = self.inner.make_request_with_vias(
155-
Method::Notify,
156-
None,
157-
self.inner.build_vias_from_request()?,
158-
headers,
159-
body,
160-
)?;
154+
let request =
155+
self.inner
156+
.make_request(rsip::Method::Notify, None, None, None, headers, body)?;
161157
self.inner.do_request(request).await
162158
}
163159

@@ -176,13 +172,9 @@ impl ServerSubscriptionDialog {
176172
if !self.inner.is_confirmed() {
177173
return Ok(None);
178174
}
179-
let request = self.inner.make_request_with_vias(
180-
method,
181-
None,
182-
self.inner.build_vias_from_request()?,
183-
headers,
184-
body,
185-
)?;
175+
let request = self
176+
.inner
177+
.make_request(method, None, None, None, headers, body)?;
186178
self.inner.do_request(request).await
187179
}
188180

src/dialog/tests/test_dialog_states.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,23 @@ fn create_response(status: StatusCode, from_tag: &str, to_tag: &str, call_id: &s
6161
pub async fn create_test_endpoint() -> crate::Result<crate::transaction::endpoint::Endpoint> {
6262
let token = CancellationToken::new();
6363
let tl = TransportLayer::new(token.child_token());
64+
65+
// Create a dummy UDP connection for testing using tokio's UdpSocket directly
66+
let tokio_socket = tokio::net::UdpSocket::bind("127.0.0.1:0").await?;
67+
let local_addr = tokio_socket.local_addr()?;
68+
69+
let udp_conn = crate::transport::udp::UdpConnection::attach(
70+
crate::transport::udp::UdpInner {
71+
conn: tokio_socket,
72+
addr: crate::transport::SipAddr::from(local_addr),
73+
},
74+
None,
75+
Some(token.child_token()),
76+
)
77+
.await;
78+
79+
tl.inner.add_listener(udp_conn.into());
80+
6481
let endpoint = EndpointBuilder::new()
6582
.with_user_agent("rsipstack-test")
6683
.with_transport_layer(tl)

src/dialog/tests/test_server_dialog.rs

Lines changed: 103 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,16 @@ async fn test_dialog_make_request() -> crate::Result<()> {
4242
.expect("Failed to create dialog inner");
4343

4444
let bye = dialog_inner
45-
.make_request_with_vias(
46-
rsip::Method::Bye,
47-
None,
48-
dialog_inner
49-
.build_vias_from_request()
50-
.expect("Failed to build vias"),
51-
None,
52-
None,
53-
)
45+
.make_request(rsip::Method::Bye, None, None, None, None, None)
5446
.expect("Failed to make request");
5547
assert_eq!(bye.method, rsip::Method::Bye);
5648

57-
assert_eq!(
58-
bye.via_header()
59-
.expect("not via header")
60-
.typed()?
61-
.received()?,
62-
"172.0.0.1".parse().ok()
63-
);
49+
assert!(bye
50+
.via_header()
51+
.expect("not via header")
52+
.typed()?
53+
.received()?
54+
.is_none());
6455
assert!(
6556
bye.via_header().expect("not via header").typed()?.branch()
6657
!= invite_req
@@ -159,3 +150,99 @@ async fn test_accept_with_public_contact_preserves_contact_header() -> crate::Re
159150

160151
Ok(())
161152
}
153+
154+
#[tokio::test]
155+
async fn test_server_dialog_bye_via() -> crate::Result<()> {
156+
let dialog_id = DialogId {
157+
call_id: "server-bye-test".to_string(),
158+
local_tag: "bob-tag".to_string(),
159+
remote_tag: "alice-tag".to_string(),
160+
};
161+
162+
let endpoint = create_test_endpoint().await?;
163+
let (tu_sender, _tu_receiver) = unbounded_channel();
164+
let (state_sender, _state_receiver) = unbounded_channel();
165+
166+
// Create an INVITE request FROM alice (remote)
167+
// This invite has Via: SIP/2.0/UDP alice.example.com:5060;branch=...;received=172.0.0.1
168+
let invite_req = create_invite_request(&dialog_id.remote_tag, "", &dialog_id.call_id);
169+
170+
let dialog_inner = DialogInner::new(
171+
TransactionRole::Server,
172+
dialog_id.clone(),
173+
invite_req.clone(),
174+
endpoint.inner.clone(),
175+
state_sender,
176+
None,
177+
None,
178+
tu_sender,
179+
)
180+
.expect("Failed to create dialog inner");
181+
182+
let server_dialog = ServerInviteDialog {
183+
inner: Arc::new(dialog_inner),
184+
};
185+
186+
// Generate BYE request
187+
let bye_req =
188+
server_dialog
189+
.inner
190+
.make_request(rsip::Method::Bye, None, None, None, None, None)?;
191+
192+
assert_eq!(bye_req.method, rsip::Method::Bye);
193+
let via = bye_req.via_header().expect("no via").typed()?;
194+
195+
// The Via in BYE should NOT have received=172.0.0.1 (which was in the incoming INVITE)
196+
assert!(via.received().expect("failed to get received").is_none());
197+
198+
// The host should be our local address (127.0.0.1) and NOT alice.example.com
199+
assert_eq!(via.uri.host_with_port.host.to_string(), "127.0.0.1");
200+
201+
Ok(())
202+
}
203+
204+
#[tokio::test]
205+
async fn test_server_dialog_reinvite_via() -> crate::Result<()> {
206+
let dialog_id = DialogId {
207+
call_id: "server-reinvite-test".to_string(),
208+
local_tag: "bob-tag".to_string(),
209+
remote_tag: "alice-tag".to_string(),
210+
};
211+
212+
let endpoint = create_test_endpoint().await?;
213+
let (tu_sender, _tu_receiver) = unbounded_channel();
214+
let (state_sender, _state_receiver) = unbounded_channel();
215+
216+
let invite_req = create_invite_request(&dialog_id.remote_tag, "", &dialog_id.call_id);
217+
218+
let dialog_inner = DialogInner::new(
219+
TransactionRole::Server,
220+
dialog_id.clone(),
221+
invite_req.clone(),
222+
endpoint.inner.clone(),
223+
state_sender,
224+
None,
225+
None,
226+
tu_sender,
227+
)
228+
.expect("Failed to create dialog inner");
229+
230+
let server_dialog = ServerInviteDialog {
231+
inner: Arc::new(dialog_inner),
232+
};
233+
234+
// Generate re-INVITE request
235+
let reinvite_req =
236+
server_dialog
237+
.inner
238+
.make_request(rsip::Method::Invite, None, None, None, None, None)?;
239+
240+
assert_eq!(reinvite_req.method, rsip::Method::Invite);
241+
let via = reinvite_req.via_header().expect("no via").typed()?;
242+
243+
// Should not have mirrored the "received" param
244+
assert!(via.received().unwrap().is_none());
245+
assert_eq!(via.uri.host_with_port.host.to_string(), "127.0.0.1");
246+
247+
Ok(())
248+
}

src/transport/transport_layer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl TransportLayerInner {
260260
}
261261
}
262262

263-
pub(super) fn add_listener(&self, connection: SipConnection) {
263+
pub fn add_listener(&self, connection: SipConnection) {
264264
match self.listens.write() {
265265
Ok(mut listens) => {
266266
listens.push(connection);

0 commit comments

Comments
 (0)