Skip to main content

sipx_sip/transaction/
server.rs

1//! Server transactions: RFC 3261 §17.2, amended by RFC 6026.
2
3use std::time::Duration;
4
5use crate::message::{Message, Method, Request, Response, StatusCode};
6use crate::transaction::timing::{Timer, Timers};
7use crate::transaction::{Output, Reason, Reliability, TuEvent};
8
9/// The state of a server transaction.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ServerState {
12    /// Non-INVITE: the request is with the transaction user and nothing has been sent.
13    Trying,
14    /// A provisional response has been sent, or an INVITE is being processed.
15    Proceeding,
16    /// A final response has been sent; waiting out request retransmissions, or an ACK.
17    Completed,
18    /// INVITE: the ACK arrived; waiting out its retransmissions.
19    Confirmed,
20    /// RFC 6026: a 2xx was sent and the ACK belongs to the transaction user.
21    Accepted,
22    /// Over.
23    Terminated,
24}
25
26impl ServerState {
27    /// Whether the transaction has finished and can be dropped.
28    #[must_use]
29    pub fn is_terminated(self) -> bool {
30        matches!(self, Self::Terminated)
31    }
32}
33
34/// A server transaction.
35#[derive(Debug)]
36pub struct ServerTransaction {
37    request: Request,
38    is_invite: bool,
39    state: ServerState,
40    reliability: Reliability,
41    timers: Timers,
42    /// The last response sent, for answering request retransmissions.
43    last_response: Option<Response>,
44    /// The current Timer G interval.
45    interval: Duration,
46}
47
48impl ServerTransaction {
49    /// Start a server transaction from a received request.
50    ///
51    /// The request is handed to the transaction user exactly once. Every later copy of it is
52    /// answered by the transaction itself — which is the whole point of the layer, because a
53    /// UDP peer that misses one response resends the request every T1, and an application
54    /// that saw each copy would process the same REGISTER seven times.
55    #[must_use]
56    pub fn new(request: Request, reliability: Reliability, timers: Timers) -> (Self, Vec<Output>) {
57        let is_invite = request.method == Method::Invite;
58        let tx = Self {
59            request: request.clone(),
60            is_invite,
61            state: if is_invite {
62                ServerState::Proceeding
63            } else {
64                ServerState::Trying
65            },
66            reliability,
67            timers,
68            last_response: None,
69            interval: timers.t1,
70        };
71
72        let mut out = vec![Output::to_tu(TuEvent::Request(Box::new(request)))];
73        if is_invite {
74            // RFC 3261 §17.2.1: if the TU has not answered within 200 ms, the transaction
75            // sends 100 Trying itself, so the far end stops retransmitting while the
76            // application thinks.
77            out.push(Output::SetTimer {
78                timer: Timer::Trying100,
79                after: timers.trying_100(),
80            });
81        }
82        (tx, out)
83    }
84
85    /// The current state.
86    #[must_use]
87    pub fn state(&self) -> ServerState {
88        self.state
89    }
90
91    /// The request that created this transaction.
92    #[must_use]
93    pub fn request(&self) -> &Request {
94        &self.request
95    }
96
97    /// Feed in a request that matched this transaction.
98    ///
99    /// This is either a retransmission of the original or, for an INVITE, an ACK.
100    pub fn on_request(&mut self, request: &Request) -> Vec<Output> {
101        if request.method == Method::Ack {
102            return self.on_ack(request);
103        }
104        match self.state {
105            ServerState::Proceeding | ServerState::Completed => self
106                .last_response
107                .as_ref()
108                .map(|r| Output::send(Message::Response(r.clone())))
109                .into_iter()
110                .collect(),
111            // Absorbed silently, for two different reasons that happen to look the same. In
112            // Trying the TU has not answered, so there is nothing to resend. In Confirmed and
113            // Accepted a repeat is exactly what the absorption timers are there to swallow.
114            // In every case the TU hears nothing, which is the point of the layer.
115            _ => Vec::new(),
116        }
117    }
118
119    fn on_ack(&mut self, ack: &Request) -> Vec<Output> {
120        match self.state {
121            ServerState::Completed => {
122                // The ACK for a non-2xx is part of this transaction and stops here.
123                self.state = ServerState::Confirmed;
124                vec![
125                    Output::ClearTimer(Timer::G),
126                    Output::ClearTimer(Timer::H),
127                    Output::SetTimer {
128                        timer: Timer::I,
129                        after: self.timers.absorb(self.reliability),
130                    },
131                ]
132            }
133            ServerState::Accepted => {
134                // RFC 6026: the ACK for a 2xx is a separate transaction, so it goes up rather
135                // than being swallowed. The transaction stays alive on Timer L only so that a
136                // retransmitted 2xx does not create a second one.
137                vec![Output::to_tu(TuEvent::Ack(Box::new(ack.clone())))]
138            }
139            // In Confirmed, retransmitted ACKs are exactly what Timer I is absorbing.
140            _ => Vec::new(),
141        }
142    }
143
144    /// The transaction user wants to send a response.
145    pub fn on_tu_response(&mut self, response: Response) -> Vec<Output> {
146        let status = response.status;
147        match self.state {
148            ServerState::Trying | ServerState::Proceeding => {
149                let mut out = vec![Output::ClearTimer(Timer::Trying100)];
150                self.last_response = Some(response.clone());
151                out.push(Output::send(Message::Response(response)));
152
153                if status.is_provisional() {
154                    self.state = ServerState::Proceeding;
155                    return out;
156                }
157
158                if self.is_invite {
159                    if status.is_success() {
160                        self.state = ServerState::Accepted;
161                        out.push(Output::SetTimer {
162                            timer: Timer::L,
163                            after: self.timers.timeout(),
164                        });
165                    } else {
166                        self.state = ServerState::Completed;
167                        if !self.reliability.is_reliable() {
168                            self.interval = self.timers.t1;
169                            out.push(Output::SetTimer {
170                                timer: Timer::G,
171                                after: self.interval,
172                            });
173                        }
174                        out.push(Output::SetTimer {
175                            timer: Timer::H,
176                            after: self.timers.timeout(),
177                        });
178                    }
179                } else {
180                    self.state = ServerState::Completed;
181                    out.push(Output::SetTimer {
182                        timer: Timer::J,
183                        after: self.timers.timer_j(self.reliability),
184                    });
185                }
186                out
187            }
188            ServerState::Accepted if status.is_success() => {
189                // The TU retransmitting its own 2xx, which it must do until it sees an ACK.
190                self.last_response = Some(response.clone());
191                vec![Output::send(Message::Response(response))]
192            }
193            _ => Vec::new(),
194        }
195    }
196
197    /// Feed a fired timer in.
198    pub fn on_timer(&mut self, timer: Timer) -> Vec<Output> {
199        match (self.state, timer) {
200            (ServerState::Proceeding, Timer::Trying100) => {
201                // Only if the TU really has not answered. The transaction emits a ClearTimer
202                // when the TU responds, but a state machine that depends on its driver having
203                // honoured a cancellation is one race away from sending a 100 Trying after a
204                // 180 Ringing.
205                if self.last_response.is_some() {
206                    return Vec::new();
207                }
208                // The TU is still thinking. Answer 100 so the far end stops retransmitting.
209                let Some(trying) = self.build_trying() else {
210                    return Vec::new();
211                };
212                self.last_response = Some(trying.clone());
213                vec![Output::send(Message::Response(trying))]
214            }
215            (ServerState::Completed, Timer::G) => {
216                self.interval = self.timers.double_capped(self.interval);
217                let mut out = Vec::new();
218                if let Some(response) = &self.last_response {
219                    out.push(Output::send(Message::Response(response.clone())));
220                }
221                out.push(Output::SetTimer {
222                    timer: Timer::G,
223                    after: self.interval,
224                });
225                out
226            }
227            (ServerState::Completed, Timer::H) => {
228                // No ACK ever came. The far end is gone.
229                self.state = ServerState::Terminated;
230                vec![
231                    Output::to_tu(TuEvent::Timeout),
232                    Output::Terminated(Reason::Timeout),
233                ]
234            }
235            (ServerState::Completed, Timer::J)
236            | (ServerState::Confirmed, Timer::I)
237            | (ServerState::Accepted, Timer::L) => {
238                self.state = ServerState::Terminated;
239                vec![Output::Terminated(Reason::Completed)]
240            }
241            _ => Vec::new(),
242        }
243    }
244
245    /// The transport could not deliver a response.
246    pub fn on_transport_error(&mut self) -> Vec<Output> {
247        if self.state.is_terminated() {
248            return Vec::new();
249        }
250        self.state = ServerState::Terminated;
251        vec![
252            Output::to_tu(TuEvent::TransportError),
253            Output::Terminated(Reason::TransportError),
254        ]
255    }
256
257    fn build_trying(&self) -> Option<Response> {
258        let status = StatusCode::new(100)?;
259        crate::build::ResponseBuilder::to_request(&self.request, status, "Trying")
260            .ok()
261            .map(crate::build::ResponseBuilder::build)
262    }
263}