Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/dialog/authenticate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub struct Credential {
/// // This is typically called automatically by dialog methods
/// let new_tx = handle_client_authenticate(
/// new_seq,
/// original_tx,
/// &original_tx,
/// auth_challenge_response,
/// &credential
/// ).await?;
Expand Down Expand Up @@ -159,7 +159,7 @@ pub struct Credential {
/// StatusCode::Unauthorized | StatusCode::ProxyAuthenticationRequired => {
/// // Handle authentication challenge
/// let auth_tx = handle_client_authenticate(
/// new_seq, tx, resp, &credential
/// new_seq, &tx, resp, &credential
/// ).await?;
///
/// // Send authenticated request
Expand All @@ -186,7 +186,7 @@ pub struct Credential {
/// This function handles SIP authentication challenges and creates authenticated requests.
pub async fn handle_client_authenticate(
new_seq: u32,
tx: Transaction,
tx: &Transaction,
resp: Response,
cred: &Credential,
) -> Result<Transaction> {
Expand Down
4 changes: 2 additions & 2 deletions src/dialog/client_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ impl ClientInviteDialog {

pub async fn process_invite(
&self,
mut tx: Transaction,
tx: &mut Transaction,
) -> Result<(DialogId, Option<Response>)> {
self.inner.transition(DialogState::Calling(self.id()))?;
let mut auth_sent = false;
Expand Down Expand Up @@ -662,7 +662,7 @@ impl ClientInviteDialog {
}
auth_sent = true;
if let Some(credential) = &self.inner.credential {
tx = handle_client_authenticate(
*tx = handle_client_authenticate(
self.inner.increment_local_seq(),
tx,
resp,
Expand Down
4 changes: 2 additions & 2 deletions src/dialog/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ impl DialogInner {
auth_sent = true;
if let Some(cred) = &self.credential {
let new_seq = self.increment_local_seq();
tx = handle_client_authenticate(new_seq, tx, resp, cred).await?;
tx = handle_client_authenticate(new_seq, &tx, resp, cred).await?;
tx.send().await?;
continue;
} else {
Expand Down Expand Up @@ -921,7 +921,7 @@ impl DialogInner {
rsip::Method::Cancel => self.get_local_seq(),
_ => self.increment_local_seq(),
};
tx = handle_client_authenticate(new_seq, tx, resp, cred).await?;
tx = handle_client_authenticate(new_seq, &tx, resp, cred).await?;
tx.send().await?;
continue;
} else {
Expand Down
60 changes: 57 additions & 3 deletions src/dialog/invitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use super::{
dialog_layer::DialogLayer,
};
use crate::{
dialog::{dialog::Dialog, dialog_layer::DialogLayerInnerRef, DialogId},
dialog::{
dialog::{Dialog, DialogState, TerminatedReason},
dialog_layer::DialogLayerInnerRef,
DialogId,
},
transaction::{
key::{TransactionKey, TransactionRole},
make_tag,
Expand All @@ -17,7 +21,7 @@ use crate::{
use futures::FutureExt;
use rsip::{
prelude::{HeadersExt, ToTypedHeader},
Request, Response,
Request, Response, SipMessage, StatusCodeKind,
};
use std::sync::Arc;
use tracing::{debug, info, warn};
Expand Down Expand Up @@ -171,6 +175,7 @@ impl Drop for DialogGuard {
pub(super) struct DialogGuardForUnconfirmed<'a> {
pub dialog_layer_inner: &'a DialogLayerInnerRef,
pub id: &'a DialogId,
invite_tx: Option<Transaction>,
}

impl<'a> Drop for DialogGuardForUnconfirmed<'a> {
Expand All @@ -180,7 +185,50 @@ impl<'a> Drop for DialogGuardForUnconfirmed<'a> {
Ok(mut dialogs) => match dialogs.remove(&self.id.to_string()) {
Some(dlg) => {
info!(%self.id, "unconfirmed dialog dropped, cancelling it");
let invite_tx = self.invite_tx.take();
let _ = tokio::spawn(async move {
if let Dialog::ClientInvite(ref client_dialog) = dlg {
if client_dialog.inner.can_cancel() {
if let Err(e) = client_dialog.cancel().await {
warn!(id = %client_dialog.id(), "dialog cancel failed: {}", e);
return;
}

if let Some(mut invite_tx) = invite_tx {
let duration = tokio::time::Duration::from_secs(2);
let timeout = tokio::time::sleep(duration);
tokio::pin!(timeout);
loop {
tokio::select! {
_ = &mut timeout => break,
msg = invite_tx.receive() => {
if let Some(msg) = msg{
if let SipMessage::Response(resp) = msg {
if resp.status_code.kind() != StatusCodeKind::Provisional {
debug!(
id = %client_dialog.id(),
status = %resp.status_code,
"received final response"
);
break;
}
}
}else{
break;
}
}
}
}
}
let _ = client_dialog.inner.transition(DialogState::Terminated(
client_dialog.id(),
TerminatedReason::UacCancel,
));
tracing::info!(id = %client_dialog.id(), "dialog terminated");
return;
}
}

if let Err(e) = dlg.hangup().await {
info!(id=%dlg.id(), "failed to hangup unconfirmed dialog: {}", e);
}
Expand Down Expand Up @@ -426,11 +474,17 @@ impl DialogLayer {
.ok();

info!(%id, "client invite dialog created");
let _guard = DialogGuardForUnconfirmed {
let mut guard = DialogGuardForUnconfirmed {
dialog_layer_inner: &self.inner,
id: &id,
invite_tx: Some(tx),
};

let tx = guard
.invite_tx
.as_mut()
.expect("transcation should be avaible");

let r = dialog.process_invite(tx).boxed().await;
self.inner
.dialogs
Expand Down
2 changes: 1 addition & 1 deletion src/dialog/registration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ impl Registration {

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

tx.send().await?;
auth_sent = true;
Expand Down
2 changes: 1 addition & 1 deletion src/dialog/tests/test_authenticate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ async fn test_authenticate_via_header_branch_update() -> crate::Result<()> {
};

// Call handle_client_authenticate
let new_tx = handle_client_authenticate(2, tx, resp, &cred).await?;
let new_tx = handle_client_authenticate(2, &tx, resp, &cred).await?;

// Verify the new request has updated Via header
let new_via = new_tx
Expand Down
Loading