1 /*
2 * This file is part of the Sofia-SIP package
3 *
4 * Copyright (C) 2005 Nokia Corporation.
5 *
6 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25 /**@CFILE nta.c
26 * @brief Sofia SIP Transaction API implementation
27 *
28 * This source file has been divided into sections as follows:
29 * 1) agent
30 * 2) tport handling
31 * 3) dispatching messages received from network
32 * 4) message creation and message utility functions
33 * 5) stateless operation
34 * 6) dialogs (legs)
35 * 7) server transactions (incoming)
36 * 8) client transactions (outgoing)
37 * 9) resolving URLs for client transactions
38 * 10) 100rel reliable responses (reliable)
39 * 11) SigComp handling and public transport interface
40 *
41 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
42 *
43 * @date Created: Tue Jun 13 02:57:51 2000 ppessi
44 *
45 * @sa
46 * @RFC3261, @RFC4320
47 */
48
49 #include "config.h"
50 #ifdef HAVE_ZLIB_COMPRESS
51 #include <zlib.h>
52 #endif
53 #include <sofia-sip/su_string.h>
54
55 /** @internal SU message argument structure type */
56 #define SU_MSG_ARG_T union sm_arg_u
57 /** @internal SU timer argument pointer type */
58 #define SU_TIMER_ARG_T struct nta_agent_s
59
60 #include <sofia-sip/su_alloc.h>
61 #include <sofia-sip/su.h>
62 #include <sofia-sip/su_time.h>
63 #include <sofia-sip/su_wait.h>
64 #include <sofia-sip/su_tagarg.h>
65
66 #include <sofia-sip/base64.h>
67 #include <sofia-sip/su_uniqueid.h>
68
69 #include <sofia-sip/sip.h>
70 #include <sofia-sip/sip_header.h>
71 #include <sofia-sip/sip_util.h>
72 #include <sofia-sip/sip_status.h>
73
74 #include <sofia-sip/hostdomain.h>
75 #include <sofia-sip/url_tag.h>
76
77 #include <sofia-sip/msg_addr.h>
78 #include <sofia-sip/msg_parser.h>
79 #include <sofia-sip/htable.h>
80
81 /* Resolver context type */
82 #define SRES_CONTEXT_T nta_outgoing_t
83
84 /* We are customer of tport_t */
85 #define TP_AGENT_T nta_agent_t
86 #define TP_MAGIC_T sip_via_t
87 #define TP_CLIENT_T nta_outgoing_t
88
89 #include "nta_internal.h"
90
91 #include <stddef.h>
92 #include <stdlib.h>
93 #include <stdio.h>
94 #include <stdarg.h>
95 #include <assert.h>
96 #include <limits.h>
97 #include <errno.h>
98
99 /* From AM_INIT/AC_INIT in our "config.h" */
100 char const nta_version[] = PACKAGE_VERSION;
101
102 #if HAVE_FUNC
103 #elif HAVE_FUNCTION
104 #define __func__ __FUNCTION__
105 #else
106 static char const __func__[] = "nta";
107 #endif
108
109 #ifndef _MSC_VER
110 #define NONE ((void *)-1)
111 #else
112 #define NONE ((void *)(INT_PTR)-1)
113 #endif
114 /* ------------------------------------------------------------------------- */
115
116 /** Resolving order */
117 enum nta_res_order_e
118 {
119 nta_res_ip6_ip4,
120 nta_res_ip4_ip6,
121 nta_res_ip6_only,
122 nta_res_ip4_only
123 };
124
125 HTABLE_DECLARE_WITH(leg_htable, lht, nta_leg_t, size_t, hash_value_t);
126 HTABLE_DECLARE_WITH(outgoing_htable, oht, nta_outgoing_t, size_t, hash_value_t);
127 HTABLE_DECLARE_WITH(incoming_htable, iht, nta_incoming_t, size_t, hash_value_t);
128
129 typedef struct outgoing_queue_t {
130 nta_outgoing_t **q_tail;
131 nta_outgoing_t *q_head;
132 size_t q_length;
133 unsigned q_timeout;
134 } outgoing_queue_t;
135
136 typedef struct incoming_queue_t {
137 nta_incoming_t **q_tail;
138 nta_incoming_t *q_head;
139 size_t q_length;
140 unsigned q_timeout;
141 } incoming_queue_t;
142
143 struct nta_agent_s
144 {
145 su_home_t sa_home[1];
146 su_root_t *sa_root;
147 su_timer_t *sa_timer;
148 nta_agent_magic_t *sa_magic;
149 nta_message_f *sa_callback;
150
151 nta_update_magic_t *sa_update_magic;
152 nta_update_tport_f *sa_update_tport;
153
154 nta_error_magic_t *sa_error_magic;
155 nta_error_tport_f *sa_error_tport;
156
157 uint32_t sa_next; /**< Timestamp for next agent_timer. */
158
159 msg_mclass_t const *sa_mclass;
160 uint32_t sa_flags; /**< SIP message flags */
161 unsigned sa_preload; /**< Memory preload for SIP messages. */
162
163 tport_t *sa_tports;
164 sip_contact_t *sa_contact;
165 sip_via_t *sa_vias; /**< @Via headers for all transports */
166 sip_via_t *sa_public_vias; /**< @Vias for public transports */
167 sip_contact_t *sa_aliases;/**< List of aliases for agent */
168
169 uint64_t sa_branch; /**< Generator for branch parameters */
170 uint64_t sa_tags; /**< Generator for tag parameters */
171
172 #if HAVE_SOFIA_SRESOLV
173 sres_resolver_t *sa_resolver; /**< DNS resolver */
174 enum nta_res_order_e sa_res_order; /** Resolving order (AAAA/A) */
175 #endif
176
177 url_t *sa_default_proxy; /**< Default outbound proxy */
178 unsigned sa_bad_req_mask; /**< Request error mask */
179 unsigned sa_bad_resp_mask; /**< Response error mask */
180 usize_t sa_maxsize; /**< Maximum size of incoming messages */
181 usize_t sa_max_proceeding; /**< Maximum size of proceeding queue */
182
183 unsigned sa_udp_mtu; /**< Maximum size of outgoing UDP requests */
184
185 unsigned sa_t1; /**< SIP T1 - initial retransmit interval (500 ms) */
186 unsigned sa_t2; /**< SIP T2 - maximum retransmit interval (4000 ms) */
187 unsigned sa_t4; /**< SIP T4 - clear message time (5000 ms) */
188
189
190 unsigned sa_t1x64; /**< SIP T1X64 - transaction lifetime (32 s) */
191
192 unsigned sa_progress; /**< Progress timer.
193 Interval between retransmitting
194 provisional responses. */
195
196 unsigned sa_timer_c; /**< SIP timer C.
197 Maximum interval between receiving
198 provisional responses. */
199
200 unsigned sa_graylist; /**< Graylisting period */
201 unsigned sa_blacklist; /**< Blacklisting period */
202
203 unsigned sa_drop_prob : 10; /**< NTA is used to test packet drop */
204 unsigned sa_is_a_uas : 1; /**< NTA is acting as an User Agent server */
205 unsigned sa_is_stateless : 1; /**< Process requests statelessly
206 * unless they match existing dialog.
207 */
208 unsigned sa_user_via:1; /**< Let application provide @Via headers */
209 unsigned sa_extra_100:1; /**< Allow NTA to return "100 Trying" response
210 * even if application has not responded.
211 */
212 unsigned sa_pass_100:1; /**< Pass the "100 Trying"
213 * provisional responses to the application
214 */
215 unsigned sa_timeout_408:1; /**< A "408 Request Timeout" message
216 * is generated when outgoing request expires.
217 */
218 unsigned sa_pass_408:1; /**< A "408 Request Timeout" responses
219 * are passed to client.
220 */
221 unsigned sa_merge_482 : 1; /**< A "482 Request Merged" response is returned
222 * to merged requests.
223 */
224 unsigned sa_cancel_2543 : 1; /**< Send a CANCEL to an INVITE without
225 * waiting for an provisional response.
226 */
227 unsigned sa_cancel_487 : 1; /**< Return 487 response automatically when
228 * a CANCEL is received.
229 */
230
231 unsigned sa_invite_100rel:1; /**< Include 100rel in INVITE requests. */
232 unsigned sa_timestamp : 1; /**< Insert @Timestamp in requests. */
233
234 unsigned sa_tport_ip4 : 1; /**< Transports support IPv4. */
235 unsigned sa_tport_ip6 : 1; /**< Transports support IPv6. */
236 unsigned sa_tport_udp : 1; /**< Transports support UDP. */
237 unsigned sa_tport_tcp : 1; /**< Transports support TCP. */
238 unsigned sa_tport_sctp : 1; /**< Transports support SCTP. */
239 unsigned sa_tport_tls : 1; /**< Transports support TLS. */
240 unsigned sa_tport_ws : 1; /**< Transports support WS. */
241 unsigned sa_tport_wss : 1; /**< Transports support WSS. */
242
243 unsigned sa_use_naptr : 1; /**< Use NAPTR lookup */
244 unsigned sa_use_srv : 1; /**< Use SRV lookup */
245
246 unsigned sa_srv_503 : 1; /**< SRV: choice another destination on 503 RFC 3263 */
247
248 unsigned sa_tport_threadpool:1; /**< Transports use threadpool */
249
250 unsigned sa_rport:1; /**< Use rport at client */
251 unsigned sa_server_rport:2; /**< Use rport at server */
252 unsigned sa_tcp_rport:1; /**< Use rport with tcp, too */
253 unsigned sa_tls_rport:1; /**< Use rport with tls, too */
254
255 unsigned sa_auto_comp:1; /**< Automatically create compartments */
256 unsigned sa_in_timer:1; /**< Set when executing timers */
257 unsigned sa_use_timer_c:1; /**< Application has set value for timer C */
258
259 unsigned :0;
260
261 #if HAVE_SMIME
262 sm_object_t *sa_smime;
263 #else
264 void *sa_smime;
265 #endif
266
267 /** @MaxForwards */
268 sip_max_forwards_t sa_max_forwards[1];
269
270 /** Name of SigComp algorithm */
271 char const *sa_algorithm;
272 /** Options for SigComp. */
273 char const *sa_sigcomp_options;
274 char const* const *sa_sigcomp_option_list;
275 char const *sa_sigcomp_option_free;
276
277 nta_compressor_t *sa_compressor;
278
279 /* Statistics */
280 struct {
281 usize_t as_recv_msg;
282 usize_t as_recv_request;
283 usize_t as_recv_response;
284 usize_t as_bad_message;
285 usize_t as_bad_request;
286 usize_t as_bad_response;
287 usize_t as_drop_request;
288 usize_t as_drop_response;
289 usize_t as_client_tr;
290 usize_t as_server_tr;
291 usize_t as_dialog_tr;
292 usize_t as_acked_tr;
293 usize_t as_canceled_tr;
294 usize_t as_trless_request;
295 usize_t as_trless_to_tr;
296 usize_t as_trless_response;
297 usize_t as_trless_200;
298 usize_t as_merged_request;
299 usize_t as_sent_msg;
300 usize_t as_sent_request;
301 usize_t as_sent_response;
302 usize_t as_retry_request;
303 usize_t as_retry_response;
304 usize_t as_recv_retry;
305 usize_t as_tout_request;
306 usize_t as_tout_response;
307 } sa_stats[1];
308
309 /** Hash of dialogs. */
310 leg_htable_t sa_dialogs[1];
311 /** Default leg */
312 nta_leg_t *sa_default_leg;
313 /** Hash of legs without dialogs. */
314 leg_htable_t sa_defaults[1];
315 /** Hash table for outgoing transactions */
316 outgoing_htable_t sa_outgoing[1];
317 nta_outgoing_t *sa_default_outgoing;
318 /** Hash table for incoming transactions */
319 incoming_htable_t sa_incoming[1];
320 nta_incoming_t *sa_default_incoming;
321
322 /* Queues (states) for outgoing client transactions */
323 struct {
324 /** Queue for retrying client transactions */
325 nta_outgoing_t *re_list;
326 nta_outgoing_t **re_t1; /**< Special place for T1 timer */
327 size_t re_length; /**< Length of sa_out.re_list */
328
329 outgoing_queue_t delayed[1];
330 outgoing_queue_t resolving[1];
331
332 outgoing_queue_t trying[1]; /* Timer F / Timer E */
333 outgoing_queue_t completed[1]; /* Timer K */
334 outgoing_queue_t terminated[1];
335
336 /* Special queues (states) for outgoing INVITE transactions */
337 outgoing_queue_t inv_calling[1]; /* Timer B/A */
338 outgoing_queue_t inv_proceeding[1]; /* Timer C */
339 outgoing_queue_t inv_completed[1]; /* Timer D */
340
341 /* Temporary queue for transactions waiting to be freed */
342 outgoing_queue_t *free;
343 } sa_out;
344
345 /* Queues (states) for incoming server transactions */
346 struct {
347 /** Queue for retransmitting response of server transactions */
348 nta_incoming_t *re_list;
349 nta_incoming_t **re_t1; /**< Special place for T1 timer */
350 size_t re_length; /**< Length of sa_in.re_list */
351
352 incoming_queue_t proceeding[1]; /**< Request received */
353 incoming_queue_t preliminary[1]; /**< 100rel sent */
354 incoming_queue_t completed[1]; /**< Final answer sent (non-invite). */
355 incoming_queue_t inv_completed[1]; /**< Final answer sent (INVITE). */
356 incoming_queue_t inv_confirmed[1]; /**< Final answer sent, ACK recvd. */
357 incoming_queue_t terminated[1]; /**< Terminated, ready to free. */
358 incoming_queue_t final_failed[1];
359 } sa_in;
360
361 /* Special task for freeing memory */
362 su_clone_r sa_terminator;
363 };
364
365 struct nta_leg_s
366 {
367 su_home_t leg_home[1];
368 hash_value_t leg_hash;
369
370 unsigned leg_dialog : 1;
371 unsigned leg_stateless : 1; /**< Process requests statelessly */
372 #ifdef NTA_STRICT_ROUTING
373 unsigned leg_contact_set : 1;
374 #else
375 unsigned leg_loose_route : 1; /**< Topmost route in set is LR */
376 #endif
377 unsigned leg_route_set : 1; /**< Route set has been saved */
378 unsigned leg_local_is_to : 1; /**< Backwards-compatibility. */
379 unsigned leg_tagged : 1; /**< Tagged after creation.
380 *
381 * Request missing @To tag matches
382 * a tagged leg even after tagging.
383 */
384 unsigned leg_compressed:1;
385 unsigned:0;
386 nta_request_f *leg_callback;
387 nta_leg_magic_t *leg_magic;
388 nta_agent_t *leg_agent;
389
390 url_t const *leg_url; /**< Match incoming requests. */
391 char const *leg_method; /**< Match incoming requests. */
392
393 uint32_t leg_seq; /**< Sequence number for next transaction */
394 uint32_t leg_rseq; /**< Remote sequence number */
395 sip_call_id_t *leg_id; /**< Call ID */
396 sip_from_t *leg_remote; /**< Remote address (@To/@From) */
397 sip_to_t *leg_local; /**< Local address (@From/@To) */
398
399 sip_route_t *leg_route; /**< @Route for outgoing requests. */
400 sip_contact_t *leg_target; /**< Remote destination (from @Contact). */
401 };
402
403 struct nta_incoming_s
404 {
405 su_home_t *irq_home;
406 hash_value_t irq_hash;
407 nta_agent_t *irq_agent;
408 nta_ack_cancel_f *irq_callback;
409 nta_incoming_magic_t *irq_magic;
410
411 /* Timeout/state queue */
412 nta_incoming_t **irq_prev;
413 nta_incoming_t *irq_next;
414 incoming_queue_t *irq_queue;
415
416 /* Retry queue */
417 nta_incoming_t **irq_rprev;
418 nta_incoming_t *irq_rnext;
419
420 sip_method_t irq_method;
421 sip_request_t *irq_rq;
422 sip_from_t *irq_from;
423 sip_to_t *irq_to;
424 char const *irq_tag;
425 sip_cseq_t *irq_cseq;
426 sip_call_id_t *irq_call_id;
427 sip_via_t *irq_via;
428 sip_record_route_t *irq_record_route;
429 char const *irq_branch;
430
431 uint32_t irq_rseq;
432
433 sip_timestamp_t *irq_timestamp;
434 su_time_t irq_received;
435
436 uint32_t irq_timeout; /**< Timer H, I, J */
437 uint32_t irq_retry; /**< Timer G */
438 unsigned short irq_interval; /**< Next timer */
439
440 short irq_status;
441
442 unsigned irq_retries:8;
443 unsigned irq_default:1; /**< Default transaction */
444 unsigned irq_canceled:1; /**< Transaction is canceled */
445 unsigned irq_completed:1; /**< Transaction is completed */
446 unsigned irq_confirmed:1; /**< Response has been acked */
447 unsigned irq_terminated:1; /**< Transaction is terminated */
448 unsigned irq_final_failed:1; /**< Sending final response failed */
449 unsigned irq_destroyed :1; /**< Transaction is destroyed */
450 unsigned irq_in_callback:1; /**< Callback is being invoked */
451 unsigned irq_reliable_tp:1; /**< Transport is reliable */
452 unsigned irq_sigcomp_zap:1; /**< Reset SigComp */
453 unsigned irq_must_100rel:1; /**< 100rel is required */
454 unsigned irq_extra_100:1; /**< 100 Trying should be sent */
455 unsigned irq_tag_set:1; /**< Tag is not from request */
456 unsigned irq_compressed:1;
457 unsigned :0;
458
459 tp_name_t irq_tpn[1];
460 tport_t *irq_tport;
461 struct sigcomp_compartment *irq_cc;
462 msg_t *irq_request;
463 msg_t *irq_request2; /**< ACK/CANCEL */
464 msg_t *irq_response;
465
466 nta_reliable_t *irq_reliable; /**< List of reliable responses */
467 };
468
469 struct nta_reliable_s
470 {
471 nta_reliable_t *rel_next;
472 nta_incoming_t *rel_irq;
473 nta_prack_f *rel_callback;
474 nta_reliable_magic_t *rel_magic;
475 uint32_t rel_rseq;
476 unsigned short rel_status;
477 unsigned rel_pracked:1;
478 unsigned rel_precious:1;
479 msg_t *rel_response;
480 msg_t *rel_unsent;
481 };
482
483 typedef struct sipdns_resolver sipdns_resolver_t;
484
485 struct nta_outgoing_s
486 {
487 hash_value_t orq_hash; /**< Hash value */
488 nta_agent_t *orq_agent;
489 nta_response_f *orq_callback;
490 nta_outgoing_magic_t *orq_magic;
491
492 /* Timeout/state queue */
493 nta_outgoing_t **orq_prev;
494 nta_outgoing_t *orq_next;
495 outgoing_queue_t *orq_queue;
496
497 /* Retry queue */
498 nta_outgoing_t **orq_rprev;
499 nta_outgoing_t *orq_rnext;
500
501 sip_method_t orq_method;
502 char const *orq_method_name;
503 url_t const *orq_url; /**< Original RequestURI */
504
505 sip_from_t const *orq_from;
506 sip_to_t const *orq_to;
507 char const *orq_tag; /**< Tag from final response. */
508
509 sip_cseq_t const *orq_cseq;
510 sip_call_id_t const *orq_call_id;
511
512 msg_t *orq_request;
513 msg_t *orq_response;
514
515 su_time_t orq_sent; /**< When request was sent? */
516 unsigned orq_delay; /**< RTT estimate */
517
518 uint32_t orq_retry; /**< Timer A, E */
519 uint32_t orq_timeout; /**< Timer B, D, F, K */
520
521 unsigned short orq_interval; /**< Next timer A/E */
522
523 unsigned short orq_status;
524 unsigned char orq_retries; /**< Number of tries this far */
525
526 unsigned orq_default:1; /**< This is default transaction */
527 unsigned orq_inserted:1;
528 unsigned orq_resolved:1;
529 unsigned orq_via_added:1;
530 unsigned orq_prepared:1;
531 unsigned orq_canceled:1;
532 unsigned orq_terminated:1;
533 unsigned orq_destroyed:1;
534 unsigned orq_completed:1;
535 unsigned orq_delayed:1;
536 unsigned orq_user_tport:1; /**< Application provided tport - don't retry */
537 unsigned orq_try_tcp_instead:1;
538 unsigned orq_try_udp_instead:1;
539 unsigned orq_reliable:1; /**< Transport is reliable */
540
541 unsigned orq_forked:1; /**< Tagged fork */
542
543 /* Attributes */
544 unsigned orq_sips:1;
545 unsigned orq_uas:1; /**< Running this transaction as UAS */
546 unsigned orq_user_via:1;
547 unsigned orq_stateless:1;
548 unsigned orq_pass_100:1;
549 unsigned orq_sigcomp_new:1; /**< Create compartment if needed */
550 unsigned orq_sigcomp_zap:1; /**< Reset SigComp after completing */
551 unsigned orq_must_100rel:1;
552 unsigned orq_timestamp:1; /**< Insert @Timestamp header. */
553 unsigned orq_100rel:1; /**< Support 100rel */
554 unsigned:0; /* pad */
555
556 #if HAVE_SOFIA_SRESOLV
557 sipdns_resolver_t *orq_resolver;
558 #endif
559 url_t *orq_route; /**< Route URL */
560 tp_name_t orq_tpn[1]; /**< Where to send request */
561
562 tport_t *orq_tport;
563 struct sigcomp_compartment *orq_cc;
564 tagi_t *orq_tags; /**< Tport tag items */
565
566 char const *orq_branch; /**< Transaction branch */
567 char const *orq_via_branch; /**< @Via branch */
568
569 int *orq_status2b; /**< Delayed response */
570
571 nta_outgoing_t *orq_cancel; /**< Delayed CANCEL transaction */
572
573 nta_outgoing_t *orq_forking; /**< Untagged transaction */
574 nta_outgoing_t *orq_forks; /**< Tagged transactions */
575 uint32_t orq_rseq; /**< Latest incoming rseq */
576 int orq_pending; /**< Request is pending in tport */
577 };
578
579 /* ------------------------------------------------------------------------- */
580
581 /* Internal tags */
582
583 /* Delay sending of request */
584 #define NTATAG_DELAY_SENDING(x) ntatag_delay_sending, tag_bool_v((x))
585 #define NTATAG_DELAY_SENDING_REF(x) \
586 ntatag_delay_sending_ref, tag_bool_vr(&(x))
587
588 extern tag_typedef_t ntatag_delay_sending;
589 extern tag_typedef_t ntatag_delay_sending_ref;
590
591 /* Allow sending incomplete responses */
592 #define NTATAG_INCOMPLETE(x) ntatag_incomplete, tag_bool_v((x))
593 #define NTATAG_INCOMPLETE_REF(x) \
594 ntatag_incomplete_ref, tag_bool_vr(&(x))
595
596 extern tag_typedef_t ntatag_incomplete;
597 extern tag_typedef_t ntatag_incomplete_ref;
598
599 nta_compressor_vtable_t *nta_compressor_vtable = NULL;
600
601 /* Agent */
602 static int agent_tag_init(nta_agent_t *self);
603 static int agent_timer_init(nta_agent_t *agent);
604 static void agent_timer(su_root_magic_t *rm, su_timer_t *, nta_agent_t *);
605 static int agent_launch_terminator(nta_agent_t *agent);
606 static void agent_kill_terminator(nta_agent_t *agent);
607 static int agent_set_params(nta_agent_t *agent, tagi_t *tags);
608 static void agent_set_udp_params(nta_agent_t *self, usize_t udp_mtu);
609 static int agent_get_params(nta_agent_t *agent, tagi_t *tags);
610
611 /* Transport interface */
612 static sip_via_t const *agent_tport_via(tport_t *tport);
613 static int outgoing_insert_via(nta_outgoing_t *orq, sip_via_t const *);
614 static int nta_tpn_by_via(tp_name_t *tpn, sip_via_t const *v, int *using_rport);
615
616 static msg_t *nta_msg_create_for_transport(nta_agent_t *agent, int flags,
617 char const data[], usize_t dlen,
618 tport_t const *tport,
619 tp_client_t *via);
620
621 static int complete_response(msg_t *response,
622 int status, char const *phrase,
623 msg_t *request);
624
625 static int mreply(nta_agent_t *agent,
626 msg_t *reply,
627 int status, char const *phrase,
628 msg_t *req_msg,
629 tport_t *tport,
630 int incomplete,
631 int sdwn_after,
632 char const *to_tag,
633 tag_type_t tag, tag_value_t value, ...);
634
635 #define IF_SIGCOMP_TPTAG_COMPARTMENT(cc) TAG_IF(cc && cc != NONE, TPTAG_COMPARTMENT(cc)),
636 #define IF_SIGCOMP_TPTAG_COMPARTMENT_REF(cc) TPTAG_COMPARTMENT_REF(cc),
637
638 struct sigcomp_compartment;
639
640 struct sigcomp_compartment *
641 nta_compartment_ref(struct sigcomp_compartment *cc);
642
643 static
644 struct sigcomp_compartment *
645 agent_compression_compartment(nta_agent_t *sa, tport_t *tp, tp_name_t const *tpn,
646 int new_if_needed);
647
648 static
649 int agent_accept_compressed(nta_agent_t *sa, msg_t *msg,
650 struct sigcomp_compartment *cc);
651
652 static int agent_close_compressor(nta_agent_t *sa,
653 struct sigcomp_compartment *cc);
654
655 static int agent_zap_compressor(nta_agent_t *sa,
656 struct sigcomp_compartment *cc);
657
658
659 static char const * stateful_branch(su_home_t *home, nta_agent_t *);
660 static char const * stateless_branch(nta_agent_t *, msg_t *, sip_t const *,
661 tp_name_t const *tp);
662
663 #define NTA_BRANCH_PRIME SU_U64_C(0xB9591D1C361C6521)
664 #define NTA_TAG_PRIME SU_U64_C(0xB9591D1C361C6521)
665
666 #ifndef UINT32_MAX
667 #define UINT32_MAX (0xffffffffU)
668 #endif
669
670 HTABLE_PROTOS_WITH(leg_htable, lht, nta_leg_t, size_t, hash_value_t);
671 static nta_leg_t *leg_find(nta_agent_t const *sa,
672 char const *method_name,
673 url_t const *request_uri,
674 sip_call_id_t const *i,
675 char const *from_tag,
676 char const *to_tag);
677 static nta_leg_t *dst_find(nta_agent_t const *sa, url_t const *u0,
678 char const *method);
679 static void leg_recv(nta_leg_t *, msg_t *, sip_t *, tport_t *);
680 static void leg_free(nta_agent_t *sa, nta_leg_t *leg);
681
682 #define NTA_HASH(i, cs) ((i)->i_hash + 26839U * (uint32_t)(cs))
683
684 HTABLE_PROTOS_WITH(incoming_htable, iht, nta_incoming_t, size_t, hash_value_t);
685 static nta_incoming_t *incoming_create(nta_agent_t *agent,
686 msg_t *request,
687 sip_t *sip,
688 tport_t *tport,
689 char const *tag);
690 static int incoming_callback(nta_leg_t *leg, nta_incoming_t *irq, sip_t *sip);
691 static void incoming_free(nta_incoming_t *irq);
692 su_inline void incoming_cut_off(nta_incoming_t *irq);
693 su_inline void incoming_reclaim(nta_incoming_t *irq);
694 static void incoming_queue_init(incoming_queue_t *,
695 unsigned timeout);
696 static void incoming_queue_adjust(nta_agent_t *sa,
697 incoming_queue_t *queue,
698 unsigned timeout);
699
700 static nta_incoming_t *incoming_find(nta_agent_t const *agent,
701 sip_t const *sip,
702 sip_via_t const *v,
703 nta_incoming_t **merge,
704 nta_incoming_t **ack,
705 nta_incoming_t **cancel);
706 static int incoming_reply(nta_incoming_t *irq, msg_t *msg, sip_t *sip);
707 su_inline int incoming_recv(nta_incoming_t *irq, msg_t *msg, sip_t *sip,
708 tport_t *tport);
709 su_inline int incoming_ack(nta_incoming_t *irq, msg_t *msg, sip_t *sip,
710 tport_t *tport);
711 su_inline int incoming_cancel(nta_incoming_t *irq, msg_t *msg, sip_t *sip,
712 tport_t *tport);
713 static void request_merge(nta_agent_t *,
714 msg_t *msg, sip_t *sip, tport_t *tport,
715 char const *to_tag);
716 su_inline int incoming_timestamp(nta_incoming_t *, msg_t *, sip_t *);
717 static void _nta_incoming_timer(nta_agent_t *);
718
719 static nta_reliable_t *reliable_mreply(nta_incoming_t *,
720 nta_prack_f *, nta_reliable_magic_t *,
721 msg_t *, sip_t *);
722 static int reliable_send(nta_incoming_t *, nta_reliable_t *, msg_t *, sip_t *);
723 static int reliable_final(nta_incoming_t *irq, msg_t *msg, sip_t *sip);
724 static msg_t *reliable_response(nta_incoming_t *irq);
725 static nta_reliable_t *reliable_find(nta_agent_t const *, sip_t const *);
726 static int reliable_recv(nta_reliable_t *rel, msg_t *, sip_t *, tport_t *);
727 static void reliable_flush(nta_incoming_t *irq);
728 static void reliable_timeout(nta_incoming_t *irq, int timeout);
729
730 HTABLE_PROTOS_WITH(outgoing_htable, oht, nta_outgoing_t, size_t, hash_value_t);
731 static nta_outgoing_t *outgoing_create(nta_agent_t *agent,
732 nta_response_f *callback,
733 nta_outgoing_magic_t *magic,
734 url_string_t const *route_url,
735 tp_name_t const *tpn,
736 msg_t *msg,
737 tag_type_t tag, tag_value_t value, ...);
738 static void outgoing_queue_init(outgoing_queue_t *,
739 unsigned timeout);
740 static void outgoing_queue_adjust(nta_agent_t *sa,
741 outgoing_queue_t *queue,
742 unsigned timeout);
743 static void outgoing_free(nta_outgoing_t *orq);
744 su_inline void outgoing_cut_off(nta_outgoing_t *orq);
745 su_inline void outgoing_reclaim(nta_outgoing_t *orq);
746 static nta_outgoing_t *outgoing_find(nta_agent_t const *sa,
747 msg_t const *msg,
748 sip_t const *sip,
749 sip_via_t const *v);
750 static int outgoing_recv(nta_outgoing_t *orq, int status, msg_t *, sip_t *);
751 static void outgoing_default_recv(nta_outgoing_t *, int, msg_t *, sip_t *);
752 static void _nta_outgoing_timer(nta_agent_t *);
753 static int outgoing_recv_reliable(nta_outgoing_t *orq, msg_t *msg, sip_t *sip);
754
755 /* Internal message passing */
756 union sm_arg_u {
757 struct outgoing_recv_s {
758 nta_outgoing_t *orq;
759 msg_t *msg;
760 sip_t *sip;
761 int status;
762 } a_outgoing_recv[1];
763
764 incoming_queue_t a_incoming_queue[1];
765 outgoing_queue_t a_outgoing_queue[1];
766 };
767
768 /* Global module data */
769
770 /**@var char const NTA_DEBUG[];
771 *
772 * Environment variable determining the default debug log level.
773 *
774 * The NTA_DEBUG environment variable is used to determine the default
775 * debug logging level. The normal level is 3.
776 *
777 * @sa <sofia-sip/su_debug.h>, #su_log_global, #SOFIA_DEBUG
778 */
779 #ifdef DOXYGEN
780 extern char const NTA_DEBUG[]; /* dummy declaration for Doxygen */
781 #endif
782
783 #ifndef SU_DEBUG
784 #define SU_DEBUG 3
785 #endif
786
787 /**Debug log for @b nta module.
788 *
789 * The nta_log is the log object used by @b nta module. The level of
790 * nta_log is set using #NTA_DEBUG environment variable.
791 */
792 su_log_t nta_log[] = { SU_LOG_INIT("nta", "NTA_DEBUG", SU_DEBUG) };
793
794 /* ====================================================================== */
795 /* 1) Agent */
796
797 /**
798 * Create an NTA agent object.
799 *
800 * Create an NTA agent object. The agent
801 * object creates and binds a server socket with address specified in @e url.
802 * If the @e host portion of the @e url is @c "*", the agent listens to all
803 * addresses available on the host.
804 *
805 * When a message is received, the agent object parses it. If the result is
806 * a valid SIP message, the agent object passes the message to the
807 * application by invoking the nta_message_f @e callback function.
808 *
809 * @note
810 * The @e url can be either parsed url (of type url_t ()), or a valid
811 * SIP URL as a string.
812 *
813 * @note
814 * If @e url is @c NULL, the default @e url @c "sip:*" is used.
815 * @par
816 * If @e url is @c NONE (iow, (void*)-1), no server sockets are bound.
817 * @par
818 * If @p transport parameters are specified in @a url, agent uses only
819 * specified transport type.
820 *
821 * @par
822 * If an @p maddr parameter is specified in @e url, agent binds to the
823 * specified address, but uses @e host part of @e url when it generates
824 * @Contact and @Via headers. The @p maddr parameter is also included,
825 * unless it equals to @c INADDR_ANY (@p 0.0.0.0 or @p [::]).
826 *
827 * @param root pointer to a su_root_t used for synchronization
828 * @param contact_url URL that agent uses to bind the server sockets
829 * @param callback pointer to callback function
830 * @param magic pointer to user data
831 * @param tag,value,... tagged arguments
832 *
833 * @TAGS
834 * NTATAG_ALIASES(),
835 * NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), NTATAG_BLACKLIST(),
836 * NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_CLIENT_RPORT(),
837 * NTATAG_DEBUG_DROP_PROB(), NTATAG_DEFAULT_PROXY(),
838 * NTATAG_EXTRA_100(), NTATAG_GRAYLIST(),
839 * NTATAG_MAXSIZE(), NTATAG_MAX_FORWARDS(), NTATAG_MERGE_482(), NTATAG_MCLASS()
840 * NTATAG_PASS_100(), NTATAG_PASS_408(), NTATAG_PRELOAD(), NTATAG_PROGRESS(),
841 * NTATAG_REL100(),
842 * NTATAG_SERVER_RPORT(),
843 * NTATAG_SIPFLAGS(),
844 * NTATAG_SIP_T1X64(), NTATAG_SIP_T1(), NTATAG_SIP_T2(), NTATAG_SIP_T4(),
845 * NTATAG_STATELESS(),
846 * NTATAG_TAG_3261(), NTATAG_TCP_RPORT(), NTATAG_TIMEOUT_408(),
847 * NTATAG_TLS_RPORT(),
848 * NTATAG_TIMER_C(), NTATAG_MAX_PROCEEDING(),
849 * NTATAG_UA(), NTATAG_UDP_MTU(), NTATAG_USER_VIA(),
850 * NTATAG_USE_NAPTR(), NTATAG_USE_SRV() and NTATAG_USE_TIMESTAMP().
851 *
852 * @note The value from following tags are stored, but they currently do nothing:
853 * NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_OPTIONS(), NTATAG_SMIME()
854 *
855 * @note It is possible to provide @c (url_string_t*)-1 as @a contact_url.
856 * In that case, no server sockets are bound.
857 *
858 * @retval handle to the agent when successful,
859 * @retval NULL upon an error.
860 *
861 * @sa NUTAG_
862 */
nta_agent_create(su_root_t * root,url_string_t const * contact_url,nta_message_f * callback,nta_agent_magic_t * magic,tag_type_t tag,tag_value_t value,...)863 nta_agent_t *nta_agent_create(su_root_t *root,
864 url_string_t const *contact_url,
865 nta_message_f *callback,
866 nta_agent_magic_t *magic,
867 tag_type_t tag, tag_value_t value, ...)
868 {
869 nta_agent_t *agent;
870 ta_list ta;
871
872 if (root == NULL)
873 return su_seterrno(EINVAL), NULL;
874
875 ta_start(ta, tag, value);
876
877 if ((agent = su_home_new(sizeof(*agent)))) {
878 unsigned timer_c = 0, timer_d = 32000;
879
880 agent->sa_root = root;
881 agent->sa_callback = callback;
882 agent->sa_magic = magic;
883 agent->sa_flags = MSG_DO_CANONIC;
884
885 agent->sa_maxsize = 2 * 1024 * 1024; /* 2 MB */
886 agent->sa_bad_req_mask =
887 /*
888 * Bit-wise not of these - what is left is suitable for UAs with
889 * 100rel, timer, events, publish
890 */
891 (unsigned) ~(sip_mask_response | sip_mask_proxy | sip_mask_registrar |
892 sip_mask_pref | sip_mask_privacy);
893 agent->sa_bad_resp_mask =
894 (unsigned) ~(sip_mask_request | sip_mask_proxy | sip_mask_registrar |
895 sip_mask_pref | sip_mask_privacy);
896 agent->sa_t1 = NTA_SIP_T1;
897 agent->sa_t2 = NTA_SIP_T2;
898 agent->sa_t4 = NTA_SIP_T4;
899 agent->sa_t1x64 = 64 * NTA_SIP_T1;
900 agent->sa_timer_c = 185 * 1000;
901 agent->sa_graylist = 600;
902 agent->sa_drop_prob = 0;
903 agent->sa_is_a_uas = 0;
904 agent->sa_progress = 60 * 1000;
905 agent->sa_user_via = 0;
906 agent->sa_extra_100 = 0;
907 agent->sa_pass_100 = 0;
908 agent->sa_timeout_408 = 1;
909 agent->sa_pass_408 = 0;
910 agent->sa_merge_482 = 0;
911 agent->sa_cancel_2543 = 0;
912 agent->sa_cancel_487 = 1;
913 agent->sa_invite_100rel = 0;
914 agent->sa_timestamp = 0;
915 agent->sa_use_naptr = 1;
916 agent->sa_use_srv = 1;
917 agent->sa_srv_503 = 1;
918 agent->sa_auto_comp = 0;
919 agent->sa_server_rport = 1;
920
921 /* RFC 3261 section 8.1.1.6 */
922 sip_max_forwards_init(agent->sa_max_forwards);
923
924 if (getenv("SIPCOMPACT"))
925 agent->sa_flags |= MSG_DO_COMPACT;
926
927 agent_set_params(agent, ta_args(ta));
928
929 if (agent->sa_mclass == NULL)
930 agent->sa_mclass = sip_default_mclass();
931
932 agent->sa_in.re_t1 = &agent->sa_in.re_list;
933
934 incoming_queue_init(agent->sa_in.proceeding, 0);
935 incoming_queue_init(agent->sa_in.preliminary, agent->sa_t1x64); /* P1 */
936 incoming_queue_init(agent->sa_in.inv_completed, agent->sa_t1x64); /* H */
937 incoming_queue_init(agent->sa_in.inv_confirmed, agent->sa_t4); /* I */
938 incoming_queue_init(agent->sa_in.completed, agent->sa_t1x64); /* J */
939 incoming_queue_init(agent->sa_in.terminated, 0);
940 incoming_queue_init(agent->sa_in.final_failed, 0);
941
942 agent->sa_out.re_t1 = &agent->sa_out.re_list;
943
944 if (agent->sa_use_timer_c || !agent->sa_is_a_uas)
945 timer_c = agent->sa_timer_c;
946 if (timer_d < agent->sa_t1x64)
947 timer_d = agent->sa_t1x64;
948
949 outgoing_queue_init(agent->sa_out.delayed, 0);
950 outgoing_queue_init(agent->sa_out.resolving, 0);
951 outgoing_queue_init(agent->sa_out.trying, agent->sa_t1x64); /* F */
952 outgoing_queue_init(agent->sa_out.completed, agent->sa_t4); /* K */
953 outgoing_queue_init(agent->sa_out.terminated, 0);
954 /* Special queues (states) for outgoing INVITE transactions */
955 outgoing_queue_init(agent->sa_out.inv_calling, agent->sa_t1x64); /* B */
956 outgoing_queue_init(agent->sa_out.inv_proceeding, timer_c); /* C */
957 outgoing_queue_init(agent->sa_out.inv_completed, timer_d); /* D */
958
959 if (leg_htable_resize(agent->sa_home, agent->sa_dialogs, 0) < 0 ||
960 leg_htable_resize(agent->sa_home, agent->sa_defaults, 0) < 0 ||
961 outgoing_htable_resize(agent->sa_home, agent->sa_outgoing, 0) < 0 ||
962 incoming_htable_resize(agent->sa_home, agent->sa_incoming, 0) < 0) {
963 SU_DEBUG_0(("nta_agent_create: failure with %s\n", "hash tables"));
964 goto deinit;
965 }
966 SU_DEBUG_9(("nta_agent_create: initialized %s\n", "hash tables"));
967
968 if (contact_url != (url_string_t *)-1 &&
969 nta_agent_add_tport(agent, contact_url, ta_tags(ta)) < 0) {
970 SU_DEBUG_7(("nta_agent_create: failure with %s\n", "transport"));
971 goto deinit;
972 }
973 SU_DEBUG_9(("nta_agent_create: initialized %s\n", "transports"));
974
975 if (agent_tag_init(agent) < 0) {
976 SU_DEBUG_3(("nta_agent_create: failure with %s\n", "random identifiers"));
977 goto deinit;
978 }
979 SU_DEBUG_9(("nta_agent_create: initialized %s\n", "random identifiers"));
980
981 if (agent_timer_init(agent) < 0) {
982 SU_DEBUG_0(("nta_agent_create: failure with %s\n", "timer"));
983 goto deinit;
984 }
985 SU_DEBUG_9(("nta_agent_create: initialized %s\n", "timer"));
986
987 if (agent_launch_terminator(agent) == 0)
988 SU_DEBUG_9(("nta_agent_create: initialized %s\n", "threads"));
989
990 #if HAVE_SOFIA_SRESOLV
991 agent->sa_resolver = sres_resolver_create(root, NULL, ta_tags(ta));
992 if (!agent->sa_resolver) {
993 SU_DEBUG_0(("nta_agent_create: failure with %s\n", "resolver"));
994 }
995 SU_DEBUG_9(("nta_agent_create: initialized %s\n", "resolver"));
996 #endif
997
998 ta_end(ta);
999
1000 return agent;
1001
1002 deinit:
1003 nta_agent_destroy(agent);
1004 }
1005
1006 ta_end(ta);
1007
1008 return NULL;
1009 }
1010
1011 /**
1012 * Destroy an NTA agent object.
1013 *
1014 * @param agent the NTA agent object to be destroyed.
1015 *
1016 */
nta_agent_destroy(nta_agent_t * agent)1017 void nta_agent_destroy(nta_agent_t *agent)
1018 {
1019 if (agent) {
1020 size_t i;
1021 outgoing_htable_t *oht = agent->sa_outgoing;
1022 incoming_htable_t *iht = agent->sa_incoming;
1023 /* Currently, this is pretty pointless, as legs don't keep any resources */
1024 leg_htable_t *lht;
1025 nta_leg_t *leg;
1026
1027 for (i = 0, lht = agent->sa_dialogs; i < lht->lht_size; i++) {
1028 if ((leg = lht->lht_table[i])) {
1029 SU_DEBUG_3(("nta_agent_destroy: destroying dialog with <"
1030 URL_PRINT_FORMAT ">\n",
1031 URL_PRINT_ARGS(leg->leg_remote->a_url)));
1032 leg_free(agent, leg);
1033 }
1034 }
1035
1036 for (i = 0, lht = agent->sa_defaults; i < lht->lht_size; i++) {
1037 if ((leg = lht->lht_table[i])) {
1038 SU_DEBUG_3(("%s: destroying leg for <"
1039 URL_PRINT_FORMAT ">\n",
1040 __func__, URL_PRINT_ARGS(leg->leg_url)));
1041 leg_free(agent, leg);
1042 }
1043 }
1044
1045 if (agent->sa_default_leg)
1046 leg_free(agent, agent->sa_default_leg);
1047
1048 for (i = iht->iht_size; i-- > 0; )
1049 while (iht->iht_table[i]) {
1050 nta_incoming_t *irq = iht->iht_table[i];
1051
1052 if (!irq->irq_destroyed)
1053 SU_DEBUG_3(("%s: destroying %s server transaction from <"
1054 URL_PRINT_FORMAT ">\n",
1055 __func__, irq->irq_rq->rq_method_name,
1056 URL_PRINT_ARGS(irq->irq_from->a_url)));
1057
1058 incoming_free(irq);
1059 }
1060
1061 for (i = oht->oht_size; i-- > 0;)
1062 while (oht->oht_table[i]) {
1063 nta_outgoing_t *orq = oht->oht_table[i];
1064
1065 if (!orq->orq_destroyed)
1066 SU_DEBUG_3(("%s: destroying %s%s client transaction to <"
1067 URL_PRINT_FORMAT ">\n",
1068 __func__,
1069 (orq->orq_forking || orq->orq_forks) ? "forked " : "forking",
1070 orq->orq_method_name,
1071 URL_PRINT_ARGS(orq->orq_to->a_url)));
1072
1073 orq->orq_forks = NULL, orq->orq_forking = NULL;
1074 outgoing_free(orq);
1075 }
1076
1077 su_timer_destroy(agent->sa_timer), agent->sa_timer = NULL;
1078
1079 # if HAVE_SOFIA_SRESOLV
1080 sres_resolver_destroy(agent->sa_resolver), agent->sa_resolver = NULL;
1081 # endif
1082
1083 tport_destroy(agent->sa_tports), agent->sa_tports = NULL;
1084
1085 agent_kill_terminator(agent);
1086
1087 su_home_unref(agent->sa_home);
1088 }
1089 }
1090
1091 /** Return agent context. */
nta_agent_magic(nta_agent_t const * agent)1092 nta_agent_magic_t *nta_agent_magic(nta_agent_t const *agent)
1093 {
1094 return agent ? agent->sa_magic : NULL;
1095 }
1096
1097 /** Return @Contact header.
1098 *
1099 * Get a @Contact header, which can be used to reach @a agent.
1100 *
1101 * @param agent NTA agent object
1102 *
1103 * User agents can insert the @Contact header in the outgoing REGISTER,
1104 * INVITE, and ACK requests and replies to incoming INVITE and OPTIONS
1105 * transactions.
1106 *
1107 * Proxies can use the @Contact header to create appropriate @RecordRoute
1108 * headers:
1109 * @code
1110 * r_r = sip_record_route_create(msg_home(msg),
1111 * sip->sip_request->rq_url,
1112 * contact->m_url);
1113 * @endcode
1114 *
1115 * @return A sip_contact_t object corresponding to the @a agent.
1116 */
nta_agent_contact(nta_agent_t const * agent)1117 sip_contact_t *nta_agent_contact(nta_agent_t const *agent)
1118 {
1119 return agent ? agent->sa_contact : NULL;
1120 }
1121
1122 /** Return a list of @Via headers.
1123 *
1124 * Get @Via headers for all activated transport.
1125 *
1126 * @param agent NTA agent object
1127 *
1128 * @return A list of #sip_via_t objects used by the @a agent.
1129 */
nta_agent_via(nta_agent_t const * agent)1130 sip_via_t *nta_agent_via(nta_agent_t const *agent)
1131 {
1132 return agent ? agent->sa_vias : NULL;
1133 }
1134
1135 /** Return a list of public (UPnP, STUN) @Via headers.
1136 *
1137 * Get public @Via headers for all activated transports.
1138 *
1139 * @param agent NTA agent object
1140 *
1141 * @return A list of #sip_via_t objects used by the @a agent.
1142 */
nta_agent_public_via(nta_agent_t const * agent)1143 sip_via_t *nta_agent_public_via(nta_agent_t const *agent)
1144 {
1145 return agent ? agent->sa_public_vias : NULL;
1146 }
1147
1148 /** Match a @Via header @a v with @Via headers in @a agent.
1149 *
1150 */
1151 static
agent_has_via(nta_agent_t const * agent,sip_via_t const * via)1152 sip_via_t *agent_has_via(nta_agent_t const *agent, sip_via_t const *via)
1153 {
1154 sip_via_t const *v;
1155
1156 for (v = agent->sa_public_vias; v; v = v->v_next) {
1157 if (!su_casematch(via->v_host, v->v_host))
1158 continue;
1159 if (!su_strmatch(via->v_port, v->v_port))
1160 continue;
1161 if (!su_casematch(via->v_protocol, v->v_protocol))
1162 continue;
1163 return (sip_via_t *)v;
1164 }
1165
1166 for (v = agent->sa_vias; v; v = v->v_next) {
1167 if (!su_casematch(via->v_host, v->v_host))
1168 continue;
1169 if (!su_strmatch(via->v_port, v->v_port))
1170 continue;
1171 if (!su_casematch(via->v_protocol, v->v_protocol))
1172 continue;
1173 return (sip_via_t *)v;
1174 }
1175
1176 return NULL;
1177 }
1178
1179 /** Return @UserAgent header.
1180 *
1181 * Get @UserAgent information with NTA version.
1182 *
1183 * @param agent NTA agent object (may be NULL)
1184 *
1185 * @return A string containing the @a agent version.
1186 */
nta_agent_version(nta_agent_t const * agent)1187 char const *nta_agent_version(nta_agent_t const *agent)
1188 {
1189 return "nta" "/" VERSION;
1190 }
1191
1192 /** Initialize default tag */
agent_tag_init(nta_agent_t * self)1193 static int agent_tag_init(nta_agent_t *self)
1194 {
1195 sip_contact_t *m = self->sa_contact;
1196 uint32_t hash = su_random();
1197
1198 if (m) {
1199 if (m->m_url->url_user)
1200 hash = 914715421U * hash + msg_hash_string(m->m_url->url_user);
1201 if (m->m_url->url_host)
1202 hash = 914715421U * hash + msg_hash_string(m->m_url->url_host);
1203 if (m->m_url->url_port)
1204 hash = 914715421U * hash + msg_hash_string(m->m_url->url_port);
1205 if (m->m_url->url_params)
1206 hash = 914715421U * hash + msg_hash_string(m->m_url->url_params);
1207 }
1208
1209 if (hash == 0)
1210 hash = 914715421U;
1211
1212 self->sa_branch = NTA_BRANCH_PRIME * (uint64_t)su_nanotime(NULL);
1213 self->sa_branch *= hash;
1214
1215 self->sa_tags = NTA_TAG_PRIME * self->sa_branch;
1216
1217 return 0;
1218 }
1219
1220 /** Initialize agent timer. */
1221 static
agent_timer_init(nta_agent_t * agent)1222 int agent_timer_init(nta_agent_t *agent)
1223 {
1224 agent->sa_timer = su_timer_create(su_root_task(agent->sa_root),
1225 NTA_SIP_T1 / 8);
1226 #if 0
1227 return su_timer_set(agent->sa_timer,
1228 agent_timer,
1229 agent);
1230 #endif
1231 return -(agent->sa_timer == NULL);
1232 }
1233
1234 /**
1235 * Agent timer routine.
1236 */
1237 static
agent_timer(su_root_magic_t * rm,su_timer_t * timer,nta_agent_t * agent)1238 void agent_timer(su_root_magic_t *rm, su_timer_t *timer, nta_agent_t *agent)
1239 {
1240 su_time_t stamp = su_now();
1241 uint32_t now = su_time_ms(stamp), next, latest;
1242
1243 now += now == 0;
1244
1245 agent->sa_next = 0;
1246
1247 agent->sa_in_timer = 1;
1248
1249
1250 _nta_outgoing_timer(agent);
1251 _nta_incoming_timer(agent);
1252
1253 agent->sa_in_timer = 0;
1254
1255 /* Calculate next timeout */
1256 next = latest = now + NTA_TIME_MAX + 1;
1257
1258 #define NEXT_TIMEOUT(next, p, f, now) \
1259 (void)(p && (int32_t)(p->f - (next)) < 0 && \
1260 ((next) = ((int32_t)(p->f - (now)) > 0 ? p->f : (now))))
1261
1262 NEXT_TIMEOUT(next, agent->sa_out.re_list, orq_retry, now);
1263 NEXT_TIMEOUT(next, agent->sa_out.inv_completed->q_head, orq_timeout, now);
1264 NEXT_TIMEOUT(next, agent->sa_out.completed->q_head, orq_timeout, now);
1265 NEXT_TIMEOUT(next, agent->sa_out.inv_calling->q_head, orq_timeout, now);
1266 if (agent->sa_out.inv_proceeding->q_timeout)
1267 NEXT_TIMEOUT(next, agent->sa_out.inv_proceeding->q_head, orq_timeout, now);
1268 NEXT_TIMEOUT(next, agent->sa_out.trying->q_head, orq_timeout, now);
1269
1270 NEXT_TIMEOUT(next, agent->sa_in.preliminary->q_head, irq_timeout, now);
1271 NEXT_TIMEOUT(next, agent->sa_in.inv_completed->q_head, irq_timeout, now);
1272 NEXT_TIMEOUT(next, agent->sa_in.inv_confirmed->q_head, irq_timeout, now);
1273 NEXT_TIMEOUT(next, agent->sa_in.completed->q_head, irq_timeout, now);
1274 NEXT_TIMEOUT(next, agent->sa_in.re_list, irq_retry, now);
1275
1276 if (agent->sa_next)
1277 NEXT_TIMEOUT(next, agent, sa_next, now);
1278
1279 #undef NEXT_TIMEOUT
1280
1281 if (next == latest) {
1282 /* Do not set timer? */
1283 /* check it there are still things queued, if there are, that means everything scheduled is > 15 days in the future */
1284 /* in this case, we had a large time shift, we should schedule for 15 days in the future (which is probably still before now) */
1285 /* and this should sort itself out on the next run through */
1286 if ( !agent->sa_out.completed->q_head && !agent->sa_out.trying->q_head && !agent->sa_out.inv_calling->q_head &&
1287 !agent->sa_out.re_list && !agent->sa_in.inv_confirmed->q_head && !agent->sa_in.preliminary->q_head &&
1288 !agent->sa_in.completed->q_head && !agent->sa_in.inv_completed->q_head && !agent->sa_in.re_list ) {
1289 SU_DEBUG_9(("nta: timer not set\n" VA_NONE));
1290 return;
1291 }
1292 }
1293
1294 if (next == now) if (++next == 0) ++next;
1295
1296 SU_DEBUG_9(("nta: timer %s to %ld ms\n", "set next", (long)(next - now)));
1297
1298 agent->sa_next = next;
1299
1300 su_timer_set_at(timer, agent_timer, agent, su_time_add(stamp, next - now));
1301 }
1302
1303 /** Add uin32_t milliseconds to the time. */
add_milliseconds(su_time_t t0,uint32_t ms)1304 static su_time_t add_milliseconds(su_time_t t0, uint32_t ms)
1305 {
1306 unsigned long sec = ms / 1000, usec = (ms % 1000) * 1000;
1307
1308 t0.tv_usec += usec;
1309 t0.tv_sec += sec;
1310
1311 if (t0.tv_usec >= 1000000) {
1312 t0.tv_sec += 1;
1313 t0.tv_usec -= 1000000;
1314 }
1315
1316 return t0;
1317 }
1318
1319 /** Calculate nonzero value for timeout.
1320 *
1321 * Sets or adjusts agent timer when needed.
1322 *
1323 * @retval 0 if offset is 0
1324 * @retval timeout (millisecond counter) otherwise
1325 */
1326 static
set_timeout(nta_agent_t * agent,uint32_t offset)1327 uint32_t set_timeout(nta_agent_t *agent, uint32_t offset)
1328 {
1329 su_time_t now;
1330 uint32_t next, ms;
1331
1332 if (offset == 0)
1333 return 0;
1334
1335 now = su_now();
1336 ms = su_time_ms(now);
1337
1338 next = ms + offset;
1339
1340 if (next == 0) next = 1;
1341
1342 if (agent->sa_in_timer) /* Currently executing timer */
1343 return next;
1344
1345 if (agent->sa_next == 0 || (int32_t)(agent->sa_next - next - 5L) > 0) {
1346 /* Set timer */
1347 if (agent->sa_next)
1348 SU_DEBUG_9(("nta: timer %s to %ld ms\n", "shortened", (long)offset));
1349 else
1350 SU_DEBUG_9(("nta: timer %s to %ld ms\n", "set", (long)offset));
1351
1352 su_timer_set_at(agent->sa_timer, agent_timer, agent,
1353 add_milliseconds(now, offset));
1354 agent->sa_next = next;
1355 }
1356
1357 return next;
1358 }
1359
1360
1361 /** Return current timeval. */
1362 static
agent_now(nta_agent_t const * agent)1363 su_time_t agent_now(nta_agent_t const *agent)
1364 {
1365 return su_now();
1366 }
1367
1368
1369 /** Launch transaction terminator task */
1370 static
agent_launch_terminator(nta_agent_t * agent)1371 int agent_launch_terminator(nta_agent_t *agent)
1372 {
1373 #ifdef TPTAG_THRPSIZE
1374 if (agent->sa_tport_threadpool) {
1375 su_home_threadsafe(agent->sa_home);
1376 return su_clone_start(agent->sa_root,
1377 agent->sa_terminator,
1378 NULL,
1379 NULL,
1380 NULL);
1381 }
1382 #endif
1383 return -1;
1384 }
1385
1386 /** Kill transaction terminator task */
1387 static
agent_kill_terminator(nta_agent_t * agent)1388 void agent_kill_terminator(nta_agent_t *agent)
1389 {
1390 su_clone_wait(agent->sa_root, agent->sa_terminator);
1391 }
1392
1393
1394 /**Set NTA Parameters.
1395 *
1396 * The nta_agent_set_params() function sets the stack parameters. The
1397 * parameters determine the way NTA handles the retransmissions, how long
1398 * NTA keeps transactions alive, does NTA apply proxy or user-agent logic to
1399 * INVITE transactions, or how the @Via headers are generated.
1400 *
1401 * @note
1402 * Setting the parameters NTATAG_MAXSIZE(), NTATAG_UDP_MTU(), NTATAG_MAX_PROCEEDING(),
1403 * NTATAG_SIP_T1X64(), NTATAG_SIP_T1(), NTATAG_SIP_T2(), NTATAG_SIP_T4() to
1404 * 0 selects the default value.
1405 *
1406 * @TAGS
1407 * NTATAG_ALIASES(),
1408 * NTATAG_BAD_REQ_MASK(), NTATAG_BAD_RESP_MASK(), NTATAG_BLACKLIST(),
1409 * NTATAG_CANCEL_2543(), NTATAG_CANCEL_487(), NTATAG_CLIENT_RPORT(),
1410 * NTATAG_DEBUG_DROP_PROB(), NTATAG_DEFAULT_PROXY(),
1411 * NTATAG_EXTRA_100(), NTATAG_GRAYLIST(),
1412 * NTATAG_MAXSIZE(), NTATAG_MAX_FORWARDS(), NTATAG_MERGE_482(), NTATAG_MCLASS()
1413 * NTATAG_PASS_100(), NTATAG_PASS_408(), NTATAG_PRELOAD(), NTATAG_PROGRESS(),
1414 * NTATAG_REL100(),
1415 * NTATAG_SERVER_RPORT(),
1416 * NTATAG_SIPFLAGS(),
1417 * NTATAG_SIP_T1X64(), NTATAG_SIP_T1(), NTATAG_SIP_T2(), NTATAG_SIP_T4(),
1418 * NTATAG_STATELESS(),
1419 * NTATAG_TAG_3261(), NTATAG_TCP_RPORT(), NTATAG_TIMEOUT_408(),
1420 * NTATAG_TLS_RPORT(),
1421 * NTATAG_TIMER_C(), NTATAG_MAX_PROCEEDING(),
1422 * NTATAG_UA(), NTATAG_UDP_MTU(), NTATAG_USER_VIA(),
1423 * NTATAG_USE_NAPTR(), NTATAG_USE_SRV() and NTATAG_USE_TIMESTAMP().
1424 *
1425 * @note The value from following tags are stored, but they currently do nothing:
1426 * NTATAG_SIGCOMP_ALGORITHM(), NTATAG_SIGCOMP_OPTIONS(), NTATAG_SMIME()
1427 */
nta_agent_set_params(nta_agent_t * agent,tag_type_t tag,tag_value_t value,...)1428 int nta_agent_set_params(nta_agent_t *agent,
1429 tag_type_t tag, tag_value_t value, ...)
1430 {
1431 int retval;
1432
1433 if (agent) {
1434 ta_list ta;
1435 ta_start(ta, tag, value);
1436 retval = agent_set_params(agent, ta_args(ta));
1437 ta_end(ta);
1438 } else {
1439 su_seterrno(EINVAL);
1440 retval = -1;
1441 }
1442
1443 return retval;
1444 }
1445
1446 /** Internal function for setting tags */
1447 static
agent_set_params(nta_agent_t * agent,tagi_t * tags)1448 int agent_set_params(nta_agent_t *agent, tagi_t *tags)
1449 {
1450 int n, nC, m;
1451 unsigned bad_req_mask = agent->sa_bad_req_mask;
1452 unsigned bad_resp_mask = agent->sa_bad_resp_mask;
1453 usize_t maxsize = agent->sa_maxsize;
1454 usize_t max_proceeding = agent->sa_max_proceeding;
1455 unsigned max_forwards = agent->sa_max_forwards->mf_count;
1456 unsigned udp_mtu = agent->sa_udp_mtu;
1457 unsigned sip_t1 = agent->sa_t1;
1458 unsigned sip_t2 = agent->sa_t2;
1459 unsigned sip_t4 = agent->sa_t4;
1460 unsigned sip_t1x64 = agent->sa_t1x64;
1461 unsigned timer_c = agent->sa_timer_c;
1462 unsigned timer_d = 32000;
1463 unsigned graylist = agent->sa_graylist;
1464 unsigned blacklist = agent->sa_blacklist;
1465 int ua = agent->sa_is_a_uas;
1466 unsigned progress = agent->sa_progress;
1467 int stateless = agent->sa_is_stateless;
1468 unsigned drop_prob = agent->sa_drop_prob;
1469 int user_via = agent->sa_user_via;
1470 int extra_100 = agent->sa_extra_100;
1471 int pass_100 = agent->sa_pass_100;
1472 int timeout_408 = agent->sa_timeout_408;
1473 int pass_408 = agent->sa_pass_408;
1474 int merge_482 = agent->sa_merge_482;
1475 int cancel_2543 = agent->sa_cancel_2543;
1476 int cancel_487 = agent->sa_cancel_487;
1477 int invite_100rel = agent->sa_invite_100rel;
1478 int use_timestamp = agent->sa_timestamp;
1479 int use_naptr = agent->sa_use_naptr;
1480 int use_srv = agent->sa_use_srv;
1481 int srv_503 = agent->sa_srv_503;
1482 void *smime = agent->sa_smime;
1483 uint32_t flags = agent->sa_flags;
1484 int rport = agent->sa_rport;
1485 int server_rport = agent->sa_server_rport;
1486 int tcp_rport = agent->sa_tcp_rport;
1487 int tls_rport = agent->sa_tls_rport;
1488 unsigned preload = agent->sa_preload;
1489 unsigned threadpool = agent->sa_tport_threadpool;
1490 char const *sigcomp = agent->sa_sigcomp_options;
1491 char const *algorithm = NONE;
1492 msg_mclass_t const *mclass = NONE;
1493 sip_contact_t const *aliases = NONE;
1494 url_string_t const *proxy = NONE;
1495 tport_t *tport;
1496
1497 su_home_t *home = agent->sa_home;
1498
1499 n = tl_gets(tags,
1500 NTATAG_ALIASES_REF(aliases),
1501 NTATAG_BAD_REQ_MASK_REF(bad_req_mask),
1502 NTATAG_BAD_RESP_MASK_REF(bad_resp_mask),
1503 NTATAG_BLACKLIST_REF(blacklist),
1504 NTATAG_CANCEL_2543_REF(cancel_2543),
1505 NTATAG_CANCEL_487_REF(cancel_487),
1506 NTATAG_DEBUG_DROP_PROB_REF(drop_prob),
1507 NTATAG_DEFAULT_PROXY_REF(proxy),
1508 NTATAG_EXTRA_100_REF(extra_100),
1509 NTATAG_GRAYLIST_REF(graylist),
1510 NTATAG_MAXSIZE_REF(maxsize),
1511 NTATAG_MAX_PROCEEDING_REF(max_proceeding),
1512 NTATAG_MAX_FORWARDS_REF(max_forwards),
1513 NTATAG_MCLASS_REF(mclass),
1514 NTATAG_MERGE_482_REF(merge_482),
1515 NTATAG_PASS_100_REF(pass_100),
1516 NTATAG_PASS_408_REF(pass_408),
1517 NTATAG_PRELOAD_REF(preload),
1518 NTATAG_PROGRESS_REF(progress),
1519 NTATAG_REL100_REF(invite_100rel),
1520 NTATAG_RPORT_REF(rport),
1521 NTATAG_SERVER_RPORT_REF(server_rport),
1522 NTATAG_SIGCOMP_ALGORITHM_REF(algorithm),
1523 NTATAG_SIGCOMP_OPTIONS_REF(sigcomp),
1524 NTATAG_SIPFLAGS_REF(flags),
1525 NTATAG_SIP_T1X64_REF(sip_t1x64),
1526 NTATAG_SIP_T1_REF(sip_t1),
1527 NTATAG_SIP_T2_REF(sip_t2),
1528 NTATAG_SIP_T4_REF(sip_t4),
1529 #if HAVE_SOFIA_SMIME
1530 NTATAG_SMIME_REF(smime),
1531 #endif
1532 NTATAG_STATELESS_REF(stateless),
1533 NTATAG_TCP_RPORT_REF(tcp_rport),
1534 NTATAG_TLS_RPORT_REF(tls_rport),
1535 NTATAG_TIMEOUT_408_REF(timeout_408),
1536 NTATAG_UA_REF(ua),
1537 NTATAG_UDP_MTU_REF(udp_mtu),
1538 NTATAG_USER_VIA_REF(user_via),
1539 NTATAG_USE_NAPTR_REF(use_naptr),
1540 NTATAG_USE_SRV_REF(use_srv),
1541 NTATAG_USE_TIMESTAMP_REF(use_timestamp),
1542 #ifdef TPTAG_THRPSIZE
1543 /* If threadpool is enabled, start a separate "reaper thread" */
1544 TPTAG_THRPSIZE_REF(threadpool),
1545 #endif
1546 NTATAG_SRV_503_REF(srv_503),
1547 TAG_END());
1548 nC = tl_gets(tags,
1549 NTATAG_TIMER_C_REF(timer_c),
1550 TAG_END());
1551 n += nC;
1552
1553 if (mclass != NONE)
1554 agent->sa_mclass = mclass ? mclass : sip_default_mclass();
1555
1556 m = 0;
1557 for (tport = agent->sa_tports; tport; tport = tport_next(tport)) {
1558 int m0 = tport_set_params(tport, TAG_NEXT(tags));
1559 if (m0 < 0)
1560 return m0;
1561 if (m0 > m)
1562 m = m0;
1563 }
1564
1565 n += m;
1566
1567 if (aliases != NONE) {
1568 sip_contact_t const *m, *m_next;
1569
1570 m = agent->sa_aliases;
1571 agent->sa_aliases = sip_contact_dup(home, aliases);
1572
1573 for (; m; m = m_next) { /* Free old aliases */
1574 m_next = m->m_next;
1575 su_free(home, (void *)m);
1576 }
1577 }
1578
1579 if (proxy != NONE) {
1580 url_t *dp = url_hdup(home, proxy->us_url);
1581
1582 url_sanitize(dp);
1583
1584 if (dp == NULL || dp->url_type == url_sip || dp->url_type == url_sips) {
1585 if (agent->sa_default_proxy)
1586 su_free(home, agent->sa_default_proxy);
1587 agent->sa_default_proxy = dp;
1588 }
1589 else
1590 n = -1;
1591 }
1592
1593 if (algorithm != NONE)
1594 agent->sa_algorithm = su_strdup(home, algorithm);
1595
1596 if (!su_strmatch(sigcomp, agent->sa_sigcomp_options)) {
1597 msg_param_t const *l = NULL;
1598 char *s = su_strdup(home, sigcomp);
1599 char *s1 = su_strdup(home, s), *s2 = s1;
1600
1601 if (s && s2 && msg_avlist_d(home, &s2, &l) == 0 && *s2 == '\0') {
1602 su_free(home, (void *)agent->sa_sigcomp_options);
1603 su_free(home, (void *)agent->sa_sigcomp_option_list);
1604 agent->sa_sigcomp_options = s;
1605 agent->sa_sigcomp_option_free = s1;
1606 agent->sa_sigcomp_option_list = l;
1607 } else {
1608 su_free(home, s);
1609 su_free(home, s1);
1610 su_free(home, (void *)l);
1611 n = -1;
1612 }
1613 }
1614
1615 if (maxsize == 0) maxsize = 2 * 1024 * 1024;
1616 if (maxsize > UINT32_MAX) maxsize = UINT32_MAX;
1617 agent->sa_maxsize = maxsize;
1618
1619 if (max_proceeding == 0) max_proceeding = USIZE_MAX;
1620 agent->sa_max_proceeding = max_proceeding;
1621
1622 if (max_forwards == 0) max_forwards = 70; /* Default value */
1623 agent->sa_max_forwards->mf_count = max_forwards;
1624
1625 if (udp_mtu == 0) udp_mtu = 1300;
1626 if (udp_mtu > 65535) udp_mtu = 65535;
1627 if (agent->sa_udp_mtu != udp_mtu) {
1628 agent->sa_udp_mtu = udp_mtu;
1629 agent_set_udp_params(agent, udp_mtu);
1630 }
1631
1632 if (sip_t1 == 0) sip_t1 = NTA_SIP_T1;
1633 if (sip_t1 > NTA_TIME_MAX) sip_t1 = NTA_TIME_MAX;
1634 agent->sa_t1 = sip_t1;
1635
1636 if (sip_t2 == 0) sip_t2 = NTA_SIP_T2;
1637 if (sip_t2 > NTA_TIME_MAX) sip_t2 = NTA_TIME_MAX;
1638 agent->sa_t2 = sip_t2;
1639
1640 if (sip_t4 == 0) sip_t4 = NTA_SIP_T4;
1641 if (sip_t4 > NTA_TIME_MAX) sip_t4 = NTA_TIME_MAX;
1642 if (agent->sa_t4 != sip_t4) {
1643 incoming_queue_adjust(agent, agent->sa_in.inv_confirmed, sip_t4);
1644 outgoing_queue_adjust(agent, agent->sa_out.completed, sip_t4);
1645 }
1646 agent->sa_t4 = sip_t4;
1647
1648 if (sip_t1x64 == 0) sip_t1x64 = NTA_SIP_T1 * 64;
1649 if (sip_t1x64 > NTA_TIME_MAX) sip_t1x64 = NTA_TIME_MAX;
1650 if (agent->sa_t1x64 != sip_t1x64) {
1651 incoming_queue_adjust(agent, agent->sa_in.preliminary, sip_t1x64);
1652 incoming_queue_adjust(agent, agent->sa_in.completed, sip_t1x64);
1653 incoming_queue_adjust(agent, agent->sa_in.inv_completed, sip_t1x64);
1654 outgoing_queue_adjust(agent, agent->sa_out.trying, sip_t1x64);
1655 outgoing_queue_adjust(agent, agent->sa_out.inv_calling, sip_t1x64);
1656 }
1657 agent->sa_t1x64 = sip_t1x64;
1658 if (nC == 1) {
1659 agent->sa_use_timer_c = 1;
1660 if (timer_c == 0)
1661 timer_c = 185 * 1000;
1662 agent->sa_timer_c = timer_c;
1663 outgoing_queue_adjust(agent, agent->sa_out.inv_proceeding, timer_c);
1664 }
1665 if (timer_d < sip_t1x64)
1666 timer_d = sip_t1x64;
1667 outgoing_queue_adjust(agent, agent->sa_out.inv_completed, timer_d);
1668
1669 if (graylist > 24 * 60 * 60)
1670 graylist = 24 * 60 * 60;
1671 agent->sa_graylist = graylist;
1672
1673 if (blacklist > 24 * 60 * 60)
1674 blacklist = 24 * 60 * 60;
1675 agent->sa_blacklist = blacklist;
1676
1677 if (progress == 0)
1678 progress = 60 * 1000;
1679 agent->sa_progress = progress;
1680
1681 if (server_rport > 3)
1682 server_rport = 1;
1683 else if (server_rport < 0)
1684 server_rport = 1;
1685 agent->sa_server_rport = server_rport;
1686
1687 agent->sa_bad_req_mask = bad_req_mask;
1688 agent->sa_bad_resp_mask = bad_resp_mask;
1689
1690 agent->sa_is_a_uas = ua != 0;
1691 agent->sa_is_stateless = stateless != 0;
1692 agent->sa_drop_prob = drop_prob < 1000 ? drop_prob : 1000;
1693 agent->sa_user_via = user_via != 0;
1694 agent->sa_extra_100 = extra_100 != 0;
1695 agent->sa_pass_100 = pass_100 != 0;
1696 agent->sa_timeout_408 = timeout_408 != 0;
1697 agent->sa_pass_408 = pass_408 != 0;
1698 agent->sa_merge_482 = merge_482 != 0;
1699 agent->sa_cancel_2543 = cancel_2543 != 0;
1700 agent->sa_cancel_487 = cancel_487 != 0;
1701 agent->sa_invite_100rel = invite_100rel != 0;
1702 agent->sa_timestamp = use_timestamp != 0;
1703 agent->sa_use_naptr = use_naptr != 0;
1704 agent->sa_use_srv = use_srv != 0;
1705 agent->sa_srv_503 = srv_503 != 0;
1706 agent->sa_smime = smime;
1707 agent->sa_flags = flags & MSG_FLG_USERMASK;
1708 agent->sa_rport = rport != 0;
1709 agent->sa_tcp_rport = tcp_rport != 0;
1710 agent->sa_tls_rport = tls_rport != 0;
1711 agent->sa_preload = preload;
1712 agent->sa_tport_threadpool = threadpool;
1713
1714 return n;
1715 }
1716
1717 static
agent_set_udp_params(nta_agent_t * self,usize_t udp_mtu)1718 void agent_set_udp_params(nta_agent_t *self, usize_t udp_mtu)
1719 {
1720 tport_t *tp;
1721
1722 /* Set via fields for the tports */
1723 for (tp = tport_primaries(self->sa_tports); tp; tp = tport_next(tp)) {
1724 if (tport_is_udp(tp))
1725 tport_set_params(tp,
1726 TPTAG_TIMEOUT(2 * self->sa_t1x64),
1727 TPTAG_MTU(udp_mtu),
1728 TAG_END());
1729 }
1730 }
1731
1732 /**Get NTA Parameters.
1733 *
1734 * The nta_agent_get_params() function retrieves the stack parameters. The
1735 * parameters determine the way NTA handles the retransmissions, how long
1736 * NTA keeps transactions alive, does NTA apply proxy or user-agent logic to
1737 * INVITE transactions, or how the @Via headers are generated.
1738 *
1739 * @TAGS
1740 * NTATAG_ALIASES_REF(), NTATAG_BLACKLIST_REF(),
1741 * NTATAG_CANCEL_2543_REF(), NTATAG_CANCEL_487_REF(),
1742 * NTATAG_CLIENT_RPORT_REF(), NTATAG_CONTACT_REF(),
1743 * NTATAG_DEBUG_DROP_PROB_REF(), NTATAG_DEFAULT_PROXY_REF(),
1744 * NTATAG_EXTRA_100_REF(), NTATAG_GRAYLIST_REF(),
1745 * NTATAG_MAXSIZE_REF(), NTATAG_MAX_FORWARDS_REF(), NTATAG_MCLASS_REF(),
1746 * NTATAG_MERGE_482_REF(), NTATAG_MAX_PROCEEDING_REF(),
1747 * NTATAG_PASS_100_REF(), NTATAG_PASS_408_REF(), NTATAG_PRELOAD_REF(),
1748 * NTATAG_PROGRESS_REF(),
1749 * NTATAG_REL100_REF(),
1750 * NTATAG_SERVER_RPORT_REF(),
1751 * NTATAG_SIGCOMP_ALGORITHM_REF(), NTATAG_SIGCOMP_OPTIONS_REF(),
1752 * NTATAG_SIPFLAGS_REF(),
1753 * NTATAG_SIP_T1_REF(), NTATAG_SIP_T1X64_REF(), NTATAG_SIP_T2_REF(),
1754 * NTATAG_SIP_T4_REF(), NTATAG_SMIME_REF(), NTATAG_STATELESS_REF(),
1755 * NTATAG_TAG_3261_REF(), NTATAG_TIMEOUT_408_REF(), NTATAG_TIMER_C_REF(),
1756 * NTATAG_UA_REF(), NTATAG_UDP_MTU_REF(), NTATAG_USER_VIA_REF(),
1757 * NTATAG_USE_NAPTR_REF(), NTATAG_USE_SRV_REF(),
1758 * and NTATAG_USE_TIMESTAMP_REF().
1759 *
1760 */
nta_agent_get_params(nta_agent_t * agent,tag_type_t tag,tag_value_t value,...)1761 int nta_agent_get_params(nta_agent_t *agent,
1762 tag_type_t tag, tag_value_t value, ...)
1763 {
1764 int n;
1765 ta_list ta;
1766
1767 if (agent) {
1768 ta_start(ta, tag, value);
1769 n = agent_get_params(agent, ta_args(ta));
1770 ta_end(ta);
1771 return n;
1772 }
1773
1774 su_seterrno(EINVAL);
1775 return -1;
1776 }
1777
1778 /** Get NTA parameters */
1779 static
agent_get_params(nta_agent_t * agent,tagi_t * tags)1780 int agent_get_params(nta_agent_t *agent, tagi_t *tags)
1781 {
1782 return
1783 tl_tgets(tags,
1784 NTATAG_ALIASES(agent->sa_aliases),
1785 NTATAG_BLACKLIST(agent->sa_blacklist),
1786 NTATAG_CANCEL_2543(agent->sa_cancel_2543),
1787 NTATAG_CANCEL_487(agent->sa_cancel_487),
1788 NTATAG_CLIENT_RPORT(agent->sa_rport),
1789 NTATAG_CONTACT(agent->sa_contact),
1790 NTATAG_DEBUG_DROP_PROB(agent->sa_drop_prob),
1791 NTATAG_DEFAULT_PROXY(agent->sa_default_proxy),
1792 NTATAG_EXTRA_100(agent->sa_extra_100),
1793 NTATAG_GRAYLIST(agent->sa_graylist),
1794 NTATAG_MAXSIZE(agent->sa_maxsize),
1795 NTATAG_MAX_PROCEEDING(agent->sa_max_proceeding),
1796 NTATAG_MAX_FORWARDS(agent->sa_max_forwards->mf_count),
1797 NTATAG_MCLASS(agent->sa_mclass),
1798 NTATAG_MERGE_482(agent->sa_merge_482),
1799 NTATAG_PASS_100(agent->sa_pass_100),
1800 NTATAG_PASS_408(agent->sa_pass_408),
1801 NTATAG_PRELOAD(agent->sa_preload),
1802 NTATAG_PROGRESS(agent->sa_progress),
1803 NTATAG_REL100(agent->sa_invite_100rel),
1804 NTATAG_SERVER_RPORT((int)(agent->sa_server_rport)),
1805 NTATAG_SIGCOMP_ALGORITHM(agent->sa_algorithm),
1806 NTATAG_SIGCOMP_OPTIONS(agent->sa_sigcomp_options ?
1807 agent->sa_sigcomp_options :
1808 "sip"),
1809 NTATAG_SIPFLAGS(agent->sa_flags),
1810 NTATAG_SIP_T1(agent->sa_t1),
1811 NTATAG_SIP_T1X64(agent->sa_t1x64),
1812 NTATAG_SIP_T2(agent->sa_t2),
1813 NTATAG_SIP_T4(agent->sa_t4),
1814 #if HAVE_SOFIA_SMIME
1815 NTATAG_SMIME(agent->sa_smime),
1816 #else
1817 NTATAG_SMIME(NULL),
1818 #endif
1819 NTATAG_STATELESS(agent->sa_is_stateless),
1820 NTATAG_TAG_3261(1),
1821 NTATAG_TIMEOUT_408(agent->sa_timeout_408),
1822 NTATAG_TIMER_C(agent->sa_timer_c),
1823 NTATAG_UA(agent->sa_is_a_uas),
1824 NTATAG_UDP_MTU(agent->sa_udp_mtu),
1825 NTATAG_USER_VIA(agent->sa_user_via),
1826 NTATAG_USE_NAPTR(agent->sa_use_naptr),
1827 NTATAG_USE_SRV(agent->sa_use_srv),
1828 NTATAG_USE_TIMESTAMP(agent->sa_timestamp),
1829 NTATAG_SRV_503(agent->sa_srv_503),
1830 TAG_END());
1831 }
1832
1833 /**Get NTA statistics.
1834 *
1835 * The nta_agent_get_stats() function retrieves the stack statistics.
1836 *
1837 * @TAGS
1838 * NTATAG_S_ACKED_TR_REF(),
1839 * NTATAG_S_BAD_MESSAGE_REF(),
1840 * NTATAG_S_BAD_REQUEST_REF(),
1841 * NTATAG_S_BAD_RESPONSE_REF(),
1842 * NTATAG_S_CANCELED_TR_REF(),
1843 * NTATAG_S_CLIENT_TR_REF(),
1844 * NTATAG_S_DIALOG_TR_REF(),
1845 * NTATAG_S_DROP_REQUEST_REF(),
1846 * NTATAG_S_DROP_RESPONSE_REF(),
1847 * NTATAG_S_IRQ_HASH_REF(),
1848 * NTATAG_S_IRQ_HASH_USED_REF(),
1849 * NTATAG_S_LEG_HASH_REF(),
1850 * NTATAG_S_LEG_HASH_USED_REF(),
1851 * NTATAG_S_MERGED_REQUEST_REF(),
1852 * NTATAG_S_ORQ_HASH_REF(),
1853 * NTATAG_S_ORQ_HASH_USED_REF(),
1854 * NTATAG_S_RECV_MSG_REF(),
1855 * NTATAG_S_RECV_REQUEST_REF(),
1856 * NTATAG_S_RECV_RESPONSE_REF(),
1857 * NTATAG_S_RECV_RETRY_REF(),
1858 * NTATAG_S_RETRY_REQUEST_REF(),
1859 * NTATAG_S_RETRY_RESPONSE_REF(),
1860 * NTATAG_S_SENT_MSG_REF(),
1861 * NTATAG_S_SENT_REQUEST_REF(),
1862 * NTATAG_S_SENT_RESPONSE_REF(),
1863 * NTATAG_S_SERVER_TR_REF(),
1864 * NTATAG_S_TOUT_REQUEST_REF(),
1865 * NTATAG_S_TOUT_RESPONSE_REF(),
1866 * NTATAG_S_TRLESS_200_REF(),
1867 * NTATAG_S_TRLESS_REQUEST_REF(),
1868 * NTATAG_S_TRLESS_RESPONSE_REF(), and
1869 * NTATAG_S_TRLESS_TO_TR_REF(),
1870 */
nta_agent_get_stats(nta_agent_t * agent,tag_type_t tag,tag_value_t value,...)1871 int nta_agent_get_stats(nta_agent_t *agent,
1872 tag_type_t tag, tag_value_t value, ...)
1873 {
1874 int n;
1875 ta_list ta;
1876
1877 if (!agent)
1878 return su_seterrno(EINVAL), -1;
1879
1880 ta_start(ta, tag, value);
1881
1882 n = tl_tgets(ta_args(ta),
1883 NTATAG_S_IRQ_HASH(agent->sa_incoming->iht_size),
1884 NTATAG_S_ORQ_HASH(agent->sa_outgoing->oht_size),
1885 NTATAG_S_LEG_HASH(agent->sa_dialogs->lht_size),
1886 NTATAG_S_IRQ_HASH_USED(agent->sa_incoming->iht_used),
1887 NTATAG_S_ORQ_HASH_USED(agent->sa_outgoing->oht_used),
1888 NTATAG_S_LEG_HASH_USED(agent->sa_dialogs->lht_used),
1889 NTATAG_S_RECV_MSG(agent->sa_stats->as_recv_msg),
1890 NTATAG_S_RECV_REQUEST(agent->sa_stats->as_recv_request),
1891 NTATAG_S_RECV_RESPONSE(agent->sa_stats->as_recv_response),
1892 NTATAG_S_BAD_MESSAGE(agent->sa_stats->as_bad_message),
1893 NTATAG_S_BAD_REQUEST(agent->sa_stats->as_bad_request),
1894 NTATAG_S_BAD_RESPONSE(agent->sa_stats->as_bad_response),
1895 NTATAG_S_DROP_REQUEST(agent->sa_stats->as_drop_request),
1896 NTATAG_S_DROP_RESPONSE(agent->sa_stats->as_drop_response),
1897 NTATAG_S_CLIENT_TR(agent->sa_stats->as_client_tr),
1898 NTATAG_S_SERVER_TR(agent->sa_stats->as_server_tr),
1899 NTATAG_S_DIALOG_TR(agent->sa_stats->as_dialog_tr),
1900 NTATAG_S_ACKED_TR(agent->sa_stats->as_acked_tr),
1901 NTATAG_S_CANCELED_TR(agent->sa_stats->as_canceled_tr),
1902 NTATAG_S_TRLESS_REQUEST(agent->sa_stats->as_trless_request),
1903 NTATAG_S_TRLESS_TO_TR(agent->sa_stats->as_trless_to_tr),
1904 NTATAG_S_TRLESS_RESPONSE(agent->sa_stats->as_trless_response),
1905 NTATAG_S_TRLESS_200(agent->sa_stats->as_trless_200),
1906 NTATAG_S_MERGED_REQUEST(agent->sa_stats->as_merged_request),
1907 NTATAG_S_SENT_MSG(agent->sa_stats->as_sent_msg),
1908 NTATAG_S_SENT_REQUEST(agent->sa_stats->as_sent_request),
1909 NTATAG_S_SENT_RESPONSE(agent->sa_stats->as_sent_response),
1910 NTATAG_S_RETRY_REQUEST(agent->sa_stats->as_retry_request),
1911 NTATAG_S_RETRY_RESPONSE(agent->sa_stats->as_retry_response),
1912 NTATAG_S_RECV_RETRY(agent->sa_stats->as_recv_retry),
1913 NTATAG_S_TOUT_REQUEST(agent->sa_stats->as_tout_request),
1914 NTATAG_S_TOUT_RESPONSE(agent->sa_stats->as_tout_response),
1915 TAG_END());
1916
1917 ta_end(ta);
1918
1919 return n;
1920 }
1921
1922 /**Calculate a new unique tag.
1923 *
1924 * This function generates a series of 2**64 unique tags for @From or @To
1925 * headers. The start of the tag series is derived from the NTP time the NTA
1926 * agent was initialized.
1927 *
1928 */
nta_agent_newtag(su_home_t * home,char const * fmt,nta_agent_t * sa)1929 char const *nta_agent_newtag(su_home_t *home, char const *fmt, nta_agent_t *sa)
1930 {
1931 char tag[(8 * 8 + 4)/ 5 + 1];
1932
1933 if (sa == NULL)
1934 return su_seterrno(EINVAL), NULL;
1935
1936 /* XXX - use a cryptographically safe func here? */
1937 sa->sa_tags += NTA_TAG_PRIME;
1938
1939 msg_random_token(tag, sizeof(tag) - 1, &sa->sa_tags, sizeof(sa->sa_tags));
1940
1941 if (fmt && fmt[0])
1942 return su_sprintf(home, fmt, tag);
1943 else
1944 return su_strdup(home, tag);
1945 }
1946
1947 /**
1948 * Calculate branch value.
1949 */
stateful_branch(su_home_t * home,nta_agent_t * sa)1950 static char const *stateful_branch(su_home_t *home, nta_agent_t *sa)
1951 {
1952 char branch[(8 * 8 + 4)/ 5 + 1];
1953
1954 /* XXX - use a cryptographically safe func here? */
1955 sa->sa_branch += NTA_BRANCH_PRIME;
1956
1957 msg_random_token(branch, sizeof(branch) - 1,
1958 &sa->sa_branch, sizeof(sa->sa_branch));
1959
1960 return su_sprintf(home, "branch=z9hG4bK%s", branch);
1961 }
1962
1963 #include <sofia-sip/su_md5.h>
1964
1965 /**
1966 * Calculate branch value for stateless operation.
1967 *
1968 * XXX - should include HMAC of previous @Via line.
1969 */
1970 static
stateless_branch(nta_agent_t * sa,msg_t * msg,sip_t const * sip,tp_name_t const * tpn)1971 char const *stateless_branch(nta_agent_t *sa,
1972 msg_t *msg,
1973 sip_t const *sip,
1974 tp_name_t const *tpn)
1975 {
1976 su_md5_t md5[1];
1977 uint8_t digest[SU_MD5_DIGEST_SIZE];
1978 char branch[(SU_MD5_DIGEST_SIZE * 8 + 4)/ 5 + 1];
1979 sip_route_t const *r;
1980
1981 assert(sip->sip_request);
1982
1983 if (!sip->sip_via)
1984 return stateful_branch(msg_home(msg), sa);
1985
1986 su_md5_init(md5);
1987
1988 su_md5_str0update(md5, tpn->tpn_host);
1989 su_md5_str0update(md5, tpn->tpn_port);
1990
1991 url_update(md5, sip->sip_request->rq_url);
1992 if (sip->sip_call_id) {
1993 su_md5_str0update(md5, sip->sip_call_id->i_id);
1994 }
1995 if (sip->sip_from) {
1996 url_update(md5, sip->sip_from->a_url);
1997 su_md5_stri0update(md5, sip->sip_from->a_tag);
1998 }
1999 if (sip->sip_to) {
2000 url_update(md5, sip->sip_to->a_url);
2001 /* XXX - some broken implementations include To tag in CANCEL */
2002 /* su_md5_str0update(md5, sip->sip_to->a_tag); */
2003 }
2004 if (sip->sip_cseq) {
2005 uint32_t cseq = htonl(sip->sip_cseq->cs_seq);
2006 su_md5_update(md5, &cseq, sizeof(cseq));
2007 }
2008
2009 for (r = sip->sip_route; r; r = r->r_next)
2010 url_update(md5, r->r_url);
2011
2012 su_md5_digest(md5, digest);
2013
2014 msg_random_token(branch, sizeof(branch) - 1, digest, sizeof(digest));
2015
2016 return su_sprintf(msg_home(msg), "branch=z9hG4bK.%s", branch);
2017 }
2018
2019 /* ====================================================================== */
2020 /* 2) Transport interface */
2021
2022 /* Local prototypes */
2023 static int agent_create_master_transport(nta_agent_t *self, tagi_t *tags);
2024 static int agent_init_via(nta_agent_t *self, tport_t *primaries, int use_maddr);
2025 static int agent_init_contact(nta_agent_t *self);
2026 static void agent_recv_message(nta_agent_t *agent,
2027 tport_t *tport,
2028 msg_t *msg,
2029 sip_via_t *tport_via,
2030 su_time_t now);
2031 static void agent_tp_error(nta_agent_t *agent,
2032 tport_t *tport,
2033 int errcode,
2034 char const *remote);
2035 static void agent_update_tport(nta_agent_t *agent, tport_t *);
2036
2037 /**For each transport, we have name used by tport module, SRV prefixes used
2038 * for resolving, and NAPTR service/conversion.
2039 */
2040 static
2041 struct sipdns_tport {
2042 char name[6]; /**< Named used by tport module */
2043 char port[6]; /**< Default port number */
2044 char prefix[14]; /**< Prefix for SRV domains */
2045 char service[10]; /**< NAPTR service */
2046 }
2047 #define SIPDNS_TRANSPORTS (6)
2048 const sipdns_tports[SIPDNS_TRANSPORTS] = {
2049 { "udp", "5060", "_sip._udp.", "SIP+D2U" },
2050 { "tcp", "5060", "_sip._tcp.", "SIP+D2T" },
2051 { "sctp", "5060", "_sip._sctp.", "SIP+D2S" },
2052 { "tls", "5061", "_sips._tcp.", "SIPS+D2T" },
2053 { "ws", "5080", "_sips._ws.", "SIP+D2W" },
2054 { "wss", "5081", "_sips._wss.", "SIPS+D2W" },
2055 };
2056
2057 static char const * const tports_sip[] =
2058 {
2059 "udp", "tcp", "sctp", "ws", NULL
2060 };
2061
2062 static char const * const tports_sips[] =
2063 {
2064 "tls", "wss", "ws", NULL
2065 };
2066
2067 static tport_stack_class_t nta_agent_class[1] =
2068 {{
2069 sizeof(nta_agent_class),
2070 agent_recv_message,
2071 agent_tp_error,
2072 nta_msg_create_for_transport,
2073 agent_update_tport,
2074 }};
2075
2076
2077 /** Add a transport to the agent.
2078 *
2079 * Creates a new transport and binds it
2080 * to the port specified by the @a uri. The @a uri must have sip: or sips:
2081 * scheme or be a wildcard uri ("*"). The @a uri syntax allowed is as
2082 * follows:
2083 *
2084 * @code url <scheme>:<host>[:<port>]<url-params> @endcode
2085 * where <url-params> may be
2086 * @code
2087 * ;transport=<xxx>
2088 * ;maddr=<actual addr>
2089 * ;comp=sigcomp
2090 * @endcode
2091 *
2092 * The scheme part determines which transports are used. "sip" implies UDP
2093 * and TCP, "sips" TLS over TCP. In the future, more transports can be
2094 * supported, for instance, "sip" can use SCTP or DCCP, "sips" DTLS or TLS
2095 * over SCTP.
2096 *
2097 * The "host" part determines what address/domain name is used in @Contact.
2098 * An "*" in "host" part is shorthand for any local IP address. 0.0.0.0
2099 * means that the only the IPv4 addresses are used. [::] means that only
2100 * the IPv6 addresses are used. If a domain name or a specific IP address
2101 * is given as "host" part, an additional "maddr" parameter can be used to
2102 * control which addresses are used by the stack when binding listen
2103 * sockets for incoming requests.
2104 *
2105 * The "port" determines what port is used in contact, and to which port the
2106 * stack binds in order to listen for incoming requests. Empty or missing
2107 * port means that default port should be used (5060 for sip, 5061 for
2108 * sips). An "*" in "port" part means any port, i.e., the stack binds to an
2109 * ephemeral port.
2110 *
2111 * The "transport" parameter determines the transport protocol that is used
2112 * and how they are preferred. If no protocol is specified, both UDP and TCP
2113 * are used for SIP URL and TLS for SIPS URL. The preference can be
2114 * indicated with a comma-separated list of transports, for instance,
2115 * parameter @code transport=tcp,udp @endcode indicates that TCP is
2116 * preferred to UDP.
2117 *
2118 * The "maddr" parameter determines to which address the stack binds in
2119 * order to listen for incoming requests. An "*" in "maddr" parameter is
2120 * shorthand for any local IP address. 0.0.0.0 means that only IPv4 sockets
2121 * are created. [::] means that only IPv6 sockets are created.
2122 *
2123 * The "comp" parameter determines the supported compression protocol.
2124 * Currently only sigcomp is supported (with suitable library).
2125 *
2126 * @par Examples:
2127 * @code sip:172.21.40.24;maddr=* @endcode \n
2128 * @code sip:172.21.40.24:50600;transport=TCP,UDP;comp=sigcomp @endcode \n
2129 * @code sips:* @endcode
2130 *
2131 * @return
2132 * On success, zero is returned. On error, -1 is returned, and @a errno is
2133 * set appropriately.
2134 */
nta_agent_add_tport(nta_agent_t * self,url_string_t const * uri,tag_type_t tag,tag_value_t value,...)2135 int nta_agent_add_tport(nta_agent_t *self,
2136 url_string_t const *uri,
2137 tag_type_t tag, tag_value_t value, ...)
2138 {
2139 url_t *url;
2140 char tp[32];
2141 char maddr[256];
2142 char comp[32];
2143 tp_name_t tpn[1] = {{ NULL }};
2144 char const * const * tports = tports_sip;
2145 int error;
2146 ta_list ta;
2147 char *tps[9] = {0};
2148
2149 if (self == NULL) {
2150 su_seterrno(EINVAL);
2151 return -1;
2152 }
2153
2154 if (uri == NULL)
2155 uri = (url_string_t *)"sip:*";
2156 else if (url_string_p(uri) ?
2157 strcmp(uri->us_str, "*") == 0 :
2158 uri->us_url->url_type == url_any) {
2159 uri = (url_string_t *)"sip:*:*";
2160 }
2161
2162 if (!(url = url_hdup(self->sa_home, uri->us_url)) ||
2163 (url->url_type != url_sip && url->url_type != url_sips)) {
2164 if (url_string_p(uri))
2165 SU_DEBUG_1(("nta: %s: invalid bind URL\n", uri->us_str));
2166 else
2167 SU_DEBUG_1(("nta: invalid bind URL\n" VA_NONE));
2168 su_seterrno(EINVAL);
2169 return -1;
2170 }
2171
2172 tpn->tpn_canon = url->url_host;
2173 tpn->tpn_host = url->url_host;
2174 tpn->tpn_port = url_port(url);
2175
2176 if (url->url_type == url_sip) {
2177 tpn->tpn_proto = "*";
2178 tports = tports_sip;
2179 if (!tpn->tpn_port || !tpn->tpn_port[0])
2180 tpn->tpn_port = SIP_DEFAULT_SERV;
2181 }
2182 else {
2183 assert(url->url_type == url_sips);
2184 tpn->tpn_proto = "*";
2185 tports = tports_sips;
2186 if (!tpn->tpn_port || !tpn->tpn_port[0])
2187 tpn->tpn_port = SIPS_DEFAULT_SERV;
2188 }
2189
2190 if (url->url_params) {
2191 if (url_param(url->url_params, "transport", tp, sizeof(tp)) > 0) {
2192 if (strchr(tp, ',')) {
2193 int i; char *t;
2194
2195 /* Split tp into transports */
2196 for (i = 0, t = tp; t && i < 8; i++) {
2197 tps[i] = t;
2198 if ((t = strchr(t, ',')))
2199 *t++ = '\0';
2200 }
2201
2202 tps[i] = NULL;
2203 tports = (char const * const *)tps;
2204 } else {
2205 tpn->tpn_proto = tp;
2206 }
2207 }
2208 if (url_param(url->url_params, "maddr", maddr, sizeof(maddr)) > 0)
2209 tpn->tpn_host = maddr;
2210 if (url_param(url->url_params, "comp", comp, sizeof(comp)) > 0)
2211 tpn->tpn_comp = comp;
2212
2213 if (tpn->tpn_comp &&
2214 (nta_compressor_vtable == NULL ||
2215 !su_casematch(tpn->tpn_comp, nta_compressor_vtable->ncv_name))) {
2216 SU_DEBUG_1(("nta(%p): comp=%s not supported for " URL_PRINT_FORMAT "\n",
2217 (void *)self, tpn->tpn_comp, URL_PRINT_ARGS(url)));
2218 }
2219 }
2220
2221 ta_start(ta, tag, value);
2222
2223 if (self->sa_tports == NULL) {
2224 if (agent_create_master_transport(self, ta_args(ta)) < 0) {
2225 error = su_errno();
2226 SU_DEBUG_1(("nta: cannot create master transport: %s\n",
2227 su_strerror(error)));
2228 goto error;
2229 }
2230 }
2231
2232 if (tport_tbind(self->sa_tports, tpn, tports, ta_tags(ta)) < 0) {
2233 error = su_errno();
2234 SU_DEBUG_1(("nta: bind(%s:%s;transport=%s%s%s%s%s): %s\n",
2235 tpn->tpn_canon, tpn->tpn_port, tpn->tpn_proto,
2236 tpn->tpn_canon != tpn->tpn_host ? ";maddr=" : "",
2237 tpn->tpn_canon != tpn->tpn_host ? tpn->tpn_host : "",
2238 tpn->tpn_comp ? ";comp=" : "",
2239 tpn->tpn_comp ? tpn->tpn_comp : "",
2240 su_strerror(error)));
2241 goto error;
2242 }
2243 else
2244 SU_DEBUG_5(("nta: bound to (%s:%s;transport=%s%s%s%s%s)\n",
2245 tpn->tpn_canon, tpn->tpn_port, tpn->tpn_proto,
2246 tpn->tpn_canon != tpn->tpn_host ? ";maddr=" : "",
2247 tpn->tpn_canon != tpn->tpn_host ? tpn->tpn_host : "",
2248 tpn->tpn_comp ? ";comp=" : "",
2249 tpn->tpn_comp ? tpn->tpn_comp : ""));
2250
2251 /* XXX - when to use maddr? */
2252 if ((agent_init_via(self, tport_primaries(self->sa_tports), 0)) < 0) {
2253 error = su_errno();
2254 SU_DEBUG_1(("nta: cannot create Via headers\n" VA_NONE));
2255 goto error;
2256 }
2257 else
2258 SU_DEBUG_9(("nta: Via fields initialized\n" VA_NONE));
2259
2260 if ((agent_init_contact(self)) < 0) {
2261 error = su_errno();
2262 SU_DEBUG_1(("nta: cannot create Contact header\n" VA_NONE));
2263 goto error;
2264 }
2265 else
2266 SU_DEBUG_9(("nta: Contact header created\n" VA_NONE));
2267
2268 su_free(self->sa_home, url);
2269 ta_end(ta);
2270
2271 return 0;
2272
2273 error:
2274 ta_end(ta);
2275 su_seterrno(error);
2276 return -1;
2277 }
2278
2279 static
agent_create_master_transport(nta_agent_t * self,tagi_t * tags)2280 int agent_create_master_transport(nta_agent_t *self, tagi_t *tags)
2281 {
2282 self->sa_tports =
2283 tport_tcreate(self, nta_agent_class, self->sa_root,
2284 TPTAG_IDLE(1800000),
2285 TAG_NEXT(tags));
2286
2287 if (!self->sa_tports)
2288 return -1;
2289
2290 SU_DEBUG_9(("nta: master transport created\n" VA_NONE));
2291
2292 return 0;
2293 }
2294
2295
2296 /** Initialize @Via headers. */
2297 static
agent_init_via(nta_agent_t * self,tport_t * primaries,int use_maddr)2298 int agent_init_via(nta_agent_t *self, tport_t *primaries, int use_maddr)
2299 {
2300 sip_via_t *via = NULL, *new_via, *dup_via, *v, **vv = &via;
2301 sip_via_t *new_vias, **next_new_via, *new_publics, **next_new_public;
2302 tport_t *tp;
2303 su_addrinfo_t const *ai;
2304
2305 su_home_t autohome[SU_HOME_AUTO_SIZE(2048)];
2306
2307 su_home_auto(autohome, sizeof autohome);
2308
2309 self->sa_tport_ip4 = 0;
2310 self->sa_tport_ip6 = 0;
2311 self->sa_tport_udp = 0;
2312 self->sa_tport_tcp = 0;
2313 self->sa_tport_sctp = 0;
2314 self->sa_tport_tls = 0;
2315 self->sa_tport_ws = 0;
2316 self->sa_tport_wss = 0;
2317
2318 /* Set via fields for the tports */
2319 for (tp = primaries; tp; tp = tport_next(tp)) {
2320 int maddr;
2321 tp_name_t tpn[1];
2322 char const *comp = NULL;
2323
2324 *tpn = *tport_name(tp);
2325
2326 assert(tpn->tpn_proto);
2327 assert(tpn->tpn_canon);
2328 assert(tpn->tpn_host);
2329 assert(tpn->tpn_port);
2330
2331 #if 0
2332 if (getenv("SIP_UDP_CONNECT")
2333 && strcmp(tpn->tpn_proto, "udp") == 0)
2334 tport_set_params(tp, TPTAG_CONNECT(1), TAG_END());
2335 #endif
2336
2337 if (tport_has_ip4(tp)) self->sa_tport_ip4 = 1;
2338
2339 #if SU_HAVE_IN6
2340 if (tport_has_ip6(tp)) self->sa_tport_ip6 = 1;
2341 #endif
2342
2343 if (su_casematch(tpn->tpn_proto, "udp"))
2344 self->sa_tport_udp = 1;
2345 else if (su_casematch(tpn->tpn_proto, "tcp"))
2346 self->sa_tport_tcp = 1;
2347 else if (su_casematch(tpn->tpn_proto, "sctp"))
2348 self->sa_tport_sctp = 1;
2349 else if (su_casematch(tpn->tpn_proto, "ws"))
2350 self->sa_tport_ws = 1;
2351 else if (su_casematch(tpn->tpn_proto, "wss"))
2352 self->sa_tport_wss = 1;
2353
2354 if (tport_has_tls(tp)) self->sa_tport_tls = 1;
2355
2356 ai = tport_get_address(tp);
2357
2358 for (; ai; ai = ai->ai_next) {
2359 char host[TPORT_HOSTPORTSIZE] = "";
2360 char sport[8];
2361 char const *canon = ai->ai_canonname;
2362 su_sockaddr_t *su = (void *)ai->ai_addr;
2363 int port;
2364
2365 if (su) {
2366 su_inet_ntop(su->su_family, SU_ADDR(su), host, sizeof host);
2367 maddr = use_maddr && !su_casematch(canon, host);
2368 port = ntohs(su->su_port);
2369 }
2370 else {
2371 msg_random_token(host, 16, NULL, 0);
2372 canon = strcat(host, ".is.invalid");
2373 maddr = 0;
2374 port = 0;
2375 }
2376
2377 if (su_casenmatch(tpn->tpn_proto, "tls", 3)
2378 ? port == SIPS_DEFAULT_PORT
2379 : port == SIP_DEFAULT_PORT)
2380 port = 0;
2381
2382 snprintf(sport, sizeof sport, ":%u", port);
2383
2384 comp = tpn->tpn_comp;
2385
2386 SU_DEBUG_9(("nta: agent_init_via: "
2387 "%s/%s %s%s%s%s%s%s (%s)\n",
2388 SIP_VERSION_CURRENT, tpn->tpn_proto,
2389 canon, port ? sport : "",
2390 maddr ? ";maddr=" : "", maddr ? host : "",
2391 comp ? ";comp=" : "", comp ? comp : "",
2392 tpn->tpn_ident ? tpn->tpn_ident : "*"));
2393
2394 v = sip_via_format(autohome,
2395 "%s/%s %s%s%s%s%s%s",
2396 SIP_VERSION_CURRENT, tpn->tpn_proto,
2397 canon, port ? sport : "",
2398 maddr ? ";maddr=" : "", maddr ? host : "",
2399 comp ? ";comp=" : "", comp ? comp : "");
2400 if (v == NULL)
2401 goto error;
2402
2403 v->v_comment = tpn->tpn_ident;
2404 v->v_common->h_data = tp; /* Nasty trick */
2405 *vv = v; vv = &(*vv)->v_next;
2406 }
2407 }
2408
2409 if (!via) {
2410 SU_DEBUG_9(("nta: agent_init_via failed\n" VA_NONE));
2411 goto error;
2412 }
2413
2414 /* Duplicate the list bind to the transports */
2415 new_via = sip_via_dup(self->sa_home, via);
2416 /* Duplicate the complete list shown to the application */
2417 dup_via = sip_via_dup(self->sa_home, via);
2418
2419 if (via && (!new_via || !dup_via)) {
2420 msg_header_free(self->sa_home, (void *)new_via);
2421 msg_header_free(self->sa_home, (void *)dup_via);
2422 goto error;
2423 }
2424
2425 new_vias = NULL, next_new_via = &new_vias;
2426 new_publics = NULL, next_new_public = &new_publics;
2427
2428 /* Set via field magic for the tports */
2429 for (tp = primaries; tp; tp = tport_next(tp)) {
2430 assert(via->v_common->h_data == tp);
2431 v = tport_magic(tp);
2432 tport_set_magic(tp, new_via);
2433 msg_header_free(self->sa_home, (void *)v);
2434
2435 if (tport_is_public(tp))
2436 *next_new_public = dup_via;
2437 else
2438 *next_new_via = dup_via;
2439
2440 while (via->v_next && via->v_next->v_common->h_data == tp)
2441 via = via->v_next, new_via = new_via->v_next, dup_via = dup_via->v_next;
2442
2443 via = via->v_next;
2444 /* Break the link in via list between transports */
2445 vv = &new_via->v_next, new_via = *vv, *vv = NULL;
2446 vv = &dup_via->v_next, dup_via = *vv, *vv = NULL;
2447
2448 if (tport_is_public(tp))
2449 while (*next_new_public) next_new_public = &(*next_new_public)->v_next;
2450 else
2451 while (*next_new_via) next_new_via = &(*next_new_via)->v_next;
2452 }
2453
2454 assert(dup_via == NULL);
2455 assert(new_via == NULL);
2456
2457 if (self->sa_tport_udp)
2458 agent_set_udp_params(self, self->sa_udp_mtu);
2459
2460 v = self->sa_vias;
2461 self->sa_vias = new_vias;
2462 msg_header_free(self->sa_home, (void *)v);
2463
2464 v = self->sa_public_vias;
2465 self->sa_public_vias = new_publics;
2466 msg_header_free(self->sa_home, (void *)v);
2467
2468 su_home_deinit(autohome);
2469
2470 return 0;
2471
2472 error:
2473 su_home_deinit(autohome);
2474 return -1;
2475 }
2476
2477
2478 /** Initialize main contact header. */
2479 static
agent_init_contact(nta_agent_t * self)2480 int agent_init_contact(nta_agent_t *self)
2481 {
2482 sip_via_t const *v1, *v2;
2483 char const *tp;
2484
2485 if (self->sa_contact)
2486 return 0;
2487
2488 for (v1 = self->sa_vias ? self->sa_vias : self->sa_public_vias;
2489 v1;
2490 v1 = v1->v_next) {
2491 if (host_is_ip_address(v1->v_host)) {
2492 if (!host_is_local(v1->v_host))
2493 break;
2494 }
2495 else if (!host_has_domain_invalid(v1->v_host)) {
2496 break;
2497 }
2498 }
2499
2500 if (v1 == NULL)
2501 v1 = self->sa_vias ? self->sa_vias : self->sa_public_vias;
2502
2503 if (!v1)
2504 return -1;
2505
2506 tp = strrchr(v1->v_protocol, '/');
2507 if (!tp++)
2508 return -1;
2509
2510 v2 = v1->v_next;
2511
2512 if (v2 &&
2513 su_casematch(v1->v_host, v2->v_host) &&
2514 su_casematch(v1->v_port, v2->v_port)) {
2515 char const *p1 = v1->v_protocol, *p2 = v2->v_protocol;
2516
2517 if (!su_casematch(p1, sip_transport_udp))
2518 p1 = v2->v_protocol, p2 = v1->v_protocol;
2519
2520 if (su_casematch(p1, sip_transport_udp) &&
2521 su_casematch(p2, sip_transport_tcp))
2522 /* Do not include transport if we have both UDP and TCP */
2523 tp = NULL;
2524 }
2525
2526 self->sa_contact =
2527 sip_contact_create_from_via_with_transport(self->sa_home, v1, NULL, tp);
2528
2529 if (!self->sa_contact)
2530 return -1;
2531
2532 agent_tag_init(self);
2533
2534 return 0;
2535 }
2536
2537 /** Return @Via line corresponging to tport. */
2538 static
agent_tport_via(tport_t * tport)2539 sip_via_t const *agent_tport_via(tport_t *tport)
2540 {
2541 sip_via_t *v = tport_magic(tport);
2542 while (v && v->v_next)
2543 v = v->v_next;
2544 return v;
2545 }
2546
2547 /** Insert @Via to a request message */
2548 static
outgoing_insert_via(nta_outgoing_t * orq,sip_via_t const * via)2549 int outgoing_insert_via(nta_outgoing_t *orq,
2550 sip_via_t const *via)
2551 {
2552 nta_agent_t *self = orq->orq_agent;
2553 msg_t *msg = orq->orq_request;
2554 sip_t *sip = sip_object(msg);
2555 char const *branch = orq->orq_via_branch;
2556 int already = orq->orq_user_via || orq->orq_via_added;
2557 int user_via = orq->orq_user_via;
2558 sip_via_t *v;
2559 int clear = 0;
2560
2561 assert(sip); assert(via);
2562
2563 if (already && sip->sip_via) {
2564 /* Use existing @Via */
2565 v = sip->sip_via;
2566 }
2567 else if (msg && via && sip->sip_request &&
2568 (v = sip_via_copy(msg_home(msg), via))) {
2569 if (msg_header_insert(msg, (msg_pub_t *)sip, (msg_header_t *)v) < 0)
2570 return -1;
2571 orq->orq_via_added = 1;
2572 }
2573 else
2574 return -1;
2575
2576 if (!v->v_rport &&
2577 ((self->sa_rport && v->v_protocol == sip_transport_udp) ||
2578 (self->sa_tcp_rport && v->v_protocol == sip_transport_tcp) ||
2579 (self->sa_tls_rport && v->v_protocol == sip_transport_tls)))
2580 msg_header_add_param(msg_home(msg), v->v_common, "rport");
2581
2582 if (!orq->orq_tpn->tpn_comp)
2583 msg_header_remove_param(v->v_common, "comp");
2584
2585 if (branch && branch != v->v_branch) {
2586 char const *bvalue = branch + strcspn(branch, "=");
2587 if (*bvalue) bvalue++;
2588 if (!v->v_branch || !su_casematch(bvalue, v->v_branch))
2589 msg_header_replace_param(msg_home(msg), v->v_common, branch);
2590 }
2591
2592 if (!su_casematch(via->v_protocol, v->v_protocol))
2593 clear = 1, v->v_protocol = via->v_protocol;
2594
2595 /* XXX - should we do this? */
2596 if ((!user_via || !v->v_host) &&
2597 !su_strmatch(via->v_host, v->v_host))
2598 clear = 1, v->v_host = via->v_host;
2599
2600 if ((!user_via || !v->v_port ||
2601 /* Replace port in user Via only if we use udp and no rport */
2602 (v->v_protocol == sip_transport_udp && !v->v_rport &&
2603 !orq->orq_stateless)) &&
2604 !su_strmatch(via->v_port, v->v_port))
2605 clear = 1, v->v_port = via->v_port;
2606
2607 if (clear)
2608 msg_fragment_clear(v->v_common);
2609
2610 return 0;
2611 }
2612
2613 /** Get destination name from @Via.
2614 *
2615 * If @a using_rport is non-null, try rport.
2616 * If *using_rport is non-zero, try rport even if <protocol> is not UDP.
2617 * If <protocol> is UDP, set *using_rport to zero.
2618 */
2619 static
nta_tpn_by_via(tp_name_t * tpn,sip_via_t const * v,int * using_rport)2620 int nta_tpn_by_via(tp_name_t *tpn, sip_via_t const *v, int *using_rport)
2621 {
2622 if (!v)
2623 return -1;
2624
2625 tpn->tpn_proto = sip_via_transport(v);
2626 tpn->tpn_canon = v->v_host;
2627
2628 if (v->v_maddr)
2629 tpn->tpn_host = v->v_maddr;
2630 else if (v->v_received)
2631 tpn->tpn_host = v->v_received;
2632 else
2633 tpn->tpn_host = v->v_host;
2634
2635 tpn->tpn_port = sip_via_port(v, using_rport);
2636 tpn->tpn_comp = v->v_comp;
2637 tpn->tpn_ident = NULL;
2638
2639 return 0;
2640 }
2641
2642 /** Get transport name from URL. */
2643 static int
nta_tpn_by_url(su_home_t * home,tp_name_t * tpn,char const ** scheme,char const ** port,url_string_t const * us)2644 nta_tpn_by_url(su_home_t *home,
2645 tp_name_t *tpn,
2646 char const **scheme,
2647 char const **port,
2648 url_string_t const *us)
2649 {
2650 url_t url[1];
2651 isize_t n;
2652 char *b;
2653
2654 n = url_xtra(us->us_url);
2655 b = su_alloc(home, n);
2656
2657 if (b == NULL || url_dup(b, n, url, us->us_url) < 0) {
2658 su_free(home, b);
2659 return -1;
2660 }
2661
2662 if (url->url_type != url_sip &&
2663 url->url_type != url_sips &&
2664 url->url_type != url_im &&
2665 url->url_type != url_pres) {
2666 su_free(home, b);
2667 return -1;
2668 }
2669
2670 SU_DEBUG_7(("nta: selecting scheme %s\n", url->url_scheme));
2671
2672 *scheme = url->url_scheme;
2673
2674 tpn->tpn_proto = NULL;
2675 tpn->tpn_canon = url->url_host;
2676 tpn->tpn_host = url->url_host;
2677
2678 if (url->url_params) {
2679 for (b = (char *)url->url_params; b[0]; b += n) {
2680 n = strcspn(b, ";");
2681
2682 if (n > 10 && su_casenmatch(b, "transport=", 10))
2683 tpn->tpn_proto = b + 10;
2684 else if (n > 5 && su_casenmatch(b, "comp=", 5))
2685 tpn->tpn_comp = b + 5;
2686 else if (n > 6 && su_casenmatch(b, "maddr=", 6))
2687 tpn->tpn_host = b + 6;
2688
2689 if (b[n])
2690 b[n++] = '\0';
2691 }
2692 }
2693
2694 if ((*port = url->url_port))
2695 tpn->tpn_port = url->url_port;
2696
2697 tpn->tpn_ident = NULL;
2698
2699 if (tpn->tpn_proto) {
2700 if (su_casematch(url->url_scheme, "sips") && su_casematch(tpn->tpn_proto, "ws")) {
2701 tpn->tpn_proto = "wss";
2702 }
2703 return 1;
2704 }
2705
2706 if (su_casematch(url->url_scheme, "sips"))
2707 tpn->tpn_proto = "tls";
2708 else
2709 tpn->tpn_proto = "*";
2710
2711 return 0;
2712 }
2713
2714 /** Handle transport errors. */
2715 static
agent_tp_error(nta_agent_t * agent,tport_t * tport,int errcode,char const * remote)2716 void agent_tp_error(nta_agent_t *agent,
2717 tport_t *tport,
2718 int errcode,
2719 char const *remote)
2720 {
2721 su_llog(nta_log, 1,
2722 "nta_agent: tport: %s%s%s\n",
2723 remote ? remote : "", remote ? ": " : "",
2724 su_strerror(errcode));
2725
2726 if (agent->sa_error_tport) {
2727 agent->sa_error_tport(agent->sa_error_magic, agent, tport);
2728 }
2729 }
2730
2731 /** Handle updated transport addresses */
agent_update_tport(nta_agent_t * self,tport_t * tport)2732 static void agent_update_tport(nta_agent_t *self, tport_t *tport)
2733 {
2734 /* Initialize local Vias first */
2735 agent_init_via(self, tport_primaries(self->sa_tports), 0);
2736
2737 if (self->sa_update_tport) {
2738 self->sa_update_tport(self->sa_update_magic, self);
2739 }
2740 else {
2741 /* XXX - we should do something else? */
2742 SU_DEBUG_3(("%s(%p): %s\n", "nta", (void *)self,
2743 "transport address updated"));
2744 }
2745 }
2746
2747 /* ====================================================================== */
2748 /* 3) Message dispatch */
2749
2750 static void agent_recv_request(nta_agent_t *agent,
2751 msg_t *msg,
2752 sip_t *sip,
2753 tport_t *tport);
2754 static int agent_check_request_via(nta_agent_t *agent,
2755 msg_t *msg,
2756 sip_t *sip,
2757 sip_via_t *v,
2758 tport_t *tport);
2759 static int agent_aliases(nta_agent_t const *, url_t [], tport_t *);
2760 static void agent_recv_response(nta_agent_t*, msg_t *, sip_t *,
2761 sip_via_t *, tport_t*);
2762 static void agent_recv_garbage(nta_agent_t*, msg_t*, tport_t*);
2763
2764 #if HAVE_SOFIA_SRESOLV
2765 static void outgoing_resolve(nta_outgoing_t *orq,
2766 int explicit_transport,
2767 enum nta_res_order_e order);
2768 su_inline void outgoing_cancel_resolver(nta_outgoing_t *orq);
2769 su_inline void outgoing_destroy_resolver(nta_outgoing_t *orq);
2770 static int outgoing_other_destinations(nta_outgoing_t const *orq);
2771 static int outgoing_try_another(nta_outgoing_t *orq);
2772 #else
2773 #define outgoing_other_destinations(orq) (0)
2774 #define outgoing_try_another(orq) (0)
2775 #endif
2776
2777 /** Handle incoming message. */
2778 static
agent_recv_message(nta_agent_t * agent,tport_t * tport,msg_t * msg,sip_via_t * tport_via,su_time_t now)2779 void agent_recv_message(nta_agent_t *agent,
2780 tport_t *tport,
2781 msg_t *msg,
2782 sip_via_t *tport_via,
2783 su_time_t now)
2784 {
2785 sip_t *sip = sip_object(msg);
2786
2787 if (sip && sip->sip_request) {
2788 agent_recv_request(agent, msg, sip, tport);
2789 }
2790 else if (sip && sip->sip_status) {
2791 agent_recv_response(agent, msg, sip, tport_via, tport);
2792 }
2793 else {
2794 agent_recv_garbage(agent, msg, tport);
2795 }
2796 }
2797
2798 #ifdef HAVE_ZLIB_COMPRESS
sip_content_encoding_Xflate(msg_t * msg,sip_t * sip,int inflate,int check)2799 int sip_content_encoding_Xflate(msg_t *msg, sip_t *sip, int inflate, int check)
2800 {
2801 char const *method_name;
2802 unsigned cseq = sip->sip_cseq ? sip->sip_cseq->cs_seq : 0;
2803 int ok = !check;
2804
2805 if (!sip->sip_payload) {
2806 return 0;
2807 }
2808
2809 if (sip->sip_request) {
2810 method_name = sip->sip_request->rq_method_name;
2811 } else if (sip->sip_cseq) {
2812 method_name = sip->sip_cseq->cs_method_name;
2813 } else {
2814 method_name = "Unknown";
2815 }
2816
2817 if (!ok) {
2818 if (sip->sip_content_encoding && sip->sip_content_encoding->k_items) {
2819 const char *val = sip->sip_content_encoding->k_items[0];
2820 if (val && (!strcasecmp(val, "gzip") || !strcasecmp(val, "deflate"))) {
2821 ok = 1;
2822 }
2823 }
2824 }
2825
2826 if (ok) {
2827 unsigned long n = 0;
2828 void *decoded = NULL;
2829 const char *id = "N/A";
2830 const char *orig_payload = sip->sip_payload->pl_data;
2831
2832 n = sip->sip_payload->pl_len * 10;
2833
2834 decoded = su_alloc(msg_home(msg), n);
2835 assert(decoded);
2836
2837 if (inflate) {
2838 uncompress(decoded, &n, (void *)sip->sip_payload->pl_data, (unsigned long)sip->sip_payload->pl_len);
2839 } else {
2840 compress(decoded, &n, (void *)sip->sip_payload->pl_data, (unsigned long)sip->sip_payload->pl_len);
2841 }
2842
2843 sip->sip_payload = sip_payload_create(msg_home(msg), decoded, n);
2844 sip->sip_content_encoding = sip_content_encoding_make(msg_home(msg), "deflate");
2845
2846 if (sip->sip_call_id) {
2847 id = sip->sip_call_id->i_id;
2848 }
2849
2850 if (inflate) {
2851 SU_DEBUG_1(("nta: %s (%u) (%s) Inflating compressed body:\n%s\n", method_name, cseq, id, (char *)decoded));
2852 } else {
2853 SU_DEBUG_1(("nta: %s (%u) (%s) Deflating compressed body:\n%s\n", method_name, cseq, id, orig_payload));
2854 }
2855
2856 return 1;
2857 }
2858
2859 return 0;
2860 }
2861 #endif
2862
2863 /** @internal Handle incoming requests. */
2864 static
agent_recv_request(nta_agent_t * agent,msg_t * msg,sip_t * sip,tport_t * tport)2865 void agent_recv_request(nta_agent_t *agent,
2866 msg_t *msg,
2867 sip_t *sip,
2868 tport_t *tport)
2869 {
2870 nta_leg_t *leg;
2871 nta_incoming_t *irq, *merge = NULL, *ack = NULL, *cancel = NULL;
2872 sip_method_t method = sip->sip_request->rq_method;
2873 char const *method_name = sip->sip_request->rq_method_name;
2874 url_t url[1];
2875 unsigned cseq = sip->sip_cseq ? sip->sip_cseq->cs_seq : 0;
2876 int insane, errors, stream;
2877 unsigned compressed = 0;
2878
2879 agent->sa_stats->as_recv_msg++;
2880 agent->sa_stats->as_recv_request++;
2881
2882 SU_DEBUG_5(("nta: received %s " URL_PRINT_FORMAT " %s (CSeq %u)\n",
2883 method_name,
2884 URL_PRINT_ARGS(sip->sip_request->rq_url),
2885 sip->sip_request->rq_version, cseq));
2886
2887 if (agent->sa_drop_prob && !tport_is_reliable(tport)) {
2888 if ((unsigned)su_randint(0, 1000) < agent->sa_drop_prob) {
2889 SU_DEBUG_5(("nta: %s (%u) is %s\n",
2890 method_name, cseq, "dropped simulating packet loss"));
2891 agent->sa_stats->as_drop_request++;
2892 msg_destroy(msg);
2893 return;
2894 }
2895 }
2896
2897 stream = tport_is_stream(tport);
2898
2899 /* Try to use compression on reverse direction if @Via has comp=sigcomp */
2900 if (stream &&
2901 sip->sip_via && sip->sip_via->v_comp &&
2902 tport_can_send_sigcomp(tport) &&
2903 tport_name(tport)->tpn_comp == NULL &&
2904 tport_has_compression(tport_parent(tport), sip->sip_via->v_comp)) {
2905 tport_set_compression(tport, sip->sip_via->v_comp);
2906 }
2907
2908 if (sip->sip_flags & MSG_FLG_TOOLARGE) {
2909 SU_DEBUG_5(("nta: %s (%u) is %s\n",
2910 method_name, cseq, sip_413_Request_too_large));
2911 agent->sa_stats->as_bad_request++;
2912 mreply(agent, NULL, SIP_413_REQUEST_TOO_LARGE, msg,
2913 tport, 1, stream, NULL,
2914 TAG_END());
2915 return;
2916 }
2917
2918 insane = 0;
2919
2920 if (agent->sa_bad_req_mask != ~0U)
2921 errors = msg_extract_errors(msg) & agent->sa_bad_req_mask;
2922 else
2923 errors = sip->sip_error != NULL;
2924
2925 if (errors ||
2926 (sip->sip_flags & MSG_FLG_ERROR) /* Fatal error */ ||
2927 (insane = (sip_sanity_check(sip) < 0))) {
2928 sip_header_t const *h;
2929 char const *badname = NULL, *phrase;
2930
2931 agent->sa_stats->as_bad_message++;
2932 agent->sa_stats->as_bad_request++;
2933
2934 if (insane)
2935 SU_DEBUG_5(("nta: %s (%u) %s\n", method_name, cseq,
2936 "failed sanity check"));
2937
2938 for (h = (sip_header_t const *)sip->sip_error; h; h = h->sh_next) {
2939 char const *bad;
2940
2941 if (h->sh_class == sip_error_class)
2942 bad = h->sh_error->er_name;
2943 else
2944 bad = h->sh_class->hc_name;
2945
2946 if (bad)
2947 SU_DEBUG_5(("nta: %s has bad %s header\n", method_name, bad));
2948
2949 if (!badname)
2950 badname = bad;
2951 }
2952
2953 if (sip->sip_via && method != sip_method_ack) {
2954 msg_t *reply = nta_msg_create(agent, 0);
2955
2956 agent_check_request_via(agent, msg, sip, sip->sip_via, tport);
2957
2958 if (badname && reply)
2959 phrase = su_sprintf(msg_home(reply), "Bad %s Header", badname);
2960 else
2961 phrase = sip_400_Bad_request;
2962
2963 SU_DEBUG_5(("nta: %s (%u) is %s\n", method_name, cseq, phrase));
2964
2965 mreply(agent, reply, 400, phrase, msg,
2966 tport, 1, stream, NULL,
2967 TAG_END());
2968 }
2969 else {
2970 msg_destroy(msg);
2971 if (stream) /* Send FIN */
2972 tport_shutdown(tport, 1);
2973 }
2974
2975 return;
2976 }
2977
2978 if (!su_casematch(sip->sip_request->rq_version, sip_version_2_0)) {
2979 agent->sa_stats->as_bad_request++;
2980 agent->sa_stats->as_bad_message++;
2981
2982 SU_DEBUG_5(("nta: bad version %s for %s (%u)\n",
2983 sip->sip_request->rq_version, method_name, cseq));
2984
2985 mreply(agent, NULL, SIP_505_VERSION_NOT_SUPPORTED, msg,
2986 tport, 0, stream, NULL,
2987 TAG_END());
2988
2989 return;
2990 }
2991
2992 if (agent_check_request_via(agent, msg, sip, sip->sip_via, tport) < 0) {
2993 agent->sa_stats->as_bad_message++;
2994 agent->sa_stats->as_bad_request++;
2995 SU_DEBUG_5(("nta: %s (%u) %s\n", method_name, cseq, "has invalid Via"));
2996 msg_destroy(msg);
2997 return;
2998 }
2999
3000 #ifdef HAVE_ZLIB_COMPRESS
3001 compressed = sip_content_encoding_Xflate(msg, sip, 1, 1);
3002 #endif
3003
3004 /* First, try existing incoming requests */
3005 irq = incoming_find(agent, sip, sip->sip_via,
3006 agent->sa_merge_482 &&
3007 !sip->sip_to->a_tag &&
3008 method != sip_method_ack
3009 ? &merge
3010 : NULL,
3011 method == sip_method_ack ? &ack : NULL,
3012 method == sip_method_cancel ? &cancel : NULL);
3013
3014 if (irq) {
3015 /* Match - this is a retransmission */
3016 SU_DEBUG_5(("nta: %s (%u) going to existing %s transaction\n",
3017 method_name, cseq, irq->irq_rq->rq_method_name));
3018 if (incoming_recv(irq, msg, sip, tport) >= 0)
3019 return;
3020 }
3021 else if (ack) {
3022 SU_DEBUG_5(("nta: %s (%u) is going to %s (%u)\n",
3023 method_name, cseq,
3024 ack->irq_cseq->cs_method_name, ack->irq_cseq->cs_seq));
3025 if (incoming_ack(ack, msg, sip, tport) >= 0)
3026 return;
3027 }
3028 else if (cancel) {
3029 SU_DEBUG_5(("nta: %s (%u) is going to %s (%u)\n",
3030 method_name, cseq,
3031 cancel->irq_cseq->cs_method_name, cancel->irq_cseq->cs_seq));
3032 if (incoming_cancel(cancel, msg, sip, tport) >= 0)
3033 return;
3034 }
3035 else if (merge) {
3036 SU_DEBUG_5(("nta: %s (%u) %s\n",
3037 method_name, cseq, "is a merged request"));
3038 request_merge(agent, msg, sip, tport, merge->irq_tag);
3039 return;
3040 }
3041
3042 if (method == sip_method_prack && sip->sip_rack) {
3043 nta_reliable_t *rel = reliable_find(agent, sip);
3044 if (rel) {
3045 SU_DEBUG_5(("nta: %s (%u) is going to %s (%u)\n",
3046 method_name, cseq,
3047 rel->rel_irq->irq_cseq->cs_method_name,
3048 rel->rel_irq->irq_cseq->cs_seq));
3049 reliable_recv(rel, msg, sip, tport);
3050 return;
3051 }
3052 }
3053
3054 *url = *sip->sip_request->rq_url;
3055 url->url_params = NULL;
3056 agent_aliases(agent, url, tport); /* canonize urls */
3057
3058 if (method != sip_method_subscribe && (leg = leg_find(agent,
3059 method_name, url,
3060 sip->sip_call_id,
3061 sip->sip_from->a_tag,
3062 sip->sip_to->a_tag))) {
3063 /* Try existing dialog */
3064 SU_DEBUG_5(("nta: %s (%u) %s\n",
3065 method_name, cseq, "going to existing leg"));
3066 leg->leg_compressed = compressed;
3067 leg_recv(leg, msg, sip, tport);
3068 return;
3069 }
3070 else if (!agent->sa_is_stateless &&
3071 (leg = dst_find(agent, url, method_name))) {
3072 /* Dialogless legs - let application process transactions statefully */
3073 SU_DEBUG_5(("nta: %s (%u) %s\n",
3074 method_name, cseq, "going to a dialogless leg"));
3075 leg->leg_compressed = compressed;
3076 leg_recv(leg, msg, sip, tport);
3077 }
3078 else if (!agent->sa_is_stateless && (leg = agent->sa_default_leg)) {
3079 if (method == sip_method_invite &&
3080 agent->sa_in.proceeding->q_length >= agent->sa_max_proceeding) {
3081 SU_DEBUG_5(("nta: proceeding queue full for %s (%u)\n",
3082 method_name, cseq));
3083 mreply(agent, NULL, SIP_503_SERVICE_UNAVAILABLE, msg,
3084 tport, 0, 0, NULL,
3085 TAG_END());
3086 return;
3087 }
3088 else {
3089 SU_DEBUG_5(("nta: %s (%u) %s\n",
3090 method_name, cseq, "going to a default leg"));
3091 leg->leg_compressed = compressed;
3092 leg_recv(leg, msg, sip, tport);
3093 }
3094 }
3095 else if (agent->sa_callback) {
3096 /* Stateless processing for request */
3097 agent->sa_stats->as_trless_request++;
3098 SU_DEBUG_5(("nta: %s (%u) %s\n",
3099 method_name, cseq, "to message callback"));
3100 (void)agent->sa_callback(agent->sa_magic, agent, msg, sip);
3101 }
3102 else {
3103 agent->sa_stats->as_trless_request++;
3104 SU_DEBUG_5(("nta: %s (%u) %s\n",
3105 method_name, cseq,
3106 "not processed by application: returning 501"));
3107 if (method != sip_method_ack)
3108 mreply(agent, NULL, SIP_501_NOT_IMPLEMENTED, msg,
3109 tport, 0, 0, NULL,
3110 TAG_END());
3111 else
3112 msg_destroy(msg);
3113 }
3114 }
3115
3116 /** Check @Via header.
3117 *
3118 */
3119 static
agent_check_request_via(nta_agent_t * agent,msg_t * msg,sip_t * sip,sip_via_t * v,tport_t * tport)3120 int agent_check_request_via(nta_agent_t *agent,
3121 msg_t *msg,
3122 sip_t *sip,
3123 sip_via_t *v,
3124 tport_t *tport)
3125 {
3126 enum { receivedlen = sizeof("received=") - 1 };
3127 char received[receivedlen + TPORT_HOSTPORTSIZE];
3128 char *hostport = received + receivedlen;
3129 char const *rport;
3130 su_sockaddr_t const *from;
3131 sip_via_t const *tpv = agent_tport_via(tport);
3132
3133 assert(tport); assert(msg); assert(sip);
3134 assert(sip->sip_request); assert(tpv);
3135
3136 from = msg_addr(msg);
3137
3138 if (v == NULL) {
3139 /* Make up a via line */
3140 v = sip_via_format(msg_home(msg), "SIP/2.0/%s %s",
3141 tport_name(tport)->tpn_proto,
3142 tport_hostport(hostport, TPORT_HOSTPORTSIZE, from, 1));
3143 msg_header_insert(msg, (msg_pub_t *)sip, (msg_header_t *)v);
3144
3145 return v ? 0 : -1;
3146 }
3147
3148 if (!su_strmatch(v->v_protocol, tpv->v_protocol)) {
3149 tport_hostport(hostport, TPORT_HOSTPORTSIZE, from, 1);
3150 SU_DEBUG_1(("nta: Via check: invalid transport \"%s\" from %s\n",
3151 v->v_protocol, hostport));
3152 return -1;
3153 }
3154
3155 if (v->v_received) {
3156 /* Nasty, nasty */
3157 tport_hostport(hostport, TPORT_HOSTPORTSIZE, from, 1);
3158 SU_DEBUG_1(("nta: Via check: extra received=%s from %s\n",
3159 v->v_received, hostport));
3160 msg_header_remove_param(v->v_common, "received");
3161 }
3162
3163 if (!tport_hostport(hostport, TPORT_HOSTPORTSIZE, from, 0))
3164 return -1;
3165
3166 if (!su_casematch(hostport, v->v_host)) {
3167 size_t rlen;
3168 /* Add the "received" field */
3169 memcpy(received, "received=", receivedlen);
3170
3171 if (hostport[0] == '[') {
3172 rlen = strlen(hostport + 1) - 1;
3173 memmove(hostport, hostport + 1, rlen);
3174 hostport[rlen] = '\0';
3175 }
3176
3177 msg_header_replace_param(msg_home(msg), v->v_common,
3178 su_strdup(msg_home(msg), received));
3179 SU_DEBUG_5(("nta: Via check: %s\n", received));
3180 }
3181
3182 if (!agent->sa_server_rport) {
3183 /*Xyzzy*/;
3184 }
3185 else if (v->v_rport) {
3186 rport = su_sprintf(msg_home(msg), "rport=%u", ntohs(from->su_port));
3187 msg_header_replace_param(msg_home(msg), v->v_common, rport);
3188 }
3189 else if (tport_is_tcp(tport)) {
3190 rport = su_sprintf(msg_home(msg), "rport=%u", ntohs(from->su_port));
3191 msg_header_replace_param(msg_home(msg), v->v_common, rport);
3192 }
3193 else if (agent->sa_server_rport == 2 ||
3194 (agent->sa_server_rport == 3 && sip && sip->sip_user_agent &&
3195 sip->sip_user_agent->g_string &&
3196 (!strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) ||
3197 !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20) ||
3198 !strncasecmp(sip->sip_user_agent->g_string, "ADTRAN_Total_Access", 19)))) {
3199 rport = su_sprintf(msg_home(msg), "rport=%u", ntohs(from->su_port));
3200 msg_header_replace_param(msg_home(msg), v->v_common, rport);
3201 }
3202
3203 return 0;
3204 }
3205
3206 /** @internal Handle aliases of local node.
3207 *
3208 * Return true if @a url is modified.
3209 */
3210 static
agent_aliases(nta_agent_t const * agent,url_t url[],tport_t * tport)3211 int agent_aliases(nta_agent_t const *agent, url_t url[], tport_t *tport)
3212 {
3213 sip_contact_t *m;
3214 sip_via_t const *lv;
3215 char const *tport_port = "";
3216
3217 if (!url->url_host)
3218 return 0;
3219
3220 if (tport)
3221 tport_port = tport_name(tport)->tpn_port;
3222
3223 assert(tport_port);
3224
3225 for (m = agent->sa_aliases ? agent->sa_aliases : agent->sa_contact;
3226 m;
3227 m = m->m_next) {
3228 if (url->url_type != m->m_url->url_type)
3229 continue;
3230
3231 if (host_cmp(url->url_host, m->m_url->url_host))
3232 continue;
3233
3234 if (url->url_port == NULL)
3235 break;
3236
3237 if (m->m_url->url_port) {
3238 if (strcmp(url->url_port, m->m_url->url_port))
3239 continue;
3240 } else {
3241 if (strcmp(url->url_port, tport_port))
3242 continue;
3243 }
3244
3245 break;
3246 }
3247
3248 if (!m)
3249 return 0;
3250
3251 SU_DEBUG_7(("nta: canonizing " URL_PRINT_FORMAT " with %s\n",
3252 URL_PRINT_ARGS(url),
3253 agent->sa_aliases ? "aliases" : "contact"));
3254
3255 url->url_host = "%";
3256
3257 if (agent->sa_aliases) {
3258 url->url_type = agent->sa_aliases->m_url->url_type;
3259 url->url_scheme = agent->sa_aliases->m_url->url_scheme;
3260 url->url_port = agent->sa_aliases->m_url->url_port;
3261 return 1;
3262 }
3263 else {
3264 /* Canonize the request URL port */
3265 if (tport) {
3266 lv = agent_tport_via(tport_parent(tport)); assert(lv);
3267 if (lv->v_port)
3268 /* Add non-default port */
3269 url->url_port = lv->v_port;
3270 return 1;
3271 }
3272 if (su_strmatch(url->url_port, url_port_default((enum url_type_e)url->url_type)) ||
3273 su_strmatch(url->url_port, ""))
3274 /* Remove default or empty port */
3275 url->url_port = NULL;
3276
3277 return 0;
3278 }
3279 }
3280
3281 /** @internal Handle incoming responses. */
3282 static
agent_recv_response(nta_agent_t * agent,msg_t * msg,sip_t * sip,sip_via_t * tport_via,tport_t * tport)3283 void agent_recv_response(nta_agent_t *agent,
3284 msg_t *msg,
3285 sip_t *sip,
3286 sip_via_t *tport_via,
3287 tport_t *tport)
3288 {
3289 int status = sip->sip_status->st_status;
3290 int errors;
3291 char const *phrase = sip->sip_status->st_phrase;
3292 char const *method =
3293 sip->sip_cseq ? sip->sip_cseq->cs_method_name : "<UNKNOWN>";
3294 uint32_t cseq = sip->sip_cseq ? sip->sip_cseq->cs_seq : 0;
3295 nta_outgoing_t *orq;
3296 su_home_t *home;
3297 char const *branch = NONE;
3298
3299
3300 agent->sa_stats->as_recv_msg++;
3301 agent->sa_stats->as_recv_response++;
3302
3303 SU_DEBUG_5(("nta: received %03d %s for %s (%u)\n",
3304 status, phrase, method, cseq));
3305
3306 if (agent->sa_drop_prob && !tport_is_reliable(tport)) {
3307 if ((unsigned)su_randint(0, 1000) < agent->sa_drop_prob) {
3308 SU_DEBUG_5(("nta: %03d %s %s\n",
3309 status, phrase, "dropped simulating packet loss"));
3310 agent->sa_stats->as_drop_response++;
3311 msg_destroy(msg);
3312 return;
3313 }
3314 }
3315
3316 if (agent->sa_bad_resp_mask)
3317 errors = msg_extract_errors(msg) & agent->sa_bad_resp_mask;
3318 else
3319 errors = sip->sip_error != NULL;
3320
3321 if (errors ||
3322 sip_sanity_check(sip) < 0) {
3323 sip_header_t const *h;
3324
3325 agent->sa_stats->as_bad_response++;
3326 agent->sa_stats->as_bad_message++;
3327
3328 SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase,
3329 errors
3330 ? "has fatal syntax errors"
3331 : "failed sanity check"));
3332
3333 for (h = (sip_header_t const *)sip->sip_error; h; h = h->sh_next) {
3334 if (h->sh_class->hc_name) {
3335 SU_DEBUG_5(("nta: %03d has bad %s header\n", status,
3336 h->sh_class->hc_name));
3337 }
3338 }
3339
3340 msg_destroy(msg);
3341 return;
3342 }
3343
3344 if (!su_casematch(sip->sip_status->st_version, sip_version_2_0)) {
3345 agent->sa_stats->as_bad_response++;
3346 agent->sa_stats->as_bad_message++;
3347
3348 SU_DEBUG_5(("nta: bad version %s %03d %s\n",
3349 sip->sip_status->st_version, status, phrase));
3350 msg_destroy(msg);
3351 return;
3352 }
3353
3354 if (sip->sip_cseq && sip->sip_cseq->cs_method == sip_method_ack) {
3355 /* Drop response messages to ACK */
3356 agent->sa_stats->as_bad_response++;
3357 agent->sa_stats->as_bad_message++;
3358 SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "is response to ACK"));
3359 msg_destroy(msg);
3360 return;
3361 }
3362
3363 /* XXX - should check if msg should be discarded based on via? */
3364
3365 #ifdef HAVE_ZLIB_COMPRESS
3366 sip_content_encoding_Xflate(msg, sip, 1, 1);
3367 #endif
3368
3369 if ((orq = outgoing_find(agent, msg, sip, sip->sip_via))) {
3370 SU_DEBUG_5(("nta: %03d %s %s\n",
3371 status, phrase, "is going to a transaction"));
3372 /* RFC3263 4.3 "503 error response" */
3373 if(agent->sa_srv_503 && status == 503 && outgoing_other_destinations(orq)) {
3374 SU_DEBUG_5(("%s(%p): <%03d> for <%s>, %s\n", "nta", (void *)orq, status, method, "try next after timeout"));
3375 home = msg_home(msg);
3376 if (agent->sa_is_stateless)
3377 branch = stateless_branch(agent, msg, sip, orq->orq_tpn);
3378 else
3379 branch = stateful_branch(home, agent);
3380
3381 orq->orq_branch = branch;
3382 orq->orq_via_branch = branch;
3383 outgoing_try_another(orq);
3384 return;
3385 }
3386
3387 if (outgoing_recv(orq, status, msg, sip) == 0)
3388 return;
3389 }
3390
3391
3392 agent->sa_stats->as_trless_response++;
3393
3394 if ((orq = agent->sa_default_outgoing)) {
3395 SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase,
3396 "to the default transaction"));
3397 outgoing_default_recv(orq, status, msg, sip);
3398 return;
3399 }
3400 else if (agent->sa_callback) {
3401 SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "to message callback"));
3402 /*
3403 * Store message and transport to hook for the duration of the callback
3404 * so that the transport can be obtained by nta_transport().
3405 */
3406 (void)agent->sa_callback(agent->sa_magic, agent, msg, sip);
3407 return;
3408 }
3409
3410 if (sip->sip_cseq->cs_method == sip_method_invite
3411 && 200 <= sip->sip_status->st_status
3412 && sip->sip_status->st_status < 300
3413 /* Exactly one Via header, belonging to us */
3414 && sip->sip_via && !sip->sip_via->v_next
3415 && agent_has_via(agent, sip->sip_via)) {
3416 agent->sa_stats->as_trless_200++;
3417 }
3418
3419 SU_DEBUG_5(("nta: %03d %s %s\n", status, phrase, "was discarded"));
3420 msg_destroy(msg);
3421 }
3422
3423 /** @internal Agent receives garbage */
3424 static
agent_recv_garbage(nta_agent_t * agent,msg_t * msg,tport_t * tport)3425 void agent_recv_garbage(nta_agent_t *agent,
3426 msg_t *msg,
3427 tport_t *tport)
3428 {
3429 agent->sa_stats->as_recv_msg++;
3430 agent->sa_stats->as_bad_message++;
3431
3432 #if SU_DEBUG >= 3
3433 if (nta_log->log_level >= 3) {
3434 tp_name_t tpn[1];
3435
3436 tport_delivered_from(tport, msg, tpn);
3437
3438 SU_DEBUG_3(("nta_agent: received garbage from " TPN_FORMAT "\n",
3439 TPN_ARGS(tpn)));
3440 }
3441 #endif
3442
3443 msg_destroy(msg);
3444 }
3445
3446 /* ====================================================================== */
3447 /* 4) Message handling - create, complete, destroy */
3448
3449 /** Create a new message belonging to the agent */
nta_msg_create(nta_agent_t * agent,int flags)3450 msg_t *nta_msg_create(nta_agent_t *agent, int flags)
3451 {
3452 msg_t *msg;
3453
3454 if (agent == NULL)
3455 return su_seterrno(EINVAL), NULL;
3456
3457 msg = msg_create(agent->sa_mclass, agent->sa_flags | flags);
3458
3459 if (agent->sa_preload)
3460 su_home_preload(msg_home(msg), 1, agent->sa_preload);
3461
3462 return msg;
3463 }
3464
3465 /** Create a new message for transport */
nta_msg_create_for_transport(nta_agent_t * agent,int flags,char const data[],usize_t dlen,tport_t const * tport,tp_client_t * via)3466 msg_t *nta_msg_create_for_transport(nta_agent_t *agent, int flags,
3467 char const data[], usize_t dlen,
3468 tport_t const *tport, tp_client_t *via)
3469 {
3470 msg_t *msg = msg_create(agent->sa_mclass, agent->sa_flags | flags);
3471
3472 msg_maxsize(msg, agent->sa_maxsize);
3473
3474 if (agent->sa_preload)
3475 su_home_preload(msg_home(msg), 1, dlen + agent->sa_preload);
3476
3477 return msg;
3478 }
3479
3480 /** Complete a message. */
nta_msg_complete(msg_t * msg)3481 int nta_msg_complete(msg_t *msg)
3482 {
3483 return sip_complete_message(msg);
3484 }
3485
3486 /** Discard a message */
nta_msg_discard(nta_agent_t * agent,msg_t * msg)3487 void nta_msg_discard(nta_agent_t *agent, msg_t *msg)
3488 {
3489 msg_destroy(msg);
3490 }
3491
3492 /** Check if the headers are from response generated locally by NTA. */
nta_sip_is_internal(sip_t const * sip)3493 int nta_sip_is_internal(sip_t const *sip)
3494 {
3495 return
3496 sip == NULL /* No message generated */
3497 || (sip->sip_flags & NTA_INTERNAL_MSG) == NTA_INTERNAL_MSG;
3498 }
3499
3500 /** Check if the message is internally generated by NTA. */
nta_msg_is_internal(msg_t const * msg)3501 int nta_msg_is_internal(msg_t const *msg)
3502 {
3503 return msg_get_flags(msg, NTA_INTERNAL_MSG) == NTA_INTERNAL_MSG;
3504 }
3505
3506 /** Check if the message is internally generated by NTA.
3507 *
3508 * @deprecated Use nta_msg_is_internal() instead
3509 */
nta_is_internal_msg(msg_t const * msg)3510 int nta_is_internal_msg(msg_t const *msg) { return nta_msg_is_internal(msg); }
3511
3512 /* ====================================================================== */
3513 /* 5) Stateless operation */
3514
3515 /**Forward a request or response message.
3516 *
3517 * @note
3518 * The ownership of @a msg is taken over by the function even if the
3519 * function fails.
3520 */
nta_msg_tsend(nta_agent_t * agent,msg_t * msg,url_string_t const * u,tag_type_t tag,tag_value_t value,...)3521 int nta_msg_tsend(nta_agent_t *agent, msg_t *msg, url_string_t const *u,
3522 tag_type_t tag, tag_value_t value, ...)
3523 {
3524 int retval = -1;
3525 ta_list ta;
3526 sip_t *sip = sip_object(msg);
3527 tp_name_t tpn[1] = {{ NULL }};
3528 char const *what;
3529
3530 if (!sip) {
3531 msg_destroy(msg);
3532 return -1;
3533 }
3534
3535 what =
3536 sip->sip_status ? "nta_msg_tsend(response)" :
3537 sip->sip_request ? "nta_msg_tsend(request)" :
3538 "nta_msg_tsend()";
3539
3540 ta_start(ta, tag, value);
3541
3542 if (sip_add_tl(msg, sip, ta_tags(ta)) < 0)
3543 SU_DEBUG_3(("%s: cannot add headers\n", what));
3544 else if (sip->sip_status) {
3545 tport_t *tport = NULL;
3546 int *use_rport = NULL;
3547 int retry_without_rport = 0;
3548
3549 struct sigcomp_compartment *cc; cc = NONE;
3550
3551 if (agent->sa_server_rport)
3552 use_rport = &retry_without_rport, retry_without_rport = 1;
3553
3554 tl_gets(ta_args(ta),
3555 NTATAG_TPORT_REF(tport),
3556 IF_SIGCOMP_TPTAG_COMPARTMENT_REF(cc)
3557 /* NTATAG_INCOMPLETE_REF(incomplete), */
3558 TAG_END());
3559
3560 if (!sip->sip_separator &&
3561 !(sip->sip_separator = sip_separator_create(msg_home(msg))))
3562 SU_DEBUG_3(("%s: cannot create sip_separator\n", what));
3563 else if (msg_serialize(msg, (msg_pub_t *)sip) != 0)
3564 SU_DEBUG_3(("%s: sip_serialize() failed\n", what));
3565 else if (!sip_via_remove(msg, sip))
3566 SU_DEBUG_3(("%s: cannot remove Via\n", what));
3567 else if (nta_tpn_by_via(tpn, sip->sip_via, use_rport) < 0)
3568 SU_DEBUG_3(("%s: bad via\n", what));
3569 else {
3570 if (!tport)
3571 tport = tport_by_name(agent->sa_tports, tpn);
3572 if (!tport)
3573 tport = tport_by_protocol(agent->sa_tports, tpn->tpn_proto);
3574
3575 if (retry_without_rport)
3576 tpn->tpn_port = sip_via_port(sip->sip_via, NULL);
3577
3578 if (tport && tpn->tpn_comp && cc == NONE)
3579 cc = agent_compression_compartment(agent, tport, tpn, -1);
3580
3581 if (tport_tsend(tport, msg, tpn,
3582 IF_SIGCOMP_TPTAG_COMPARTMENT(cc)
3583 TPTAG_MTU(INT_MAX), ta_tags(ta), TAG_END())) {
3584 agent->sa_stats->as_sent_msg++;
3585 agent->sa_stats->as_sent_response++;
3586 retval = 0;
3587 }
3588 else {
3589 SU_DEBUG_3(("%s: send fails\n", what));
3590 }
3591 }
3592 }
3593 else {
3594 /* Send request */
3595 if (outgoing_create(agent, NULL, NULL, u, NULL, msg_ref_create(msg),
3596 NTATAG_STATELESS(1),
3597 ta_tags(ta)))
3598 retval = 0;
3599 }
3600
3601 if (retval == 0)
3602 SU_DEBUG_5(("%s\n", what));
3603
3604 ta_end(ta);
3605
3606 msg_destroy(msg);
3607
3608 return retval;
3609 }
3610
3611 /** Reply to a request message.
3612 *
3613 * @param agent nta agent object
3614 * @param req_msg request message
3615 * @param status status code
3616 * @param phrase status phrase (may be NULL if status code is well-known)
3617 * @param tag, value, ... optional additional headers terminated by TAG_END()
3618 *
3619 * @retval 0 when succesful
3620 * @retval -1 upon an error
3621 *
3622 * @note
3623 * The ownership of @a msg is taken over by the function even if the
3624 * function fails.
3625 */
nta_msg_treply(nta_agent_t * agent,msg_t * req_msg,int status,char const * phrase,tag_type_t tag,tag_value_t value,...)3626 int nta_msg_treply(nta_agent_t *agent,
3627 msg_t *req_msg,
3628 int status, char const *phrase,
3629 tag_type_t tag, tag_value_t value, ...)
3630 {
3631 int retval;
3632 ta_list ta;
3633
3634 ta_start(ta, tag, value);
3635
3636 retval = mreply(agent, NULL, status, phrase, req_msg,
3637 NULL, 0, 0, NULL,
3638 ta_tags(ta));
3639 ta_end(ta);
3640
3641 return retval;
3642 }
3643
3644 /**Reply to the request message.
3645 *
3646 * @note
3647 * The ownership of @a msg is taken over by the function even if the
3648 * function fails.
3649 */
nta_msg_mreply(nta_agent_t * agent,msg_t * reply,sip_t * sip,int status,char const * phrase,msg_t * req_msg,tag_type_t tag,tag_value_t value,...)3650 int nta_msg_mreply(nta_agent_t *agent,
3651 msg_t *reply, sip_t *sip,
3652 int status, char const *phrase,
3653 msg_t *req_msg,
3654 tag_type_t tag, tag_value_t value, ...)
3655 {
3656 int retval = -1;
3657 ta_list ta;
3658
3659 ta_start(ta, tag, value);
3660
3661 retval = mreply(agent, reply, status, phrase, req_msg,
3662 NULL, 0, 0, NULL,
3663 ta_tags(ta));
3664 ta_end(ta);
3665
3666 return retval;
3667 }
3668
3669 static
mreply(nta_agent_t * agent,msg_t * reply,int status,char const * phrase,msg_t * req_msg,tport_t * tport,int incomplete,int sdwn_after,char const * to_tag,tag_type_t tag,tag_value_t value,...)3670 int mreply(nta_agent_t *agent,
3671 msg_t *reply,
3672 int status, char const *phrase,
3673 msg_t *req_msg,
3674 tport_t *tport,
3675 int incomplete,
3676 int sdwn_after,
3677 char const *to_tag,
3678 tag_type_t tag, tag_value_t value, ...)
3679 {
3680 ta_list ta;
3681 sip_t *sip;
3682 int *use_rport = NULL;
3683 int retry_without_rport = 0;
3684 tp_name_t tpn[1];
3685 int retval = -1;
3686
3687 if (!agent)
3688 return -1;
3689
3690 if (agent->sa_server_rport)
3691 use_rport = &retry_without_rport, retry_without_rport = 1;
3692
3693 ta_start(ta, tag, value);
3694
3695 tl_gets(ta_args(ta), NTATAG_TPORT_REF(tport), TAG_END());
3696
3697 if (reply == NULL) {
3698 reply = nta_msg_create(agent, 0);
3699 }
3700 sip = sip_object(reply);
3701
3702 if (!sip) {
3703 SU_DEBUG_3(("%s: cannot create response msg\n", __func__));
3704 }
3705 else if (sip_add_tl(reply, sip, ta_tags(ta)) < 0) {
3706 SU_DEBUG_3(("%s: cannot add user headers\n", __func__));
3707 }
3708 else if (complete_response(reply, status, phrase, req_msg) < 0 &&
3709 !incomplete) {
3710 SU_DEBUG_3(("%s: cannot complete message\n", __func__));
3711 }
3712 else if (sip->sip_status && sip->sip_status->st_status > 100 &&
3713 sip->sip_to && !sip->sip_to->a_tag &&
3714 (to_tag == NONE ? 0 :
3715 to_tag != NULL
3716 ? sip_to_tag(msg_home(reply), sip->sip_to, to_tag) < 0
3717 : sip_to_tag(msg_home(reply), sip->sip_to,
3718 nta_agent_newtag(msg_home(reply), "tag=%s", agent)) < 0)) {
3719 SU_DEBUG_3(("%s: cannot add To tag\n", __func__));
3720 }
3721 else if (nta_tpn_by_via(tpn, sip->sip_via, use_rport) < 0) {
3722 SU_DEBUG_3(("%s: no Via\n", __func__));
3723 }
3724 else {
3725 struct sigcomp_compartment *cc = NONE;
3726
3727 if (tport == NULL)
3728 tport = tport_delivered_by(agent->sa_tports, req_msg);
3729
3730 if (!tport) {
3731 tport_t *primary = tport_by_protocol(agent->sa_tports, tpn->tpn_proto);
3732
3733 tport = tport_by_name(primary, tpn);
3734
3735 if (!tport)
3736 tport = primary;
3737 }
3738
3739 if (retry_without_rport)
3740 tpn->tpn_port = sip_via_port(sip->sip_via, NULL);
3741
3742 if (tport && tpn->tpn_comp) {
3743 tl_gets(ta_args(ta), TPTAG_COMPARTMENT_REF(cc),
3744 /* XXX - should also check ntatag_sigcomp_close() */
3745 TAG_END());
3746 if (cc == NONE)
3747 cc = agent_compression_compartment(agent, tport, tpn, -1);
3748
3749 if (cc != NULL && cc != NONE &&
3750 tport_delivered_with_comp(tport, req_msg, NULL) != -1) {
3751 agent_accept_compressed(agent, req_msg, cc);
3752 }
3753 }
3754
3755 if (tport_tsend(tport, reply, tpn,
3756 IF_SIGCOMP_TPTAG_COMPARTMENT(cc)
3757 TPTAG_MTU(INT_MAX),
3758 TPTAG_SDWN_AFTER(sdwn_after),
3759 ta_tags(ta))) {
3760 agent->sa_stats->as_sent_msg++;
3761 agent->sa_stats->as_sent_response++;
3762 retval = 0; /* Success! */
3763 }
3764 else {
3765 SU_DEBUG_3(("%s: send fails\n", __func__));
3766 }
3767 }
3768
3769 msg_destroy(reply);
3770 msg_destroy(req_msg);
3771
3772 ta_end(ta);
3773
3774 return retval;
3775 }
3776
3777 /** Add headers from the request to the response message. */
3778 static
complete_response(msg_t * response,int status,char const * phrase,msg_t * request)3779 int complete_response(msg_t *response,
3780 int status, char const *phrase,
3781 msg_t *request)
3782 {
3783 su_home_t *home = msg_home(response);
3784 sip_t *response_sip = sip_object(response);
3785 sip_t const *request_sip = sip_object(request);
3786
3787 int incomplete = 0;
3788
3789 if (!response_sip || !request_sip || !request_sip->sip_request)
3790 return -1;
3791
3792 if (!response_sip->sip_status)
3793 response_sip->sip_status = sip_status_create(home, status, phrase, NULL);
3794 if (!response_sip->sip_via)
3795 response_sip->sip_via = sip_via_dup(home, request_sip->sip_via);
3796 if (!response_sip->sip_from)
3797 response_sip->sip_from = sip_from_dup(home, request_sip->sip_from);
3798 if (!response_sip->sip_to)
3799 response_sip->sip_to = sip_to_dup(home, request_sip->sip_to);
3800 if (!response_sip->sip_call_id)
3801 response_sip->sip_call_id =
3802 sip_call_id_dup(home, request_sip->sip_call_id);
3803 if (!response_sip->sip_cseq)
3804 response_sip->sip_cseq = sip_cseq_dup(home, request_sip->sip_cseq);
3805
3806 if (!response_sip->sip_record_route && request_sip->sip_record_route)
3807 sip_add_dup(response, response_sip, (void*)request_sip->sip_record_route);
3808
3809 incomplete = sip_complete_message(response) < 0;
3810
3811 msg_serialize(response, (msg_pub_t *)response_sip);
3812
3813 if (incomplete ||
3814 !response_sip->sip_status ||
3815 !response_sip->sip_via ||
3816 !response_sip->sip_from ||
3817 !response_sip->sip_to ||
3818 !response_sip->sip_call_id ||
3819 !response_sip->sip_cseq ||
3820 !response_sip->sip_content_length ||
3821 !response_sip->sip_separator ||
3822 (request_sip->sip_record_route && !response_sip->sip_record_route))
3823 return -1;
3824
3825 return 0;
3826 }
3827
3828 /** ACK and BYE an unknown 200 OK response to INVITE.
3829 *
3830 * A UAS may still return a 2XX series response to client request after the
3831 * client transactions has been terminated. In that case, the UAC can not
3832 * really accept the call. This function was used to accept and immediately
3833 * terminate such a call.
3834 *
3835 * @deprecated This was a bad idea: see sf.net bug #1750691. It can be used
3836 * to amplify DoS attacks. Let UAS take care of retransmission timeout and
3837 * let it terminate the session. As of @VERSION_1_12_7, this function just
3838 * returns -1.
3839 */
nta_msg_ackbye(nta_agent_t * agent,msg_t * msg)3840 int nta_msg_ackbye(nta_agent_t *agent, msg_t *msg)
3841 {
3842 sip_t *sip = sip_object(msg);
3843 msg_t *amsg = nta_msg_create(agent, 0);
3844 sip_t *asip = sip_object(amsg);
3845 msg_t *bmsg = NULL;
3846 sip_t *bsip;
3847 url_string_t const *ruri;
3848 nta_outgoing_t *ack = NULL, *bye = NULL;
3849 sip_cseq_t *cseq;
3850 sip_request_t *rq;
3851 sip_route_t *route = NULL, *r, r0[1];
3852 su_home_t *home = msg_home(amsg);
3853
3854 if (asip == NULL)
3855 return -1;
3856
3857 sip_add_tl(amsg, asip,
3858 SIPTAG_TO(sip->sip_to),
3859 SIPTAG_FROM(sip->sip_from),
3860 SIPTAG_CALL_ID(sip->sip_call_id),
3861 TAG_END());
3862
3863 if (sip->sip_contact) {
3864 ruri = (url_string_t const *)sip->sip_contact->m_url;
3865 } else {
3866 ruri = (url_string_t const *)sip->sip_to->a_url;
3867 }
3868
3869 /* Reverse (and fix) record route */
3870 route = sip_route_reverse(home, sip->sip_record_route);
3871
3872 if (route && !url_has_param(route->r_url, "lr")) {
3873 for (r = route; r->r_next; r = r->r_next)
3874 ;
3875
3876 /* Append r-uri */
3877 *sip_route_init(r0)->r_url = *ruri->us_url;
3878 r->r_next = sip_route_dup(home, r0);
3879
3880 /* Use topmost route as request-uri */
3881 ruri = (url_string_t const *)route->r_url;
3882 route = route->r_next;
3883 }
3884
3885 msg_header_insert(amsg, (msg_pub_t *)asip, (msg_header_t *)route);
3886
3887 bmsg = msg_copy(amsg); bsip = sip_object(bmsg);
3888
3889 if (!(cseq = sip_cseq_create(home, sip->sip_cseq->cs_seq, SIP_METHOD_ACK)))
3890 goto err;
3891 else
3892 msg_header_insert(amsg, (msg_pub_t *)asip, (msg_header_t *)cseq);
3893
3894 if (!(rq = sip_request_create(home, SIP_METHOD_ACK, ruri, NULL)))
3895 goto err;
3896 else
3897 msg_header_insert(amsg, (msg_pub_t *)asip, (msg_header_t *)rq);
3898
3899 if (!(ack = nta_outgoing_mcreate(agent, NULL, NULL, NULL, amsg,
3900 NTATAG_ACK_BRANCH(sip->sip_via->v_branch),
3901 NTATAG_STATELESS(1),
3902 TAG_END())))
3903 goto err;
3904 else
3905 nta_outgoing_destroy(ack);
3906
3907 home = msg_home(bmsg);
3908
3909 if (!(cseq = sip_cseq_create(home, 0x7fffffff, SIP_METHOD_BYE)))
3910 goto err;
3911 else
3912 msg_header_insert(bmsg, (msg_pub_t *)bsip, (msg_header_t *)cseq);
3913
3914 if (!(rq = sip_request_create(home, SIP_METHOD_BYE, ruri, NULL)))
3915 goto err;
3916 else
3917 msg_header_insert(bmsg, (msg_pub_t *)bsip, (msg_header_t *)rq);
3918
3919 if (!(bye = nta_outgoing_mcreate(agent, NULL, NULL, NULL, bmsg,
3920 NTATAG_STATELESS(1),
3921 TAG_END())))
3922 goto err;
3923
3924 msg_destroy(msg);
3925 return 0;
3926
3927 err:
3928
3929 msg_destroy(bmsg);
3930 msg_destroy(amsg);
3931
3932 return -1;
3933 }
3934
3935 /**Complete a request with values from dialog.
3936 *
3937 * Complete a request message @a msg belonging to a dialog associated with
3938 * @a leg. It increments the local @CSeq value, adds @CallID, @To, @From and
3939 * @Route headers (if there is such headers present in @a leg), and creates
3940 * a new request line object from @a method, @a method_name and @a
3941 * request_uri.
3942 *
3943 * @param msg pointer to a request message object
3944 * @param leg pointer to a #nta_leg_t object
3945 * @param method request method number or #sip_method_unknown
3946 * @param method_name method name (if @a method == #sip_method_unknown)
3947 * @param request_uri request URI
3948 *
3949 * If @a request_uri contains query part, the query part is converted as SIP
3950 * headers and added to the request.
3951 *
3952 * @retval 0 when successful
3953 * @retval -1 upon an error
3954 *
3955 * @sa nta_outgoing_mcreate(), nta_outgoing_tcreate()
3956 */
nta_msg_request_complete(msg_t * msg,nta_leg_t * leg,sip_method_t method,char const * method_name,url_string_t const * request_uri)3957 int nta_msg_request_complete(msg_t *msg,
3958 nta_leg_t *leg,
3959 sip_method_t method,
3960 char const *method_name,
3961 url_string_t const *request_uri)
3962 {
3963 su_home_t *home = msg_home(msg);
3964 sip_t *sip = sip_object(msg);
3965 sip_to_t const *to;
3966 uint32_t seq;
3967 url_t reg_url[1];
3968 url_string_t const *original = request_uri;
3969
3970 if (!leg || !msg || !sip)
3971 return -1;
3972
3973 if (!sip->sip_route && leg->leg_route) {
3974 if (leg->leg_loose_route) {
3975 if (leg->leg_target) {
3976 request_uri = (url_string_t *)leg->leg_target->m_url;
3977 }
3978 sip->sip_route = sip_route_dup(home, leg->leg_route);
3979 }
3980 else {
3981 sip_route_t **rr;
3982
3983 request_uri = (url_string_t *)leg->leg_route->r_url;
3984 sip->sip_route = sip_route_dup(home, leg->leg_route->r_next);
3985
3986 for (rr = &sip->sip_route; *rr; rr = &(*rr)->r_next)
3987 ;
3988
3989 if (leg->leg_target)
3990 *rr = sip_route_dup(home, (sip_route_t *)leg->leg_target);
3991 }
3992 }
3993 else if (leg->leg_target)
3994 request_uri = (url_string_t *)leg->leg_target->m_url;
3995
3996 if (!request_uri && sip->sip_request)
3997 request_uri = (url_string_t *)sip->sip_request->rq_url;
3998
3999 to = sip->sip_to ? sip->sip_to : leg->leg_remote;
4000
4001 if (!request_uri && to) {
4002 if (method != sip_method_register)
4003 request_uri = (url_string_t *)to->a_url;
4004 else {
4005 /* Remove user part from REGISTER requests */
4006 *reg_url = *to->a_url;
4007 reg_url->url_user = reg_url->url_password = NULL;
4008 request_uri = (url_string_t *)reg_url;
4009 }
4010 }
4011
4012 if (!request_uri)
4013 return -1;
4014
4015 if (method || method_name) {
4016 sip_request_t *rq = sip->sip_request;
4017 int use_headers =
4018 request_uri == original || (url_t *)request_uri == rq->rq_url;
4019
4020 if (!rq
4021 || request_uri != (url_string_t *)rq->rq_url
4022 || method != rq->rq_method
4023 || !su_strmatch(method_name, rq->rq_method_name))
4024 rq = NULL;
4025
4026 if (rq == NULL) {
4027 rq = sip_request_create(home, method, method_name, request_uri, NULL);
4028 if (msg_header_insert(msg, (msg_pub_t *)sip, (msg_header_t *)rq) < 0)
4029 return -1;
4030 }
4031
4032 /* @RFC3261 table 1 (page 152):
4033 * Req-URI cannot contain method parameter or headers
4034 */
4035 if (rq->rq_url->url_params) {
4036 rq->rq_url->url_params =
4037 url_strip_param_string((char *)rq->rq_url->url_params, "method");
4038 sip_fragment_clear(rq->rq_common);
4039 }
4040
4041 if (rq->rq_url->url_headers) {
4042 if (use_headers) {
4043 char *s = url_query_as_header_string(msg_home(msg),
4044 rq->rq_url->url_headers);
4045 if (!s)
4046 return -1;
4047 msg_header_parse_str(msg, (msg_pub_t*)sip, s);
4048 }
4049 rq->rq_url->url_headers = NULL, sip_fragment_clear(rq->rq_common);
4050 }
4051 }
4052
4053 if (!sip->sip_request)
4054 return -1;
4055
4056 if (!sip->sip_max_forwards)
4057 sip_add_dup(msg, sip, (sip_header_t *)leg->leg_agent->sa_max_forwards);
4058
4059 if (!sip->sip_from)
4060 sip->sip_from = sip_from_dup(home, leg->leg_local);
4061 else if (leg->leg_local && leg->leg_local->a_tag &&
4062 (!sip->sip_from->a_tag ||
4063 !su_casematch(sip->sip_from->a_tag, leg->leg_local->a_tag)))
4064 sip_from_tag(home, sip->sip_from, leg->leg_local->a_tag);
4065
4066 if (sip->sip_from && !sip->sip_from->a_tag) {
4067 sip_fragment_clear(sip->sip_from->a_common);
4068 sip_from_add_param(home, sip->sip_from,
4069 nta_agent_newtag(home, "tag=%s", leg->leg_agent));
4070 }
4071
4072 if (sip->sip_to) {
4073 if (leg->leg_remote && leg->leg_remote->a_tag)
4074 sip_to_tag(home, sip->sip_to, leg->leg_remote->a_tag);
4075 }
4076 else if (leg->leg_remote) {
4077 sip->sip_to = sip_to_dup(home, leg->leg_remote);
4078 }
4079 else {
4080 sip_to_t *to = sip_to_create(home, request_uri);
4081 if (to) sip_aor_strip(to->a_url);
4082 sip->sip_to = to;
4083 }
4084
4085 if (!sip->sip_from || !sip->sip_from || !sip->sip_to)
4086 return -1;
4087
4088 method = sip->sip_request->rq_method;
4089 method_name = sip->sip_request->rq_method_name;
4090
4091 if (!leg->leg_id && sip->sip_cseq)
4092 seq = sip->sip_cseq->cs_seq;
4093 else if (method == sip_method_ack || method == sip_method_cancel)
4094 /* Dangerous - we may do PRACK/UPDATE meanwhile */
4095 seq = sip->sip_cseq ? sip->sip_cseq->cs_seq : leg->leg_seq;
4096 else if (leg->leg_seq)
4097 seq = ++leg->leg_seq;
4098 else if (sip->sip_cseq) /* Obtain initial value from existing CSeq header */
4099 seq = leg->leg_seq = sip->sip_cseq->cs_seq;
4100 else
4101 seq = leg->leg_seq = (sip_now() >> 1) & 0x7ffffff;
4102
4103 if (!sip->sip_call_id) {
4104 if (leg->leg_id)
4105 sip->sip_call_id = sip_call_id_dup(home, leg->leg_id);
4106 else
4107 sip->sip_call_id = sip_call_id_create(home, NULL);
4108 }
4109
4110 if (!sip->sip_cseq ||
4111 seq != sip->sip_cseq->cs_seq ||
4112 method != sip->sip_cseq->cs_method ||
4113 !su_strmatch(method_name, sip->sip_cseq->cs_method_name)) {
4114 sip_cseq_t *cseq = sip_cseq_create(home, seq, method, method_name);
4115 if (msg_header_insert(msg, (msg_pub_t *)sip, (msg_header_t *)cseq) < 0)
4116 return -1;
4117 }
4118
4119 return 0;
4120 }
4121
4122 /* ====================================================================== */
4123 /* 6) Dialogs (legs) */
4124
4125 static void leg_insert(nta_agent_t *agent, nta_leg_t *leg);
4126 static int leg_route(nta_leg_t *leg,
4127 sip_record_route_t const *route,
4128 sip_record_route_t const *reverse,
4129 sip_contact_t const *contact,
4130 int reroute);
4131 static int leg_callback_default(nta_leg_magic_t*, nta_leg_t*,
4132 nta_incoming_t*, sip_t const *);
4133 #define HTABLE_HASH_LEG(leg) ((leg)->leg_hash)
4134
4135 #ifdef __clang__
4136 #pragma clang diagnostic push
4137 #pragma clang diagnostic ignored "-Wunused-function"
4138 #endif
4139
4140 HTABLE_BODIES_WITH(leg_htable, lht, nta_leg_t, HTABLE_HASH_LEG, size_t, hash_value_t);
4141
4142 #ifdef __clang__
4143 #pragma clang diagnostic pop
4144 #endif
4145
4146 su_inline
4147 hash_value_t hash_istring(char const *, char const *, hash_value_t);
4148
4149 /**@typedef nta_request_f
4150 *
4151 * Callback for incoming requests
4152 *
4153 * This is a callback function invoked by NTA for each incoming SIP request.
4154 *
4155 * @param lmagic call leg context
4156 * @param leg call leg handle
4157 * @param ireq incoming request
4158 * @param sip incoming request contents
4159 *
4160 * @retval 100..699
4161 * NTA constructs a reply message with given error code and corresponding
4162 * standard phrase, then sends the reply.
4163 *
4164 * @retval 0
4165 * The application takes care of sending (or not sending) the reply.
4166 *
4167 * @retval other
4168 * All other return values will be interpreted as
4169 * @e 500 @e Internal @e server @e error.
4170 */
4171
4172
4173 /**
4174 * Create a new leg object.
4175 *
4176 * Creates a leg object, which is used to represent dialogs, partial dialogs
4177 * (for example, in case of REGISTER), and destinations within a particular
4178 * NTA object.
4179 *
4180 * When a leg is created, a callback pointer and a application context is
4181 * provided. All other parameters are optional.
4182 *
4183 * @param agent agent object
4184 * @param callback function which is called for each
4185 * incoming request belonging to this leg
4186 * @param magic call leg context
4187 * @param tag,value,... optional extra headers in taglist
4188 *
4189 * When a leg representing dialog is created, the tags SIPTAG_CALL_ID(),
4190 * SIPTAG_FROM(), SIPTAG_TO(), and SIPTAG_CSEQ() (for local @CSeq number) are used
4191 * to establish dialog context. The SIPTAG_FROM() is used to pass local
4192 * address (@From header when making a call, @To header when answering
4193 * to a call) to the newly created leg. Respectively, the SIPTAG_TO() is
4194 * used to pass remote address (@To header when making a call, @From
4195 * header when answering to a call).
4196 *
4197 * If there is a (preloaded) route associated with the leg, SIPTAG_ROUTE()
4198 * and NTATAG_TARGET() can be used. A client or server can also set the
4199 * route using @RecordRoute and @Contact headers from a response or
4200 * request message with the functions nta_leg_client_route() and
4201 * nta_leg_server_route(), respectively.
4202 *
4203 * When a leg representing a local destination is created, the tags
4204 * NTATAG_NO_DIALOG(1), NTATAG_METHOD(), and URLTAG_URL() are used. When a
4205 * request with matching request-URI (URLTAG_URL()) and method
4206 * (NTATAG_METHOD()) is received, it is passed to the callback function
4207 * provided with the leg.
4208 *
4209 * @sa nta_leg_stateful(), nta_leg_bind(),
4210 * nta_leg_tag(), nta_leg_rtag(),
4211 * nta_leg_client_route(), nta_leg_server_route(),
4212 * nta_leg_destroy(), nta_outgoing_tcreate(), and nta_request_f().
4213 *
4214 * @TAGS
4215 * NTATAG_NO_DIALOG(), NTATAG_STATELESS(), NTATAG_METHOD(),
4216 * URLTAG_URL(), SIPTAG_CALL_ID(), SIPTAG_CALL_ID_STR(), SIPTAG_FROM(),
4217 * SIPTAG_FROM_STR(), SIPTAG_TO(), SIPTAG_TO_STR(), SIPTAG_ROUTE(),
4218 * NTATAG_TARGET() and SIPTAG_CSEQ().
4219 *
4220 */
nta_leg_tcreate(nta_agent_t * agent,nta_request_f * callback,nta_leg_magic_t * magic,tag_type_t tag,tag_value_t value,...)4221 nta_leg_t *nta_leg_tcreate(nta_agent_t *agent,
4222 nta_request_f *callback,
4223 nta_leg_magic_t *magic,
4224 tag_type_t tag, tag_value_t value, ...)
4225 {
4226 sip_route_t const *route = NULL;
4227 sip_contact_t const *contact = NULL;
4228 sip_cseq_t const *cs = NULL;
4229 sip_call_id_t const *i = NULL;
4230 sip_from_t const *from = NULL;
4231 sip_to_t const *to = NULL;
4232 char const *method = NULL;
4233 char const *i_str = NULL, *to_str = NULL, *from_str = NULL, *cs_str = NULL;
4234 url_string_t const *url_string = NULL;
4235 int no_dialog = 0;
4236 unsigned rseq = 0;
4237 /* RFC 3261 section 12.2.1.1 */
4238 uint32_t seq = 0;
4239 ta_list ta;
4240 nta_leg_t *leg;
4241 su_home_t *home;
4242 url_t *url;
4243 char const *what = NULL;
4244
4245 if (agent == NULL)
4246 return su_seterrno(EINVAL), NULL;
4247
4248 ta_start(ta, tag, value);
4249
4250 tl_gets(ta_args(ta),
4251 NTATAG_NO_DIALOG_REF(no_dialog),
4252 NTATAG_METHOD_REF(method),
4253 URLTAG_URL_REF(url_string),
4254 SIPTAG_CALL_ID_REF(i),
4255 SIPTAG_CALL_ID_STR_REF(i_str),
4256 SIPTAG_FROM_REF(from),
4257 SIPTAG_FROM_STR_REF(from_str),
4258 SIPTAG_TO_REF(to),
4259 SIPTAG_TO_STR_REF(to_str),
4260 SIPTAG_ROUTE_REF(route),
4261 NTATAG_TARGET_REF(contact),
4262 NTATAG_REMOTE_CSEQ_REF(rseq),
4263 SIPTAG_CSEQ_REF(cs),
4264 SIPTAG_CSEQ_STR_REF(cs_str),
4265 TAG_END());
4266
4267 ta_end(ta);
4268
4269 if (cs)
4270 seq = cs->cs_seq;
4271 else if (cs_str)
4272 seq = strtoul(cs_str, (char **)&cs_str, 10);
4273
4274 if (i == NONE) /* Magic value, used for compatibility */
4275 no_dialog = 1;
4276
4277 if (!(leg = su_home_clone(NULL, sizeof(*leg))))
4278 return NULL;
4279 home = leg->leg_home;
4280
4281 leg->leg_agent = agent;
4282 nta_leg_bind(leg, callback, magic);
4283
4284 if (from) {
4285 /* Now this is kludge */
4286 leg->leg_local_is_to = sip_is_to((sip_header_t*)from);
4287 leg->leg_local = sip_to_dup(home, from);
4288 }
4289 else if (from_str)
4290 leg->leg_local = sip_to_make(home, from_str);
4291
4292 if (to && no_dialog) {
4293 /* Remove tag, if any */
4294 sip_to_t to0[1]; *to0 = *to; to0->a_params = NULL;
4295 leg->leg_remote = sip_from_dup(home, to0);
4296 }
4297 else if (to)
4298 leg->leg_remote = sip_from_dup(home, to);
4299 else if (to_str)
4300 leg->leg_remote = sip_from_make(home, to_str);
4301
4302 if (route && route != NONE)
4303 leg->leg_route = sip_route_dup(home, route), leg->leg_route_set = 1;
4304
4305 if (contact && contact != NONE) {
4306 sip_contact_t m[1];
4307 sip_contact_init(m);
4308 *m->m_url = *contact->m_url;
4309 m->m_url->url_headers = NULL;
4310 leg->leg_target = sip_contact_dup(home, m);
4311 }
4312
4313 url = url_hdup(home, url_string->us_url);
4314
4315 /* Match to local hosts */
4316 if (url && agent_aliases(agent, url, NULL)) {
4317 url_t *changed = url_hdup(home, url);
4318 su_free(home, url);
4319 url = changed;
4320 }
4321
4322 leg->leg_rseq = rseq;
4323 leg->leg_seq = seq;
4324 leg->leg_url = url;
4325
4326 if (from && from != NONE && leg->leg_local == NULL) {
4327 what = "cannot duplicate local address";
4328 goto err;
4329 }
4330 else if (to && to != NONE && leg->leg_remote == NULL) {
4331 what = "cannot duplicate remote address";
4332 goto err;
4333 }
4334 else if (route && route != NONE && leg->leg_route == NULL) {
4335 what = "cannot duplicate route";
4336 goto err;
4337 }
4338 else if (contact && contact != NONE && leg->leg_target == NULL) {
4339 what = "cannot duplicate target";
4340 goto err;
4341 }
4342 else if (url_string && leg->leg_url == NULL) {
4343 what = "cannot duplicate local destination";
4344 goto err;
4345 }
4346
4347 if (!no_dialog) {
4348 if (!leg->leg_local || !leg->leg_remote) {
4349 /* To and/or From header missing */
4350 if (leg->leg_remote)
4351 what = "Missing local dialog address";
4352 else if (leg->leg_local)
4353 what = "Missing remote dialog address";
4354 else
4355 what = "Missing dialog addresses";
4356 goto err;
4357 }
4358
4359 leg->leg_dialog = 1;
4360
4361 if (i != NULL)
4362 leg->leg_id = sip_call_id_dup(home, i);
4363 else if (i_str != NULL)
4364 leg->leg_id = sip_call_id_make(home, i_str);
4365 else
4366 leg->leg_id = sip_call_id_create(home, NULL);
4367
4368 if (!leg->leg_id) {
4369 what = "cannot create Call-ID";
4370 goto err;
4371 }
4372
4373 leg->leg_hash = leg->leg_id->i_hash;
4374 }
4375 else if (url) {
4376 /* This is "default leg" with a destination URL. */
4377 hash_value_t hash = 0;
4378
4379 if (method) {
4380 leg->leg_method = su_strdup(home, method);
4381 }
4382 #if 0
4383 else if (url->url_params) {
4384 int len = url_param(url->url_params, "method", NULL, 0);
4385 if (len) {
4386 char *tmp = su_alloc(home, len);
4387 leg->leg_method = tmp;
4388 url_param(url->url_params, "method", tmp, len);
4389 }
4390 }
4391 #endif
4392
4393 if (url->url_user && strcmp(url->url_user, "") == 0)
4394 url->url_user = "%"; /* Match to any user */
4395
4396 hash = hash_istring(url->url_scheme, ":", 0);
4397 hash = hash_istring(url->url_host, "", hash);
4398 hash = hash_istring(url->url_user, "@", hash);
4399
4400 leg->leg_hash = hash;
4401 }
4402 else {
4403 /* This is "default leg" without a destination URL. */
4404 if (agent->sa_default_leg) {
4405 SU_DEBUG_1(("%s(): %s\n", "nta_leg_tcreate", "tried to create second default leg"));
4406 su_seterrno(EEXIST);
4407 goto err;
4408 }
4409 else {
4410 agent->sa_default_leg = leg;
4411 }
4412 return leg;
4413 }
4414
4415 if (url) {
4416 /* Parameters are ignored when comparing incoming URLs */
4417 url->url_params = NULL;
4418 }
4419
4420 leg_insert(agent, leg);
4421
4422 SU_DEBUG_9(("%s(%p)\n", "nta_leg_tcreate", (void *)leg));
4423
4424 return leg;
4425
4426 err:
4427 if (what)
4428 SU_DEBUG_9(("%s(): %s\n", "nta_leg_tcreate", what));
4429
4430 su_home_zap(leg->leg_home);
4431
4432 return NULL;
4433 }
4434
4435 /** Return the default leg, if any */
nta_default_leg(nta_agent_t const * agent)4436 nta_leg_t *nta_default_leg(nta_agent_t const *agent)
4437 {
4438 return agent ? agent->sa_default_leg : NULL;
4439 }
4440
4441
4442 /**
4443 * Insert a call leg to agent.
4444 */
4445 static
leg_insert(nta_agent_t * sa,nta_leg_t * leg)4446 void leg_insert(nta_agent_t *sa, nta_leg_t *leg)
4447 {
4448 leg_htable_t *leg_hash;
4449 assert(leg);
4450 assert(sa);
4451
4452 if (leg->leg_dialog)
4453 leg_hash = sa->sa_dialogs;
4454 else
4455 leg_hash = sa->sa_defaults;
4456
4457 if (leg_htable_is_full(leg_hash)) {
4458 leg_htable_resize(sa->sa_home, leg_hash, 0);
4459 assert(leg_hash->lht_table);
4460 SU_DEBUG_7(("nta: resized%s leg hash to "MOD_ZU"\n",
4461 leg->leg_dialog ? "" : " default", leg_hash->lht_size));
4462 }
4463
4464 /* Insert entry into hash table (before other legs with same hash) */
4465 leg_htable_insert(leg_hash, leg);
4466 }
4467
4468 /**
4469 * Destroy a leg.
4470 *
4471 * @param leg leg to be destroyed
4472 */
nta_leg_destroy(nta_leg_t * leg)4473 void nta_leg_destroy(nta_leg_t *leg)
4474 {
4475 SU_DEBUG_9(("nta_leg_destroy(%p)\n", (void *)leg));
4476
4477 if (leg) {
4478 leg_htable_t *leg_hash;
4479 nta_agent_t *sa = leg->leg_agent;
4480
4481 assert(sa);
4482
4483 if (leg->leg_dialog) {
4484 assert(sa->sa_dialogs);
4485 leg_hash = sa->sa_dialogs;
4486 }
4487 else if (leg != sa->sa_default_leg) {
4488 assert(sa->sa_defaults);
4489 leg_hash = sa->sa_defaults;
4490 }
4491 else {
4492 sa->sa_default_leg = NULL;
4493 leg_hash = NULL;
4494 }
4495
4496 if (leg_hash)
4497 leg_htable_remove(leg_hash, leg);
4498
4499 leg_free(sa, leg);
4500 }
4501 }
4502
4503 static
leg_free(nta_agent_t * sa,nta_leg_t * leg)4504 void leg_free(nta_agent_t *sa, nta_leg_t *leg)
4505 {
4506 //su_free(sa->sa_home, leg);
4507 su_home_unref((su_home_t *)leg);
4508 }
4509
4510 /** Return application context for the leg */
nta_leg_magic(nta_leg_t const * leg,nta_request_f * callback)4511 nta_leg_magic_t *nta_leg_magic(nta_leg_t const *leg,
4512 nta_request_f *callback)
4513 {
4514 if (leg)
4515 if (!callback || leg->leg_callback == callback)
4516 return leg->leg_magic;
4517
4518 return NULL;
4519 }
4520
4521 /**Bind a callback function and context to a leg object.
4522 *
4523 * Change the callback function and context pointer attached to a leg
4524 * object.
4525 *
4526 * @param leg leg object to be bound
4527 * @param callback new callback function (or NULL if no callback is desired)
4528 * @param magic new context pointer
4529 */
nta_leg_bind(nta_leg_t * leg,nta_request_f * callback,nta_leg_magic_t * magic)4530 void nta_leg_bind(nta_leg_t *leg,
4531 nta_request_f *callback,
4532 nta_leg_magic_t *magic)
4533 {
4534 if (leg) {
4535 if (callback)
4536 leg->leg_callback = callback;
4537 else
4538 leg->leg_callback = leg_callback_default;
4539 leg->leg_magic = magic;
4540 }
4541 }
4542
4543 /** Add a local tag to the leg.
4544 *
4545 * @param leg leg to be tagged
4546 * @param tag tag to be added (if NULL, a tag generated by @b NTA is added)
4547 *
4548 * @return
4549 * Pointer to tag if successful, NULL otherwise.
4550 */
nta_leg_tag(nta_leg_t * leg,char const * tag)4551 char const *nta_leg_tag(nta_leg_t *leg, char const *tag)
4552 {
4553 if (!leg || !leg->leg_local)
4554 return su_seterrno(EINVAL), NULL;
4555
4556 if (tag && strchr(tag, '='))
4557 tag = strchr(tag, '=') + 1;
4558
4559 /* If there already is a tag,
4560 return NULL if it does not match with new one */
4561 if (leg->leg_local->a_tag) {
4562 if (tag == NULL || su_casematch(tag, leg->leg_local->a_tag))
4563 return leg->leg_local->a_tag;
4564 else
4565 return NULL;
4566 }
4567
4568 if (tag) {
4569 if (sip_to_tag(leg->leg_home, leg->leg_local, tag) < 0)
4570 return NULL;
4571 leg->leg_tagged = 1;
4572 return leg->leg_local->a_tag;
4573 }
4574
4575 tag = nta_agent_newtag(leg->leg_home, "tag=%s", leg->leg_agent);
4576
4577 if (!tag || sip_to_add_param(leg->leg_home, leg->leg_local, tag) < 0)
4578 return NULL;
4579
4580 leg->leg_tagged = 1;
4581
4582 return leg->leg_local->a_tag;
4583 }
4584
4585 /** Get local tag. */
nta_leg_get_tag(nta_leg_t const * leg)4586 char const *nta_leg_get_tag(nta_leg_t const *leg)
4587 {
4588 if (leg && leg->leg_local)
4589 return leg->leg_local->a_tag;
4590 else
4591 return NULL;
4592 }
4593
4594 /** Add a remote tag to the leg.
4595 *
4596 * @note No remote tag is ever generated.
4597 *
4598 * @param leg leg to be tagged
4599 * @param tag tag to be added (@b must be non-NULL)
4600 *
4601 * @return
4602 * Pointer to tag if successful, NULL otherwise.
4603 */
nta_leg_rtag(nta_leg_t * leg,char const * tag)4604 char const *nta_leg_rtag(nta_leg_t *leg, char const *tag)
4605 {
4606 /* Add a tag parameter, unless there already is a tag */
4607 if (leg && leg->leg_remote && tag) {
4608 if (sip_from_tag(leg->leg_home, leg->leg_remote, tag) < 0)
4609 return NULL;
4610 }
4611
4612 if (leg && leg->leg_remote)
4613 return leg->leg_remote->a_tag;
4614 else
4615 return NULL;
4616 }
4617
4618 /** Get remote tag. */
nta_leg_get_rtag(nta_leg_t const * leg)4619 char const *nta_leg_get_rtag(nta_leg_t const *leg)
4620 {
4621 if (leg && leg->leg_remote)
4622 return leg->leg_remote->a_tag;
4623 else
4624 return NULL;
4625 }
4626
4627 /** Get local request sequence number. */
nta_leg_get_seq(nta_leg_t const * leg)4628 uint32_t nta_leg_get_seq(nta_leg_t const *leg)
4629 {
4630 return leg ? leg->leg_seq : 0;
4631 }
4632
4633 /** Get remote request sequence number. */
nta_leg_get_rseq(nta_leg_t const * leg)4634 uint32_t nta_leg_get_rseq(nta_leg_t const *leg)
4635 {
4636 return leg ? leg->leg_rseq : 0;
4637 }
4638
4639 /** Save target and route set at UAC side.
4640 *
4641 * @sa nta_leg_client_reroute(), nta_leg_server_route(), @RFC3261 section 12.1.2
4642 *
4643 * @bug Allows modifying the route set after initial transaction, if initial
4644 * transaction had no @RecordRoute headers.
4645 *
4646 * @deprecated Use nta_leg_client_reroute() instead.
4647 */
nta_leg_client_route(nta_leg_t * leg,sip_record_route_t const * route,sip_contact_t const * contact)4648 int nta_leg_client_route(nta_leg_t *leg,
4649 sip_record_route_t const *route,
4650 sip_contact_t const *contact)
4651 {
4652 return leg_route(leg, NULL, route, contact, 0);
4653 }
4654
4655 /** Save target and route set at UAC side.
4656 *
4657 * If @a initial is true, the route set is modified even if it has been set
4658 * earlier.
4659 *
4660 * @param leg pointer to dialog leg
4661 * @param route @RecordRoute headers from response
4662 * @param contact @Contact header from response
4663 * @param initial true if response to initial transaction
4664 *
4665 * @sa nta_leg_client_route(), nta_leg_server_route(), @RFC3261 section 12.1.2
4666 *
4667 * @NEW_1_12_11
4668 */
nta_leg_client_reroute(nta_leg_t * leg,sip_record_route_t const * route,sip_contact_t const * contact,int initial)4669 int nta_leg_client_reroute(nta_leg_t *leg,
4670 sip_record_route_t const *route,
4671 sip_contact_t const *contact,
4672 int initial)
4673 {
4674 return leg_route(leg, NULL, route, contact, initial ? 2 : 1);
4675 }
4676
4677 /** Save target and route set at UAS side.
4678 *
4679 * @param leg pointer to dialog leg
4680 * @param route @RecordRoute headers from request
4681 * @param contact @Contact header from request
4682 *
4683 * @sa nta_leg_client_reroute(), @RFC3261 section 12.1.1
4684 */
nta_leg_server_route(nta_leg_t * leg,sip_record_route_t const * route,sip_contact_t const * contact)4685 int nta_leg_server_route(nta_leg_t *leg,
4686 sip_record_route_t const *route,
4687 sip_contact_t const *contact)
4688 {
4689 return leg_route(leg, route, NULL, contact, 1);
4690 }
4691
4692 /** Return route components. */
nta_leg_get_route(nta_leg_t * leg,sip_route_t const ** return_route,sip_contact_t const ** return_target)4693 int nta_leg_get_route(nta_leg_t *leg,
4694 sip_route_t const **return_route,
4695 sip_contact_t const **return_target)
4696 {
4697 if (!leg)
4698 return -1;
4699
4700 if (return_route)
4701 *return_route = leg->leg_route;
4702
4703 if (return_target)
4704 *return_target = leg->leg_target;
4705
4706 return 0;
4707 }
4708
4709 /** Generate @Replaces header.
4710 *
4711 * @since New in @VERSION_1_12_2.
4712 */
4713 sip_replaces_t *
nta_leg_make_replaces(nta_leg_t * leg,su_home_t * home,int early_only)4714 nta_leg_make_replaces(nta_leg_t *leg,
4715 su_home_t *home,
4716 int early_only)
4717 {
4718 char const *from_tag, *to_tag;
4719
4720 if (!leg)
4721 return NULL;
4722 if (!leg->leg_dialog || !leg->leg_local || !leg->leg_remote || !leg->leg_id)
4723 return NULL;
4724
4725 from_tag = leg->leg_local->a_tag; if (!from_tag) from_tag = "0";
4726 to_tag = leg->leg_remote->a_tag; if (!to_tag) to_tag = "0";
4727
4728 return sip_replaces_format(home, "%s;from-tag=%s;to-tag=%s%s",
4729 leg->leg_id->i_id, from_tag, to_tag,
4730 early_only ? ";early-only" : "");
4731 }
4732
4733 /** Get dialog leg by @Replaces header.
4734 *
4735 * @since New in @VERSION_1_12_2.
4736 */
4737 nta_leg_t *
nta_leg_by_replaces(nta_agent_t * sa,sip_replaces_t const * rp)4738 nta_leg_by_replaces(nta_agent_t *sa, sip_replaces_t const *rp)
4739 {
4740 nta_leg_t *leg = NULL;
4741
4742 if (sa && rp && rp->rp_call_id && rp->rp_from_tag && rp->rp_to_tag) {
4743 char const *from_tag = rp->rp_from_tag, *to_tag = rp->rp_to_tag;
4744 sip_call_id_t id[1];
4745 sip_call_id_init(id);
4746
4747 id->i_hash = msg_hash_string(id->i_id = rp->rp_call_id);
4748
4749 leg = leg_find(sa, NULL, NULL, id, from_tag, to_tag);
4750
4751 if (leg == NULL && strcmp(from_tag, "0") == 0)
4752 leg = leg_find(sa, NULL, NULL, id, NULL, to_tag);
4753 if (leg == NULL && strcmp(to_tag, "0") == 0)
4754 leg = leg_find(sa, NULL, NULL, id, from_tag, NULL);
4755 }
4756
4757 return leg;
4758 }
4759
4760 /**@internal
4761 * Find a leg corresponding to the request message.
4762 *
4763 */
4764 static nta_leg_t *
leg_find_call_id(nta_agent_t const * sa,sip_call_id_t const * i)4765 leg_find_call_id(nta_agent_t const *sa,
4766 sip_call_id_t const *i)
4767 {
4768 hash_value_t hash = i->i_hash;
4769 leg_htable_t const *lht = sa->sa_dialogs;
4770 nta_leg_t **ll, *leg = NULL;
4771
4772 for (ll = leg_htable_hash(lht, hash);
4773 (leg = *ll);
4774 ll = leg_htable_next(lht, ll)) {
4775 sip_call_id_t const *leg_i = leg->leg_id;
4776
4777 if (leg->leg_hash != hash)
4778 continue;
4779 if (strcmp(leg_i->i_id, i->i_id) != 0)
4780 continue;
4781
4782 return leg;
4783 }
4784
4785 return leg;
4786 }
4787
4788 /** Get dialog leg by @CallID.
4789 *
4790 * @note Usually there should be only single dialog per @CallID on
4791 * User-Agents. However, proxies may fork requests initiating the dialog and
4792 * result in multiple calls per @CallID.
4793 *
4794 * @since New in @VERSION_1_12_9.
4795 */
4796 nta_leg_t *
nta_leg_by_call_id(nta_agent_t * sa,const char * call_id)4797 nta_leg_by_call_id(nta_agent_t *sa, const char *call_id)
4798 {
4799 nta_leg_t *leg = NULL;
4800
4801 if (call_id) {
4802 sip_call_id_t id[1];
4803 sip_call_id_init(id);
4804
4805 id->i_hash = msg_hash_string(id->i_id = call_id);
4806
4807 leg = leg_find_call_id(sa, id);
4808 }
4809
4810 return leg;
4811 }
4812
4813 /** Calculate a simple case-insensitive hash over a string */
4814 su_inline
hash_istring(char const * s,char const * term,hash_value_t hash)4815 hash_value_t hash_istring(char const *s, char const *term, hash_value_t hash)
4816 {
4817 if (s) {
4818 for (; *s; s++) {
4819 unsigned char c = *s;
4820 if ('A' <= c && c <= 'Z')
4821 c += 'a' - 'A';
4822 hash = 38501U * (hash + c);
4823 }
4824 for (s = term; *s; s++) {
4825 unsigned char c = *s;
4826 hash = 38501U * (hash + c);
4827 }
4828 }
4829
4830 return hash;
4831 }
4832
4833 /** @internal Handle requests intended for this leg. */
4834 static
leg_recv(nta_leg_t * leg,msg_t * msg,sip_t * sip,tport_t * tport)4835 void leg_recv(nta_leg_t *leg, msg_t *msg, sip_t *sip, tport_t *tport)
4836 {
4837 nta_agent_t *agent = leg->leg_agent;
4838 nta_incoming_t *irq;
4839 sip_method_t method = sip->sip_request->rq_method;
4840 char const *method_name = sip->sip_request->rq_method_name;
4841 char const *tag = NULL;
4842 int status;
4843
4844 if (leg->leg_local)
4845 tag = leg->leg_local->a_tag;
4846
4847 if (leg->leg_dialog)
4848 agent->sa_stats->as_dialog_tr++;
4849
4850 /* RFC-3262 section 3 (page 4) */
4851 if (agent->sa_is_a_uas && method == sip_method_prack) {
4852 mreply(agent, NULL, 481, "No such response", msg,
4853 tport, 0, 0, NULL,
4854 TAG_END());
4855 return;
4856 }
4857
4858 if (!(irq = incoming_create(agent, msg, sip, tport, tag))) {
4859 SU_DEBUG_3(("nta: leg_recv(%p): cannot create transaction for %s\n",
4860 (void *)leg, method_name));
4861 mreply(agent, NULL, SIP_500_INTERNAL_SERVER_ERROR, msg,
4862 tport, 0, 0, NULL,
4863 TAG_END());
4864 return;
4865 }
4866
4867 irq->irq_compressed = leg->leg_compressed;
4868 irq->irq_in_callback = 1;
4869 status = incoming_callback(leg, irq, sip);
4870 irq->irq_in_callback = 0;
4871
4872 if (irq->irq_destroyed) {
4873 if (irq->irq_terminated) {
4874 incoming_free(irq);
4875 return;
4876 }
4877 if (status < 200)
4878 status = 500;
4879 }
4880
4881 if (status == 0)
4882 return;
4883
4884 if (status < 100 || status > 699) {
4885 SU_DEBUG_3(("nta_leg(%p): invalid status %03d from callback\n",
4886 (void *)leg, status));
4887 status = 500;
4888 }
4889 else if (method == sip_method_invite && status >= 200 && status < 300) {
4890 SU_DEBUG_3(("nta_leg(%p): invalid INVITE status %03d from callback\n",
4891 (void *)leg, status));
4892 status = 500;
4893 }
4894
4895 if (status >= 100 && irq->irq_status < 200)
4896 nta_incoming_treply(irq, status, NULL, TAG_END());
4897
4898 if (status >= 200)
4899 nta_incoming_destroy(irq);
4900 }
4901
4902 #if 0
4903 /**Compare two SIP from/to fields.
4904 *
4905 * @retval nonzero if matching.
4906 * @retval zero if not matching.
4907 */
4908 su_inline
4909 int addr_cmp(url_t const *a, url_t const *b)
4910 {
4911 if (b == NULL)
4912 return 0;
4913 else
4914 return
4915 host_cmp(a->url_host, b->url_host) ||
4916 su_strcmp(a->url_port, b->url_port) ||
4917 su_strcmp(a->url_user, b->url_user);
4918 }
4919 #endif
4920
4921 /** Get a leg by dialog.
4922 *
4923 * Search for a dialog leg from agent's hash table. The matching rules based
4924 * on parameters are as follows:
4925 *
4926 * @param agent pointer to agent object
4927 * @param request_uri if non-NULL, and there is destination URI
4928 * associated with the dialog, these URIs must match
4929 * @param call_id if non-NULL, must match with @CallID header contents
4930 * @param remote_tag if there is remote tag
4931 * associated with dialog, @a remote_tag must match
4932 * @param remote_uri ignored
4933 * @param local_tag if non-NULL and there is local tag associated with leg,
4934 * it must math
4935 * @param local_uri ignored
4936 *
4937 * @note
4938 * If @a remote_tag or @a local_tag is an empty string (""), the tag is
4939 * ignored when matching legs.
4940 */
nta_leg_by_dialog(nta_agent_t const * agent,url_t const * request_uri,sip_call_id_t const * call_id,char const * remote_tag,url_t const * remote_uri,char const * local_tag,url_t const * local_uri)4941 nta_leg_t *nta_leg_by_dialog(nta_agent_t const *agent,
4942 url_t const *request_uri,
4943 sip_call_id_t const *call_id,
4944 char const *remote_tag,
4945 url_t const *remote_uri,
4946 char const *local_tag,
4947 url_t const *local_uri)
4948 {
4949 void *to_be_freed = NULL;
4950 url_t *url;
4951 url_t url0[1];
4952 nta_leg_t *leg;
4953
4954 if (!agent || !call_id)
4955 return su_seterrno(EINVAL), NULL;
4956
4957 if (request_uri == NULL) {
4958 url = NULL;
4959 }
4960 else if (URL_IS_STRING(request_uri)) {
4961 /* accept a string as URL */
4962 to_be_freed = url = url_hdup(NULL, request_uri);
4963 }
4964 else {
4965 *url0 = *request_uri, url = url0;
4966 }
4967
4968 if (url) {
4969 url->url_params = NULL;
4970 agent_aliases(agent, url, NULL); /* canonize url */
4971 }
4972
4973 if (remote_tag && remote_tag[0] == '\0')
4974 remote_tag = NULL;
4975 if (local_tag && local_tag[0] == '\0')
4976 local_tag = NULL;
4977
4978 leg = leg_find(agent,
4979 NULL, url,
4980 call_id,
4981 remote_tag,
4982 local_tag);
4983
4984 if (to_be_freed) su_free(NULL, to_be_freed);
4985
4986 return leg;
4987 }
4988
4989 /**@internal
4990 * Find a leg corresponding to the request message.
4991 *
4992 * A leg matches to message if leg_match_request() returns true ("Call-ID",
4993 * "To"-tag, and "From"-tag match).
4994 */
4995 static
leg_find(nta_agent_t const * sa,char const * method_name,url_t const * request_uri,sip_call_id_t const * i,char const * from_tag,char const * to_tag)4996 nta_leg_t *leg_find(nta_agent_t const *sa,
4997 char const *method_name,
4998 url_t const *request_uri,
4999 sip_call_id_t const *i,
5000 char const *from_tag,
5001 char const *to_tag)
5002 {
5003 hash_value_t hash = i->i_hash;
5004 leg_htable_t const *lht = sa->sa_dialogs;
5005 nta_leg_t **ll, *leg, *loose_match = NULL;
5006
5007 for (ll = leg_htable_hash(lht, hash);
5008 (leg = *ll);
5009 ll = leg_htable_next(lht, ll)) {
5010 sip_call_id_t const *leg_i = leg->leg_id;
5011 char const *remote_tag = leg->leg_remote->a_tag;
5012 char const *local_tag = leg->leg_local->a_tag;
5013
5014 url_t const *leg_url = leg->leg_url;
5015 char const *leg_method = leg->leg_method;
5016
5017 if (leg->leg_hash != hash)
5018 continue;
5019 if (strcmp(leg_i->i_id, i->i_id) != 0)
5020 continue;
5021
5022 /* Do not match if the incoming To has tag, but the local does not */
5023 if (!local_tag && to_tag)
5024 continue;
5025
5026 /*
5027 * Do not match if incoming To has no tag and we have local tag
5028 * and the tag has been there from the beginning.
5029 */
5030 if (local_tag && !to_tag && !leg->leg_tagged)
5031 continue;
5032
5033 /* Do not match if incoming From has no tag but remote has a tag */
5034 if (remote_tag && !from_tag)
5035 continue;
5036
5037 /* Avoid matching with itself */
5038 if (!remote_tag != !from_tag && !local_tag != !to_tag)
5039 continue;
5040
5041 if (local_tag && to_tag && !su_casematch(local_tag, to_tag) && to_tag[0])
5042 continue;
5043 if (remote_tag && from_tag && !su_casematch(remote_tag, from_tag) && from_tag[0])
5044 continue;
5045
5046 if (leg_url && request_uri && url_cmp(leg_url, request_uri))
5047 continue;
5048 if (leg_method && method_name && !su_casematch(method_name, leg_method))
5049 continue;
5050
5051 /* Perfect match if both local and To have tag
5052 * or local does not have tag.
5053 */
5054 if ((!local_tag || to_tag))
5055 return leg;
5056
5057 if (loose_match == NULL)
5058 loose_match = leg;
5059 }
5060
5061 return loose_match;
5062 }
5063
5064 /** Get leg by destination */
nta_leg_by_uri(nta_agent_t const * agent,url_string_t const * us)5065 nta_leg_t *nta_leg_by_uri(nta_agent_t const *agent, url_string_t const *us)
5066 {
5067 url_t *url;
5068 nta_leg_t *leg = NULL;
5069
5070 if (!agent)
5071 return NULL;
5072
5073 if (!us)
5074 return agent->sa_default_leg;
5075
5076 url = url_hdup(NULL, us->us_url);
5077
5078 if (url) {
5079 agent_aliases(agent, url, NULL);
5080 leg = dst_find(agent, url, NULL);
5081 su_free(NULL, url);
5082 }
5083
5084 return leg;
5085 }
5086
5087 /** Find a non-dialog leg corresponding to the request uri u0 */
5088 static
dst_find(nta_agent_t const * sa,url_t const * u0,char const * method_name)5089 nta_leg_t *dst_find(nta_agent_t const *sa,
5090 url_t const *u0,
5091 char const *method_name)
5092 {
5093 hash_value_t hash, hash2;
5094 leg_htable_t const *lht = sa->sa_defaults;
5095 nta_leg_t **ll, *leg, *loose_match = NULL;
5096 int again;
5097 url_t url[1];
5098
5099 *url = *u0;
5100 hash = hash_istring(url->url_scheme, ":", 0);
5101 hash = hash_istring(url->url_host, "", hash);
5102 hash2 = hash_istring("%", "@", hash);
5103 hash = hash_istring(url->url_user, "@", hash);
5104
5105 /* First round, search with user name */
5106 /* Second round, search without user name */
5107 do {
5108 for (ll = leg_htable_hash(lht, hash);
5109 (leg = *ll);
5110 ll = leg_htable_next(lht, ll)) {
5111 if (leg->leg_hash != hash)
5112 continue;
5113 if (url_cmp(url, leg->leg_url))
5114 continue;
5115 if (!method_name) {
5116 if (leg->leg_method)
5117 continue;
5118 return leg;
5119 }
5120 else if (leg->leg_method) {
5121 if (!su_casematch(method_name, leg->leg_method))
5122 continue;
5123 return leg;
5124 }
5125 loose_match = leg;
5126 }
5127 if (loose_match)
5128 return loose_match;
5129
5130 again = 0;
5131
5132 if (url->url_user && strcmp(url->url_user, "%")) {
5133 url->url_user = "%";
5134 hash = hash2;
5135 again = 1;
5136 }
5137 } while (again);
5138
5139 return NULL;
5140 }
5141
5142 /** Set leg route and target URL.
5143 *
5144 * Sets the leg route and contact using the @RecordRoute and @Contact
5145 * headers.
5146 *
5147 * @param reroute - allow rerouting
5148 * - if 1, follow @RFC3261 semantics
5149 * - if 2, response to initial transaction)
5150 */
5151 static
leg_route(nta_leg_t * leg,sip_record_route_t const * route,sip_record_route_t const * reverse,sip_contact_t const * contact,int reroute)5152 int leg_route(nta_leg_t *leg,
5153 sip_record_route_t const *route,
5154 sip_record_route_t const *reverse,
5155 sip_contact_t const *contact,
5156 int reroute)
5157 {
5158 su_home_t *home = leg->leg_home;
5159 sip_route_t *r, r0[1], *old;
5160 int route_is_set;
5161
5162 if (!leg)
5163 return -1;
5164
5165 if (route == NULL && reverse == NULL && contact == NULL)
5166 return 0;
5167
5168 sip_route_init(r0);
5169
5170 route_is_set = reroute ? leg->leg_route_set : leg->leg_route != NULL;
5171
5172 if (route_is_set && reroute <= 1) {
5173 r = leg->leg_route;
5174 }
5175 else if (route) {
5176 r = sip_route_fixdup(home, route); if (!r) return -1;
5177 }
5178 else if (reverse) {
5179 r = sip_route_reverse(home, reverse); if (!r) return -1;
5180 }
5181 else
5182 r = NULL;
5183
5184 #ifdef NTA_STRICT_ROUTING
5185 /*
5186 * Handle Contact according to the RFC2543bis04 sections 16.1, 16.2 and 16.4.
5187 */
5188 if (contact) {
5189 *r0->r_url = *contact->m_url;
5190
5191 if (!(m_r = sip_route_dup(leg->leg_home, r0)))
5192 return -1;
5193
5194 /* Append, but replace last entry if it was generated from contact */
5195 for (rr = &r; *rr; rr = &(*rr)->r_next)
5196 if (leg->leg_contact_set && (*rr)->r_next == NULL)
5197 break;
5198 }
5199 else
5200 rr = NULL;
5201
5202 if (rr) {
5203 if (*rr)
5204 su_free(leg->leg_home, *rr);
5205 *rr = m_r;
5206 }
5207 if (m_r != NULL)
5208 leg->leg_contact_set = 1;
5209
5210 #else
5211 if (r && r->r_url->url_params)
5212 leg->leg_loose_route = url_has_param(r->r_url, "lr");
5213
5214 if (contact) {
5215 sip_contact_t *target, m[1], *m0;
5216
5217 sip_contact_init(m);
5218 *m->m_url = *contact->m_url;
5219 m->m_url->url_headers = NULL;
5220 target = sip_contact_dup(leg->leg_home, m);
5221
5222 if (target && target->m_url->url_params) {
5223 /* Remove ttl, method. @RFC3261 table 1, page 152 */
5224 char *p = (char *)target->m_url->url_params;
5225 p = url_strip_param_string(p, "method");
5226 p = url_strip_param_string(p, "ttl");
5227 target->m_url->url_params = p;
5228 }
5229
5230 m0 = leg->leg_target, leg->leg_target = target;
5231
5232 if (m0)
5233 su_free(leg->leg_home, m0);
5234 }
5235 #endif
5236
5237 old = leg->leg_route;
5238 leg->leg_route = r;
5239
5240 if (old && old != r)
5241 msg_header_free(leg->leg_home, (msg_header_t *)old);
5242
5243 leg->leg_route_set = 1;
5244
5245 return 0;
5246 }
5247
5248 /** @internal Default leg callback. */
5249 static int
leg_callback_default(nta_leg_magic_t * magic,nta_leg_t * leg,nta_incoming_t * irq,sip_t const * sip)5250 leg_callback_default(nta_leg_magic_t *magic,
5251 nta_leg_t *leg,
5252 nta_incoming_t *irq,
5253 sip_t const *sip)
5254 {
5255 nta_incoming_treply(irq,
5256 SIP_501_NOT_IMPLEMENTED,
5257 TAG_END());
5258 return 501;
5259 }
5260
5261 /* ====================================================================== */
5262 /* 7) Server-side (incoming) transactions */
5263
5264 #define HTABLE_HASH_IRQ(irq) ((irq)->irq_hash)
5265 HTABLE_BODIES_WITH(incoming_htable, iht, nta_incoming_t, HTABLE_HASH_IRQ,
5266 size_t, hash_value_t);
5267
5268 static void incoming_insert(nta_agent_t *agent,
5269 incoming_queue_t *queue,
5270 nta_incoming_t *irq);
5271
5272 su_inline int incoming_is_queued(nta_incoming_t const *irq);
5273 su_inline void incoming_queue(incoming_queue_t *queue, nta_incoming_t *);
5274 su_inline void incoming_remove(nta_incoming_t *irq);
5275 su_inline void incoming_set_timer(nta_incoming_t *, uint32_t interval);
5276 su_inline void incoming_reset_timer(nta_incoming_t *);
5277 su_inline size_t incoming_mass_destroy(nta_agent_t *, incoming_queue_t *);
5278
5279 static int incoming_set_params(nta_incoming_t *irq, tagi_t const *tags);
5280 su_inline
5281 int incoming_set_compartment(nta_incoming_t *irq, tport_t *tport, msg_t *msg,
5282 int create_if_needed);
5283
5284 su_inline nta_incoming_t
5285 *incoming_call_callback(nta_incoming_t *, msg_t *, sip_t *);
5286 su_inline int incoming_final_failed(nta_incoming_t *irq, msg_t *);
5287 static void incoming_retransmit_reply(nta_incoming_t *irq, tport_t *tport);
5288
5289 /** Create a default server transaction.
5290 *
5291 * The default server transaction is used by a proxy to forward responses
5292 * statelessly.
5293 *
5294 * @param agent pointer to agent object
5295 *
5296 * @retval pointer to default server transaction object
5297 * @retval NULL if failed
5298 */
nta_incoming_default(nta_agent_t * agent)5299 nta_incoming_t *nta_incoming_default(nta_agent_t *agent)
5300 {
5301 msg_t *msg;
5302 su_home_t *home;
5303 nta_incoming_t *irq;
5304
5305 if (agent == NULL)
5306 return su_seterrno(EFAULT), NULL;
5307 if (agent->sa_default_incoming)
5308 return su_seterrno(EEXIST), NULL;
5309
5310 msg = nta_msg_create(agent, 0);
5311 if (!msg)
5312 return NULL;
5313
5314 irq = su_zalloc(home = msg_home(msg), sizeof(*irq));
5315 if (!irq)
5316 return (void)msg_destroy(msg), NULL;
5317
5318 irq->irq_home = home;
5319 irq->irq_request = NULL;
5320 irq->irq_agent = agent;
5321 irq->irq_received = agent_now(agent);
5322 irq->irq_method = sip_method_invalid;
5323
5324 irq->irq_default = 1;
5325 agent->sa_default_incoming = irq;
5326
5327 return irq;
5328 }
5329
5330 /** Create a server transaction.
5331 *
5332 * Create a server transaction for a request message. This function is used
5333 * when an element processing requests statelessly wants to process a
5334 * particular request statefully.
5335 *
5336 * @param agent pointer to agent object
5337 * @param leg pointer to leg object (either @a agent or @a leg may be NULL)
5338 * @param msg pointer to message object
5339 * @param sip pointer to SIP structure (may be NULL)
5340 * @param tag,value,... optional tagged parameters
5341 *
5342 * @note
5343 * The ownership of @a msg is taken over by the function even if the
5344 * function fails.
5345 *
5346 * @TAGS
5347 * @TAG NTATAG_TPORT() specifies the transport used to receive the request
5348 * and also default transport for sending the response.
5349 *
5350 * @retval nta_incoming_t pointer to the newly created server transaction
5351 * @retval NULL if failed
5352 */
nta_incoming_create(nta_agent_t * agent,nta_leg_t * leg,msg_t * msg,sip_t * sip,tag_type_t tag,tag_value_t value,...)5353 nta_incoming_t *nta_incoming_create(nta_agent_t *agent,
5354 nta_leg_t *leg,
5355 msg_t *msg,
5356 sip_t *sip,
5357 tag_type_t tag, tag_value_t value, ...)
5358 {
5359 char const *to_tag = NULL;
5360 tport_t *tport = NULL;
5361 ta_list ta;
5362 nta_incoming_t *irq;
5363
5364 if (msg == NULL)
5365 return NULL;
5366
5367 if (agent == NULL && leg != NULL)
5368 agent = leg->leg_agent;
5369
5370 if (sip == NULL)
5371 sip = sip_object(msg);
5372
5373 if (agent == NULL || sip == NULL || !sip->sip_request || !sip->sip_cseq)
5374 return msg_destroy(msg), NULL;
5375
5376 ta_start(ta, tag, value);
5377
5378 tl_gets(ta_args(ta),
5379 NTATAG_TPORT_REF(tport),
5380 TAG_END());
5381 ta_end(ta);
5382
5383 if (leg && leg->leg_local)
5384 to_tag = leg->leg_local->a_tag;
5385
5386 if (tport == NULL)
5387 tport = tport_delivered_by(agent->sa_tports, msg);
5388
5389 irq = incoming_create(agent, msg, sip, tport, to_tag);
5390
5391 if (!irq)
5392 msg_destroy(msg);
5393
5394 return irq;
5395 }
5396
5397 /** @internal Create a new incoming transaction object. */
5398 static
incoming_create(nta_agent_t * agent,msg_t * msg,sip_t * sip,tport_t * tport,char const * tag)5399 nta_incoming_t *incoming_create(nta_agent_t *agent,
5400 msg_t *msg,
5401 sip_t *sip,
5402 tport_t *tport,
5403 char const *tag)
5404 {
5405 nta_incoming_t *irq = su_zalloc(msg_home(msg), sizeof(*irq));
5406
5407 agent->sa_stats->as_server_tr++;
5408
5409 if (irq) {
5410 su_home_t *home;
5411 incoming_queue_t *queue;
5412 sip_method_t method = sip->sip_request->rq_method;
5413
5414 irq->irq_request = msg;
5415 irq->irq_home = home = msg_home(msg_ref_create(msg));
5416 irq->irq_agent = agent;
5417
5418 irq->irq_received = agent_now(agent); /* Timestamp originally from tport */
5419
5420 irq->irq_method = method;
5421 irq->irq_rq = sip_request_copy(home, sip->sip_request);
5422 irq->irq_from = sip_from_copy(home, sip->sip_from);
5423 irq->irq_to = sip_to_copy(home, sip->sip_to);
5424 irq->irq_call_id = sip_call_id_copy(home, sip->sip_call_id);
5425 irq->irq_cseq = sip_cseq_copy(home, sip->sip_cseq);
5426 irq->irq_via = sip_via_copy(home, sip->sip_via);
5427 switch (method) {
5428 case sip_method_ack:
5429 case sip_method_cancel:
5430 case sip_method_bye:
5431 case sip_method_options:
5432 case sip_method_register: /* Handling Path is up to application */
5433 case sip_method_info:
5434 case sip_method_prack:
5435 case sip_method_publish:
5436 break;
5437 default:
5438 irq->irq_record_route =
5439 sip_record_route_copy(home, sip->sip_record_route);
5440 }
5441 irq->irq_branch = sip->sip_via->v_branch;
5442 irq->irq_reliable_tp = tport_is_reliable(tport);
5443 irq->irq_extra_100 = 0; /* Sending extra 100 trying false by default */
5444
5445 if (sip->sip_timestamp)
5446 irq->irq_timestamp = sip_timestamp_copy(home, sip->sip_timestamp);
5447
5448 /* Tag transaction */
5449 if (tag)
5450 sip_to_tag(home, irq->irq_to, tag);
5451 irq->irq_tag = irq->irq_to->a_tag;
5452
5453 if (method != sip_method_ack) {
5454 int *use_rport = NULL;
5455 int retry_without_rport = 0;
5456
5457 if (agent->sa_server_rport)
5458 use_rport = &retry_without_rport, retry_without_rport = 1;
5459
5460 if (nta_tpn_by_via(irq->irq_tpn, irq->irq_via, use_rport) < 0)
5461 SU_DEBUG_1(("%s: bad via\n", __func__));
5462 }
5463
5464 incoming_set_compartment(irq, tport, msg, 0);
5465
5466 if (method == sip_method_invite) {
5467 irq->irq_must_100rel =
5468 sip->sip_require && sip_has_feature(sip->sip_require, "100rel");
5469
5470 if (irq->irq_must_100rel ||
5471 (sip->sip_supported &&
5472 sip_has_feature(sip->sip_supported, "100rel"))) {
5473 irq->irq_rseq = su_randint(1, 0x7fffffff); /* Initialize rseq */
5474 }
5475
5476 queue = agent->sa_in.proceeding;
5477
5478 if (irq->irq_reliable_tp)
5479 incoming_set_timer(irq, agent->sa_t2 / 2); /* N1 = T2 / 2 */
5480 else
5481 incoming_set_timer(irq, 200); /* N1 = 200 ms */
5482
5483 irq->irq_tport = tport_ref(tport);
5484 }
5485 else if (method == sip_method_ack) {
5486 irq->irq_status = 700; /* Never send reply to ACK */
5487 irq->irq_completed = 1;
5488 if (irq->irq_reliable_tp || !agent->sa_is_a_uas) {
5489 queue = agent->sa_in.terminated;
5490 irq->irq_terminated = 1;
5491 }
5492 else {
5493 queue = agent->sa_in.completed; /* Timer J */
5494 }
5495 }
5496 else {
5497 queue = agent->sa_in.proceeding;
5498 /* RFC 4320 (nit-actions-03):
5499
5500 Blacklisting on a late response occurs even over reliable transports.
5501 Thus, if an element processing a request received over a reliable
5502 transport is delaying its final response at all, sending a 100 Trying
5503 well in advance of the timeout will prevent blacklisting. Sending a
5504 100 Trying immediately will not harm the transaction as it would over
5505 UDP, but a policy of always sending such a message results in
5506 unneccessary traffic. A policy of sending a 100 Trying after the
5507 period of time in which Timer E reaches T2 had this been a UDP hop is
5508 one reasonable compromise.
5509
5510 */
5511 if (agent->sa_extra_100 && irq->irq_reliable_tp)
5512 incoming_set_timer(irq, agent->sa_t2 / 2); /* T2 / 2 */
5513
5514 irq->irq_tport = tport_ref(tport);
5515 }
5516
5517 irq->irq_hash = NTA_HASH(irq->irq_call_id, irq->irq_cseq->cs_seq);
5518
5519 incoming_insert(agent, queue, irq);
5520 }
5521
5522 return irq;
5523 }
5524
5525 /** @internal
5526 * Insert incoming transaction to hash table.
5527 */
5528 static void
incoming_insert(nta_agent_t * agent,incoming_queue_t * queue,nta_incoming_t * irq)5529 incoming_insert(nta_agent_t *agent,
5530 incoming_queue_t *queue,
5531 nta_incoming_t *irq)
5532 {
5533 incoming_queue(queue, irq);
5534
5535 if (incoming_htable_is_full(agent->sa_incoming))
5536 incoming_htable_resize(agent->sa_home, agent->sa_incoming, 0);
5537
5538 if (irq->irq_method != sip_method_ack)
5539 incoming_htable_insert(agent->sa_incoming, irq);
5540 else
5541 /* ACK is appended - final response with tags match with it,
5542 * not with the original INVITE transaction */
5543 /* XXX - what about rfc2543 servers, which do not add tag? */
5544 incoming_htable_append(agent->sa_incoming, irq);
5545 }
5546
5547 /** Call callback for incoming request */
5548 static
incoming_callback(nta_leg_t * leg,nta_incoming_t * irq,sip_t * sip)5549 int incoming_callback(nta_leg_t *leg, nta_incoming_t *irq, sip_t *sip)
5550 {
5551 sip_method_t method = sip->sip_request->rq_method;
5552 char const *method_name = sip->sip_request->rq_method_name;
5553
5554 /* RFC-3261 section 12.2.2 (page 76) */
5555 if (leg->leg_dialog &&
5556 irq->irq_agent->sa_is_a_uas &&
5557 method != sip_method_ack) {
5558 uint32_t seq = sip->sip_cseq->cs_seq;
5559
5560 if (leg->leg_rseq > sip->sip_cseq->cs_seq) {
5561 SU_DEBUG_3(("nta_leg(%p): out-of-order %s (%u < %u)\n",
5562 (void *)leg, method_name, seq, leg->leg_rseq));
5563 return 500;
5564 }
5565
5566 leg->leg_rseq = seq;
5567 }
5568
5569 return leg->leg_callback(leg->leg_magic, leg, irq, sip);
5570 }
5571
5572 /**
5573 * Destroy an incoming transaction.
5574 *
5575 * This function does not actually free transaction object, but marks it as
5576 * disposable. The object is freed after a timeout.
5577 *
5578 * @param irq incoming request object to be destroyed
5579 */
nta_incoming_destroy(nta_incoming_t * irq)5580 void nta_incoming_destroy(nta_incoming_t *irq)
5581 {
5582 if (irq) {
5583 irq->irq_callback = NULL;
5584 irq->irq_magic = NULL;
5585 irq->irq_destroyed = 1;
5586 if (!irq->irq_in_callback) {
5587 if (irq->irq_terminated || irq->irq_default)
5588 incoming_free(irq);
5589 else if (irq->irq_status < 200)
5590 nta_incoming_treply(irq, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
5591 }
5592 }
5593 }
5594
5595 /** @internal
5596 * Initialize a queue for incoming transactions.
5597 */
5598 static void
incoming_queue_init(incoming_queue_t * queue,unsigned timeout)5599 incoming_queue_init(incoming_queue_t *queue, unsigned timeout)
5600 {
5601 memset(queue, 0, sizeof *queue);
5602 queue->q_tail = &queue->q_head;
5603 queue->q_timeout = timeout;
5604 }
5605
5606 /** Change the timeout value of a queue */
5607 static void
incoming_queue_adjust(nta_agent_t * sa,incoming_queue_t * queue,uint32_t timeout)5608 incoming_queue_adjust(nta_agent_t *sa,
5609 incoming_queue_t *queue,
5610 uint32_t timeout)
5611 {
5612 nta_incoming_t *irq;
5613 uint32_t latest;
5614
5615 if (timeout >= queue->q_timeout || !queue->q_head) {
5616 queue->q_timeout = timeout;
5617 return;
5618 }
5619
5620 latest = set_timeout(sa, queue->q_timeout = timeout);
5621
5622 for (irq = queue->q_head; irq; irq = irq->irq_next) {
5623 if ((int32_t)(irq->irq_timeout - latest) > 0)
5624 irq->irq_timeout = latest;
5625 }
5626 }
5627
5628 /** @internal
5629 * Test if an incoming transaction is in a queue.
5630 */
5631 su_inline
incoming_is_queued(nta_incoming_t const * irq)5632 int incoming_is_queued(nta_incoming_t const *irq)
5633 {
5634 return irq && irq->irq_queue;
5635 }
5636
5637 /** @internal
5638 * Insert an incoming transaction into a queue.
5639 *
5640 * Insert a server transaction into a queue, and sets the corresponding
5641 * timeout at the same time.
5642 */
5643 su_inline
incoming_queue(incoming_queue_t * queue,nta_incoming_t * irq)5644 void incoming_queue(incoming_queue_t *queue,
5645 nta_incoming_t *irq)
5646 {
5647 if (irq->irq_queue == queue) {
5648 assert(queue->q_timeout == 0);
5649 return;
5650 }
5651
5652 if (incoming_is_queued(irq))
5653 incoming_remove(irq);
5654
5655 assert(*queue->q_tail == NULL);
5656
5657 irq->irq_timeout = set_timeout(irq->irq_agent, queue->q_timeout);
5658
5659 irq->irq_queue = queue;
5660 irq->irq_prev = queue->q_tail;
5661 *queue->q_tail = irq;
5662 queue->q_tail = &irq->irq_next;
5663 queue->q_length++;
5664 }
5665
5666 /** @internal
5667 * Remove an incoming transaction from a queue.
5668 */
5669 su_inline
incoming_remove(nta_incoming_t * irq)5670 void incoming_remove(nta_incoming_t *irq)
5671 {
5672 assert(incoming_is_queued(irq));
5673 assert(irq->irq_queue->q_length > 0);
5674
5675 if ((*irq->irq_prev = irq->irq_next))
5676 irq->irq_next->irq_prev = irq->irq_prev;
5677 else
5678 irq->irq_queue->q_tail = irq->irq_prev, assert(!*irq->irq_queue->q_tail);
5679
5680 irq->irq_queue->q_length--;
5681 irq->irq_next = NULL;
5682 irq->irq_prev = NULL;
5683 irq->irq_queue = NULL;
5684 irq->irq_timeout = 0;
5685 }
5686
5687 su_inline
incoming_set_timer(nta_incoming_t * irq,uint32_t interval)5688 void incoming_set_timer(nta_incoming_t *irq, uint32_t interval)
5689 {
5690 nta_incoming_t **rq;
5691
5692 assert(irq);
5693
5694 if (interval == 0) {
5695 incoming_reset_timer(irq);
5696 return;
5697 }
5698
5699 if (irq->irq_rprev) {
5700 if ((*irq->irq_rprev = irq->irq_rnext))
5701 irq->irq_rnext->irq_rprev = irq->irq_rprev;
5702 if (irq->irq_agent->sa_in.re_t1 == &irq->irq_rnext)
5703 irq->irq_agent->sa_in.re_t1 = irq->irq_rprev;
5704 } else {
5705 irq->irq_agent->sa_in.re_length++;
5706 }
5707
5708 irq->irq_retry = set_timeout(irq->irq_agent, irq->irq_interval = interval);
5709
5710 rq = irq->irq_agent->sa_in.re_t1;
5711
5712 if (!(*rq) || (int32_t)((*rq)->irq_retry - irq->irq_retry) > 0)
5713 rq = &irq->irq_agent->sa_in.re_list;
5714
5715 while (*rq && (int32_t)((*rq)->irq_retry - irq->irq_retry) <= 0)
5716 rq = &(*rq)->irq_rnext;
5717
5718 if ((irq->irq_rnext = *rq))
5719 irq->irq_rnext->irq_rprev = &irq->irq_rnext;
5720 *rq = irq;
5721 irq->irq_rprev = rq;
5722
5723 /* Optimization: keep special place for transactions with T1 interval */
5724 if (interval == irq->irq_agent->sa_t1)
5725 irq->irq_agent->sa_in.re_t1 = rq;
5726 }
5727
5728 su_inline
incoming_reset_timer(nta_incoming_t * irq)5729 void incoming_reset_timer(nta_incoming_t *irq)
5730 {
5731 if (irq->irq_rprev) {
5732 if ((*irq->irq_rprev = irq->irq_rnext))
5733 irq->irq_rnext->irq_rprev = irq->irq_rprev;
5734 if (irq->irq_agent->sa_in.re_t1 == &irq->irq_rnext)
5735 irq->irq_agent->sa_in.re_t1 = irq->irq_rprev;
5736 irq->irq_agent->sa_in.re_length--;
5737 }
5738
5739 irq->irq_interval = 0, irq->irq_retry = 0;
5740 irq->irq_rnext = NULL, irq->irq_rprev = NULL;
5741 }
5742
5743 /** @internal
5744 * Free an incoming transaction.
5745 */
5746 static
incoming_free(nta_incoming_t * irq)5747 void incoming_free(nta_incoming_t *irq)
5748 {
5749 SU_DEBUG_9(("nta: incoming_free(%p)\n", (void *)irq));
5750
5751 incoming_cut_off(irq);
5752 incoming_reclaim(irq);
5753 }
5754
5755 /** Remove references to the irq */
5756 su_inline
incoming_cut_off(nta_incoming_t * irq)5757 void incoming_cut_off(nta_incoming_t *irq)
5758 {
5759 nta_agent_t *agent = irq->irq_agent;
5760
5761 assert(agent);
5762
5763 if (irq->irq_default) {
5764 if (irq == agent->sa_default_incoming)
5765 agent->sa_default_incoming = NULL;
5766 irq->irq_default = 0;
5767 return;
5768 }
5769
5770 if (incoming_is_queued(irq))
5771 incoming_remove(irq);
5772
5773 incoming_reset_timer(irq);
5774
5775 incoming_htable_remove(agent->sa_incoming, irq);
5776
5777 if (irq->irq_cc)
5778 nta_compartment_decref(&irq->irq_cc);
5779
5780 if (irq->irq_tport)
5781 tport_decref(&irq->irq_tport);
5782 }
5783
5784 /** Reclaim the memory used by irq */
5785 su_inline
incoming_reclaim(nta_incoming_t * irq)5786 void incoming_reclaim(nta_incoming_t *irq)
5787 {
5788 su_home_t *home = irq->irq_home;
5789 nta_reliable_t *rel, *rel_next;
5790
5791 if (irq->irq_request)
5792 msg_destroy(irq->irq_request), irq->irq_request = NULL;
5793 if (irq->irq_request2)
5794 msg_destroy(irq->irq_request2), irq->irq_request2 = NULL;
5795 if (irq->irq_response)
5796 msg_destroy(irq->irq_response), irq->irq_response = NULL;
5797
5798 for (rel = irq->irq_reliable; rel; rel = rel_next) {
5799 rel_next = rel->rel_next;
5800 if (rel->rel_unsent)
5801 msg_destroy(rel->rel_unsent);
5802 su_free(irq->irq_agent->sa_home, rel);
5803 }
5804
5805 irq->irq_home = NULL;
5806
5807 su_free(home, irq);
5808
5809 msg_destroy((msg_t *)home);
5810 }
5811
5812 /** Queue request to be freed */
5813 su_inline
incoming_free_queue(incoming_queue_t * q,nta_incoming_t * irq)5814 void incoming_free_queue(incoming_queue_t *q, nta_incoming_t *irq)
5815 {
5816 incoming_cut_off(irq);
5817 incoming_queue(q, irq);
5818 }
5819
5820 /** Reclaim memory used by queue of requests */
5821 static
incoming_reclaim_queued(su_root_magic_t * rm,su_msg_r msg,union sm_arg_u * u)5822 void incoming_reclaim_queued(su_root_magic_t *rm,
5823 su_msg_r msg,
5824 union sm_arg_u *u)
5825 {
5826 incoming_queue_t *q = u->a_incoming_queue;
5827 nta_incoming_t *irq, *irq_next;
5828
5829 SU_DEBUG_9(("incoming_reclaim_all(%p, %p, %p)\n",
5830 (void *)rm, (void *)msg, (void *)u));
5831
5832 for (irq = q->q_head; irq; irq = irq_next) {
5833 irq_next = irq->irq_next;
5834 incoming_reclaim(irq);
5835 }
5836 }
5837
5838 /**Bind a callback and context to an incoming transaction object
5839 *
5840 * Set the callback function and context pointer attached to an incoming
5841 * request object. The callback function will be invoked if the incoming
5842 * request is cancelled, or if the final response to an incoming @b INVITE
5843 * request has been acknowledged.
5844 *
5845 * If the callback is NULL, or no callback has been bound, NTA invokes the
5846 * request callback of the call leg.
5847 *
5848 * @param irq incoming transaction
5849 * @param callback callback function
5850 * @param magic application context
5851 */
nta_incoming_bind(nta_incoming_t * irq,nta_ack_cancel_f * callback,nta_incoming_magic_t * magic)5852 void nta_incoming_bind(nta_incoming_t *irq,
5853 nta_ack_cancel_f *callback,
5854 nta_incoming_magic_t *magic)
5855 {
5856 if (irq) {
5857 irq->irq_callback = callback;
5858 irq->irq_magic = magic;
5859 }
5860 }
5861
5862 /** Add a @To tag to incoming request if needed.
5863 *
5864 * If @a tag is NULL, a new tag is generated.
5865 */
nta_incoming_tag(nta_incoming_t * irq,char const * tag)5866 char const *nta_incoming_tag(nta_incoming_t *irq, char const *tag)
5867 {
5868 if (!irq)
5869 return su_seterrno(EFAULT), NULL;
5870
5871 if (irq->irq_default)
5872 return su_seterrno(EINVAL), NULL;
5873
5874 if (tag && strchr(tag, '='))
5875 tag = strchr(tag, '=') + 1;
5876
5877 if (tag && irq->irq_tag && !su_casematch(tag, irq->irq_tag))
5878 return NULL;
5879
5880 if (!irq->irq_tag) {
5881 if (tag)
5882 tag = su_strdup(irq->irq_home, tag);
5883 else
5884 tag = nta_agent_newtag(irq->irq_home, NULL, irq->irq_agent);
5885
5886 if (!tag)
5887 return tag;
5888
5889 irq->irq_tag = tag;
5890 irq->irq_tag_set = 1;
5891 }
5892
5893 return irq->irq_tag;
5894 }
5895
5896
5897 /**Get request message.
5898 *
5899 * Retrieve the incoming request message of the incoming transaction. Note
5900 * that the message is not copied, but a new reference to it is created.
5901 *
5902 * @param irq incoming transaction handle
5903 *
5904 * @retval
5905 * A pointer to request message is returned.
5906 */
nta_incoming_getrequest(nta_incoming_t * irq)5907 msg_t *nta_incoming_getrequest(nta_incoming_t *irq)
5908 {
5909 msg_t *msg = NULL;
5910
5911 if (irq && !irq->irq_default)
5912 msg = msg_ref_create(irq->irq_request);
5913
5914 return msg;
5915 }
5916
5917 /**Get ACK or CANCEL message.
5918 *
5919 * Retrieve the incoming ACK or CANCEL request message of the incoming
5920 * transaction. Note that the ACK or CANCEL message is not copied, but a new
5921 * reference to it is created.
5922 *
5923 * @param irq incoming transaction handle
5924 *
5925 * @retval A pointer to request message is returned, or NULL if there is no
5926 * CANCEL or ACK received.
5927 */
nta_incoming_getrequest_ackcancel(nta_incoming_t * irq)5928 msg_t *nta_incoming_getrequest_ackcancel(nta_incoming_t *irq)
5929 {
5930 msg_t *msg = NULL;
5931
5932 if (irq && irq->irq_request2)
5933 msg = msg_ref_create(irq->irq_request2);
5934
5935 return msg;
5936 }
5937
5938 /**Get response message.
5939 *
5940 * Retrieve the response message latest sent by the server transaction. Note
5941 * that the message is not copied, but a new reference to it is created. Use
5942 * msg_dup() or msg_copy() to make a copy of it.
5943 *
5944 * @param irq incoming transaction handle
5945 *
5946 * @retval
5947 * A pointer to a response message is returned.
5948 */
nta_incoming_getresponse(nta_incoming_t * irq)5949 msg_t *nta_incoming_getresponse(nta_incoming_t *irq)
5950 {
5951 msg_t *msg = NULL;
5952
5953 if (irq && irq->irq_response)
5954 msg = msg_ref_create(irq->irq_response);
5955
5956 return msg;
5957 }
5958
5959 /** Get method of a server transaction. */
nta_incoming_method(nta_incoming_t const * irq)5960 sip_method_t nta_incoming_method(nta_incoming_t const *irq)
5961 {
5962 return irq ? irq->irq_method : sip_method_invalid;
5963 }
5964
5965 /** Get method name of a server transaction. */
nta_incoming_method_name(nta_incoming_t const * irq)5966 char const *nta_incoming_method_name(nta_incoming_t const *irq)
5967 {
5968 if (irq == NULL)
5969 return NULL;
5970 else if (irq->irq_rq)
5971 return irq->irq_rq->rq_method_name;
5972 else
5973 return "*";
5974 }
5975
5976 /** Get Request-URI of a server transaction */
nta_incoming_url(nta_incoming_t const * irq)5977 url_t const *nta_incoming_url(nta_incoming_t const *irq)
5978 {
5979 return irq && irq->irq_rq ? irq->irq_rq->rq_url : NULL;
5980 }
5981
5982 /** Get sequence number of a server transaction.
5983 */
nta_incoming_cseq(nta_incoming_t const * irq)5984 uint32_t nta_incoming_cseq(nta_incoming_t const *irq)
5985 {
5986 return irq && irq->irq_cseq ? irq->irq_cseq->cs_seq : 0;
5987 }
5988
5989 /** Get local tag for incoming request */
nta_incoming_gettag(nta_incoming_t const * irq)5990 char const *nta_incoming_gettag(nta_incoming_t const *irq)
5991 {
5992 return irq ? irq->irq_tag : 0;
5993 }
5994
5995 /**
5996 * Get status code of a server transaction.
5997 */
nta_incoming_status(nta_incoming_t const * irq)5998 int nta_incoming_status(nta_incoming_t const *irq)
5999 {
6000 return irq ? irq->irq_status : 400;
6001 }
6002
6003 /** Get application context for a server transaction.
6004 *
6005 * @param irq server transaction
6006 * @param callback callback pointer
6007 *
6008 * Return the application context bound to the server transaction. If the @a
6009 * callback function pointer is given, return application context only if
6010 * the callback matches with the callback bound to the server transaction.
6011 *
6012 */
nta_incoming_magic(nta_incoming_t * irq,nta_ack_cancel_f * callback)6013 nta_incoming_magic_t *nta_incoming_magic(nta_incoming_t *irq,
6014 nta_ack_cancel_f *callback)
6015 {
6016 return irq && (callback == NULL || irq->irq_callback == callback)
6017 ? irq->irq_magic : NULL;
6018 }
6019
6020 /** When received.
6021 *
6022 * Return timestamp from the reception of the initial request.
6023 *
6024 * @NEW_1_12_7.
6025 */
nta_incoming_received(nta_incoming_t * irq,su_nanotime_t * return_nano)6026 sip_time_t nta_incoming_received(nta_incoming_t *irq,
6027 su_nanotime_t *return_nano)
6028 {
6029 su_time_t tv = { 0, 0 };
6030
6031 if (irq)
6032 tv = irq->irq_received;
6033
6034 if (return_nano)
6035 *return_nano = (su_nanotime_t)tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
6036
6037 return tv.tv_sec;
6038 }
6039
6040 /** Find incoming transaction. */
nta_incoming_find(nta_agent_t const * agent,sip_t const * sip,sip_via_t const * v)6041 nta_incoming_t *nta_incoming_find(nta_agent_t const *agent,
6042 sip_t const *sip,
6043 sip_via_t const *v)
6044 {
6045 if (agent && sip && v)
6046 return incoming_find(agent, sip, v, NULL, NULL, NULL);
6047 else
6048 return NULL;
6049 }
6050
6051 /** Find a matching server transaction object.
6052 *
6053 * Check also for requests to merge, to ACK, or to CANCEL.
6054 */
incoming_find(nta_agent_t const * agent,sip_t const * sip,sip_via_t const * v,nta_incoming_t ** return_merge,nta_incoming_t ** return_ack,nta_incoming_t ** return_cancel)6055 static nta_incoming_t *incoming_find(nta_agent_t const *agent,
6056 sip_t const *sip,
6057 sip_via_t const *v,
6058 nta_incoming_t **return_merge,
6059 nta_incoming_t **return_ack,
6060 nta_incoming_t **return_cancel)
6061 {
6062 sip_cseq_t const *cseq = sip->sip_cseq;
6063 sip_call_id_t const *i = sip->sip_call_id;
6064 sip_to_t const *to = sip->sip_to;
6065 sip_from_t const *from = sip->sip_from;
6066 sip_request_t *rq = sip->sip_request;
6067 incoming_htable_t const *iht = agent->sa_incoming;
6068 hash_value_t hash = NTA_HASH(i, cseq->cs_seq);
6069 char const *magic_branch;
6070
6071 nta_incoming_t **ii, *irq;
6072
6073 int is_uas_ack = return_ack && agent->sa_is_a_uas;
6074
6075 if (v->v_branch && su_casenmatch(v->v_branch, "z9hG4bK", 7))
6076 magic_branch = v->v_branch + 7;
6077 else
6078 magic_branch = NULL;
6079
6080 for (ii = incoming_htable_hash(iht, hash);
6081 (irq = *ii);
6082 ii = incoming_htable_next(iht, ii)) {
6083 if (hash != irq->irq_hash ||
6084 irq->irq_call_id->i_hash != i->i_hash ||
6085 strcmp(irq->irq_call_id->i_id, i->i_id))
6086 continue;
6087 if (irq->irq_cseq->cs_seq != cseq->cs_seq)
6088 continue;
6089 if (su_strcasecmp(irq->irq_from->a_tag, from->a_tag))
6090 continue;
6091
6092 if (is_uas_ack &&
6093 irq->irq_method == sip_method_invite &&
6094 200 <= irq->irq_status && irq->irq_status < 300 &&
6095 su_casematch(irq->irq_tag, to->a_tag)) {
6096 *return_ack = irq;
6097 return NULL;
6098 }
6099
6100 if (magic_branch) {
6101 /* RFC3261 17.2.3:
6102 *
6103 * The request matches a transaction if branch and sent-by in topmost
6104 * the method of the request matches the one that created the
6105 * transaction, except for ACK, where the method of the request
6106 * that created the transaction is INVITE.
6107 */
6108 if (irq->irq_via->v_branch &&
6109 su_casematch(irq->irq_via->v_branch + 7, magic_branch) &&
6110 su_casematch(irq->irq_via->v_host, v->v_host) &&
6111 su_strmatch(irq->irq_via->v_port, v->v_port)) {
6112 if (irq->irq_method == cseq->cs_method &&
6113 strcmp(irq->irq_cseq->cs_method_name,
6114 cseq->cs_method_name) == 0)
6115 return irq;
6116 if (return_ack && irq->irq_method == sip_method_invite)
6117 return *return_ack = irq, NULL;
6118 if (return_cancel && irq->irq_method != sip_method_ack)
6119 return *return_cancel = irq, NULL;
6120 }
6121 }
6122 else {
6123 /* No magic branch */
6124
6125 /* INVITE request matches a transaction if
6126 the Request-URI, To tag, From tag, Call-ID, CSeq, and
6127 top Via header match */
6128
6129 /* From tag, Call-ID, and CSeq number has been matched above */
6130
6131 /* Match top Via header field */
6132 if (!su_casematch(irq->irq_via->v_branch, v->v_branch) ||
6133 !su_casematch(irq->irq_via->v_host, v->v_host) ||
6134 !su_strmatch(irq->irq_via->v_port, v->v_port))
6135 ;
6136 /* Match Request-URI */
6137 else if (url_cmp(irq->irq_rq->rq_url, rq->rq_url))
6138 ;
6139 else {
6140 /* Match CSeq */
6141 if (irq->irq_method == cseq->cs_method &&
6142 su_strmatch(irq->irq_cseq->cs_method_name, cseq->cs_method_name)) {
6143 /* Match To tag */
6144 if (!su_strcasecmp(irq->irq_to->a_tag, to->a_tag))
6145 return irq; /* found */
6146 }
6147 else if (
6148 /* Tag set by UAS */
6149 su_strcasecmp(irq->irq_tag, to->a_tag) &&
6150 /* Original tag */
6151 su_strcasecmp(irq->irq_to->a_tag, to->a_tag))
6152 ;
6153 else if (return_ack && irq->irq_method == sip_method_invite)
6154 return *return_ack = irq, NULL;
6155 else if (return_cancel && irq->irq_method != sip_method_ack)
6156 return *return_cancel = irq, NULL;
6157 }
6158 }
6159
6160 /* RFC3261 - section 8.2.2.2 Merged Requests */
6161 if (return_merge) {
6162 if (irq->irq_cseq->cs_method == cseq->cs_method &&
6163 strcmp(irq->irq_cseq->cs_method_name,
6164 cseq->cs_method_name) == 0)
6165 *return_merge = irq, return_merge = NULL;
6166 }
6167 }
6168
6169 return NULL;
6170 }
6171
6172 /** Process retransmitted requests. */
6173 su_inline
6174 int
incoming_recv(nta_incoming_t * irq,msg_t * msg,sip_t * sip,tport_t * tport)6175 incoming_recv(nta_incoming_t *irq, msg_t *msg, sip_t *sip, tport_t *tport)
6176 {
6177 nta_agent_t *agent = irq->irq_agent;
6178
6179 agent->sa_stats->as_recv_retry++;
6180
6181 if (irq->irq_status >= 100) {
6182 SU_DEBUG_5(("nta: re-received %s request, retransmitting %u reply\n",
6183 sip->sip_request->rq_method_name, irq->irq_status));
6184 incoming_retransmit_reply(irq, tport);
6185 }
6186 else if (irq->irq_agent->sa_extra_100 &&
6187 irq->irq_extra_100) {
6188 /* Agent and Irq configured to answer automatically with 100 Trying */
6189 if (irq->irq_method == sip_method_invite ||
6190 /*
6191 * Send 100 trying to non-invite if at least half of T2 has expired
6192 * since the transaction was created.
6193 */
6194 su_duration(agent_now(irq->irq_agent), irq->irq_received) * 2U >
6195 irq->irq_agent->sa_t2) {
6196 SU_DEBUG_5(("nta: re-received %s request, sending 100 Trying\n",
6197 sip->sip_request->rq_method_name));
6198 nta_incoming_treply(irq, SIP_100_TRYING, NTATAG_TPORT(tport), TAG_END());
6199 }
6200 }
6201
6202 msg_destroy(msg);
6203
6204 return 0;
6205 }
6206
6207 su_inline
incoming_ack(nta_incoming_t * irq,msg_t * msg,sip_t * sip,tport_t * tport)6208 int incoming_ack(nta_incoming_t *irq, msg_t *msg, sip_t *sip, tport_t *tport)
6209 {
6210 nta_agent_t *agent = irq->irq_agent;
6211
6212 /* Process ACK separately? */
6213 if (irq->irq_status >= 200 && irq->irq_status < 300 && !agent->sa_is_a_uas)
6214 return -1;
6215
6216 if (irq->irq_queue == agent->sa_in.inv_completed) {
6217 if (!irq->irq_confirmed)
6218 agent->sa_stats->as_acked_tr++;
6219
6220 irq->irq_confirmed = 1;
6221 incoming_reset_timer(irq); /* Reset timer G */
6222
6223 if (!irq->irq_reliable_tp) {
6224 incoming_queue(agent->sa_in.inv_confirmed, irq); /* Timer I */
6225 }
6226 else {
6227 irq->irq_terminated = 1;
6228 incoming_queue(agent->sa_in.terminated, irq);
6229 }
6230
6231 if (!irq->irq_destroyed) {
6232 if (!irq->irq_callback) /* Process ACK normally */
6233 return -1;
6234
6235 incoming_call_callback(irq, msg, sip); /* ACK callback */
6236 }
6237 } else if (irq->irq_queue == agent->sa_in.proceeding ||
6238 irq->irq_queue == agent->sa_in.preliminary)
6239 return -1;
6240 else
6241 assert(irq->irq_queue == agent->sa_in.inv_confirmed ||
6242 irq->irq_queue == agent->sa_in.terminated);
6243
6244 msg_destroy(msg);
6245
6246 return 0;
6247 }
6248
6249 /** Respond to the CANCEL. */
6250 su_inline
incoming_cancel(nta_incoming_t * irq,msg_t * msg,sip_t * sip,tport_t * tport)6251 int incoming_cancel(nta_incoming_t *irq, msg_t *msg, sip_t *sip,
6252 tport_t *tport)
6253 {
6254 nta_agent_t *agent = irq->irq_agent;
6255
6256 /* According to the RFC 3261, this INVITE has been destroyed */
6257 if (irq->irq_method == sip_method_invite &&
6258 200 <= irq->irq_status && irq->irq_status < 300) {
6259 mreply(agent, NULL, SIP_481_NO_TRANSACTION, msg,
6260 tport, 0, 0, NULL,
6261 TAG_END());
6262 return 0;
6263 }
6264
6265 /* UAS MUST use same tag in final response to CANCEL and INVITE */
6266 if (agent->sa_is_a_uas && irq->irq_tag == NULL) {
6267 nta_incoming_tag(irq, NULL);
6268 }
6269
6270 mreply(agent, NULL, SIP_200_OK, msg_ref_create(msg),
6271 tport, 0, 0, irq->irq_tag,
6272 TAG_END());
6273
6274 /* We have already sent final response */
6275 if (irq->irq_completed || irq->irq_method != sip_method_invite) {
6276 msg_destroy(msg);
6277 return 0;
6278 }
6279
6280 if (!irq->irq_canceled) {
6281 irq->irq_canceled = 1;
6282 agent->sa_stats->as_canceled_tr++;
6283 irq = incoming_call_callback(irq, msg, sip);
6284 }
6285
6286 if (irq && !irq->irq_completed && agent->sa_cancel_487)
6287 /* Respond to the cancelled request */
6288 nta_incoming_treply(irq, SIP_487_REQUEST_CANCELLED, TAG_END());
6289
6290 msg_destroy(msg);
6291
6292 return 0;
6293 }
6294
6295 /** Merge request */
6296 static
request_merge(nta_agent_t * agent,msg_t * msg,sip_t * sip,tport_t * tport,char const * to_tag)6297 void request_merge(nta_agent_t *agent,
6298 msg_t *msg, sip_t *sip, tport_t *tport,
6299 char const *to_tag)
6300 {
6301 nta_incoming_t *irq;
6302
6303 agent->sa_stats->as_merged_request++;
6304
6305 irq = incoming_create(agent, msg, sip, tport, to_tag);
6306
6307 if (irq) {
6308 nta_incoming_treply(irq, 482, "Request merged", TAG_END());
6309 nta_incoming_destroy(irq);
6310 } else {
6311 SU_DEBUG_3(("nta: request_merge(): cannot create transaction for %s\n",
6312 sip->sip_request->rq_method_name));
6313 mreply(agent, NULL, 482, "Request merged", msg,
6314 tport, 0, 0, NULL,
6315 TAG_END());
6316 }
6317 }
6318
6319 /**@typedef nta_ack_cancel_f
6320 *
6321 * Callback function prototype for CANCELed/ACKed requests
6322 *
6323 * This is a callback function is invoked by NTA when an incoming request
6324 * has been cancelled or an response to an incoming INVITE request has been
6325 * acknowledged.
6326 *
6327 * @param magic incoming request context
6328 * @param ireq incoming request
6329 * @param sip ACK/CANCEL message
6330 *
6331 * @retval 0
6332 * This callback function should return always 0.
6333 */
6334
6335 /** Call callback of incoming transaction */
6336 su_inline
6337 nta_incoming_t *
incoming_call_callback(nta_incoming_t * irq,msg_t * msg,sip_t * sip)6338 incoming_call_callback(nta_incoming_t *irq, msg_t *msg, sip_t *sip)
6339 {
6340 if (irq->irq_callback) {
6341 irq->irq_in_callback = 1;
6342 irq->irq_request2 = msg;
6343 irq->irq_callback(irq->irq_magic, irq, sip);
6344 irq->irq_request2 = NULL;
6345 irq->irq_in_callback = 0;
6346
6347 if (irq->irq_terminated && irq->irq_destroyed)
6348 incoming_free(irq), irq = NULL;
6349 }
6350 return irq;
6351 }
6352
6353 /**Set server transaction parameters.
6354 *
6355 * Sets the server transaction parameters. Among others, parameters determine the way
6356 * the SigComp compression is handled.
6357 *
6358 * @TAGS
6359 * NTATAG_COMP(), NTATAG_SIGCOMP_CLOSE() and NTATAG_EXTRA_100().
6360 *
6361 * @retval number of set parameters when succesful
6362 * @retval -1 upon an error
6363 */
nta_incoming_set_params(nta_incoming_t * irq,tag_type_t tag,tag_value_t value,...)6364 int nta_incoming_set_params(nta_incoming_t *irq,
6365 tag_type_t tag, tag_value_t value, ...)
6366 {
6367 int retval = -1;
6368
6369 if (irq) {
6370 ta_list ta;
6371 ta_start(ta, tag, value);
6372 retval = incoming_set_params(irq, ta_args(ta));
6373 ta_end(ta);
6374 }
6375 else {
6376 su_seterrno(EINVAL);
6377 }
6378
6379 return retval;
6380 }
6381
6382 static
incoming_set_params(nta_incoming_t * irq,tagi_t const * tags)6383 int incoming_set_params(nta_incoming_t *irq, tagi_t const *tags)
6384 {
6385 int retval = 0;
6386
6387 tagi_t const *t;
6388 char const *comp = NONE;
6389 struct sigcomp_compartment *cc = NONE;
6390
6391 if (irq->irq_default)
6392 return retval;
6393
6394 for (t = tags; t; t = tl_next(t)) {
6395 tag_type_t tt = t->t_tag;
6396
6397 if (ntatag_comp == tt)
6398 comp = (char const *)t->t_value, retval++;
6399
6400 else if (ntatag_sigcomp_close == tt)
6401 irq->irq_sigcomp_zap = t->t_value != 0, retval++;
6402
6403 else if (tptag_compartment == tt)
6404 cc = (void *)t->t_value, retval++;
6405
6406 else if (ntatag_extra_100 == tt)
6407 irq->irq_extra_100 = t->t_value != 0, retval++;
6408 }
6409
6410 if (cc != NONE) {
6411 if (cc)
6412 agent_accept_compressed(irq->irq_agent, irq->irq_request, cc);
6413 if (irq->irq_cc)
6414 nta_compartment_decref(&irq->irq_cc);
6415 irq->irq_cc = nta_compartment_ref(cc);
6416 }
6417 else if (comp != NULL && comp != NONE && irq->irq_cc == NULL) {
6418 incoming_set_compartment(irq, irq->irq_tport, irq->irq_request, 1);
6419 }
6420
6421 else if (comp == NULL) {
6422 irq->irq_tpn->tpn_comp = NULL;
6423 }
6424
6425 return retval;
6426 }
6427
6428 su_inline
incoming_set_compartment(nta_incoming_t * irq,tport_t * tport,msg_t * msg,int create_if_needed)6429 int incoming_set_compartment(nta_incoming_t *irq, tport_t *tport, msg_t *msg,
6430 int create_if_needed)
6431 {
6432 if (!nta_compressor_vtable)
6433 return 0;
6434
6435 if (irq->irq_cc == NULL
6436 || irq->irq_tpn->tpn_comp
6437 || tport_delivered_with_comp(tport, msg, NULL) != -1) {
6438 struct sigcomp_compartment *cc;
6439
6440 cc = agent_compression_compartment(irq->irq_agent, tport, irq->irq_tpn,
6441 create_if_needed);
6442
6443 if (cc)
6444 agent_accept_compressed(irq->irq_agent, msg, cc);
6445
6446 irq->irq_cc = cc;
6447 }
6448
6449 return 0;
6450 }
6451
6452 /** Add essential headers to the response message */
nta_incoming_response_headers(nta_incoming_t * irq,msg_t * msg,sip_t * sip)6453 static int nta_incoming_response_headers(nta_incoming_t *irq,
6454 msg_t *msg,
6455 sip_t *sip)
6456 {
6457 int clone = 0;
6458 su_home_t *home = msg_home(msg);
6459
6460 if (!sip->sip_from)
6461 clone = 1, sip->sip_from = sip_from_copy(home, irq->irq_from);
6462 if (!sip->sip_to)
6463 clone = 1, sip->sip_to = sip_to_copy(home, irq->irq_to);
6464 if (!sip->sip_call_id)
6465 clone = 1, sip->sip_call_id = sip_call_id_copy(home, irq->irq_call_id);
6466 if (!sip->sip_cseq)
6467 clone = 1, sip->sip_cseq = sip_cseq_copy(home, irq->irq_cseq);
6468 if (!sip->sip_via) {
6469 clone = 1;
6470 /* 100 responses are not forwarded by proxies, so only include the topmost Via header */
6471 if (sip->sip_status && sip->sip_status->st_status == 100)
6472 sip->sip_via = (sip_via_t *)msg_header_copy_one(home, (msg_header_t const *)irq->irq_via);
6473 else
6474 sip->sip_via = sip_via_copy(home, irq->irq_via);
6475 }
6476
6477 if (clone)
6478 msg_set_parent(msg, (msg_t *)irq->irq_home);
6479
6480 if (!sip->sip_from || !sip->sip_to || !sip->sip_call_id || !sip->sip_cseq || !sip->sip_via)
6481 return -1;
6482
6483 return 0;
6484 }
6485
6486 /** Complete a response message.
6487 *
6488 * @param irq server transaction object
6489 * @param msg response message to be completed
6490 * @param status status code (in range 100 - 699)
6491 * @param phrase status phrase (may be NULL)
6492 * @param tag,value,... taged argument list
6493 *
6494 * Generate status structure based on @a status and @a phrase.
6495 * Add essential headers to the response message:
6496 * @From, @To, @CallID, @CSeq, @Via, and optionally
6497 * @RecordRoute.
6498 */
nta_incoming_complete_response(nta_incoming_t * irq,msg_t * msg,int status,char const * phrase,tag_type_t tag,tag_value_t value,...)6499 int nta_incoming_complete_response(nta_incoming_t *irq,
6500 msg_t *msg,
6501 int status,
6502 char const *phrase,
6503 tag_type_t tag, tag_value_t value, ...)
6504 {
6505 su_home_t *home = msg_home(msg);
6506 sip_t *sip = sip_object(msg);
6507 int retval;
6508 ta_list ta;
6509
6510 if (irq == NULL || sip == NULL)
6511 return su_seterrno(EFAULT), -1;
6512
6513 if (status != 0 && (status < 100 || status > 699))
6514 return su_seterrno(EINVAL), -1;
6515
6516 if (status != 0 && !sip->sip_status)
6517 sip->sip_status = sip_status_create(home, status, phrase, NULL);
6518
6519 ta_start(ta, tag, value);
6520 retval = sip_add_tl(msg, sip, ta_tags(ta));
6521 ta_end(ta);
6522
6523 if (retval < 0)
6524 return -1;
6525
6526 if (irq->irq_default)
6527 return sip_complete_message(msg);
6528
6529 if (status > 100 && !irq->irq_tag) {
6530 if (sip->sip_to)
6531 nta_incoming_tag(irq, sip->sip_to->a_tag);
6532 else
6533 nta_incoming_tag(irq, NULL);
6534 }
6535
6536 if (nta_incoming_response_headers(irq, msg, sip) < 0)
6537 return -1;
6538
6539 if (sip->sip_status && sip->sip_status->st_status > 100 &&
6540 irq->irq_tag && sip->sip_to && !sip->sip_to->a_tag)
6541 if (sip_to_tag(home, sip->sip_to, irq->irq_tag) < 0)
6542 return -1;
6543
6544 if (status > 100 && status < 300 && !sip->sip_record_route && irq->irq_record_route)
6545 if (sip_add_dup(msg, sip, (sip_header_t *)irq->irq_record_route) < 0)
6546 return -1;
6547
6548 return sip_complete_message(msg);
6549 }
6550
6551
6552 /** Create a response message for request.
6553 *
6554 * @NEW_1_12_5.
6555 */
nta_incoming_create_response(nta_incoming_t * irq,int status,char const * phrase)6556 msg_t *nta_incoming_create_response(nta_incoming_t *irq,
6557 int status, char const *phrase)
6558 {
6559 msg_t *msg = NULL;
6560 sip_t *sip;
6561
6562 if (irq) {
6563 msg = nta_msg_create(irq->irq_agent, 0);
6564 sip = sip_object(msg);
6565
6566 if (sip) {
6567 if (status != 0)
6568 sip->sip_status = sip_status_create(msg_home(msg), status, phrase, NULL);
6569
6570 if (nta_incoming_response_headers(irq, msg, sip) < 0)
6571 msg_destroy(msg), msg = NULL;
6572 }
6573 }
6574
6575 return msg;
6576 }
6577
6578
6579 /**Reply to an incoming transaction request.
6580 *
6581 * This function creates a response message to an incoming request and sends
6582 * it to the client.
6583 *
6584 * @note
6585 * It is possible to send several non-final (1xx) responses, but only one
6586 * final response.
6587 *
6588 * @param irq incoming request
6589 * @param status status code
6590 * @param phrase status phrase (may be NULL if status code is well-known)
6591 * @param tag,value,... optional additional headers terminated by TAG_END()
6592 *
6593 * @retval 0 when succesful
6594 * @retval -1 upon an error
6595 */
nta_incoming_treply(nta_incoming_t * irq,int status,char const * phrase,tag_type_t tag,tag_value_t value,...)6596 int nta_incoming_treply(nta_incoming_t *irq,
6597 int status,
6598 char const *phrase,
6599 tag_type_t tag, tag_value_t value, ...)
6600 {
6601 int retval = -1;
6602
6603 if (irq &&
6604 (irq->irq_status < 200 || status < 200 ||
6605 (irq->irq_method == sip_method_invite && status < 300))) {
6606 ta_list ta;
6607 msg_t *msg = nta_msg_create(irq->irq_agent, 0);
6608
6609 ta_start(ta, tag, value);
6610
6611 if (!msg)
6612 ;
6613 else if (nta_incoming_complete_response(irq, msg, status, phrase,
6614 ta_tags(ta)) < 0)
6615 msg_destroy(msg);
6616 else if (incoming_set_params(irq, ta_args(ta)) < 0)
6617 msg_destroy(msg);
6618 else
6619 retval = nta_incoming_mreply(irq, msg);
6620
6621 ta_end(ta);
6622
6623 if (retval < 0 && status >= 200)
6624 incoming_final_failed(irq, NULL);
6625 }
6626
6627 return retval;
6628 }
6629
6630 /**
6631 * Return a response message to client.
6632 *
6633 * @note
6634 * The ownership of @a msg is taken over by the function even if the
6635 * function fails.
6636 *
6637 * @retval 0 when succesful
6638 * @retval -1 upon an error
6639 */
nta_incoming_mreply(nta_incoming_t * irq,msg_t * msg)6640 int nta_incoming_mreply(nta_incoming_t *irq, msg_t *msg)
6641 {
6642 sip_t *sip = sip_object(msg);
6643
6644 int status;
6645
6646 if (irq == NULL) {
6647 msg_destroy(msg);
6648 return -1;
6649 }
6650
6651 if (msg == NULL || sip == NULL)
6652 return -1;
6653
6654 if (msg == irq->irq_response)
6655 return 0;
6656
6657 if (!sip->sip_status || !sip->sip_via || !sip->sip_cseq)
6658 return incoming_final_failed(irq, msg);
6659
6660 assert (sip->sip_cseq->cs_method == irq->irq_method || irq->irq_default);
6661
6662 status = sip->sip_status->st_status;
6663
6664 if (!irq->irq_tag && status > 100 && !irq->irq_default)
6665 nta_incoming_tag(irq, NULL);
6666
6667 if (/* (irq->irq_confirmed && status >= 200) || */
6668 (irq->irq_completed && status >= 300)) {
6669 SU_DEBUG_3(("%s: already %s transaction\n", __func__,
6670 irq->irq_confirmed ? "confirmed" : "completed"));
6671 msg_destroy(msg);
6672 return -1;
6673 }
6674
6675 #ifdef HAVE_ZLIB_COMPRESS
6676 if (irq->irq_compressed) {
6677 sip_content_encoding_Xflate(msg, sip, 0, 0);
6678 }
6679 #endif
6680
6681 if (irq->irq_must_100rel && !sip->sip_rseq && status > 100 && status < 200) {
6682 /* This nta_reliable_t object will be destroyed by PRACK or timeout */
6683 if (nta_reliable_mreply(irq, NULL, NULL, msg))
6684 return 0;
6685
6686 return -1;
6687 }
6688
6689 if (status >= 200 && irq->irq_reliable && irq->irq_reliable->rel_unsent) {
6690 if (reliable_final(irq, msg, sip) == 0)
6691 return 0;
6692 }
6693
6694 return incoming_reply(irq, msg, sip);
6695 }
6696
6697
6698
6699 /** Send the response message.
6700 *
6701 * @note The ownership of msg is handled to incoming_reply().
6702 */
incoming_reply(nta_incoming_t * irq,msg_t * msg,sip_t * sip)6703 int incoming_reply(nta_incoming_t *irq, msg_t *msg, sip_t *sip)
6704 {
6705 nta_agent_t *agent = irq->irq_agent;
6706 int status = sip->sip_status->st_status;
6707 int sending = 1;
6708 int *use_rport = NULL;
6709 int retry_without_rport = 0;
6710 tp_name_t *tpn, default_tpn[1];
6711
6712 if (status == 408 &&
6713 irq->irq_method != sip_method_invite &&
6714 !agent->sa_pass_408 &&
6715 !irq->irq_default) {
6716 /* RFC 4320 nit-actions-03 Action 2:
6717
6718 A transaction-stateful SIP element MUST NOT send a response with
6719 Status-Code of 408 to a non-INVITE request. As a consequence, an
6720 element that can not respond before the transaction expires will not
6721 send a final response at all.
6722 */
6723 sending = 0;
6724 }
6725
6726 if (irq->irq_status == 0 && irq->irq_timestamp && !sip->sip_timestamp)
6727 incoming_timestamp(irq, msg, sip);
6728
6729 if (irq->irq_default) {
6730 if (agent->sa_server_rport)
6731 use_rport = &retry_without_rport, retry_without_rport = 1;
6732 tpn = default_tpn;
6733 if (nta_tpn_by_via(tpn, sip->sip_via, use_rport) < 0)
6734 tpn = NULL;
6735 }
6736 else {
6737 tpn = irq->irq_tpn;
6738 }
6739
6740 if (sip_complete_message(msg) < 0)
6741 SU_DEBUG_1(("%s: sip_complete_message() failed\n", __func__));
6742 else if (msg_serialize(msg, (msg_pub_t *)sip) < 0)
6743 SU_DEBUG_1(("%s: sip_serialize() failed\n", __func__));
6744 else if (!(irq->irq_tport) &&
6745 !(tport_decref(&irq->irq_tport),
6746 irq->irq_tport = tpn ? tport_by_name(agent->sa_tports, tpn) : 0))
6747 SU_DEBUG_1(("%s: no tport\n", __func__));
6748 else {
6749 int i, err = 0;
6750 tport_t *tp = NULL;
6751 incoming_queue_t *queue;
6752
6753 char const *method_name;
6754 uint32_t cseq;
6755
6756 if (irq->irq_default) {
6757 assert(sip->sip_cseq);
6758 method_name = sip->sip_cseq->cs_method_name, cseq = sip->sip_cseq->cs_seq;
6759 }
6760 else {
6761 method_name = irq->irq_rq->rq_method_name, cseq = irq->irq_cseq->cs_seq;
6762 }
6763
6764 if (sending) {
6765 for (i = 0; i < 3; i++) {
6766 tp = tport_tsend(irq->irq_tport, msg, tpn,
6767 IF_SIGCOMP_TPTAG_COMPARTMENT(irq->irq_cc)
6768 TPTAG_MTU(INT_MAX),
6769 TAG_END());
6770 if (tp)
6771 break;
6772
6773 err = msg_errno(msg);
6774 SU_DEBUG_5(("%s: tport_tsend: %s%s\n",
6775 __func__, su_strerror(err),
6776 err == EPIPE ? "(retrying)" : ""));
6777
6778 if (err != EPIPE && err != ECONNREFUSED)
6779 break;
6780 tport_decref(&irq->irq_tport);
6781 irq->irq_tport = tport_ref(tport_by_name(agent->sa_tports, tpn));
6782 }
6783
6784 if (!tp) {
6785 SU_DEBUG_3(("%s: tport_tsend: "
6786 "error (%s) while sending %u %s for %s (%u)\n",
6787 __func__, su_strerror(err),
6788 status, sip->sip_status->st_phrase, method_name, cseq));
6789 if (status < 200)
6790 msg_destroy(msg);
6791 else
6792 incoming_final_failed(irq, msg);
6793 return 0;
6794 }
6795
6796 agent->sa_stats->as_sent_msg++;
6797 agent->sa_stats->as_sent_response++;
6798 }
6799
6800 SU_DEBUG_5(("nta: %s %u %s for %s (%u)\n",
6801 sending ? "sent" : "not sending",
6802 status, sip->sip_status->st_phrase, method_name, cseq));
6803
6804 if (irq->irq_default) {
6805 msg_destroy(msg);
6806 return 0;
6807 }
6808
6809 incoming_reset_timer(irq);
6810
6811 if (status < 200) {
6812 queue = agent->sa_in.proceeding;
6813
6814 if (irq->irq_method == sip_method_invite && status > 100 &&
6815 agent->sa_progress != UINT_MAX && agent->sa_is_a_uas) {
6816 /* Retransmit preliminary responses in regular intervals */
6817 incoming_set_timer(irq, agent->sa_progress); /* N2 */
6818 }
6819 }
6820 else {
6821 irq->irq_completed = 1;
6822
6823 /* XXX - we should do this only after message has actually been sent! */
6824 if (irq->irq_sigcomp_zap && irq->irq_cc)
6825 agent_close_compressor(irq->irq_agent, irq->irq_cc);
6826
6827 if (irq->irq_method != sip_method_invite) {
6828 irq->irq_confirmed = 1;
6829
6830 if (irq->irq_reliable_tp) {
6831 irq->irq_terminated = 1;
6832 queue = agent->sa_in.terminated ; /* J - set for 0 seconds */
6833 } else {
6834 queue = agent->sa_in.completed; /* J */
6835 }
6836
6837 tport_decref(&irq->irq_tport);
6838 }
6839 else if (status >= 300 || agent->sa_is_a_uas) {
6840 if (status < 300 || !irq->irq_reliable_tp)
6841 incoming_set_timer(irq, agent->sa_t1); /* G */
6842 queue = agent->sa_in.inv_completed; /* H */
6843 }
6844 else {
6845 #if 1
6846 /* Avoid bug in @RFC3261:
6847 Keep INVITE transaction around in order to catch
6848 retransmitted INVITEs
6849 */
6850 irq->irq_confirmed = 1;
6851 queue = agent->sa_in.inv_confirmed; /* H */
6852 #else
6853 irq->irq_terminated = 1;
6854 queue = agent->sa_in.terminated;
6855 #endif
6856 }
6857 }
6858
6859 if (irq->irq_queue != queue)
6860 incoming_queue(queue, irq);
6861
6862 if (status >= 200 || irq->irq_status < 200) {
6863 if (irq->irq_response)
6864 msg_destroy(irq->irq_response);
6865 assert(msg_home(msg) != irq->irq_home);
6866 irq->irq_response = msg;
6867 }
6868 else {
6869 msg_destroy(msg);
6870 }
6871
6872 if (sip->sip_cseq->cs_method == irq->irq_method &&
6873 irq->irq_status < 200 && status > irq->irq_status)
6874 irq->irq_status = status;
6875
6876 return 0;
6877 }
6878
6879 /*
6880 * XXX - handling error is very problematic.
6881 * Nobody checks return code from nta_incoming_*reply()
6882 */
6883 if (status < 200) {
6884 msg_destroy(msg);
6885 return -1;
6886 }
6887
6888 /* We could not send final response. */
6889 return incoming_final_failed(irq, msg);
6890 }
6891
6892
6893 /** @internal Sending final response has failed.
6894 *
6895 * Put transaction into its own queue, try later to send the response.
6896 */
6897 su_inline
incoming_final_failed(nta_incoming_t * irq,msg_t * msg)6898 int incoming_final_failed(nta_incoming_t *irq, msg_t *msg)
6899 {
6900 msg_destroy(msg);
6901
6902 if (!irq->irq_default) {
6903 irq->irq_final_failed = 1;
6904 incoming_queue(irq->irq_agent->sa_in.final_failed, irq);
6905 }
6906
6907 return -1;
6908 }
6909
6910 /** @internal Retransmit the reply */
6911 static
incoming_retransmit_reply(nta_incoming_t * irq,tport_t * tport)6912 void incoming_retransmit_reply(nta_incoming_t *irq, tport_t *tport)
6913 {
6914 msg_t *msg = NULL;
6915
6916 if (irq->irq_final_failed)
6917 return;
6918
6919 if (tport == NULL)
6920 tport = irq->irq_tport;
6921
6922 /* Answer with existing reply */
6923 if (irq->irq_reliable && !irq->irq_reliable->rel_pracked)
6924 msg = reliable_response(irq);
6925 else
6926 msg = irq->irq_response;
6927
6928 if (msg && tport) {
6929 irq->irq_retries++;
6930
6931 if (irq->irq_retries == 2 && irq->irq_tpn->tpn_comp) {
6932 irq->irq_tpn->tpn_comp = NULL;
6933
6934 if (irq->irq_cc) {
6935 agent_close_compressor(irq->irq_agent, irq->irq_cc);
6936 nta_compartment_decref(&irq->irq_cc);
6937 }
6938 }
6939
6940 tport_tsend(tport, msg, irq->irq_tpn,
6941 IF_SIGCOMP_TPTAG_COMPARTMENT(irq->irq_cc)
6942 TPTAG_MTU(INT_MAX), TAG_END());
6943 irq->irq_agent->sa_stats->as_sent_msg++;
6944 irq->irq_agent->sa_stats->as_sent_response++;
6945 }
6946 }
6947
6948 /** @internal Create timestamp header for response */
6949 static
incoming_timestamp(nta_incoming_t * irq,msg_t * msg,sip_t * sip)6950 int incoming_timestamp(nta_incoming_t *irq, msg_t *msg, sip_t *sip)
6951 {
6952 sip_timestamp_t ts[1];
6953 su_time_t now = su_now();
6954 char delay[32];
6955 double diff = su_time_diff(now, irq->irq_received);
6956
6957 snprintf(delay, sizeof delay, "%.06f", diff);
6958
6959 *ts = *irq->irq_timestamp;
6960 ts->ts_delay = delay;
6961
6962 return sip_add_dup(msg, sip, (sip_header_t *)ts);
6963 }
6964
6965 enum {
6966 timer_max_retransmit = 30,
6967 timer_max_terminate = 100000,
6968 timer_max_timeout = 100
6969 };
6970
6971 /** @internal Timer routine for the incoming request. */
6972 static void
_nta_incoming_timer(nta_agent_t * sa)6973 _nta_incoming_timer(nta_agent_t *sa)
6974 {
6975 uint32_t now;
6976 nta_incoming_t *irq, *irq_next;
6977 size_t retransmitted = 0, timeout = 0, terminated = 0, destroyed = 0;
6978 size_t unconfirmed =
6979 sa->sa_in.inv_completed->q_length +
6980 sa->sa_in.preliminary->q_length;
6981 size_t unterminated =
6982 sa->sa_in.inv_confirmed->q_length +
6983 sa->sa_in.completed->q_length;
6984 size_t total = sa->sa_incoming->iht_used;
6985
6986 incoming_queue_t rq[1];
6987
6988 incoming_queue_init(rq, 0);
6989
6990 /* Handle retry queue */
6991 while ((irq = sa->sa_in.re_list)) {
6992
6993 now = su_time_ms(su_now());
6994
6995 if ((int32_t)(irq->irq_retry - now) > 0)
6996 break;
6997 if (retransmitted >= timer_max_retransmit)
6998 break;
6999
7000 if (irq->irq_method == sip_method_invite && irq->irq_status >= 200) {
7001 /* Timer G */
7002 assert(irq->irq_queue == sa->sa_in.inv_completed);
7003
7004 retransmitted++;
7005
7006 SU_DEBUG_5(("nta: timer %s fired, retransmitting %u reply\n",
7007 "G", irq->irq_status));
7008
7009 incoming_retransmit_reply(irq, irq->irq_tport);
7010
7011 if (2U * irq->irq_interval < sa->sa_t2)
7012 incoming_set_timer(irq, 2U * irq->irq_interval); /* G */
7013 else
7014 incoming_set_timer(irq, sa->sa_t2); /* G */
7015 }
7016 else if (irq->irq_method == sip_method_invite && irq->irq_status >= 100) {
7017 if (irq->irq_queue == sa->sa_in.preliminary) {
7018 /* Timer P1 - PRACK timer */
7019 retransmitted++;
7020 SU_DEBUG_5(("nta: timer %s fired, retransmitting %u reply\n",
7021 "P1", irq->irq_status));
7022
7023 incoming_retransmit_reply(irq, irq->irq_tport);
7024
7025 incoming_set_timer(irq, 2 * irq->irq_interval); /* P1 */
7026 }
7027 else {
7028 /* Retransmitting provisional responses */
7029 SU_DEBUG_5(("nta: timer %s fired, retransmitting %u reply\n",
7030 "N2", irq->irq_status));
7031 incoming_set_timer(irq, sa->sa_progress);
7032 retransmitted++;
7033 incoming_retransmit_reply(irq, irq->irq_tport);
7034 }
7035 }
7036 else {
7037 /* Timer N1 */
7038 incoming_reset_timer(irq);
7039
7040 if(irq->irq_extra_100) {
7041 SU_DEBUG_5(("nta: timer N1 fired, sending %u %s\n", SIP_100_TRYING));
7042 nta_incoming_treply(irq, SIP_100_TRYING, TAG_END());
7043 }
7044 else {
7045 SU_DEBUG_5(("nta: timer N1 fired, but avoided sending %u %s\n",
7046 SIP_100_TRYING));
7047 }
7048 }
7049 }
7050
7051 while ((irq = sa->sa_in.final_failed->q_head)) {
7052
7053
7054 incoming_remove(irq);
7055 irq->irq_final_failed = 0;
7056
7057 /* Report error to application */
7058 SU_DEBUG_5(("nta: sending final response failed, timeout %u response\n",
7059 irq->irq_status));
7060 reliable_timeout(irq, 0);
7061
7062 nta_incoming_treply(irq, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
7063
7064 if (!irq->irq_final_failed) /* We have taken care of the error... */
7065 continue;
7066
7067 if (irq->irq_destroyed) {
7068 incoming_free_queue(rq, irq);
7069 continue;
7070 }
7071
7072 incoming_reset_timer(irq);
7073 irq->irq_confirmed = 1;
7074 irq->irq_terminated = 1;
7075 incoming_queue(sa->sa_in.terminated, irq);
7076 }
7077
7078 /* Timeouts.
7079 * For each state the request is in, there is always a queue of its own
7080 */
7081 while ((irq = sa->sa_in.preliminary->q_head)) {
7082 assert(irq->irq_status < 200);
7083 assert(irq->irq_timeout);
7084
7085 now = su_time_ms(su_now());
7086
7087 if ((int32_t)(irq->irq_timeout - now) > 0)
7088 break;
7089 if (timeout >= timer_max_timeout)
7090 break;
7091
7092 timeout++;
7093
7094 /* Timer P2 - PRACK timer */
7095 SU_DEBUG_5(("nta: timer %s fired, %s %u response\n",
7096 "P2", "timeout", irq->irq_status));
7097 incoming_reset_timer(irq);
7098 irq->irq_timeout = 0;
7099 reliable_timeout(irq, 1);
7100 }
7101
7102 while ((irq = sa->sa_in.inv_completed->q_head)) {
7103 assert(irq->irq_status >= 200);
7104 assert(irq->irq_timeout);
7105 assert(irq->irq_method == sip_method_invite);
7106
7107 now = su_time_ms(su_now());
7108
7109 if ((int32_t)(irq->irq_timeout - now) > 0 ||
7110 timeout >= timer_max_timeout ||
7111 terminated >= timer_max_terminate)
7112 break;
7113
7114 /* Timer H */
7115 SU_DEBUG_5(("nta: timer %s fired, %s %u response\n",
7116 "H", "timeout and terminate", irq->irq_status));
7117 irq->irq_confirmed = 1;
7118 irq->irq_terminated = 1;
7119 incoming_reset_timer(irq);
7120 if (!irq->irq_destroyed) {
7121 timeout++;
7122 incoming_queue(sa->sa_in.terminated, irq);
7123 /* report timeout error to user */
7124 incoming_call_callback(irq, NULL, NULL);
7125 } else {
7126 timeout++;
7127 terminated++;
7128 incoming_free_queue(rq, irq);
7129 }
7130 }
7131
7132 while ((irq = sa->sa_in.inv_confirmed->q_head)) {
7133 assert(irq->irq_timeout);
7134 assert(irq->irq_status >= 200);
7135 assert(irq->irq_method == sip_method_invite);
7136
7137 now = su_time_ms(su_now());
7138
7139 if ((int32_t)(irq->irq_timeout - now) > 0 ||
7140 terminated >= timer_max_terminate)
7141 break;
7142
7143 /* Timer I */
7144 SU_DEBUG_5(("nta: timer %s fired, %s %u response\n",
7145 "I", "terminate", irq->irq_status));
7146
7147 terminated++;
7148 irq->irq_terminated = 1;
7149
7150 if (!irq->irq_destroyed)
7151 incoming_queue(sa->sa_in.terminated, irq);
7152 else
7153 incoming_free_queue(rq, irq);
7154 }
7155
7156 while ((irq = sa->sa_in.completed->q_head)) {
7157 assert(irq->irq_status >= 200);
7158 assert(irq->irq_timeout);
7159 assert(irq->irq_method != sip_method_invite);
7160
7161 now = su_time_ms(su_now());
7162
7163 if ((int32_t)(irq->irq_timeout - now) > 0 ||
7164 terminated >= timer_max_terminate)
7165 break;
7166
7167 /* Timer J */
7168
7169 SU_DEBUG_5(("nta: timer %s fired, %s %u response\n",
7170 "J", "terminate", irq->irq_status));
7171
7172 terminated++;
7173 irq->irq_terminated = 1;
7174
7175 if (!irq->irq_destroyed)
7176 incoming_queue(sa->sa_in.terminated, irq);
7177 else
7178 incoming_free_queue(rq, irq);
7179 }
7180
7181 for (irq = sa->sa_in.terminated->q_head; irq; irq = irq_next) {
7182
7183 irq_next = irq->irq_next;
7184 if (irq->irq_destroyed)
7185 incoming_free_queue(rq, irq);
7186 }
7187
7188 destroyed = incoming_mass_destroy(sa, rq);
7189
7190 if (retransmitted || timeout || terminated || destroyed)
7191 SU_DEBUG_5(("nta_incoming_timer: "
7192 MOD_ZU"/"MOD_ZU" resent, "
7193 MOD_ZU"/"MOD_ZU" tout, "
7194 MOD_ZU"/"MOD_ZU" term, "
7195 MOD_ZU"/"MOD_ZU" free\n",
7196 retransmitted, unconfirmed,
7197 timeout, unconfirmed,
7198 terminated, unterminated,
7199 destroyed, total));
7200 }
7201
7202 /** Mass destroy server transactions */
7203 su_inline
incoming_mass_destroy(nta_agent_t * sa,incoming_queue_t * q)7204 size_t incoming_mass_destroy(nta_agent_t *sa, incoming_queue_t *q)
7205 {
7206 size_t destroyed = q->q_length;
7207
7208 if (destroyed > 2 && *sa->sa_terminator) {
7209 su_msg_r m = SU_MSG_R_INIT;
7210
7211 if (su_msg_create(m,
7212 su_clone_task(sa->sa_terminator),
7213 su_root_task(sa->sa_root),
7214 incoming_reclaim_queued,
7215 sizeof(incoming_queue_t)) == SU_SUCCESS) {
7216 incoming_queue_t *mq = su_msg_data(m)->a_incoming_queue;
7217
7218 *mq = *q;
7219
7220 if (su_msg_send(m) == SU_SUCCESS)
7221 q->q_length = 0;
7222 }
7223 }
7224
7225 if (q->q_length > 0)
7226 incoming_reclaim_queued(NULL, NULL, (void *)q);
7227
7228 return destroyed;
7229 }
7230
7231 /* ====================================================================== */
7232 /* 8) Client-side (outgoing) transactions */
7233
7234 #define HTABLE_HASH_ORQ(orq) ((orq)->orq_hash)
7235
7236 #ifdef __clang__
7237 #pragma clang diagnostic push
7238 #pragma clang diagnostic ignored "-Wunused-function"
7239 #endif
7240
7241 HTABLE_BODIES_WITH(outgoing_htable, oht, nta_outgoing_t, HTABLE_HASH_ORQ,
7242 size_t, hash_value_t);
7243
7244 #ifdef __clang__
7245 #pragma clang diagnostic pop
7246 #endif
7247
7248 static int outgoing_features(nta_agent_t *agent, nta_outgoing_t *orq,
7249 msg_t *msg, sip_t *sip,
7250 tagi_t *tags);
7251 static void outgoing_prepare_send(nta_outgoing_t *orq);
7252 static void outgoing_send_via(nta_outgoing_t *orq, tport_t *tp);
7253 static void outgoing_send(nta_outgoing_t *orq, int retransmit);
7254 static void outgoing_try_tcp_instead(nta_outgoing_t *orq);
7255 static void outgoing_try_udp_instead(nta_outgoing_t *orq, int timeout);
7256 static void outgoing_tport_error(nta_agent_t *agent, nta_outgoing_t *orq,
7257 tport_t *tp, msg_t *msg, int error);
7258 static void outgoing_print_tport_error(nta_outgoing_t *orq,
7259 int level, char *todo,
7260 tp_name_t const *, msg_t *, int error);
7261 static void outgoing_insert(nta_agent_t *sa, nta_outgoing_t *orq);
7262 static void outgoing_destroy(nta_outgoing_t *orq);
7263 su_inline int outgoing_is_queued(nta_outgoing_t const *orq);
7264 su_inline void outgoing_queue(outgoing_queue_t *queue,
7265 nta_outgoing_t *orq);
7266 su_inline void outgoing_remove(nta_outgoing_t *orq);
7267 su_inline void outgoing_set_timer(nta_outgoing_t *orq, uint32_t interval);
7268 static void outgoing_reset_timer(nta_outgoing_t *orq);
7269 static size_t outgoing_timer_dk(outgoing_queue_t *q,
7270 char const *timer,
7271 uint32_t now);
7272 static size_t outgoing_timer_bf(outgoing_queue_t *q,
7273 char const *timer,
7274 uint32_t now);
7275 static size_t outgoing_timer_c(outgoing_queue_t *q,
7276 char const *timer,
7277 uint32_t now);
7278
7279 static void outgoing_ack(nta_outgoing_t *orq, sip_t *sip);
7280 static msg_t *outgoing_ackmsg(nta_outgoing_t *, sip_method_t, char const *,
7281 tag_type_t tag, tag_value_t value, ...);
7282 static void outgoing_retransmit(nta_outgoing_t *orq);
7283 static void outgoing_trying(nta_outgoing_t *orq);
7284 static void outgoing_timeout(nta_outgoing_t *orq, uint32_t now);
7285 static int outgoing_complete(nta_outgoing_t *orq);
7286 static void outgoing_terminate_invite(nta_outgoing_t *);
7287 static void outgoing_remove_fork(nta_outgoing_t *orq);
7288 static int outgoing_terminate(nta_outgoing_t *orq);
7289 static size_t outgoing_mass_destroy(nta_agent_t *sa, outgoing_queue_t *q);
7290 static void outgoing_estimate_delay(nta_outgoing_t *orq, sip_t *sip);
7291 static int outgoing_duplicate(nta_outgoing_t *orq,
7292 msg_t *msg,
7293 sip_t *sip);
7294 static int outgoing_reply(nta_outgoing_t *orq,
7295 int status, char const *phrase,
7296 int delayed);
7297
7298 static int outgoing_default_cb(nta_outgoing_magic_t *magic,
7299 nta_outgoing_t *request,
7300 sip_t const *sip);
7301
7302
7303 /** Create a default outgoing transaction.
7304 *
7305 * The default outgoing transaction is used when agent receives responses
7306 * not belonging to any transaction.
7307 *
7308 * @sa nta_leg_default(), nta_incoming_default().
7309 */
nta_outgoing_default(nta_agent_t * agent,nta_response_f * callback,nta_outgoing_magic_t * magic)7310 nta_outgoing_t *nta_outgoing_default(nta_agent_t *agent,
7311 nta_response_f *callback,
7312 nta_outgoing_magic_t *magic)
7313 {
7314 nta_outgoing_t *orq;
7315
7316 if (agent == NULL)
7317 return NULL;
7318
7319 if (agent->sa_default_outgoing)
7320 return NULL;
7321
7322 orq = su_zalloc(agent->sa_home, sizeof *orq);
7323 if (!orq)
7324 return NULL;
7325
7326 orq->orq_agent = agent;
7327 orq->orq_callback = callback;
7328 orq->orq_magic = magic;
7329 orq->orq_method = sip_method_invalid;
7330 orq->orq_method_name = "*";
7331 orq->orq_default = 1;
7332 orq->orq_stateless = 1;
7333 orq->orq_delay = UINT_MAX;
7334
7335 return agent->sa_default_outgoing = orq;
7336 }
7337
7338 /**Create an outgoing request and client transaction belonging to the leg.
7339 *
7340 * Create a request message and pass the request message to an outgoing
7341 * client transaction object. The request is sent to the @a route_url (if
7342 * non-NULL), default proxy (if defined by NTATAG_DEFAULT_PROXY()), or to
7343 * the address specified by @a request_uri. If no @a request_uri is
7344 * specified, it is taken from route-set target or from the @To header.
7345 *
7346 * When NTA receives response to the request, it invokes the @a callback
7347 * function.
7348 *
7349 * @param leg call leg object
7350 * @param callback callback function (may be @c NULL)
7351 * @param magic application context pointer
7352 * @param route_url optional URL used to route transaction requests
7353 * @param method method type
7354 * @param name method name
7355 * @param request_uri Request-URI
7356 * @param tag, value, ... list of tagged arguments
7357 *
7358 * @return
7359 * A pointer to a newly created outgoing transaction object if successful,
7360 * and NULL otherwise.
7361 *
7362 * @note If NTATAG_STATELESS(1) tag is given and the @a callback is NULL,
7363 * the transaction object is marked as destroyed from the beginning. In that
7364 * case, the function may return @code (nta_outgoing_t *)-1 @endcode if the
7365 * transaction is freed before returning from the function.
7366 *
7367 * @sa
7368 * nta_outgoing_mcreate(), nta_outgoing_tcancel(), nta_outgoing_destroy().
7369 *
7370 * @TAGS
7371 * NTATAG_STATELESS(), NTATAG_DELAY_SENDING(), NTATAG_BRANCH_KEY(),
7372 * NTATAG_ACK_BRANCH(), NTATAG_DEFAULT_PROXY(), NTATAG_PASS_100(),
7373 * NTATAG_USE_TIMESTAMP(), NTATAG_USER_VIA(), TPTAG_IDENT(), NTATAG_TPORT(). All
7374 * SIP tags from <sofia-sip/sip_tag.h> can be used to manipulate the request message.
7375 * SIP tags after SIPTAG_END() are ignored, however.
7376 */
nta_outgoing_tcreate(nta_leg_t * leg,nta_response_f * callback,nta_outgoing_magic_t * magic,url_string_t const * route_url,sip_method_t method,char const * name,url_string_t const * request_uri,tag_type_t tag,tag_value_t value,...)7377 nta_outgoing_t *nta_outgoing_tcreate(nta_leg_t *leg,
7378 nta_response_f *callback,
7379 nta_outgoing_magic_t *magic,
7380 url_string_t const *route_url,
7381 sip_method_t method,
7382 char const *name,
7383 url_string_t const *request_uri,
7384 tag_type_t tag, tag_value_t value, ...)
7385 {
7386 nta_agent_t *agent;
7387 msg_t *msg;
7388 sip_t *sip;
7389 nta_outgoing_t *orq = NULL;
7390 ta_list ta;
7391 tagi_t const *tagi;
7392
7393 if (leg == NULL)
7394 return NULL;
7395
7396 agent = leg->leg_agent;
7397 msg = nta_msg_create(agent, 0);
7398 sip = sip_object(msg);
7399
7400 if (route_url == NULL)
7401 route_url = (url_string_t *)agent->sa_default_proxy;
7402
7403 ta_start(ta, tag, value);
7404
7405 tagi = ta_args(ta);
7406
7407 if (sip_add_tagis(msg, sip, &tagi) < 0) {
7408 if (tagi && tagi->t_tag) {
7409 tag_type_t t = tagi->t_tag;
7410 SU_DEBUG_5(("%s(): bad tag %s::%s\n", __func__,
7411 t->tt_ns ? t->tt_ns : "", t->tt_name ? t->tt_name : ""));
7412 }
7413 }
7414 else if (route_url == NULL && leg->leg_route &&
7415 leg->leg_loose_route &&
7416 !(route_url = (url_string_t *)leg->leg_route->r_url))
7417 ;
7418 else if (nta_msg_request_complete(msg, leg, method, name, request_uri) < 0)
7419 ;
7420 else
7421 orq = outgoing_create(agent, callback, magic, route_url, NULL, msg,
7422 ta_tags(ta));
7423
7424 ta_end(ta);
7425
7426 if (!orq)
7427 msg_destroy(msg);
7428
7429 return orq;
7430 }
7431
7432 /**Create an outgoing client transaction.
7433 *
7434 * Create an outgoing transaction object. The request message is passed to
7435 * the transaction object, which sends the request to the network. The
7436 * request is sent to the @a route_url (if non-NULL), default proxy (if
7437 * defined by NTATAG_DEFAULT_PROXY()), or to the address specified by @a
7438 * request_uri. If no @a request_uri is specified, it is taken from
7439 * route-set target or from the @To header.
7440 *
7441 * When NTA receives response to the request, it invokes the @a callback
7442 * function.
7443 *
7444 * @param agent NTA agent object
7445 * @param callback callback function (may be @c NULL)
7446 * @param magic application context pointer
7447 * @param route_url optional URL used to route transaction requests
7448 * @param msg request message
7449 * @param tag, value, ... tagged parameter list
7450 *
7451 * @return
7452 * Returns a pointer to newly created outgoing transaction object if
7453 * successful, and NULL otherwise.
7454 *
7455 * @note The caller is responsible for destroying the request message @a msg
7456 * upon failure.
7457 *
7458 * @note If NTATAG_STATELESS(1) tag is given and the @a callback is NULL,
7459 * the transaction object is marked as destroyed from the beginning. In that
7460 * case, the function may return @code (nta_outgoing_t *)-1 @endcode if the
7461 * transaction is freed before returning from the function.
7462 *
7463 * @sa
7464 * nta_outgoing_tcreate(), nta_outgoing_tcancel(), nta_outgoing_destroy().
7465 *
7466 * @TAGS
7467 * NTATAG_STATELESS(), NTATAG_DELAY_SENDING(), NTATAG_BRANCH_KEY(),
7468 * NTATAG_ACK_BRANCH(), NTATAG_DEFAULT_PROXY(), NTATAG_PASS_100(),
7469 * NTATAG_USE_TIMESTAMP(), NTATAG_USER_VIA(), TPTAG_IDENT(), NTATAG_TPORT(). All
7470 * SIP tags from <sofia-sip/sip_tag.h> can be used to manipulate the request message.
7471 * SIP tags after SIPTAG_END() are ignored, however.
7472 */
nta_outgoing_mcreate(nta_agent_t * agent,nta_response_f * callback,nta_outgoing_magic_t * magic,url_string_t const * route_url,msg_t * msg,tag_type_t tag,tag_value_t value,...)7473 nta_outgoing_t *nta_outgoing_mcreate(nta_agent_t *agent,
7474 nta_response_f *callback,
7475 nta_outgoing_magic_t *magic,
7476 url_string_t const *route_url,
7477 msg_t *msg,
7478 tag_type_t tag, tag_value_t value, ...)
7479 {
7480 nta_outgoing_t *orq = NULL;
7481 int cleanup = 0;
7482
7483 if (msg == NONE)
7484 msg = nta_msg_create(agent, 0), cleanup = 1;
7485
7486 if (msg && agent) {
7487 ta_list ta;
7488 ta_start(ta, tag, value);
7489 if (sip_add_tl(msg, sip_object(msg), ta_tags(ta)) >= 0)
7490 orq = outgoing_create(agent, callback, magic, route_url, NULL, msg,
7491 ta_tags(ta));
7492 ta_end(ta);
7493 }
7494
7495 if (!orq && cleanup)
7496 msg_destroy(msg);
7497
7498 return orq;
7499 }
7500
7501 /** Cancel the request. */
nta_outgoing_cancel(nta_outgoing_t * orq)7502 int nta_outgoing_cancel(nta_outgoing_t *orq)
7503 {
7504 nta_outgoing_t *cancel =
7505 nta_outgoing_tcancel(orq, NULL, NULL, TAG_NULL());
7506
7507 return (cancel != NULL) - 1;
7508 }
7509
7510 /** Cancel the request.
7511 *
7512 * Initiate a cancel transaction for client transaction @a orq.
7513 *
7514 * @param orq client transaction to cancel
7515 * @param callback callback function (may be @c NULL)
7516 * @param magic application context pointer
7517 * @param tag, value, ... list of extra arguments
7518 *
7519 * @note The function may return @code (nta_outgoing_t *)-1 @endcode (NONE)
7520 * if callback is NULL.
7521 *
7522 * @TAGS
7523 * NTATAG_CANCEL_2534(), NTATAG_CANCEL_408() and all the tags that are
7524 * accepted by nta_outgoing_tcreate().
7525 *
7526 * If NTATAG_CANCEL_408(1) or NTATAG_CANCEL_2543(1) is given, the stack
7527 * generates a 487 response to the request internally. If
7528 * NTATAG_CANCEL_408(1) is given, no CANCEL request is actually sent.
7529 *
7530 * @note
7531 * nta_outgoing_tcancel() refuses to send a CANCEL request for non-INVITE
7532 * requests.
7533 */
nta_outgoing_tcancel(nta_outgoing_t * orq,nta_response_f * callback,nta_outgoing_magic_t * magic,tag_type_t tag,tag_value_t value,...)7534 nta_outgoing_t *nta_outgoing_tcancel(nta_outgoing_t *orq,
7535 nta_response_f *callback,
7536 nta_outgoing_magic_t *magic,
7537 tag_type_t tag, tag_value_t value, ...)
7538 {
7539 msg_t *msg;
7540 int cancel_2543, cancel_408;
7541 ta_list ta;
7542 int delay_sending;
7543
7544 if (orq == NULL || orq == NONE)
7545 return NULL;
7546
7547 if (orq->orq_destroyed) {
7548 SU_DEBUG_3(("%s: trying to cancel destroyed request\n", __func__));
7549 return NULL;
7550 }
7551 if (orq->orq_method != sip_method_invite) {
7552 SU_DEBUG_3(("%s: trying to cancel non-INVITE request\n", __func__));
7553 return NULL;
7554 }
7555
7556 if (orq->orq_forking)
7557 orq = orq->orq_forking;
7558
7559 if (orq->orq_status >= 200
7560 /* && orq->orq_method != sip_method_invite ... !multicast */) {
7561 SU_DEBUG_3(("%s: trying to cancel completed request\n", __func__));
7562 return NULL;
7563 }
7564 if (orq->orq_canceled) {
7565 SU_DEBUG_3(("%s: trying to cancel cancelled request\n", __func__));
7566 return NULL;
7567 }
7568 orq->orq_canceled = 1;
7569
7570 #if HAVE_SOFIA_SRESOLV
7571 if (!orq->orq_resolved) {
7572 outgoing_destroy_resolver(orq);
7573 outgoing_reply(orq, SIP_487_REQUEST_CANCELLED, 1);
7574 return NULL; /* XXX - Does anyone care about reply? */
7575 }
7576 #endif
7577
7578 cancel_408 = 0; /* Don't really CANCEL, this is timeout. */
7579 cancel_2543 = orq->orq_agent->sa_cancel_2543;
7580 /* CANCEL may be sent only after a provisional response has been received. */
7581 delay_sending = orq->orq_status < 100;
7582
7583 ta_start(ta, tag, value);
7584
7585 tl_gets(ta_args(ta),
7586 NTATAG_CANCEL_408_REF(cancel_408),
7587 NTATAG_CANCEL_2543_REF(cancel_2543),
7588 TAG_END());
7589
7590 if (!cancel_408)
7591 msg = outgoing_ackmsg(orq, SIP_METHOD_CANCEL, ta_tags(ta));
7592 else
7593 msg = NULL;
7594
7595 ta_end(ta);
7596
7597 if ((cancel_2543 || cancel_408) && !orq->orq_stateless)
7598 outgoing_reply(orq, SIP_487_REQUEST_CANCELLED, 1);
7599
7600 if (msg) {
7601 nta_outgoing_t *cancel;
7602 if (cancel_2543) /* Follow RFC 2543 semantics for CANCEL */
7603 delay_sending = 0;
7604
7605 cancel = outgoing_create(orq->orq_agent, callback, magic,
7606 NULL, orq->orq_tpn, msg,
7607 NTATAG_BRANCH_KEY(orq->orq_branch),
7608 NTATAG_DELAY_SENDING(delay_sending),
7609 NTATAG_USER_VIA(1),
7610 TAG_END());
7611
7612 if (delay_sending)
7613 orq->orq_cancel = cancel;
7614
7615 if (cancel) {
7616 if (!delay_sending)
7617 outgoing_complete(orq);
7618 return cancel;
7619 }
7620
7621 msg_destroy(msg);
7622 }
7623
7624 return NULL;
7625 }
7626
7627 /**Bind callback and application context to a client transaction.
7628 *
7629 * @param orq outgoing client transaction
7630 * @param callback callback function (may be NULL)
7631 * @param magic application context pointer
7632 * (given as argument to @a callback)
7633 *
7634 * @NEW_1_12_9
7635 */
7636 int
nta_outgoing_bind(nta_outgoing_t * orq,nta_response_f * callback,nta_outgoing_magic_t * magic)7637 nta_outgoing_bind(nta_outgoing_t *orq,
7638 nta_response_f *callback,
7639 nta_outgoing_magic_t *magic)
7640 {
7641 if (orq && !orq->orq_destroyed) {
7642 if (callback == NULL)
7643 callback = outgoing_default_cb;
7644 orq->orq_callback = callback;
7645 orq->orq_magic = magic;
7646 return 0;
7647 }
7648 return -1;
7649 }
7650
7651 /**Get application context bound to a client transaction.
7652 *
7653 * @param orq outgoing client transaction
7654 * @param callback callback function (may be NULL)
7655 *
7656 * Return the application context bound to a client transaction. If the @a
7657 * callback function pointer is given, return application context only if
7658 * the callback matches with the callback bound to the client transaction.
7659 *
7660 * @NEW_1_12_11
7661 */
7662 nta_outgoing_magic_t *
nta_outgoing_magic(nta_outgoing_t const * orq,nta_response_f * callback)7663 nta_outgoing_magic(nta_outgoing_t const *orq,
7664 nta_response_f *callback)
7665 {
7666 if (orq && (callback == NULL || callback == orq->orq_callback))
7667 return orq->orq_magic;
7668 else
7669 return NULL;
7670 }
7671
7672
7673 /**
7674 * Destroy a request object.
7675 *
7676 * @note
7677 * This function does not actually free the object, but marks it as
7678 * disposable. The object is freed after a timeout.
7679 */
nta_outgoing_destroy(nta_outgoing_t * orq)7680 void nta_outgoing_destroy(nta_outgoing_t *orq)
7681 {
7682 if (orq == NULL || orq == NONE)
7683 return;
7684
7685 if (orq->orq_destroyed) {
7686 SU_DEBUG_1(("%s(%p): %s\n", "nta_outgoing_destroy", (void *)orq,
7687 "already destroyed"));
7688 return;
7689 }
7690
7691 outgoing_destroy(orq);
7692 }
7693
7694 /** Return the request URI */
nta_outgoing_request_uri(nta_outgoing_t const * orq)7695 url_t const *nta_outgoing_request_uri(nta_outgoing_t const *orq)
7696 {
7697 return orq != NULL && orq != NONE ? orq->orq_url : NULL;
7698 }
7699
7700 /** Return the URI used to route the request */
nta_outgoing_route_uri(nta_outgoing_t const * orq)7701 url_t const *nta_outgoing_route_uri(nta_outgoing_t const *orq)
7702 {
7703 return orq != NULL && orq != NONE ? orq->orq_route : NULL;
7704 }
7705
7706 /** Return method of the client transaction */
nta_outgoing_method(nta_outgoing_t const * orq)7707 sip_method_t nta_outgoing_method(nta_outgoing_t const *orq)
7708 {
7709 return orq != NULL && orq != NONE ? orq->orq_method : sip_method_invalid;
7710 }
7711
7712 /** Return method name of the client transaction */
nta_outgoing_method_name(nta_outgoing_t const * orq)7713 char const *nta_outgoing_method_name(nta_outgoing_t const *orq)
7714 {
7715 return orq != NULL && orq != NONE ? orq->orq_method_name : NULL;
7716 }
7717
7718 /** Get sequence number of a client transaction.
7719 */
nta_outgoing_cseq(nta_outgoing_t const * orq)7720 uint32_t nta_outgoing_cseq(nta_outgoing_t const *orq)
7721 {
7722 return orq != NULL && orq != NONE && orq->orq_cseq
7723 ? orq->orq_cseq->cs_seq : 0;
7724 }
7725
7726 /**
7727 * Get the status code of a client transaction.
7728 */
nta_outgoing_status(nta_outgoing_t const * orq)7729 int nta_outgoing_status(nta_outgoing_t const *orq)
7730 {
7731 /* Return 500 Internal server error for invalid handles. */
7732 return orq != NULL && orq != NONE ? orq->orq_status : 500;
7733 }
7734
7735 /** Get the RTT delay measured using @Timestamp header. */
nta_outgoing_delay(nta_outgoing_t const * orq)7736 unsigned nta_outgoing_delay(nta_outgoing_t const *orq)
7737 {
7738 return orq != NULL && orq != NONE ? orq->orq_delay : UINT_MAX;
7739 }
7740
7741 /** Get the branch parameter. @NEW_1_12_7. */
nta_outgoing_branch(nta_outgoing_t const * orq)7742 char const *nta_outgoing_branch(nta_outgoing_t const *orq)
7743 {
7744 return orq != NULL && orq != NONE && orq->orq_branch
7745 ? orq->orq_branch + strlen("branch=")
7746 : NULL;
7747 }
7748
7749 /**Get reference to response message.
7750 *
7751 * Retrieve the latest incoming response message to the outgoing
7752 * transaction. Note that the message is not copied, but a new reference to
7753 * it is created instead.
7754 *
7755 * @param orq outgoing transaction handle
7756 *
7757 * @retval
7758 * A pointer to response message is returned, or NULL if no response message
7759 * has been received.
7760 */
nta_outgoing_getresponse(nta_outgoing_t * orq)7761 msg_t *nta_outgoing_getresponse(nta_outgoing_t *orq)
7762 {
7763 if (orq != NULL && orq != NONE)
7764 return msg_ref_create(orq->orq_response);
7765 else
7766 return NULL;
7767 }
7768
7769 /**Get request message.
7770 *
7771 * Retrieves the request message sent to the network. Note that the request
7772 * message is @b not copied, but a new reference to it is created.
7773 *
7774 * @retval
7775 * A pointer to the request message is returned, or NULL if an error
7776 * occurred.
7777 */
nta_outgoing_getrequest(nta_outgoing_t * orq)7778 msg_t *nta_outgoing_getrequest(nta_outgoing_t *orq)
7779 {
7780 if (orq != NULL && orq != NONE)
7781 return msg_ref_create(orq->orq_request);
7782 else
7783 return NULL;
7784 }
7785
7786 /**Create an outgoing request.
7787 *
7788 * Create an outgoing transaction object and send the request to the
7789 * network. The request is sent to the @a route_url (if non-NULL), default
7790 * proxy (if defined by NTATAG_DEFAULT_PROXY()), or to the address specified
7791 * by @a sip->sip_request->rq_url.
7792 *
7793 * When NTA receives response to the request, it invokes the @a callback
7794 * function.
7795 *
7796 * @param agent nta agent object
7797 * @param callback callback function (may be @c NULL)
7798 * @param magic application context pointer
7799 * @param route_url optional URL used to route transaction requests
7800 * @param msg request message
7801 * @param tpn (optional) transport name
7802 * @param msg request message to
7803 * @param tag, value, ... tagged arguments
7804 *
7805 * @return
7806 * Returns a pointer to newly created outgoing transaction object if
7807 * successful, and NULL otherwise.
7808 *
7809 * @note If NTATAG_STATELESS(1) tag is given and the @a callback is NULL,
7810 * the transaction object is marked as destroyed from the beginning. In that
7811 * case, the function may return @code (nta_outgoing_t *)-1 @endcode if the
7812 * transaction is freed before returning from the function.
7813 *
7814 * @TAG NTATAG_TPORT must point to an existing transport object for
7815 * 'agent' (the passed tport is otherwise ignored).
7816 *
7817 * @sa
7818 * nta_outgoing_tcreate(), nta_outgoing_tcancel(), nta_outgoing_destroy().
7819 */
outgoing_create(nta_agent_t * agent,nta_response_f * callback,nta_outgoing_magic_t * magic,url_string_t const * route_url,tp_name_t const * tpn,msg_t * msg,tag_type_t tag,tag_value_t value,...)7820 nta_outgoing_t *outgoing_create(nta_agent_t *agent,
7821 nta_response_f *callback,
7822 nta_outgoing_magic_t *magic,
7823 url_string_t const *route_url,
7824 tp_name_t const *tpn,
7825 msg_t *msg,
7826 tag_type_t tag, tag_value_t value, ...)
7827 {
7828 nta_outgoing_t *orq;
7829 sip_t *sip;
7830 su_home_t *home;
7831 char const *comp = NONE;
7832 char const *branch = NONE;
7833 char const *ack_branch = NONE;
7834 char const *tp_ident;
7835 int delay_sending = 0, sigcomp_zap = 0;
7836 int pass_100 = agent->sa_pass_100, use_timestamp = agent->sa_timestamp;
7837 enum nta_res_order_e res_order = agent->sa_res_order;
7838 struct sigcomp_compartment *cc = NULL;
7839 ta_list ta;
7840 char const *scheme = NULL;
7841 char const *port = NULL;
7842 int invalid, resolved = 0, stateless = 0, user_via = agent->sa_user_via;
7843 int invite_100rel = agent->sa_invite_100rel;
7844 int explicit_transport = 1;
7845
7846 tagi_t const *t;
7847 tport_t *override_tport = NULL;
7848
7849 if (!agent->sa_tport_ip6)
7850 res_order = nta_res_ip4_only;
7851 else if (!agent->sa_tport_ip4)
7852 res_order = nta_res_ip6_only;
7853
7854 if (!callback)
7855 callback = outgoing_default_cb;
7856 if (!route_url)
7857 route_url = (url_string_t *)agent->sa_default_proxy;
7858
7859 sip = sip_object(msg);
7860 home = msg_home(msg);
7861
7862 #ifdef HAVE_ZLIB_COMPRESS
7863 sip_content_encoding_Xflate(msg, sip_object(msg), 0, 1);
7864 #endif
7865
7866 if (!sip->sip_request || sip_complete_message(msg) < 0) {
7867 SU_DEBUG_3(("nta: outgoing_create: incomplete request\n" VA_NONE));
7868 return NULL;
7869 }
7870
7871 if (!route_url && !tpn && sip->sip_route &&
7872 sip->sip_route->r_url->url_params &&
7873 url_param(sip->sip_route->r_url->url_params, "lr", NULL, 0))
7874 route_url = (url_string_t *)sip->sip_route->r_url;
7875
7876 if (!(orq = su_zalloc(agent->sa_home, sizeof(*orq))))
7877 return NULL;
7878
7879 tp_ident = tpn ? tpn->tpn_ident : NULL;
7880
7881 ta_start(ta, tag, value);
7882
7883 /* tl_gets() is a bit too slow here... */
7884 for (t = ta_args(ta); t; t = tl_next(t)) {
7885 tag_type_t tt = t->t_tag;
7886
7887 if (ntatag_stateless == tt)
7888 stateless = t->t_value != 0;
7889 else if (ntatag_delay_sending == tt)
7890 delay_sending = t->t_value != 0;
7891 else if (ntatag_branch_key == tt)
7892 branch = (void *)t->t_value;
7893 else if (ntatag_pass_100 == tt)
7894 pass_100 = t->t_value != 0;
7895 else if (ntatag_use_timestamp == tt)
7896 use_timestamp = t->t_value != 0;
7897 else if (ntatag_user_via == tt)
7898 user_via = t->t_value != 0;
7899 else if (ntatag_ack_branch == tt)
7900 ack_branch = (void *)t->t_value;
7901 else if (ntatag_default_proxy == tt)
7902 route_url = (void *)t->t_value;
7903 else if (tptag_ident == tt)
7904 tp_ident = (void *)t->t_value;
7905 else if (ntatag_comp == tt)
7906 comp = (char const *)t->t_value;
7907 else if (ntatag_sigcomp_close == tt)
7908 sigcomp_zap = t->t_value != 0;
7909 else if (tptag_compartment == tt)
7910 cc = (void *)t->t_value;
7911 else if (ntatag_tport == tt) {
7912 override_tport = (tport_t *)t->t_value;
7913 }
7914 else if (ntatag_rel100 == tt) {
7915 invite_100rel = t->t_value != 0;
7916 }
7917 }
7918
7919 orq->orq_agent = agent;
7920 orq->orq_callback = callback;
7921 orq->orq_magic = magic;
7922 orq->orq_method = sip->sip_request->rq_method;
7923 orq->orq_method_name = sip->sip_request->rq_method_name;
7924 orq->orq_cseq = sip->sip_cseq;
7925 orq->orq_to = sip->sip_to;
7926 orq->orq_from = sip->sip_from;
7927 orq->orq_call_id = sip->sip_call_id;
7928 orq->orq_tags = tl_afilter(home, tport_tags, ta_args(ta));
7929 orq->orq_delayed = delay_sending != 0;
7930 orq->orq_pass_100 = pass_100 != 0;
7931 orq->orq_sigcomp_zap = sigcomp_zap;
7932 orq->orq_sigcomp_new = comp != NONE && comp != NULL;
7933 orq->orq_timestamp = use_timestamp;
7934 orq->orq_delay = UINT_MAX;
7935 orq->orq_stateless = stateless != 0;
7936 orq->orq_user_via = user_via != 0 && sip->sip_via;
7937 orq->orq_100rel = invite_100rel;
7938 orq->orq_uas = !stateless && agent->sa_is_a_uas;
7939
7940 if (cc)
7941 orq->orq_cc = nta_compartment_ref(cc);
7942
7943 /* Add supported features */
7944 outgoing_features(agent, orq, msg, sip, ta_args(ta));
7945
7946 ta_end(ta);
7947
7948 /* select the tport to use for the outgoing message */
7949 if (override_tport) {
7950 /* note: no ref taken to the tport as its only used once here */
7951 if (tport_is_secondary(override_tport)) {
7952 tpn = tport_name(override_tport);
7953 orq->orq_user_tport = 1;
7954 }
7955 }
7956
7957 if (tpn) {
7958 /* CANCEL or ACK to [3456]XX */
7959 invalid = tport_name_dup(home, orq->orq_tpn, tpn);
7960 #if 0 //HAVE_SOFIA_SRESOLV
7961 /* We send ACK or CANCEL only if original request was really sent */
7962 assert(tport_name_is_resolved(orq->orq_tpn));
7963 #endif
7964 resolved = tport_name_is_resolved(orq->orq_tpn);
7965 orq->orq_url = url_hdup(home, sip->sip_request->rq_url);
7966 }
7967 else if (route_url && !orq->orq_user_tport) {
7968 invalid = nta_tpn_by_url(home, orq->orq_tpn, &scheme, &port, route_url);
7969 if (invalid >= 0) {
7970 explicit_transport = invalid > 0;
7971 if (override_tport) { /* Use transport protocol name from transport */
7972 if (strcmp(orq->orq_tpn->tpn_proto, "*") == 0)
7973 orq->orq_tpn->tpn_proto = tport_name(override_tport)->tpn_proto;
7974 }
7975
7976 resolved = tport_name_is_resolved(orq->orq_tpn);
7977 orq->orq_url = url_hdup(home, sip->sip_request->rq_url);
7978 if (route_url != (url_string_t *)agent->sa_default_proxy)
7979 orq->orq_route = url_hdup(home, route_url->us_url);
7980 }
7981 }
7982 else {
7983 invalid = nta_tpn_by_url(home, orq->orq_tpn, &scheme, &port,
7984 (url_string_t *)sip->sip_request->rq_url);
7985 if (invalid >= 0) {
7986 explicit_transport = invalid > 0;
7987 resolved = tport_name_is_resolved(orq->orq_tpn);
7988 sip_fragment_clear(sip->sip_request->rq_common);
7989 }
7990 orq->orq_url = url_hdup(home, sip->sip_request->rq_url);
7991 }
7992
7993 if (!override_tport)
7994 orq->orq_tpn->tpn_ident = tp_ident;
7995 else
7996 orq->orq_tpn->tpn_ident = tport_name(override_tport)->tpn_ident;
7997
7998 if (comp == NULL)
7999 orq->orq_tpn->tpn_comp = comp;
8000
8001 if (orq->orq_user_via && su_strmatch(orq->orq_tpn->tpn_proto, "*")) {
8002 char const *proto = sip_via_transport(sip->sip_via);
8003 if (proto) orq->orq_tpn->tpn_proto = proto;
8004 }
8005
8006 if (branch && branch != NONE) {
8007 if (su_casenmatch(branch, "branch=", 7))
8008 branch = su_strdup(home, branch);
8009 else
8010 branch = su_sprintf(home, "branch=%s", branch);
8011 }
8012 else if (orq->orq_user_via && sip->sip_via->v_branch && orq->orq_method != sip_method_invite )
8013 branch = su_sprintf(home, "branch=%s", sip->sip_via->v_branch);
8014 else if (stateless)
8015 branch = stateless_branch(agent, msg, sip, orq->orq_tpn);
8016 else
8017 branch = stateful_branch(home, agent);
8018
8019 orq->orq_branch = branch;
8020 orq->orq_via_branch = branch;
8021
8022 if (orq->orq_method == sip_method_ack) {
8023 /* Find the original INVITE which we are ACKing */
8024 if (ack_branch != NULL && ack_branch != NONE) {
8025 if (su_casenmatch(ack_branch, "branch=", 7))
8026 orq->orq_branch = su_strdup(home, ack_branch);
8027 else
8028 orq->orq_branch = su_sprintf(home, "branch=%s", ack_branch);
8029 }
8030 else if (orq->orq_uas) {
8031 /*
8032 * ACK redirects further 2XX messages to it.
8033 *
8034 * Use orq_branch from INVITE, but put a different branch in topmost Via.
8035 */
8036 nta_outgoing_t *invite = outgoing_find(agent, msg, sip, NULL);
8037
8038 if (invite) {
8039 sip_t const *inv = sip_object(invite->orq_request);
8040
8041 orq->orq_branch = su_strdup(home, invite->orq_branch);
8042
8043 /* @RFC3261 section 13.2.2.4 -
8044 * The ACK MUST contain the same credentials as the INVITE.
8045 */
8046 if (!sip->sip_proxy_authorization && !sip->sip_authorization) {
8047 if (inv->sip_proxy_authorization)
8048 sip_add_dup(msg, sip, (void *)inv->sip_proxy_authorization);
8049 if (inv->sip_authorization)
8050 sip_add_dup(msg, sip, (void *)inv->sip_authorization);
8051 }
8052 }
8053 else {
8054 SU_DEBUG_1(("outgoing_create: ACK without INVITE\n" VA_NONE));
8055 assert(!"INVITE found for ACK");
8056 }
8057 }
8058 }
8059
8060 #if HAVE_SOFIA_SRESOLV
8061 if (!resolved)
8062 orq->orq_tpn->tpn_port = port;
8063 orq->orq_resolved = resolved;
8064 #else
8065 orq->orq_resolved = resolved = 1;
8066 #endif
8067 orq->orq_sips = su_casematch(scheme, "sips");
8068
8069 if (invalid < 0 || !orq->orq_branch || msg_serialize(msg, (void *)sip) < 0) {
8070 SU_DEBUG_3(("nta outgoing create: %s\n",
8071 invalid < 0 ? "invalid URI" :
8072 !orq->orq_branch ? "no branch" : "invalid message"));
8073 outgoing_free(orq);
8074 return NULL;
8075 }
8076
8077 /* Now we are committed in sending the transaction */
8078 orq->orq_request = msg;
8079 agent->sa_stats->as_client_tr++;
8080 orq->orq_hash = NTA_HASH(sip->sip_call_id, sip->sip_cseq->cs_seq);
8081
8082 if (orq->orq_user_tport)
8083 outgoing_send_via(orq, override_tport);
8084 else if (resolved)
8085 outgoing_prepare_send(orq);
8086 #if HAVE_SOFIA_SRESOLV
8087 else
8088 outgoing_resolve(orq, explicit_transport, res_order);
8089 #endif
8090
8091 if (stateless &&
8092 orq->orq_status >= 200 &&
8093 callback == outgoing_default_cb) {
8094 void *retval;
8095
8096 if (orq->orq_status < 300)
8097 retval = (void *)-1; /* NONE */
8098 else
8099 retval = NULL, orq->orq_request = NULL;
8100
8101 outgoing_free(orq);
8102
8103 return retval;
8104 }
8105
8106 assert(orq->orq_queue);
8107
8108 outgoing_insert(agent, orq);
8109
8110 return orq;
8111 }
8112
8113 /** Prepare sending a request */
8114 static void
outgoing_prepare_send(nta_outgoing_t * orq)8115 outgoing_prepare_send(nta_outgoing_t *orq)
8116 {
8117 nta_agent_t *sa = orq->orq_agent;
8118 tport_t *tp;
8119 tp_name_t *tpn = orq->orq_tpn;
8120
8121 /* Select transport by scheme */
8122 if (orq->orq_sips && strcmp(tpn->tpn_proto, "*") == 0)
8123 tpn->tpn_proto = "tls";
8124
8125 if (!tpn->tpn_port)
8126 tpn->tpn_port = "";
8127
8128 tp = tport_by_name(sa->sa_tports, tpn);
8129
8130 if (tpn->tpn_port[0] == '\0') {
8131 if (orq->orq_sips || tport_has_tls(tp))
8132 tpn->tpn_port = "5061";
8133 else
8134 tpn->tpn_port = "5060";
8135 }
8136
8137 if (tp) {
8138 outgoing_send_via(orq, tp);
8139 }
8140 else if (orq->orq_sips) {
8141 SU_DEBUG_3(("nta outgoing create: no secure transport\n" VA_NONE));
8142 outgoing_reply(orq, SIP_416_UNSUPPORTED_URI, 1);
8143 }
8144 else {
8145 SU_DEBUG_3(("nta outgoing create: no transport protocol\n" VA_NONE));
8146 outgoing_reply(orq, 503, "No transport", 1);
8147 }
8148 }
8149
8150 /** Send request using given transport */
8151 static void
outgoing_send_via(nta_outgoing_t * orq,tport_t * tp)8152 outgoing_send_via(nta_outgoing_t *orq, tport_t *tp)
8153 {
8154 tport_t *old_tp = orq->orq_tport;
8155
8156 orq->orq_tport = tport_ref(tp);
8157
8158 if (orq->orq_pending && tp != old_tp) {
8159 tport_release(old_tp, orq->orq_pending,
8160 orq->orq_request, NULL, orq, 0);
8161 orq->orq_pending = 0;
8162 }
8163
8164 if (old_tp) tport_unref(old_tp);
8165
8166 if (outgoing_insert_via(orq, agent_tport_via(tp)) < 0) {
8167 SU_DEBUG_3(("nta outgoing create: cannot insert Via line\n" VA_NONE));
8168 outgoing_reply(orq, 503, "Cannot insert Via", 1);
8169 return;
8170 }
8171
8172 #if HAVE_SOFIA_SMIME
8173 {
8174 sm_object_t *smime = sa->sa_smime;
8175 sip_t *sip = sip_object(orq->orq_request);
8176
8177 if (sa->sa_smime &&
8178 (sip->sip_request->rq_method == sip_method_invite ||
8179 sip->sip_request->rq_method == sip_method_message)) {
8180 msg_prepare(orq->orq_request);
8181 if (sm_encode_message(smime, msg, sip, SM_ID_NULL) < 0) {
8182 outgoing_tport_error(sa, orq, NULL,
8183 orq->orq_request, su_errno());
8184 return;
8185 }
8186 }
8187 }
8188 #endif
8189
8190 orq->orq_prepared = 1;
8191
8192 if (orq->orq_delayed) {
8193 SU_DEBUG_5(("nta: delayed sending %s (%u)\n",
8194 orq->orq_method_name, orq->orq_cseq->cs_seq));
8195 outgoing_queue(orq->orq_agent->sa_out.delayed, orq);
8196 return;
8197 }
8198
8199 outgoing_send(orq, 0);
8200 }
8201
8202
8203 /** Send a request */
8204 static void
outgoing_send(nta_outgoing_t * orq,int retransmit)8205 outgoing_send(nta_outgoing_t *orq, int retransmit)
8206 {
8207 int err;
8208 tp_name_t const *tpn = orq->orq_tpn;
8209 msg_t *msg = orq->orq_request;
8210 nta_agent_t *agent = orq->orq_agent;
8211 tport_t *tp;
8212 int once = 0;
8213 su_time_t now = su_now();
8214 tag_type_t tag = tag_skip;
8215 tag_value_t value = 0;
8216 struct sigcomp_compartment *cc; cc = NULL;
8217
8218 /* tport can be NULL if we are just switching network */
8219 if (orq->orq_tport == NULL) {
8220 outgoing_tport_error(agent, orq, NULL, orq->orq_request, ENETRESET);
8221 return;
8222 }
8223
8224 if (orq->orq_user_tport && !tport_is_clear_to_send(orq->orq_tport)) {
8225 outgoing_tport_error(agent, orq, NULL, orq->orq_request, EPIPE);
8226 return;
8227 }
8228
8229 if (!retransmit)
8230 orq->orq_sent = now;
8231
8232 if (orq->orq_timestamp) {
8233 sip_t *sip = sip_object(msg);
8234 sip_timestamp_t *ts =
8235 sip_timestamp_format(msg_home(msg), "%lu.%06lu",
8236 now.tv_sec, now.tv_usec);
8237
8238 if (ts) {
8239 if (sip->sip_timestamp)
8240 msg_header_remove(msg, (msg_pub_t *)sip, (msg_header_t *)sip->sip_timestamp);
8241 msg_header_insert(msg, (msg_pub_t *)sip, (msg_header_t *)ts);
8242 }
8243 }
8244
8245 for (;;) {
8246 if (tpn->tpn_comp == NULL) {
8247 /* xyzzy */
8248 }
8249 else if (orq->orq_cc) {
8250 cc = orq->orq_cc, orq->orq_cc = NULL;
8251 }
8252 else {
8253 cc = agent_compression_compartment(agent, orq->orq_tport, tpn,
8254 orq->orq_sigcomp_new);
8255 }
8256
8257 if (orq->orq_try_udp_instead)
8258 tag = tptag_mtu, value = 65535;
8259
8260 if (orq->orq_pending) {
8261 tport_release(orq->orq_tport, orq->orq_pending,
8262 orq->orq_request, NULL, orq, 0);
8263 orq->orq_pending = 0;
8264 }
8265
8266 tp = tport_tsend(orq->orq_tport, msg, tpn,
8267 tag, value,
8268 IF_SIGCOMP_TPTAG_COMPARTMENT(cc)
8269 TAG_NEXT(orq->orq_tags));
8270 if (tp)
8271 break;
8272
8273 err = msg_errno(orq->orq_request);
8274
8275 if (cc)
8276 nta_compartment_decref(&cc);
8277
8278 if (orq->orq_user_tport)
8279 /* No retries */;
8280 /* RFC3261, 18.1.1 */
8281 else if (err == EMSGSIZE && !orq->orq_try_tcp_instead) {
8282 if (su_casematch(tpn->tpn_proto, "udp") ||
8283 su_casematch(tpn->tpn_proto, "*")) {
8284 outgoing_try_tcp_instead(orq);
8285 continue;
8286 }
8287 }
8288 else if (err == ECONNREFUSED && orq->orq_try_tcp_instead) {
8289 if (su_casematch(tpn->tpn_proto, "tcp") && msg_size(msg) <= 65535) {
8290 outgoing_try_udp_instead(orq, 0);
8291 continue;
8292 }
8293 }
8294 else if (err == EPIPE) {
8295 /* Connection was closed */
8296 if (!once++) {
8297 orq->orq_retries++;
8298 continue;
8299 }
8300 }
8301
8302 outgoing_tport_error(agent, orq, NULL, orq->orq_request, err);
8303
8304 return;
8305 }
8306
8307 agent->sa_stats->as_sent_msg++;
8308 agent->sa_stats->as_sent_request++;
8309 if (retransmit)
8310 agent->sa_stats->as_retry_request++;
8311
8312 SU_DEBUG_5(("nta: %ssent %s (%u) to " TPN_FORMAT "\n",
8313 retransmit ? "re" : "",
8314 orq->orq_method_name, orq->orq_cseq->cs_seq,
8315 TPN_ARGS(tpn)));
8316
8317 if (cc) {
8318 if (orq->orq_cc)
8319 nta_compartment_decref(&orq->orq_cc);
8320 }
8321
8322 if (orq->orq_pending) {
8323 assert(orq->orq_tport);
8324 tport_release(orq->orq_tport, orq->orq_pending,
8325 orq->orq_request, NULL, orq, 0);
8326 orq->orq_pending = 0;
8327 }
8328
8329 if (orq->orq_stateless) {
8330 outgoing_reply(orq, 202, NULL, 202);
8331 return;
8332 }
8333
8334 if (orq->orq_method != sip_method_ack) {
8335 orq->orq_pending = tport_pend(tp, orq->orq_request,
8336 outgoing_tport_error, orq);
8337 if (orq->orq_pending < 0)
8338 orq->orq_pending = 0;
8339 }
8340
8341 if (tp != orq->orq_tport) {
8342 tport_decref(&orq->orq_tport);
8343 orq->orq_tport = tport_ref(tp);
8344 }
8345
8346 orq->orq_reliable = tport_is_reliable(tp);
8347
8348 if (retransmit)
8349 return;
8350
8351 outgoing_trying(orq); /* Timer B / F */
8352
8353 if (orq->orq_method == sip_method_ack)
8354 ;
8355 else if (!orq->orq_reliable) {
8356 /* race condition on initial t1 timer timeout, set minimum initial timeout to 1000ms */
8357 unsigned t1_timer = agent->sa_t1;
8358 if (t1_timer < 1000) t1_timer = 1000;
8359 outgoing_set_timer(orq, t1_timer); /* Timer A/E */
8360 } else if (orq->orq_try_tcp_instead && !tport_is_connected(tp))
8361 outgoing_set_timer(orq, agent->sa_t4); /* Timer N3 */
8362 }
8363
8364 static void
outgoing_try_tcp_instead(nta_outgoing_t * orq)8365 outgoing_try_tcp_instead(nta_outgoing_t *orq)
8366 {
8367 tport_t *tp;
8368 tp_name_t tpn[1];
8369
8370 assert(orq->orq_pending == 0);
8371
8372 *tpn = *orq->orq_tpn;
8373 tpn->tpn_proto = "tcp";
8374 orq->orq_try_tcp_instead = 1;
8375
8376 tp = tport_by_name(orq->orq_agent->sa_tports, tpn);
8377 if (tp && tp != orq->orq_tport) {
8378 sip_t *sip = sip_object(orq->orq_request);
8379 sip_fragment_clear(sip->sip_via->v_common);
8380 sip->sip_via->v_protocol = sip_transport_tcp;
8381
8382 SU_DEBUG_5(("nta: %s (%u) too large for UDP, trying TCP\n",
8383 orq->orq_method_name, orq->orq_cseq->cs_seq));
8384
8385 orq->orq_tpn->tpn_proto = "tcp";
8386 tport_decref(&orq->orq_tport);
8387 orq->orq_tport = tport_ref(tp);
8388
8389 return;
8390 }
8391
8392 /* No TCP - try again with UDP without SIP MTU limit */
8393 tpn->tpn_proto = "udp";
8394 orq->orq_try_udp_instead = 1;
8395
8396 tp = tport_by_name(orq->orq_agent->sa_tports, tpn);
8397 if (tp && tp != orq->orq_tport) {
8398 SU_DEBUG_5(("nta: %s (%u) exceed normal UDP size limit\n",
8399 orq->orq_method_name, orq->orq_cseq->cs_seq));
8400
8401 tport_decref(&orq->orq_tport);
8402 orq->orq_tport = tport_ref(tp);
8403 }
8404 }
8405
8406 static void
outgoing_try_udp_instead(nta_outgoing_t * orq,int timeout)8407 outgoing_try_udp_instead(nta_outgoing_t *orq, int timeout)
8408 {
8409 tport_t *tp;
8410 tp_name_t tpn[1];
8411
8412 if (orq->orq_pending) {
8413 tport_release(orq->orq_tport, orq->orq_pending,
8414 orq->orq_request, NULL, orq, 0);
8415 orq->orq_pending = 0;
8416 }
8417
8418 *tpn = *orq->orq_tpn;
8419 tpn->tpn_proto = "udp";
8420 orq->orq_try_udp_instead = 1;
8421
8422 tp = tport_by_name(orq->orq_agent->sa_tports, tpn);
8423 if (tp && tp != orq->orq_tport) {
8424 sip_t *sip = sip_object(orq->orq_request);
8425
8426 sip_fragment_clear(sip->sip_via->v_common);
8427 sip->sip_via->v_protocol = sip_transport_udp;
8428
8429 SU_DEBUG_5(("nta: %s (%u) TCP %s, trying UDP\n",
8430 orq->orq_method_name, orq->orq_cseq->cs_seq,
8431 timeout ? "times out" : "refused"));
8432
8433 orq->orq_tpn->tpn_proto = "udp";
8434 tport_decref(&orq->orq_tport);
8435 orq->orq_tport = tport_ref(tp);
8436 }
8437 }
8438
8439
8440 /** @internal Report transport errors. */
8441 void
outgoing_tport_error(nta_agent_t * agent,nta_outgoing_t * orq,tport_t * tp,msg_t * msg,int error)8442 outgoing_tport_error(nta_agent_t *agent, nta_outgoing_t *orq,
8443 tport_t *tp, msg_t *msg, int error)
8444 {
8445 tp_name_t const *tpn = tp ? tport_name(tp) : orq->orq_tpn;
8446
8447 if (orq->orq_pending) {
8448 assert(orq->orq_tport);
8449 tport_release(orq->orq_tport, orq->orq_pending, orq->orq_request,
8450 NULL, orq, 0);
8451 orq->orq_pending = 0;
8452 }
8453
8454 if (error == EPIPE && orq->orq_retries++ == 0) {
8455 /* XXX - we should retry only if the transport is not newly created */
8456 outgoing_print_tport_error(orq, 5, "retrying once after ",
8457 tpn, msg, error);
8458 outgoing_send(orq, 1);
8459 return;
8460 }
8461 else if (error == ECONNREFUSED && orq->orq_try_tcp_instead) {
8462 /* RFC3261, 18.1.1 */
8463 if (su_casematch(tpn->tpn_proto, "tcp") && msg_size(msg) <= 65535) {
8464 outgoing_print_tport_error(orq, 5, "retrying with UDP after ",
8465 tpn, msg, error);
8466 outgoing_try_udp_instead(orq, 0);
8467 outgoing_remove(orq); /* Reset state - this is no resend! */
8468 outgoing_send(orq, 0); /* Send */
8469 return;
8470 }
8471 }
8472 else if (error == 0) {
8473 /*
8474 * Server closed connection. RFC3261:
8475 * "there is no coupling between TCP connection state and SIP
8476 * processing."
8477 */
8478 return;
8479 }
8480
8481 if (outgoing_other_destinations(orq)) {
8482 outgoing_print_tport_error(orq, 5, "trying alternative server after ",
8483 tpn, msg, error);
8484 outgoing_try_another(orq);
8485 return;
8486 }
8487
8488 outgoing_print_tport_error(orq, 3, "", tpn, msg, error);
8489
8490 outgoing_reply(orq, SIP_503_SERVICE_UNAVAILABLE, 0);
8491 }
8492
8493 static
8494 void
outgoing_print_tport_error(nta_outgoing_t * orq,int level,char * todo,tp_name_t const * tpn,msg_t * msg,int error)8495 outgoing_print_tport_error(nta_outgoing_t *orq, int level, char *todo,
8496 tp_name_t const *tpn, msg_t *msg, int error)
8497 {
8498 su_sockaddr_t const *su = msg_addr(msg);
8499 char addr[SU_ADDRSIZE];
8500
8501 su_llog(nta_log, level,
8502 "nta: %s (%u): %s%s (%u) with %s/[%s]:%u\n",
8503 orq->orq_method_name, orq->orq_cseq->cs_seq,
8504 todo, su_strerror(error), error,
8505 tpn->tpn_proto,
8506 su_inet_ntop(su->su_family, SU_ADDR(su), addr, sizeof(addr)),
8507 htons(su->su_port));
8508 }
8509
8510 /**@internal
8511 * Add features supported.
8512 */
8513 static
outgoing_features(nta_agent_t * agent,nta_outgoing_t * orq,msg_t * msg,sip_t * sip,tagi_t * tags)8514 int outgoing_features(nta_agent_t *agent, nta_outgoing_t *orq,
8515 msg_t *msg, sip_t *sip,
8516 tagi_t *tags)
8517 {
8518 char const *supported[8];
8519 int i;
8520
8521 if (orq->orq_method != sip_method_invite) /* fast path for now */
8522 return 0;
8523
8524 supported[i = 0] = NULL;
8525
8526 if (orq->orq_method == sip_method_invite) {
8527 int require_100rel = sip_has_feature(sip->sip_require, "100rel");
8528
8529 if (require_100rel) {
8530 orq->orq_must_100rel = 1;
8531 orq->orq_100rel = 1;
8532 }
8533 else if (sip_has_feature(sip->sip_supported, "100rel")) {
8534 orq->orq_100rel = 1;
8535 }
8536 else if (orq->orq_100rel) {
8537 supported[i++] = "100rel";
8538 }
8539 }
8540
8541 if (i) {
8542 supported[i] = NULL;
8543
8544 if (sip->sip_supported) {
8545 su_home_t *home = msg_home(msg);
8546 return msg_list_append_items(home, sip->sip_supported, supported);
8547 }
8548 else {
8549 sip_supported_t s[1];
8550 sip_supported_init(s);
8551 s->k_items = supported;
8552 return sip_add_dup(msg, sip, (sip_header_t *)s);
8553 }
8554 }
8555
8556 return 0;
8557 }
8558
8559
8560 /**@internal
8561 * Insert outgoing request to agent hash table
8562 */
8563 static
outgoing_insert(nta_agent_t * agent,nta_outgoing_t * orq)8564 void outgoing_insert(nta_agent_t *agent, nta_outgoing_t *orq)
8565 {
8566 if (outgoing_htable_is_full(agent->sa_outgoing))
8567 outgoing_htable_resize(agent->sa_home, agent->sa_outgoing, 0);
8568 outgoing_htable_insert(agent->sa_outgoing, orq);
8569 orq->orq_inserted = 1;
8570 }
8571
8572 /** @internal
8573 * Initialize a queue for outgoing transactions.
8574 */
8575 static void
outgoing_queue_init(outgoing_queue_t * queue,unsigned timeout)8576 outgoing_queue_init(outgoing_queue_t *queue, unsigned timeout)
8577 {
8578 memset(queue, 0, sizeof *queue);
8579 queue->q_tail = &queue->q_head;
8580 queue->q_timeout = timeout;
8581 }
8582
8583 /** Change the timeout value of a queue */
8584 static void
outgoing_queue_adjust(nta_agent_t * sa,outgoing_queue_t * queue,unsigned timeout)8585 outgoing_queue_adjust(nta_agent_t *sa,
8586 outgoing_queue_t *queue,
8587 unsigned timeout)
8588 {
8589 nta_outgoing_t *orq;
8590 uint32_t latest;
8591
8592 if (timeout >= queue->q_timeout || !queue->q_head) {
8593 queue->q_timeout = timeout;
8594 return;
8595 }
8596
8597 latest = set_timeout(sa, queue->q_timeout = timeout);
8598
8599 for (orq = queue->q_head; orq; orq = orq->orq_next) {
8600 if (orq->orq_timeout == 0 ||
8601 (int32_t)(orq->orq_timeout - latest) > 0)
8602 orq->orq_timeout = latest;
8603 }
8604 }
8605
8606 /** @internal
8607 * Test if an outgoing transaction is in a queue.
8608 */
8609 su_inline int
outgoing_is_queued(nta_outgoing_t const * orq)8610 outgoing_is_queued(nta_outgoing_t const *orq)
8611 {
8612 return orq && orq->orq_queue;
8613 }
8614
8615 /** @internal
8616 * Insert an outgoing transaction into a queue.
8617 *
8618 * Insert a client transaction into a queue and set the corresponding
8619 * timeout at the same time.
8620 */
8621 static void
outgoing_queue(outgoing_queue_t * queue,nta_outgoing_t * orq)8622 outgoing_queue(outgoing_queue_t *queue,
8623 nta_outgoing_t *orq)
8624 {
8625 if (orq->orq_queue == queue) {
8626 //assert(queue->q_timeout == 0);
8627 return;
8628 }
8629
8630 assert(!orq->orq_forked);
8631
8632 if (outgoing_is_queued(orq))
8633 outgoing_remove(orq);
8634
8635 orq->orq_timeout = set_timeout(orq->orq_agent, queue->q_timeout);
8636
8637 orq->orq_queue = queue;
8638 orq->orq_prev = queue->q_tail;
8639 *queue->q_tail = orq;
8640 queue->q_tail = &orq->orq_next;
8641 queue->q_length++;
8642 }
8643
8644 /** @internal
8645 * Remove an outgoing transaction from a queue.
8646 */
8647 su_inline
outgoing_remove(nta_outgoing_t * orq)8648 void outgoing_remove(nta_outgoing_t *orq)
8649 {
8650 assert(outgoing_is_queued(orq));
8651 assert(orq->orq_queue->q_length > 0);
8652
8653 if ((*orq->orq_prev = orq->orq_next))
8654 orq->orq_next->orq_prev = orq->orq_prev;
8655 else
8656 orq->orq_queue->q_tail = orq->orq_prev;
8657
8658 orq->orq_queue->q_length--;
8659 orq->orq_next = NULL;
8660 orq->orq_prev = NULL;
8661 orq->orq_queue = NULL;
8662 orq->orq_timeout = 0;
8663 }
8664
8665 /** Set retransmit timer (orq_retry).
8666 *
8667 * Set the retry timer (B/D) on the outgoing request (client transaction).
8668 */
8669 su_inline
outgoing_set_timer(nta_outgoing_t * orq,uint32_t interval)8670 void outgoing_set_timer(nta_outgoing_t *orq, uint32_t interval)
8671 {
8672 nta_outgoing_t **rq;
8673
8674 assert(orq);
8675
8676 if (interval == 0) {
8677 outgoing_reset_timer(orq);
8678 return;
8679 }
8680
8681 if (orq->orq_rprev) {
8682 /* Remove transaction from retry dequeue, re-insert it later. */
8683 if ((*orq->orq_rprev = orq->orq_rnext))
8684 orq->orq_rnext->orq_rprev = orq->orq_rprev;
8685 if (orq->orq_agent->sa_out.re_t1 == &orq->orq_rnext)
8686 orq->orq_agent->sa_out.re_t1 = orq->orq_rprev;
8687 }
8688 else {
8689 orq->orq_agent->sa_out.re_length++;
8690 }
8691
8692 orq->orq_retry = set_timeout(orq->orq_agent, orq->orq_interval = interval);
8693
8694 /* Shortcut into queue at SIP T1 */
8695 rq = orq->orq_agent->sa_out.re_t1;
8696
8697 if (!(*rq) || (int32_t)((*rq)->orq_retry - orq->orq_retry) > 0)
8698 rq = &orq->orq_agent->sa_out.re_list;
8699
8700 while (*rq && (int32_t)((*rq)->orq_retry - orq->orq_retry) <= 0)
8701 rq = &(*rq)->orq_rnext;
8702
8703 if ((orq->orq_rnext = *rq))
8704 orq->orq_rnext->orq_rprev = &orq->orq_rnext;
8705 *rq = orq;
8706 orq->orq_rprev = rq;
8707
8708 if (interval == orq->orq_agent->sa_t1)
8709 orq->orq_agent->sa_out.re_t1 = rq;
8710 }
8711
8712 static
outgoing_reset_timer(nta_outgoing_t * orq)8713 void outgoing_reset_timer(nta_outgoing_t *orq)
8714 {
8715 if (orq->orq_rprev) {
8716 if ((*orq->orq_rprev = orq->orq_rnext))
8717 orq->orq_rnext->orq_rprev = orq->orq_rprev;
8718 if (orq->orq_agent->sa_out.re_t1 == &orq->orq_rnext)
8719 orq->orq_agent->sa_out.re_t1 = orq->orq_rprev;
8720 orq->orq_agent->sa_out.re_length--;
8721 }
8722
8723 orq->orq_interval = 0, orq->orq_retry = 0;
8724 orq->orq_rnext = NULL, orq->orq_rprev = NULL;
8725 }
8726
8727 /** @internal
8728 * Free resources associated with the request.
8729 */
8730 static
outgoing_free(nta_outgoing_t * orq)8731 void outgoing_free(nta_outgoing_t *orq)
8732 {
8733 SU_DEBUG_9(("nta: outgoing_free(%p)\n", (void *)orq));
8734 assert(orq->orq_forks == NULL && orq->orq_forking == NULL);
8735 outgoing_cut_off(orq);
8736 outgoing_reclaim(orq);
8737 }
8738
8739 /** Remove outgoing request from hash tables */
8740 su_inline void
outgoing_cut_off(nta_outgoing_t * orq)8741 outgoing_cut_off(nta_outgoing_t *orq)
8742 {
8743 nta_agent_t *agent = orq->orq_agent;
8744
8745 if (orq->orq_default)
8746 agent->sa_default_outgoing = NULL;
8747
8748 if (orq->orq_inserted)
8749 outgoing_htable_remove(agent->sa_outgoing, orq), orq->orq_inserted = 0;
8750
8751 if (outgoing_is_queued(orq))
8752 outgoing_remove(orq);
8753
8754 #if 0
8755 if (orq->orq_forked)
8756 outgoing_remove_fork(orq);
8757 #endif
8758
8759 outgoing_reset_timer(orq);
8760
8761 if (orq->orq_pending) {
8762 tport_release(orq->orq_tport, orq->orq_pending,
8763 orq->orq_request, NULL, orq, 0);
8764 }
8765 orq->orq_pending = 0;
8766
8767 if (orq->orq_cc)
8768 nta_compartment_decref(&orq->orq_cc);
8769
8770 if (orq->orq_tport)
8771 tport_decref(&orq->orq_tport);
8772 }
8773
8774 /** Reclaim outgoing request */
8775 su_inline
outgoing_reclaim(nta_outgoing_t * orq)8776 void outgoing_reclaim(nta_outgoing_t *orq)
8777 {
8778 if (orq->orq_status2b)
8779 *orq->orq_status2b = -1;
8780
8781 if (orq->orq_request)
8782 msg_destroy(orq->orq_request), orq->orq_request = NULL;
8783 if (orq->orq_response)
8784 msg_destroy(orq->orq_response), orq->orq_response = NULL;
8785 #if HAVE_SOFIA_SRESOLV
8786 if (orq->orq_resolver)
8787 outgoing_destroy_resolver(orq);
8788 #endif
8789 su_free(orq->orq_agent->sa_home, orq);
8790 }
8791
8792 /** Queue request to be freed */
8793 su_inline
outgoing_free_queue(outgoing_queue_t * q,nta_outgoing_t * orq)8794 void outgoing_free_queue(outgoing_queue_t *q, nta_outgoing_t *orq)
8795 {
8796 outgoing_cut_off(orq);
8797 outgoing_queue(q, orq);
8798 }
8799
8800 /** Reclaim memory used by queue of requests */
8801 static
outgoing_reclaim_queued(su_root_magic_t * rm,su_msg_r msg,union sm_arg_u * u)8802 void outgoing_reclaim_queued(su_root_magic_t *rm,
8803 su_msg_r msg,
8804 union sm_arg_u *u)
8805 {
8806 outgoing_queue_t *q = u->a_outgoing_queue;
8807 nta_outgoing_t *orq, *orq_next;
8808
8809 SU_DEBUG_9(("outgoing_reclaim_all(%p, %p, %p)\n",
8810 (void *)rm, (void *)msg, (void *)u));
8811
8812 for (orq = q->q_head; orq; orq = orq_next) {
8813 orq_next = orq->orq_next;
8814 outgoing_reclaim(orq);
8815 }
8816 }
8817
8818 /** @internal Default callback for request */
outgoing_default_cb(nta_outgoing_magic_t * magic,nta_outgoing_t * orq,sip_t const * sip)8819 int outgoing_default_cb(nta_outgoing_magic_t *magic,
8820 nta_outgoing_t *orq,
8821 sip_t const *sip)
8822 {
8823 if (sip == NULL || sip->sip_status->st_status >= 200)
8824 outgoing_destroy(orq);
8825 return 0;
8826 }
8827
8828 /** @internal Destroy an outgoing transaction */
outgoing_destroy(nta_outgoing_t * orq)8829 void outgoing_destroy(nta_outgoing_t *orq)
8830 {
8831 if (orq->orq_terminated || orq->orq_default) {
8832 if (!orq->orq_forking && !orq->orq_forks) {
8833 outgoing_free(orq);
8834 return;
8835 }
8836 }
8837 /* Application is expected to handle 200 OK statelessly
8838 => kill transaction immediately */
8839 else if (orq->orq_method == sip_method_invite && !orq->orq_completed
8840 /* (unless transaction has been canceled) */
8841 && !orq->orq_canceled
8842 /* or it has been forked */
8843 && !orq->orq_forking && !orq->orq_forks) {
8844 orq->orq_destroyed = 1;
8845 outgoing_terminate(orq);
8846 return;
8847 }
8848
8849 orq->orq_destroyed = 1;
8850 orq->orq_callback = outgoing_default_cb;
8851 orq->orq_magic = NULL;
8852 }
8853
8854 /** @internal Outgoing transaction timer routine.
8855 *
8856 */
8857 static void
_nta_outgoing_timer(nta_agent_t * sa)8858 _nta_outgoing_timer(nta_agent_t *sa)
8859 {
8860 uint32_t now = su_time_ms(su_now());
8861 nta_outgoing_t *orq;
8862 outgoing_queue_t rq[1];
8863 size_t retransmitted = 0, terminated = 0, timeout = 0, destroyed;
8864 size_t total = sa->sa_outgoing->oht_used;
8865 size_t trying = sa->sa_out.re_length;
8866 size_t pending = sa->sa_out.trying->q_length +
8867 sa->sa_out.inv_calling->q_length;
8868 size_t completed = sa->sa_out.completed->q_length +
8869 sa->sa_out.inv_completed->q_length;
8870
8871 outgoing_queue_init(sa->sa_out.free = rq, 0);
8872
8873 while ((orq = sa->sa_out.re_list)) {
8874
8875 now = su_time_ms(su_now());
8876
8877 if ((int32_t)(orq->orq_retry - now) > 0)
8878 break;
8879 if (retransmitted >= timer_max_retransmit)
8880 break;
8881
8882 if (orq->orq_reliable) {
8883 outgoing_reset_timer(orq);
8884
8885 if (!tport_is_connected(orq->orq_tport)) {
8886 /*
8887 * Timer N3: try to use UDP if trying to send via TCP
8888 * but no connection is established within SIP T4
8889 */
8890 SU_DEBUG_5(("nta: timer %s fired, %s %s (%u)\n", "N3",
8891 "try UDP instead for",
8892 orq->orq_method_name, orq->orq_cseq->cs_seq));
8893 outgoing_try_udp_instead(orq, 1);
8894 outgoing_remove(orq); /* Reset state - this is no resend! */
8895 outgoing_send(orq, 0); /* Send */
8896 }
8897 continue;
8898 }
8899
8900 assert(!orq->orq_reliable && orq->orq_interval != 0);
8901
8902 SU_DEBUG_5(("nta: timer %s fired, %s %s (%u)\n",
8903 orq->orq_method == sip_method_invite ? "A" : "E",
8904 "retransmit", orq->orq_method_name, orq->orq_cseq->cs_seq));
8905
8906 outgoing_retransmit(orq);
8907
8908 if (orq->orq_method == sip_method_invite ||
8909 2U * orq->orq_interval < sa->sa_t2)
8910 outgoing_set_timer(orq, 2U * orq->orq_interval);
8911 else
8912 outgoing_set_timer(orq, sa->sa_t2);
8913
8914 if (++retransmitted % 5 == 0)
8915 su_root_yield(sa->sa_root); /* Handle received packets */
8916 }
8917
8918 terminated
8919 = outgoing_timer_dk(sa->sa_out.inv_completed, "D", now)
8920 + outgoing_timer_dk(sa->sa_out.completed, "K", now);
8921
8922 timeout
8923 = outgoing_timer_bf(sa->sa_out.inv_calling, "B", now)
8924 + outgoing_timer_c(sa->sa_out.inv_proceeding, "C", now)
8925 + outgoing_timer_bf(sa->sa_out.trying, "F", now);
8926
8927 destroyed = outgoing_mass_destroy(sa, rq);
8928
8929 sa->sa_out.free = NULL;
8930
8931 if (retransmitted || timeout || terminated || destroyed) {
8932 SU_DEBUG_5(("nta_outgoing_timer: "
8933 MOD_ZU"/"MOD_ZU" resent, "
8934 MOD_ZU"/"MOD_ZU" tout, "
8935 MOD_ZU"/"MOD_ZU" term, "
8936 MOD_ZU"/"MOD_ZU" free\n",
8937 retransmitted, trying,
8938 timeout, pending,
8939 terminated, completed,
8940 destroyed, total));
8941 }
8942 }
8943
8944 /** @internal Retransmit the outgoing request. */
outgoing_retransmit(nta_outgoing_t * orq)8945 void outgoing_retransmit(nta_outgoing_t *orq)
8946 {
8947 if (orq->orq_prepared && !orq->orq_delayed) {
8948 orq->orq_retries++;
8949
8950 if (orq->orq_retries >= 4 && orq->orq_cc) {
8951 orq->orq_tpn->tpn_comp = NULL;
8952 if (orq->orq_retries == 4) {
8953 agent_close_compressor(orq->orq_agent, orq->orq_cc);
8954 nta_compartment_decref(&orq->orq_cc);
8955 }
8956 }
8957
8958 outgoing_send(orq, 1);
8959 }
8960 }
8961
8962 /** Trying a client transaction. */
8963 static
outgoing_trying(nta_outgoing_t * orq)8964 void outgoing_trying(nta_outgoing_t *orq)
8965 {
8966 if (orq->orq_forked)
8967 ;
8968 else if (orq->orq_method == sip_method_invite) {
8969 if (!orq->orq_completed) {
8970 outgoing_queue(orq->orq_agent->sa_out.inv_calling, orq);
8971 } else {
8972 SU_DEBUG_5(("nta(%p): completed request can not be put into inv_calling queue (%u)\n", (void *)orq, orq->orq_cseq->cs_seq));
8973 if (orq->orq_queue != orq->orq_agent->sa_out.inv_completed) {
8974 /* Put back into inv_completed if it's not there by any reason */
8975 outgoing_queue(orq->orq_agent->sa_out.inv_completed, orq); /* Timer D */
8976 }
8977 }
8978 }
8979 else
8980 outgoing_queue(orq->orq_agent->sa_out.trying, orq);
8981 }
8982
8983 /** Handle timers B and F */
8984 static
outgoing_timer_bf(outgoing_queue_t * q,char const * timer,uint32_t now)8985 size_t outgoing_timer_bf(outgoing_queue_t *q,
8986 char const *timer,
8987 uint32_t now)
8988 {
8989 nta_outgoing_t *orq;
8990 size_t timeout = 0;
8991
8992 while ((orq = q->q_head)) {
8993 if ((int32_t)(orq->orq_timeout - now) > 0 ||
8994 timeout >= timer_max_timeout)
8995 break;
8996
8997 timeout++;
8998
8999 SU_DEBUG_5(("nta: timer %s fired, %s %s (%u)\n",
9000 timer,
9001 orq->orq_method != sip_method_ack ? "timeout" : "terminating",
9002 orq->orq_method_name, orq->orq_cseq->cs_seq));
9003
9004 if (orq->orq_method != sip_method_ack)
9005 outgoing_timeout(orq, now);
9006 else
9007 outgoing_terminate(orq);
9008
9009 assert(q->q_head != orq || (int32_t)(orq->orq_timeout - now) > 0);
9010 }
9011
9012 return timeout;
9013 }
9014
9015 /** Handle timer C */
9016 static
outgoing_timer_c(outgoing_queue_t * q,char const * timer,uint32_t now)9017 size_t outgoing_timer_c(outgoing_queue_t *q,
9018 char const *timer,
9019 uint32_t now)
9020 {
9021 nta_outgoing_t *orq;
9022 size_t timeout = 0;
9023
9024 if (q->q_timeout == 0)
9025 return 0;
9026
9027 while ((orq = q->q_head)) {
9028 if ((int32_t)(orq->orq_timeout - now) > 0 || timeout >= timer_max_timeout)
9029 break;
9030
9031 timeout++;
9032
9033 SU_DEBUG_5(("nta: timer %s fired, %s %s (%u)\n",
9034 timer, "CANCEL and timeout",
9035 orq->orq_method_name, orq->orq_cseq->cs_seq));
9036 /*
9037 * If the client transaction has received a provisional response, the
9038 * proxy MUST generate a CANCEL request matching that transaction.
9039 */
9040 nta_outgoing_tcancel(orq, NULL, NULL, TAG_NULL());
9041 }
9042
9043 return timeout;
9044 }
9045
9046 /** @internal Signal transaction timeout to the application. */
outgoing_timeout(nta_outgoing_t * orq,uint32_t now)9047 void outgoing_timeout(nta_outgoing_t *orq, uint32_t now)
9048 {
9049 nta_outgoing_t *cancel = NULL;
9050
9051 if (orq->orq_status || orq->orq_canceled)
9052 ;
9053 else if (outgoing_other_destinations(orq)) {
9054 SU_DEBUG_5(("%s(%p): %s\n", "nta", (void *)orq,
9055 "try next after timeout"));
9056 outgoing_try_another(orq);
9057 return;
9058 }
9059
9060 cancel = orq->orq_cancel, orq->orq_cancel = NULL;
9061 orq->orq_agent->sa_stats->as_tout_request++;
9062
9063 outgoing_reply(orq, SIP_408_REQUEST_TIMEOUT, 0);
9064
9065 if (cancel)
9066 outgoing_timeout(cancel, now);
9067 }
9068
9069 /** Complete a client transaction.
9070 *
9071 * @return True if transaction was free()d.
9072 */
9073 static int
outgoing_complete(nta_outgoing_t * orq)9074 outgoing_complete(nta_outgoing_t *orq)
9075 {
9076 orq->orq_completed = 1;
9077
9078 outgoing_reset_timer(orq); /* Timer A / Timer E */
9079
9080 if (orq->orq_stateless)
9081 return outgoing_terminate(orq);
9082
9083 if (orq->orq_forked) {
9084 outgoing_remove_fork(orq);
9085 return outgoing_terminate(orq);
9086 }
9087
9088 if (orq->orq_reliable) {
9089 if (orq->orq_method != sip_method_invite || !orq->orq_uas)
9090 return outgoing_terminate(orq);
9091 }
9092
9093 if (orq->orq_method == sip_method_invite) {
9094 if (orq->orq_queue != orq->orq_agent->sa_out.inv_completed)
9095 outgoing_queue(orq->orq_agent->sa_out.inv_completed, orq); /* Timer D */
9096 }
9097 else {
9098 outgoing_queue(orq->orq_agent->sa_out.completed, orq); /* Timer K */
9099 }
9100
9101 return 0;
9102 }
9103
9104 /** Handle timers D and K */
9105 static
outgoing_timer_dk(outgoing_queue_t * q,char const * timer,uint32_t now)9106 size_t outgoing_timer_dk(outgoing_queue_t *q,
9107 char const *timer,
9108 uint32_t now)
9109 {
9110 nta_outgoing_t *orq;
9111 size_t terminated = 0;
9112
9113 while ((orq = q->q_head)) {
9114 if ((int32_t)(orq->orq_timeout - now) > 0 ||
9115 terminated >= timer_max_terminate)
9116 break;
9117
9118 terminated++;
9119
9120 SU_DEBUG_5(("nta: timer %s fired, %s %s (%u)\n", timer,
9121 "terminate", orq->orq_method_name, orq->orq_cseq->cs_seq));
9122
9123 if (orq->orq_method == sip_method_invite)
9124 outgoing_terminate_invite(orq);
9125 else
9126 outgoing_terminate(orq);
9127 }
9128
9129 return terminated;
9130 }
9131
9132
9133 /** Terminate an INVITE client transaction. */
9134 static void
outgoing_terminate_invite(nta_outgoing_t * original)9135 outgoing_terminate_invite(nta_outgoing_t *original)
9136 {
9137 nta_outgoing_t *orq = original;
9138
9139 while (original->orq_forks) {
9140 orq = original->orq_forks;
9141 original->orq_forks = orq->orq_forks;
9142
9143 assert(orq->orq_forking == original);
9144
9145 SU_DEBUG_5(("nta: timer %s fired, %s %s (%u);tag=%s\n", "D",
9146 "terminate", orq->orq_method_name, orq->orq_cseq->cs_seq,
9147 orq->orq_tag));
9148
9149 orq->orq_forking = NULL, orq->orq_forks = NULL, orq->orq_forked = 0;
9150
9151 if (outgoing_terminate(orq))
9152 continue;
9153
9154 if (orq->orq_status < 200) {
9155 /* Fork has timed out */
9156 orq->orq_agent->sa_stats->as_tout_request++;
9157 outgoing_reply(orq, SIP_408_REQUEST_TIMEOUT, 0);
9158 }
9159 }
9160
9161 if (outgoing_terminate(orq = original))
9162 return;
9163
9164 if (orq->orq_status < 200) {
9165 /* Original INVITE has timed out */
9166 orq->orq_agent->sa_stats->as_tout_request++;
9167 outgoing_reply(orq, SIP_408_REQUEST_TIMEOUT, 0);
9168 }
9169 }
9170
9171 static void
outgoing_remove_fork(nta_outgoing_t * orq)9172 outgoing_remove_fork(nta_outgoing_t *orq)
9173 {
9174 nta_outgoing_t **slot;
9175
9176 for (slot = &orq->orq_forking->orq_forks;
9177 slot && *slot;
9178 slot = &(*slot)->orq_forks) {
9179 if (orq == *slot) {
9180 *slot = orq->orq_forks;
9181 orq->orq_forks = NULL;
9182 orq->orq_forking = NULL;
9183 orq->orq_forked = 0;
9184 }
9185 }
9186
9187 assert(orq == NULL);
9188 }
9189
9190 /** Terminate a client transaction. */
9191 static
outgoing_terminate(nta_outgoing_t * orq)9192 int outgoing_terminate(nta_outgoing_t *orq)
9193 {
9194 orq->orq_terminated = 1;
9195
9196 if (!orq->orq_destroyed) {
9197 outgoing_queue(orq->orq_agent->sa_out.terminated, orq);
9198 return 0;
9199 }
9200 else if (orq->orq_agent->sa_out.free) {
9201 outgoing_free_queue(orq->orq_agent->sa_out.free, orq);
9202 return 1;
9203 }
9204 else {
9205 outgoing_free(orq);
9206 return 1;
9207 }
9208 }
9209
9210 /** Mass destroy client transactions */
9211 static
outgoing_mass_destroy(nta_agent_t * sa,outgoing_queue_t * q)9212 size_t outgoing_mass_destroy(nta_agent_t *sa, outgoing_queue_t *q)
9213 {
9214 size_t destroyed = q->q_length;
9215
9216 if (destroyed > 2 && *sa->sa_terminator) {
9217 su_msg_r m = SU_MSG_R_INIT;
9218
9219 if (su_msg_create(m,
9220 su_clone_task(sa->sa_terminator),
9221 su_root_task(sa->sa_root),
9222 outgoing_reclaim_queued,
9223 sizeof(outgoing_queue_t)) == SU_SUCCESS) {
9224 outgoing_queue_t *mq = su_msg_data(m)->a_outgoing_queue;
9225
9226 *mq = *q;
9227
9228 if (su_msg_send(m) == SU_SUCCESS)
9229 q->q_length = 0;
9230 }
9231 }
9232
9233 if (q->q_length)
9234 outgoing_reclaim_queued(NULL, NULL, (void*)q);
9235
9236 return destroyed;
9237 }
9238
9239 /** Find an outgoing request corresponging to a message and @Via line.
9240 *
9241 * Return an outgoing request object based on a message and the @Via line
9242 * given as argument. This function is used when doing loop checking: if we
9243 * have sent the request and it has been routed back to us.
9244 *
9245 * @param agent
9246 * @param msg
9247 * @param sip
9248 * @param v
9249 */
nta_outgoing_find(nta_agent_t const * agent,msg_t const * msg,sip_t const * sip,sip_via_t const * v)9250 nta_outgoing_t *nta_outgoing_find(nta_agent_t const *agent,
9251 msg_t const *msg,
9252 sip_t const *sip,
9253 sip_via_t const *v)
9254 {
9255 if (agent == NULL || msg == NULL || sip == NULL || v == NULL) {
9256 su_seterrno(EFAULT);
9257 return NULL;
9258 }
9259
9260 return outgoing_find(agent, msg, sip, v);
9261 }
9262
9263 /**@internal
9264 *
9265 * Find an outgoing request corresponging to a message and @Via line.
9266 *
9267 */
outgoing_find(nta_agent_t const * sa,msg_t const * msg,sip_t const * sip,sip_via_t const * v)9268 nta_outgoing_t *outgoing_find(nta_agent_t const *sa,
9269 msg_t const *msg,
9270 sip_t const *sip,
9271 sip_via_t const *v)
9272 {
9273 nta_outgoing_t **oo, *orq;
9274 outgoing_htable_t const *oht = sa->sa_outgoing;
9275 sip_cseq_t const *cseq = sip->sip_cseq;
9276 sip_call_id_t const *i = sip->sip_call_id;
9277 hash_value_t hash;
9278 sip_method_t method, method2;
9279 unsigned short status = sip->sip_status ? sip->sip_status->st_status : 0;
9280
9281 if (cseq == NULL)
9282 return NULL;
9283
9284 hash = NTA_HASH(i, cseq->cs_seq);
9285
9286 method = cseq->cs_method;
9287
9288 /* Get original invite when ACKing */
9289 if (sip->sip_request && method == sip_method_ack && v == NULL)
9290 method = sip_method_invite, method2 = sip_method_invalid;
9291 else if (sa->sa_is_a_uas && 200 <= status && status < 300 && method == sip_method_invite)
9292 method2 = sip_method_ack;
9293 else
9294 method2 = method;
9295
9296 for (oo = outgoing_htable_hash(oht, hash);
9297 (orq = *oo);
9298 oo = outgoing_htable_next(oht, oo)) {
9299 if (orq->orq_stateless)
9300 continue;
9301 /* Accept terminated transactions when looking for original INVITE */
9302 if (orq->orq_terminated && method2 != sip_method_invalid)
9303 continue;
9304 if (hash != orq->orq_hash)
9305 continue;
9306 if (orq->orq_call_id->i_hash != i->i_hash ||
9307 strcmp(orq->orq_call_id->i_id, i->i_id))
9308 continue;
9309 if (orq->orq_cseq->cs_seq != cseq->cs_seq)
9310 continue;
9311 if (method == sip_method_unknown &&
9312 strcmp(orq->orq_cseq->cs_method_name, cseq->cs_method_name))
9313 continue;
9314 if (orq->orq_method != method && orq->orq_method != method2)
9315 continue;
9316 if (su_strcasecmp(orq->orq_from->a_tag, sip->sip_from->a_tag))
9317 continue;
9318 if (orq->orq_to->a_tag &&
9319 su_strcasecmp(orq->orq_to->a_tag, sip->sip_to->a_tag))
9320 continue;
9321
9322 if (orq->orq_method == sip_method_ack && 300 <= status)
9323 continue;
9324
9325 if (v && !su_casematch(orq->orq_branch + strlen("branch="), v->v_branch))
9326 continue;
9327
9328 break; /* match */
9329 }
9330
9331 return orq;
9332 }
9333
9334 /** Process a response message. */
outgoing_recv(nta_outgoing_t * _orq,int status,msg_t * msg,sip_t * sip)9335 int outgoing_recv(nta_outgoing_t *_orq,
9336 int status,
9337 msg_t *msg,
9338 sip_t *sip)
9339 {
9340 nta_outgoing_t *orq = _orq->orq_forking ? _orq->orq_forking : _orq;
9341 nta_agent_t *sa = orq->orq_agent;
9342 int internal = sip == NULL || (sip->sip_flags & NTA_INTERNAL_MSG) != 0;
9343
9344 assert(!internal || status >= 300);
9345 assert(orq == _orq || orq->orq_method == sip_method_invite);
9346
9347 if (status < 100) status = 100;
9348
9349 if (!internal && orq->orq_delay == UINT_MAX)
9350 outgoing_estimate_delay(orq, sip);
9351
9352 if (orq->orq_cc)
9353 agent_accept_compressed(orq->orq_agent, msg, orq->orq_cc);
9354
9355 if (orq->orq_cancel) {
9356 nta_outgoing_t *cancel;
9357 cancel = orq->orq_cancel; orq->orq_cancel = NULL;
9358 cancel->orq_delayed = 0;
9359
9360 if (status < 200) {
9361 outgoing_send(cancel, 0);
9362 outgoing_complete(orq);
9363 }
9364 else {
9365 outgoing_reply(cancel, SIP_481_NO_TRANSACTION, 0);
9366 }
9367 }
9368
9369 if (orq->orq_pending) {
9370 tport_release(orq->orq_tport, orq->orq_pending, orq->orq_request,
9371 msg, orq, status < 200);
9372 if (status >= 200)
9373 orq->orq_pending = 0;
9374 }
9375
9376 /* The state machines */
9377 if (orq->orq_method == sip_method_invite) {
9378 nta_outgoing_t *original = orq;
9379
9380 orq = _orq;
9381
9382 if (orq->orq_destroyed && 200 <= status && status < 300) {
9383 if (orq->orq_uas && su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) != 0) {
9384 /* Orphan 200 Ok to INVITE. ACK and BYE it */
9385 SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE %p\n", (void *)orq));
9386 return nta_msg_ackbye(sa, msg);
9387 }
9388 return -1; /* Proxy statelessly (RFC3261 section 16.11) */
9389 }
9390
9391 outgoing_reset_timer(original); /* Retransmission */
9392
9393 if (status < 200) {
9394 if (original->orq_status < 200)
9395 original->orq_status = status;
9396 if (orq->orq_status < 200)
9397 orq->orq_status = status;
9398
9399 if (original->orq_queue == sa->sa_out.inv_calling) {
9400 outgoing_queue(sa->sa_out.inv_proceeding, original);
9401 }
9402 else if (original->orq_queue == sa->sa_out.inv_proceeding) {
9403 if (sa->sa_out.inv_proceeding->q_timeout) {
9404 outgoing_remove(original);
9405 outgoing_queue(sa->sa_out.inv_proceeding, original);
9406 }
9407 }
9408
9409 /* Handle 100rel */
9410 if (sip && sip->sip_rseq) {
9411 if (outgoing_recv_reliable(orq, msg, sip) < 0) {
9412 msg_destroy(msg);
9413 return 0;
9414 }
9415 }
9416 }
9417 else {
9418 /* Final response */
9419 if (status >= 300 && !internal)
9420 outgoing_ack(original, sip);
9421
9422 if (!original->orq_completed) {
9423 if (outgoing_complete(original))
9424 return 0;
9425
9426 if (orq->orq_uas && sip && orq == original) {
9427 /*
9428 * We silently discard duplicate final responses to INVITE below
9429 * with outgoing_duplicate()
9430 */
9431 su_home_t *home = msg_home(orq->orq_request);
9432 orq->orq_tag = su_strdup(home, sip->sip_to->a_tag);
9433 }
9434 }
9435 /* Retransmission or response from another fork */
9436 else if (orq->orq_status >= 200) {
9437 /* Once 2xx has been received, non-2xx will not be forwarded */
9438 if (status >= 300)
9439 return outgoing_duplicate(orq, msg, sip);
9440
9441 if (orq->orq_uas) {
9442 if (su_strcasecmp(sip->sip_to->a_tag, orq->orq_tag) == 0)
9443 /* Catch retransmission */
9444 return outgoing_duplicate(orq, msg, sip);
9445
9446 /* Orphan 200 Ok to INVITE. ACK and BYE it */
9447 SU_DEBUG_5(("nta: Orphan 200 Ok send ACK&BYE" VA_NONE));
9448 return nta_msg_ackbye(sa, msg);
9449 }
9450 }
9451
9452 orq->orq_status = status;
9453 }
9454 }
9455 else if (orq->orq_method != sip_method_ack) {
9456 /* Non-INVITE */
9457 if (orq->orq_queue == sa->sa_out.trying ||
9458 orq->orq_queue == sa->sa_out.resolving) {
9459 /* hacked by freeswitch, this is being hit by options 404 status with 404 orq->orq_status and orq_destroyed = 1, orq_completed = 1 */
9460 /* assert(orq->orq_status < 200); */
9461 if (orq->orq_status >= 200) {msg_destroy(msg); return 0;}
9462
9463 if (status < 200) {
9464 /* @RFC3261 17.1.2.1:
9465 * retransmissions continue for unreliable transports,
9466 * but at an interval of T2.
9467 *
9468 * @RFC4321 1.2:
9469 * Note that Timer E is not altered during the transition
9470 * to Proceeding.
9471 */
9472 if (!orq->orq_reliable)
9473 orq->orq_interval = sa->sa_t2;
9474 }
9475 else if (!outgoing_complete(orq)) {
9476 if (orq->orq_sigcomp_zap && orq->orq_tport && orq->orq_cc)
9477 agent_zap_compressor(orq->orq_agent, orq->orq_cc);
9478 }
9479 else /* outgoing_complete */ {
9480 msg_destroy(msg);
9481 return 0;
9482 }
9483 }
9484 else {
9485 /* Already completed or terminated */
9486 assert(orq->orq_queue == sa->sa_out.completed ||
9487 orq->orq_queue == sa->sa_out.terminated);
9488 assert(orq->orq_status >= 200);
9489 return outgoing_duplicate(orq, msg, sip);
9490 }
9491
9492 orq->orq_status = status;
9493 }
9494 else {
9495 /* ACK */
9496 if (sip && (sip->sip_flags & NTA_INTERNAL_MSG) == 0)
9497 /* Received re-transmitted final reply to INVITE, retransmit ACK */
9498 outgoing_retransmit(orq);
9499 msg_destroy(msg);
9500 return 0;
9501 }
9502
9503 if (100 >= status + orq->orq_pass_100) {
9504 msg_destroy(msg);
9505 return 0;
9506 }
9507
9508 if (orq->orq_destroyed) {
9509 msg_destroy(msg);
9510 return 0;
9511 }
9512
9513 if (orq->orq_response)
9514 msg_destroy(orq->orq_response);
9515 orq->orq_response = msg;
9516 /* Call callback */
9517 orq->orq_callback(orq->orq_magic, orq, sip);
9518 return 0;
9519 }
9520
outgoing_default_recv(nta_outgoing_t * orq,int status,msg_t * msg,sip_t * sip)9521 static void outgoing_default_recv(nta_outgoing_t *orq,
9522 int status,
9523 msg_t *msg,
9524 sip_t *sip)
9525 {
9526 assert(sip->sip_cseq);
9527
9528 orq->orq_status = status;
9529 orq->orq_response = msg;
9530 orq->orq_callback(orq->orq_magic, orq, sip);
9531 orq->orq_response = NULL;
9532 orq->orq_status = 0;
9533 msg_destroy(msg);
9534 }
9535
outgoing_estimate_delay(nta_outgoing_t * orq,sip_t * sip)9536 static void outgoing_estimate_delay(nta_outgoing_t *orq, sip_t *sip)
9537 {
9538 su_time_t now = su_now();
9539 double diff = 1000 * su_time_diff(now, orq->orq_sent);
9540
9541 if (orq->orq_timestamp && sip->sip_timestamp) {
9542 double diff2, delay = 0.0;
9543 su_time_t timestamp = { 0, 0 };
9544 char const *bad;
9545
9546 sscanf(sip->sip_timestamp->ts_stamp, "%lu.%lu",
9547 ×tamp.tv_sec, ×tamp.tv_usec);
9548
9549 diff2 = 1000 * su_time_diff(now, timestamp);
9550
9551 if (diff2 < 0)
9552 bad = "negative";
9553 else if (diff2 > diff + 1e-3)
9554 bad = "too large";
9555 else {
9556 if (sip->sip_timestamp->ts_delay)
9557 sscanf(sip->sip_timestamp->ts_delay, "%lg", &delay);
9558
9559 if (1000 * delay <= diff2) {
9560 diff = diff2 - 1000 * delay;
9561 orq->orq_delay = (unsigned)diff;
9562 SU_DEBUG_7(("nta_outgoing: RTT is %g ms, now is %lu.%06lu, "
9563 "Timestamp was %s %s\n",
9564 diff, now.tv_sec, now.tv_usec,
9565 sip->sip_timestamp->ts_stamp,
9566 sip->sip_timestamp->ts_delay ?
9567 sip->sip_timestamp->ts_delay : ""));
9568 return;
9569 }
9570 bad = "delay";
9571 }
9572
9573 SU_DEBUG_3(("nta_outgoing: %s Timestamp %lu.%06lu %g "
9574 "(sent %lu.%06lu, now is %lu.%06lu)\n",
9575 bad,
9576 timestamp.tv_sec, timestamp.tv_usec,
9577 delay,
9578 orq->orq_sent.tv_sec, orq->orq_sent.tv_usec,
9579 now.tv_sec, now.tv_usec));
9580 }
9581
9582 if (diff >= 0 && diff < (double)UINT_MAX) {
9583 orq->orq_delay = (unsigned)diff;
9584 SU_DEBUG_7(("nta_outgoing: RTT is %g ms\n", diff));
9585 }
9586 }
9587
9588 /**@typedef nta_response_f
9589 *
9590 * Callback for replies to outgoing requests.
9591 *
9592 * This is a callback function invoked by NTA when it has received a new
9593 * reply to an outgoing request.
9594 *
9595 * @param magic request context
9596 * @param request request handle
9597 * @param sip received status message
9598 *
9599 * @return
9600 * This callback function should return always 0.
9601 *
9602 */
9603
9604 /** Process duplicate responses */
outgoing_duplicate(nta_outgoing_t * orq,msg_t * msg,sip_t * sip)9605 static int outgoing_duplicate(nta_outgoing_t *orq,
9606 msg_t *msg,
9607 sip_t *sip)
9608 {
9609 sip_via_t *v;
9610
9611 if (sip && (sip->sip_flags & NTA_INTERNAL_MSG) == 0) {
9612 v = sip->sip_via;
9613
9614 SU_DEBUG_5(("nta: %u %s is duplicate response to %d %s\n",
9615 sip->sip_status->st_status, sip->sip_status->st_phrase,
9616 orq->orq_cseq->cs_seq, orq->orq_cseq->cs_method_name));
9617 if (v)
9618 SU_DEBUG_5(("\tVia: %s %s%s%s%s%s%s%s%s%s\n",
9619 v->v_protocol, v->v_host,
9620 SIP_STRLOG(":", v->v_port),
9621 SIP_STRLOG(" ;received=", v->v_received),
9622 SIP_STRLOG(" ;maddr=", v->v_maddr),
9623 SIP_STRLOG(" ;branch=", v->v_branch)));
9624 }
9625
9626 msg_destroy(msg);
9627 return 0;
9628 }
9629
9630 /** @internal ACK to a final response (300..699).
9631 * These messages are ACK'ed via the original URL (and tport)
9632 */
outgoing_ack(nta_outgoing_t * orq,sip_t * sip)9633 void outgoing_ack(nta_outgoing_t *orq, sip_t *sip)
9634 {
9635 msg_t *ackmsg;
9636
9637 assert(orq);
9638
9639 /* Do not ack internally generated messages... */
9640 if (sip == NULL || sip->sip_flags & NTA_INTERNAL_MSG)
9641 return;
9642
9643 assert(sip); assert(sip->sip_status);
9644 assert(sip->sip_status->st_status >= 300);
9645 assert(orq->orq_tport);
9646
9647 ackmsg = outgoing_ackmsg(orq, SIP_METHOD_ACK, SIPTAG_TO(sip->sip_to), TAG_END());
9648 if (!ackmsg)
9649 return;
9650
9651 if (!outgoing_create(orq->orq_agent, NULL, NULL,
9652 NULL, orq->orq_tpn, ackmsg,
9653 NTATAG_BRANCH_KEY(sip->sip_via->v_branch),
9654 NTATAG_USER_VIA(1),
9655 NTATAG_STATELESS(1),
9656 TAG_END()))
9657 msg_destroy(ackmsg);
9658 }
9659
9660 /** Generate messages for hop-by-hop ACK or CANCEL.
9661 */
outgoing_ackmsg(nta_outgoing_t * orq,sip_method_t m,char const * mname,tag_type_t tag,tag_value_t value,...)9662 msg_t *outgoing_ackmsg(nta_outgoing_t *orq, sip_method_t m, char const *mname,
9663 tag_type_t tag, tag_value_t value, ...)
9664 {
9665 msg_t *msg = nta_msg_create(orq->orq_agent, 0);
9666 su_home_t *home = msg_home(msg);
9667 sip_t *sip = sip_object(msg);
9668 sip_t *old = sip_object(orq->orq_request);
9669 sip_via_t via[1];
9670
9671 if (!sip)
9672 return NULL;
9673
9674 if (tag) {
9675 ta_list ta;
9676
9677 ta_start(ta, tag, value);
9678
9679 sip_add_tl(msg, sip, ta_tags(ta));
9680 /* Bug sf.net # 173323:
9681 * Ensure that request-URI, topmost Via, From, To, Call-ID, CSeq,
9682 * Max-Forward, Route, Accept-Contact, Reject-Contact and
9683 * Request-Disposition are copied from original request
9684 */
9685 if (sip->sip_from)
9686 sip_header_remove(msg, sip, (void *)sip->sip_from);
9687 if (sip->sip_to && m != sip_method_ack)
9688 sip_header_remove(msg, sip, (void *)sip->sip_to);
9689 if (sip->sip_call_id)
9690 sip_header_remove(msg, sip, (void *)sip->sip_call_id);
9691 while (sip->sip_route)
9692 sip_header_remove(msg, sip, (void *)sip->sip_route);
9693 while (sip->sip_accept_contact)
9694 sip_header_remove(msg, sip, (void *)sip->sip_accept_contact);
9695 while (sip->sip_reject_contact)
9696 sip_header_remove(msg, sip, (void *)sip->sip_reject_contact);
9697 if (sip->sip_request_disposition)
9698 sip_header_remove(msg, sip, (void *)sip->sip_request_disposition);
9699 while (sip->sip_via)
9700 sip_header_remove(msg, sip, (void *)sip->sip_via);
9701 if (sip->sip_max_forwards)
9702 sip_header_remove(msg, sip, (void *)sip->sip_max_forwards);
9703
9704 ta_end(ta);
9705 }
9706
9707 sip->sip_request =
9708 sip_request_create(home, m, mname, (url_string_t *)orq->orq_url, NULL);
9709
9710 if (sip->sip_to == NULL)
9711 sip_add_dup(msg, sip, (sip_header_t *)old->sip_to);
9712 sip_add_dup(msg, sip, (sip_header_t *)old->sip_from);
9713 sip_add_dup(msg, sip, (sip_header_t *)old->sip_call_id);
9714 sip_add_dup(msg, sip, (sip_header_t *)old->sip_route);
9715 /* @RFC3841. Bug #1326727. */
9716 sip_add_dup(msg, sip, (sip_header_t *)old->sip_accept_contact);
9717 sip_add_dup(msg, sip, (sip_header_t *)old->sip_reject_contact);
9718 sip_add_dup(msg, sip, (sip_header_t *)old->sip_request_disposition);
9719 sip_add_dup(msg, sip, (sip_header_t *)old->sip_max_forwards);
9720
9721 if (old->sip_via) {
9722 /* Add only the topmost Via header */
9723 *via = *old->sip_via; via->v_next = NULL;
9724 sip_add_dup(msg, sip, (sip_header_t *)via);
9725 }
9726
9727 sip->sip_cseq = sip_cseq_create(home, old->sip_cseq->cs_seq, m, mname);
9728
9729 if (sip->sip_request &&
9730 sip->sip_to &&
9731 sip->sip_from &&
9732 sip->sip_call_id &&
9733 (!old->sip_route || sip->sip_route) &&
9734 sip->sip_cseq)
9735 return msg;
9736
9737 msg_destroy(msg);
9738
9739 return NULL;
9740 }
9741
9742 static
9743 void outgoing_delayed_recv(su_root_magic_t *rm,
9744 su_msg_r msg,
9745 union sm_arg_u *u);
9746
9747 /** Respond internally to a transaction. */
outgoing_reply(nta_outgoing_t * orq,int status,char const * phrase,int delayed)9748 int outgoing_reply(nta_outgoing_t *orq, int status, char const *phrase,
9749 int delayed)
9750 {
9751 nta_agent_t *agent = orq->orq_agent;
9752 msg_t *msg = NULL;
9753 sip_t *sip = NULL;
9754
9755 assert(status == 202 || status >= 400);
9756
9757 if (orq->orq_pending)
9758 tport_release(orq->orq_tport, orq->orq_pending,
9759 orq->orq_request, NULL, orq, 0);
9760 orq->orq_pending = 0;
9761
9762 orq->orq_delayed = 0;
9763
9764 if (orq->orq_method == sip_method_ack) {
9765 if (status != delayed)
9766 SU_DEBUG_3(("nta(%p): responding %u %s to ACK!\n",
9767 (void *)orq, status, phrase));
9768 orq->orq_status = status;
9769 if (orq->orq_queue == NULL)
9770 outgoing_trying(orq); /* Timer F */
9771 return 0;
9772 }
9773
9774 if (orq->orq_destroyed) {
9775 if (orq->orq_status < 200)
9776 orq->orq_status = status;
9777 outgoing_complete(orq); /* Timer D / Timer K */
9778 return 0;
9779 }
9780
9781 if (orq->orq_stateless)
9782 ;
9783 else if (orq->orq_queue == NULL ||
9784 orq->orq_queue == orq->orq_agent->sa_out.resolving ||
9785 orq->orq_queue == orq->orq_agent->sa_out.delayed)
9786 outgoing_trying(orq);
9787
9788 /** Insert a dummy Via header */
9789 if (!orq->orq_prepared) {
9790 tport_t *tp = tport_primaries(orq->orq_agent->sa_tports);
9791 outgoing_insert_via(orq, agent_tport_via(tp));
9792 }
9793
9794 /* Create response message, if needed */
9795 if (!orq->orq_stateless &&
9796 !(orq->orq_callback == outgoing_default_cb) &&
9797 !(status == 408 &&
9798 orq->orq_method != sip_method_invite &&
9799 !orq->orq_agent->sa_timeout_408)) {
9800 char const *to_tag;
9801
9802 msg = nta_msg_create(agent, NTA_INTERNAL_MSG);
9803
9804 if (complete_response(msg, status, phrase, orq->orq_request) < 0) {
9805 assert(!"complete message");
9806 return -1;
9807 }
9808
9809 sip = sip_object(msg); assert(sip->sip_flags & NTA_INTERNAL_MSG);
9810 to_tag = nta_agent_newtag(msg_home(msg), "tag=%s", agent);
9811
9812 if (status > 100 &&
9813 sip->sip_to && !sip->sip_to->a_tag &&
9814 sip->sip_cseq->cs_method != sip_method_cancel &&
9815 sip_to_tag(msg_home(msg), sip->sip_to, to_tag) < 0) {
9816 assert(!"adding tag");
9817 return -1;
9818 }
9819
9820 if (status > 400 && agent->sa_blacklist) {
9821 sip_retry_after_t af[1];
9822 sip_retry_after_init(af)->af_delta = agent->sa_blacklist;
9823
9824 sip_add_dup(msg, sip, (sip_header_t *)af);
9825 }
9826 }
9827
9828 if (orq->orq_inserted && !delayed) {
9829 outgoing_recv(orq, status, msg, sip);
9830 return 0;
9831 }
9832 else if (orq->orq_stateless && orq->orq_callback == outgoing_default_cb) {
9833 /* Xyzzy */
9834 orq->orq_status = status;
9835 outgoing_complete(orq);
9836 }
9837 else {
9838 /*
9839 * The thread creating outgoing transaction must return to application
9840 * before transaction callback can be invoked. Therefore processing an
9841 * internally generated response message must be delayed until
9842 * transaction creation is completed.
9843 *
9844 * The internally generated message is transmitted using su_msg_send()
9845 * and it is delivered back to NTA when the application next time
9846 * executes the su_root_t event loop.
9847 */
9848 nta_agent_t *agent = orq->orq_agent;
9849 su_root_t *root = agent->sa_root;
9850 su_msg_r su_msg = SU_MSG_R_INIT;
9851
9852 if (su_msg_create(su_msg,
9853 su_root_task(root),
9854 su_root_task(root),
9855 outgoing_delayed_recv,
9856 sizeof(struct outgoing_recv_s)) == SU_SUCCESS) {
9857 struct outgoing_recv_s *a = su_msg_data(su_msg)->a_outgoing_recv;
9858
9859 a->orq = orq;
9860 a->msg = msg;
9861 a->sip = sip;
9862 a->status = status;
9863
9864 orq->orq_status2b = &a->status;
9865
9866 if (su_msg_send(su_msg) == SU_SUCCESS) {
9867 return 0;
9868 }
9869 }
9870 }
9871
9872 if (msg)
9873 msg_destroy(msg);
9874
9875 return -1;
9876 }
9877
9878 static
outgoing_delayed_recv(su_root_magic_t * rm,su_msg_r msg,union sm_arg_u * u)9879 void outgoing_delayed_recv(su_root_magic_t *rm,
9880 su_msg_r msg,
9881 union sm_arg_u *u)
9882 {
9883 struct outgoing_recv_s *a = u->a_outgoing_recv;
9884
9885 if (a->status > 0) {
9886 a->orq->orq_status2b = 0;
9887 if (outgoing_recv(a->orq, a->status, a->msg, a->sip) >= 0)
9888 return;
9889 }
9890
9891 msg_destroy(a->msg);
9892 }
9893
9894
9895 /* ====================================================================== */
9896 /* 9) Resolving (SIP) URL */
9897
9898 #if HAVE_SOFIA_SRESOLV
9899
9900 struct sipdns_query;
9901
9902 /** DNS resolving for (SIP) URLs */
9903 struct sipdns_resolver
9904 {
9905 tp_name_t sr_tpn[1]; /**< Copy of original transport name */
9906 sres_query_t *sr_query; /**< Current DNS Query */
9907 char const *sr_target; /**< Target for current query */
9908
9909 struct sipdns_query *sr_current; /**< Current query (with results) */
9910 char **sr_results; /**< A/AAAA results to be used */
9911
9912 struct sipdns_query *sr_head; /**< List of intermediate results */
9913 struct sipdns_query **sr_tail; /**< End of intermediate result list */
9914
9915 struct sipdns_query *sr_done; /**< Completed intermediate results */
9916
9917 struct sipdns_tport const *sr_tport; /**< Selected transport */
9918
9919 /** Transports to consider for this request */
9920 struct sipdns_tport const *sr_tports[SIPDNS_TRANSPORTS + 1];
9921
9922 uint16_t sr_a_aaaa1, sr_a_aaaa2; /**< Order of A and/or AAAA queries. */
9923
9924 unsigned
9925 sr_use_naptr:1,
9926 sr_use_srv:1,
9927 sr_use_a_aaaa:1;
9928 };
9929
9930 /** Intermediate queries */
9931 struct sipdns_query
9932 {
9933 struct sipdns_query *sq_next;
9934
9935 char const *sq_proto;
9936 char const *sq_domain;
9937 char sq_port[6]; /* port number */
9938 uint16_t sq_otype; /* origin type of query data (0 means request) */
9939 uint16_t sq_type; /* query type */
9940 uint16_t sq_priority; /* priority or preference */
9941 uint16_t sq_weight; /* preference or weight */
9942 uint16_t sq_grayish; /* candidate for graylisting */
9943 };
9944
9945 static int outgoing_resolve_next(nta_outgoing_t *orq);
9946 static int outgoing_resolving(nta_outgoing_t *orq);
9947 static int outgoing_resolving_error(nta_outgoing_t *,
9948 int status, char const *phrase);
9949 static void outgoing_graylist(nta_outgoing_t *orq, struct sipdns_query *sq);
9950 static int outgoing_query_naptr(nta_outgoing_t *orq, char const *domain);
9951 static void outgoing_answer_naptr(sres_context_t *orq, sres_query_t *q,
9952 sres_record_t *answers[]);
9953 struct sipdns_tport const *outgoing_naptr_tport(nta_outgoing_t *orq,
9954 sres_record_t *answers[]);
9955
9956 static int outgoing_make_srv_query(nta_outgoing_t *orq);
9957 static int outgoing_make_a_aaaa_query(nta_outgoing_t *orq);
9958
9959 static void outgoing_query_all(nta_outgoing_t *orq);
9960
9961 static int outgoing_query_srv(nta_outgoing_t *orq, struct sipdns_query *);
9962 static void outgoing_answer_srv(sres_context_t *orq, sres_query_t *q,
9963 sres_record_t *answers[]);
9964
9965 #if SU_HAVE_IN6
9966 static int outgoing_query_aaaa(nta_outgoing_t *orq, struct sipdns_query *);
9967 static void outgoing_answer_aaaa(sres_context_t *orq, sres_query_t *q,
9968 sres_record_t *answers[]);
9969 #endif
9970
9971 static int outgoing_query_a(nta_outgoing_t *orq, struct sipdns_query *);
9972 static void outgoing_answer_a(sres_context_t *orq, sres_query_t *q,
9973 sres_record_t *answers[]);
9974
9975 #ifdef __clang_analyzer__
9976 #define FUNC_ATTR_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
9977 #else
9978 #define FUNC_ATTR_NONNULL(...)
9979 #endif
9980
9981 static void outgoing_query_results(nta_outgoing_t *orq,
9982 struct sipdns_query *sq,
9983 char *results[],
9984 size_t rlen) FUNC_ATTR_NONNULL(3);
9985
9986
9987 #define SIPDNS_503_ERROR 503, "DNS Error"
9988
9989 /** Resolve a request destination */
9990 static void
outgoing_resolve(nta_outgoing_t * orq,int explicit_transport,enum nta_res_order_e res_order)9991 outgoing_resolve(nta_outgoing_t *orq,
9992 int explicit_transport,
9993 enum nta_res_order_e res_order)
9994 {
9995 struct sipdns_resolver *sr = NULL;
9996 char const *tpname = orq->orq_tpn->tpn_proto;
9997 int tport_known = strcmp(tpname, "*") != 0;
9998
9999 if (orq->orq_agent->sa_resolver)
10000 orq->orq_resolver = sr = su_zalloc(orq->orq_agent->sa_home, (sizeof *sr));
10001
10002 if (!sr) {
10003 outgoing_resolving_error(orq, SIP_500_INTERNAL_SERVER_ERROR);
10004 return;
10005 }
10006
10007 *sr->sr_tpn = *orq->orq_tpn;
10008 sr->sr_use_srv = orq->orq_agent->sa_use_srv;
10009 sr->sr_use_naptr = orq->orq_agent->sa_use_naptr && sr->sr_use_srv;
10010 sr->sr_use_a_aaaa = 1;
10011 sr->sr_tail = &sr->sr_head;
10012
10013 /* RFC 3263:
10014 If the TARGET was not a numeric IP address, but a port is present in
10015 the URI, the client performs an A or AAAA record lookup of the domain
10016 name. The result will be a list of IP addresses, each of which can
10017 be contacted at the specific port from the URI and transport protocol
10018 determined previously. The client SHOULD try the first record. If
10019 an attempt should fail, based on the definition of failure in Section
10020 4.3, the next SHOULD be tried, and if that should fail, the next
10021 SHOULD be tried, and so on.
10022
10023 This is a change from RFC 2543. Previously, if the port was
10024 explicit, but with a value of 5060, SRV records were used. Now, A
10025 or AAAA records will be used.
10026 */
10027 if (sr->sr_tpn->tpn_port)
10028 sr->sr_use_naptr = 0, sr->sr_use_srv = 0;
10029
10030 /* RFC3263:
10031 If [...] a transport was specified explicitly, the client performs an
10032 SRV query for that specific transport,
10033 */
10034 if (explicit_transport)
10035 sr->sr_use_naptr = 0;
10036
10037 {
10038 /* Initialize sr_tports */
10039 tport_t *tport;
10040 char const *ident = sr->sr_tpn->tpn_ident;
10041 int i, j;
10042
10043 for (tport = tport_primary_by_name(orq->orq_agent->sa_tports, orq->orq_tpn);
10044 tport;
10045 tport = tport_next(tport)) {
10046 tp_name_t const *tpn = tport_name(tport);
10047 if (tport_known && !su_casematch(tpn->tpn_proto, tpname))
10048 continue;
10049 if (ident && (tpn->tpn_ident == NULL || strcmp(ident, tpn->tpn_ident)))
10050 continue;
10051
10052 for (j = 0; j < SIPDNS_TRANSPORTS; j++)
10053 if (su_casematch(tpn->tpn_proto, sipdns_tports[j].name))
10054 break;
10055
10056 assert(j < SIPDNS_TRANSPORTS);
10057 if (j == SIPDNS_TRANSPORTS)
10058 /* Someone added transport but did not update sipdns_tports */
10059 continue;
10060
10061 for (i = 0; i < SIPDNS_TRANSPORTS; i++) {
10062 if (sipdns_tports + j == sr->sr_tports[i] || sr->sr_tports[i] == NULL)
10063 break;
10064 }
10065 sr->sr_tports[i] = sipdns_tports + j;
10066
10067 if (tport_known) /* Looking for only one transport */ {
10068 sr->sr_tport = sipdns_tports + j;
10069 break;
10070 }
10071 }
10072
10073 /* Nothing found */
10074 if (!sr->sr_tports[0]) {
10075 SU_DEBUG_3(("nta(%p): transport %s is not supported%s%s\n", (void *)orq,
10076 tpname, ident ? " by interface " : "", ident ? ident : ""));
10077 outgoing_resolving_error(orq, SIPDNS_503_ERROR);
10078 return;
10079 }
10080 }
10081
10082 switch (res_order) {
10083 default:
10084 case nta_res_ip6_ip4:
10085 sr->sr_a_aaaa1 = sres_type_aaaa, sr->sr_a_aaaa2 = sres_type_a;
10086 break;
10087 case nta_res_ip4_ip6:
10088 sr->sr_a_aaaa1 = sres_type_a, sr->sr_a_aaaa2 = sres_type_aaaa;
10089 break;
10090 case nta_res_ip6_only:
10091 sr->sr_a_aaaa1 = sres_type_aaaa, sr->sr_a_aaaa2 = sres_type_aaaa;
10092 break;
10093 case nta_res_ip4_only:
10094 sr->sr_a_aaaa1 = sres_type_a, sr->sr_a_aaaa2 = sres_type_a;
10095 break;
10096 }
10097
10098 outgoing_resolve_next(orq);
10099 }
10100
10101 /** Resolve next destination. */
10102 static int
outgoing_resolve_next(nta_outgoing_t * orq)10103 outgoing_resolve_next(nta_outgoing_t *orq)
10104 {
10105 struct sipdns_resolver *sr = orq->orq_resolver;
10106
10107 if (sr == NULL) {
10108 outgoing_resolving_error(orq, SIP_500_INTERNAL_SERVER_ERROR);
10109 return 0;
10110 }
10111
10112 if (sr->sr_results) {
10113 /* Use existing A/AAAA results */
10114 su_free(msg_home(orq->orq_request), sr->sr_results[0]);
10115 sr->sr_results++;
10116 if (sr->sr_results[0]) {
10117 struct sipdns_query *sq = sr->sr_current; assert(sq);
10118
10119 if (sq->sq_proto)
10120 orq->orq_tpn->tpn_proto = sq->sq_proto;
10121 if (sq->sq_port[0])
10122 orq->orq_tpn->tpn_port = sq->sq_port;
10123
10124 orq->orq_tpn->tpn_host = sr->sr_results[0];
10125
10126 outgoing_reset_timer(orq);
10127 outgoing_queue(orq->orq_agent->sa_out.resolving, orq);
10128 outgoing_prepare_send(orq);
10129 return 1;
10130 }
10131 else {
10132 sr->sr_current = NULL;
10133 sr->sr_results = NULL;
10134 }
10135 }
10136
10137 if (sr->sr_head)
10138 outgoing_query_all(orq);
10139 else if (sr->sr_use_naptr)
10140 outgoing_query_naptr(orq, sr->sr_tpn->tpn_host); /* NAPTR */
10141 else if (sr->sr_use_srv)
10142 outgoing_make_srv_query(orq); /* SRV */
10143 else if (sr->sr_use_a_aaaa)
10144 outgoing_make_a_aaaa_query(orq); /* A/AAAA */
10145 else
10146 return outgoing_resolving_error(orq, SIPDNS_503_ERROR);
10147
10148 return 1;
10149 }
10150
10151 /** Check if can we retry other destinations? */
10152 static int
outgoing_other_destinations(nta_outgoing_t const * orq)10153 outgoing_other_destinations(nta_outgoing_t const *orq)
10154 {
10155 struct sipdns_resolver *sr = orq->orq_resolver;
10156
10157 if (!sr)
10158 return 0;
10159
10160 if (sr->sr_use_a_aaaa || sr->sr_use_srv || sr->sr_use_naptr)
10161 return 1;
10162
10163 if (sr->sr_results && sr->sr_results[1])
10164 return 1;
10165
10166 if (sr->sr_head)
10167 return 1;
10168
10169 return 0;
10170 }
10171
10172 /** Resolve a request destination */
10173 static int
outgoing_try_another(nta_outgoing_t * orq)10174 outgoing_try_another(nta_outgoing_t *orq)
10175 {
10176 struct sipdns_resolver *sr = orq->orq_resolver;
10177
10178 if (sr == NULL)
10179 return 0;
10180
10181 *orq->orq_tpn = *sr->sr_tpn;
10182 orq->orq_try_tcp_instead = 0, orq->orq_try_udp_instead = 0;
10183 outgoing_reset_timer(orq);
10184 outgoing_queue(orq->orq_agent->sa_out.resolving, orq);
10185
10186 if (orq->orq_status > 0)
10187 /* PP: don't hack priority if a preliminary response has been received */
10188 ;
10189 else if (orq->orq_agent->sa_graylist == 0)
10190 /* PP: priority hacking disabled */
10191 ;
10192 /* NetModule hack:
10193 * Move server that did not work to end of queue in sres cache
10194 *
10195 * the next request does not try to use the server that is currently down
10196 *
10197 * @TODO: fix cases with only A or AAAA answering, or all servers down.
10198 */
10199 else if (sr && sr->sr_target) {
10200 struct sipdns_query *sq;
10201
10202 /* find latest A/AAAA record */
10203 sq = sr->sr_head;
10204 if (sq && sq->sq_type == sr->sr_a_aaaa2 && sr->sr_a_aaaa1 != sr->sr_a_aaaa2) {
10205 sq->sq_grayish = 1;
10206 }
10207 else {
10208 outgoing_graylist(orq, sr->sr_done);
10209 }
10210 }
10211
10212 return outgoing_resolve_next(orq);
10213 }
10214
10215 /** Graylist SRV records */
outgoing_graylist(nta_outgoing_t * orq,struct sipdns_query * sq)10216 static void outgoing_graylist(nta_outgoing_t *orq, struct sipdns_query *sq)
10217 {
10218 struct sipdns_resolver *sr = orq->orq_resolver;
10219 char const *target = sq->sq_domain, *proto = sq->sq_proto;
10220 unsigned prio = sq->sq_priority, maxprio = prio;
10221
10222 /* Don't know how to graylist but SRV records */
10223 if (sq->sq_otype != sres_type_srv)
10224 return;
10225
10226 SU_DEBUG_5(("nta: graylisting %s:%s;transport=%s\n", target, sq->sq_port, proto));
10227
10228 for (sq = sr->sr_head; sq; sq = sq->sq_next)
10229 if (sq->sq_otype == sres_type_srv && sq->sq_priority > maxprio)
10230 maxprio = sq->sq_priority;
10231
10232 for (sq = sr->sr_done; sq; sq = sq->sq_next)
10233 if (sq->sq_otype == sres_type_srv && sq->sq_priority > maxprio)
10234 maxprio = sq->sq_priority;
10235
10236 for (sq = sr->sr_done; sq; sq = sq->sq_next) {
10237 int modified;
10238
10239 if (sq->sq_type != sres_type_srv || strcmp(proto, sq->sq_proto))
10240 continue;
10241
10242 /* modify the SRV record(s) corresponding to the latest A/AAAA record */
10243 modified = sres_set_cached_srv_priority(
10244 orq->orq_agent->sa_resolver,
10245 sq->sq_domain,
10246 target,
10247 sq->sq_port[0] ? (uint16_t)strtoul(sq->sq_port, NULL, 10) : 0,
10248 orq->orq_agent->sa_graylist,
10249 maxprio + 1);
10250
10251 if (modified >= 0)
10252 SU_DEBUG_3(("nta: reduced priority of %d %s SRV records (increase value to %u)\n",
10253 modified, sq->sq_domain, maxprio + 1));
10254 else
10255 SU_DEBUG_3(("nta: failed to reduce %s SRV priority\n", sq->sq_domain));
10256 }
10257 }
10258
10259 /** Cancel resolver query */
outgoing_cancel_resolver(nta_outgoing_t * orq)10260 su_inline void outgoing_cancel_resolver(nta_outgoing_t *orq)
10261 {
10262 struct sipdns_resolver *sr = orq->orq_resolver;
10263
10264 assert(orq->orq_resolver);
10265
10266 if (sr->sr_query) /* Cancel resolver query */
10267 sres_query_bind(sr->sr_query, NULL, NULL), sr->sr_query = NULL;
10268 }
10269
10270 /** Destroy resolver */
outgoing_destroy_resolver(nta_outgoing_t * orq)10271 su_inline void outgoing_destroy_resolver(nta_outgoing_t *orq)
10272 {
10273 struct sipdns_resolver *sr = orq->orq_resolver;
10274
10275 assert(orq->orq_resolver);
10276
10277 outgoing_cancel_resolver(orq);
10278
10279 su_free(orq->orq_agent->sa_home, sr);
10280
10281 orq->orq_resolver = NULL;
10282 }
10283
10284 /** Check if we are resolving. If not, return 503 response. */
10285 static
outgoing_resolving(nta_outgoing_t * orq)10286 int outgoing_resolving(nta_outgoing_t *orq)
10287 {
10288 struct sipdns_resolver *sr = orq->orq_resolver;
10289
10290 assert(orq->orq_resolver);
10291
10292 if (!sr->sr_query) {
10293 return outgoing_resolving_error(orq, SIPDNS_503_ERROR);
10294 }
10295 else {
10296 outgoing_queue(orq->orq_agent->sa_out.resolving, orq);
10297 return 0;
10298 }
10299 }
10300
10301 /** Return 503 response */
10302 static
outgoing_resolving_error(nta_outgoing_t * orq,int status,char const * phrase)10303 int outgoing_resolving_error(nta_outgoing_t *orq, int status, char const *phrase)
10304 {
10305 orq->orq_resolved = 1;
10306 outgoing_reply(orq, status, phrase, 0);
10307 return -1;
10308 }
10309
10310 /* Query SRV records (with the given tport). */
10311 static
outgoing_make_srv_query(nta_outgoing_t * orq)10312 int outgoing_make_srv_query(nta_outgoing_t *orq)
10313 {
10314 struct sipdns_resolver *sr = orq->orq_resolver;
10315 su_home_t *home = msg_home(orq->orq_request);
10316 struct sipdns_query *sq;
10317 char const *host, *prefix;
10318 int i;
10319 size_t hlen, plen;
10320
10321 sr->sr_use_srv = 0;
10322
10323 host = sr->sr_tpn->tpn_host;
10324 hlen = strlen(host) + 1;
10325
10326 for (i = 0; sr->sr_tports[i]; i++) {
10327 if (sr->sr_tport && sr->sr_tports[i] != sr->sr_tport)
10328 continue;
10329
10330 prefix = sr->sr_tports[i]->prefix;
10331 plen = strlen(prefix);
10332
10333 sq = su_zalloc(home, (sizeof *sq) + plen + hlen);
10334 if (sq) {
10335 *sr->sr_tail = sq, sr->sr_tail = &sq->sq_next;
10336 sq->sq_domain = memcpy(sq + 1, prefix, plen);
10337 memcpy((char *)sq->sq_domain + plen, host, hlen);
10338 sq->sq_proto = sr->sr_tports[i]->name;
10339 sq->sq_type = sres_type_srv;
10340 sq->sq_priority = 1;
10341 sq->sq_weight = 1;
10342 }
10343 }
10344
10345 outgoing_query_all(orq);
10346
10347 return 0;
10348 }
10349
10350 /* Query A/AAAA records. */
10351 static
outgoing_make_a_aaaa_query(nta_outgoing_t * orq)10352 int outgoing_make_a_aaaa_query(nta_outgoing_t *orq)
10353 {
10354 struct sipdns_resolver *sr = orq->orq_resolver;
10355 su_home_t *home = msg_home(orq->orq_request);
10356 tp_name_t *tpn = orq->orq_tpn;
10357 struct sipdns_query *sq;
10358
10359 assert(sr);
10360
10361 sr->sr_use_a_aaaa = 0;
10362
10363 sq = su_zalloc(home, 2 * (sizeof *sq));
10364 if (!sq)
10365 return outgoing_resolving(orq);
10366
10367 sq->sq_type = sr->sr_a_aaaa1;
10368 sq->sq_domain = tpn->tpn_host;
10369 sq->sq_priority = 1;
10370
10371 /* Append */
10372 *sr->sr_tail = sq, sr->sr_tail = &sq->sq_next;
10373
10374 outgoing_query_all(orq);
10375
10376 return 0;
10377 }
10378
10379
10380 /** Start SRV/A/AAAA queries */
10381 static
outgoing_query_all(nta_outgoing_t * orq)10382 void outgoing_query_all(nta_outgoing_t *orq)
10383 {
10384 struct sipdns_resolver *sr = orq->orq_resolver;
10385 struct sipdns_query *sq = sr->sr_head;
10386
10387 if (sq == NULL) {
10388 outgoing_resolving_error(orq, SIP_500_INTERNAL_SERVER_ERROR);
10389 return;
10390 }
10391
10392 /* Remove from intermediate list */
10393 if (!(sr->sr_head = sq->sq_next))
10394 sr->sr_tail = &sr->sr_head;
10395
10396 if (sq->sq_type == sres_type_srv)
10397 outgoing_query_srv(orq, sq);
10398 #if SU_HAVE_IN6
10399 else if (sq->sq_type == sres_type_aaaa)
10400 outgoing_query_aaaa(orq, sq);
10401 #endif
10402 else if (sq->sq_type == sres_type_a)
10403 outgoing_query_a(orq, sq);
10404 else
10405 outgoing_resolving_error(orq, SIP_500_INTERNAL_SERVER_ERROR);
10406 }
10407
10408 /** Query NAPTR record. */
10409 static
outgoing_query_naptr(nta_outgoing_t * orq,char const * domain)10410 int outgoing_query_naptr(nta_outgoing_t *orq, char const *domain)
10411 {
10412 struct sipdns_resolver *sr = orq->orq_resolver;
10413 sres_record_t **answers;
10414
10415 sr->sr_use_naptr = 0;
10416
10417 sr->sr_target = domain;
10418
10419 answers = sres_cached_answers(orq->orq_agent->sa_resolver,
10420 sres_type_naptr, domain);
10421
10422 SU_DEBUG_5(("nta: for \"%s\" query \"%s\" %s%s\n",
10423 orq->orq_tpn->tpn_host, domain, "NAPTR",
10424 answers ? " (cached)" : ""));
10425
10426 if (answers) {
10427 outgoing_answer_naptr(orq, NULL, answers);
10428 return 0;
10429 }
10430 else {
10431 sr->sr_query = sres_query(orq->orq_agent->sa_resolver,
10432 outgoing_answer_naptr, orq,
10433 sres_type_naptr, domain);
10434 return outgoing_resolving(orq);
10435 }
10436 }
10437
10438 /* Process NAPTR records */
10439 static
outgoing_answer_naptr(sres_context_t * orq,sres_query_t * q,sres_record_t * answers[])10440 void outgoing_answer_naptr(sres_context_t *orq,
10441 sres_query_t *q,
10442 sres_record_t *answers[])
10443 {
10444 int i, order = -1;
10445 size_t rlen;
10446 su_home_t *home = msg_home(orq->orq_request);
10447 struct sipdns_resolver *sr = orq->orq_resolver;
10448 tp_name_t tpn[1];
10449 struct sipdns_query *sq, *selected = NULL, **tail = &selected, **at;
10450
10451 assert(sr);
10452
10453 sr->sr_query = NULL;
10454
10455 *tpn = *sr->sr_tpn;
10456
10457 /* The NAPTR results are sorted first by Order then by Preference */
10458 sres_sort_answers(orq->orq_agent->sa_resolver, answers);
10459
10460 if (sr->sr_tport == NULL)
10461 sr->sr_tport = outgoing_naptr_tport(orq, answers);
10462
10463 for (i = 0; answers && answers[i]; i++) {
10464 sres_naptr_record_t const *na = answers[i]->sr_naptr;
10465 uint16_t type;
10466 int valid_tport;
10467
10468 if (na->na_record->r_status)
10469 continue;
10470 if (na->na_record->r_type != sres_type_naptr)
10471 continue;
10472
10473 /* Check if NAPTR matches our target */
10474 if (!su_casenmatch(na->na_services, "SIP+", 4) &&
10475 !su_casenmatch(na->na_services, "SIPS+", 5))
10476 /* Not a SIP/SIPS service */
10477 continue;
10478
10479 /* Use NAPTR results, don't try extra SRV/A/AAAA records */
10480 sr->sr_use_srv = 0, sr->sr_use_a_aaaa = 0;
10481
10482 valid_tport = sr->sr_tport &&
10483 su_casematch(na->na_services, sr->sr_tport->service);
10484
10485 SU_DEBUG_5(("nta: %s IN NAPTR %u %u \"%s\" \"%s\" \"%s\" %s%s\n",
10486 na->na_record->r_name,
10487 na->na_order, na->na_prefer,
10488 na->na_flags, na->na_services,
10489 na->na_regexp, na->na_replace,
10490 order >= 0 && order != na->na_order ? " (out of order)" :
10491 valid_tport ? "" : " (tport not used)"));
10492
10493 /* RFC 2915 p 4:
10494 * Order
10495 * A 16-bit unsigned integer specifying the order in which the
10496 * NAPTR records MUST be processed to ensure the correct ordering
10497 * of rules. Low numbers are processed before high numbers, and
10498 * once a NAPTR is found whose rule "matches" the target, the
10499 * client MUST NOT consider any NAPTRs with a higher value for
10500 * order (except as noted below for the Flags field).
10501 */
10502 if (order >= 0 && order != na->na_order)
10503 continue;
10504 if (!valid_tport)
10505 continue;
10506
10507 /* OK, we found matching NAPTR */
10508 order = na->na_order;
10509
10510 /*
10511 * The "S" flag means that the next lookup should be for SRV records
10512 * ... "A" means that the next lookup should be for either an A, AAAA,
10513 * or A6 record.
10514 */
10515 if (na->na_flags[0] == 's' || na->na_flags[0] == 'S')
10516 type = sres_type_srv; /* SRV */
10517 else if (na->na_flags[0] == 'a' || na->na_flags[0] == 'A')
10518 type = sr->sr_a_aaaa1; /* A / AAAA */
10519 else
10520 continue;
10521
10522 rlen = strlen(na->na_replace) + 1;
10523 sq = su_zalloc(home, (sizeof *sq) + rlen);
10524
10525 if (sq == NULL)
10526 continue;
10527
10528 *tail = sq, tail = &sq->sq_next;
10529 sq->sq_otype = sres_type_naptr;
10530 sq->sq_priority = na->na_prefer;
10531 sq->sq_weight = 1;
10532 sq->sq_type = type;
10533 sq->sq_domain = memcpy(sq + 1, na->na_replace, rlen);
10534 sq->sq_proto = sr->sr_tport->name;
10535 }
10536
10537 sres_free_answers(orq->orq_agent->sa_resolver, answers);
10538
10539 /* RFC2915:
10540 Preference [...] specifies the order in which NAPTR
10541 records with equal "order" values SHOULD be processed, low
10542 numbers being processed before high numbers. */
10543 at = sr->sr_tail;
10544 while (selected) {
10545 sq = selected, selected = sq->sq_next;
10546
10547 for (tail = at; *tail; tail = &(*tail)->sq_next) {
10548 if (sq->sq_priority < (*tail)->sq_priority)
10549 break;
10550 if (sq->sq_priority == (*tail)->sq_priority &&
10551 sq->sq_weight < (*tail)->sq_weight)
10552 break;
10553 }
10554 /* Insert */
10555 sq->sq_next = *tail, *tail = sq;
10556
10557 if (!sq->sq_next) /* Last one */
10558 sr->sr_tail = &sq->sq_next;
10559 }
10560
10561 outgoing_resolve_next(orq);
10562 }
10563
10564 /* Find first supported protocol in order and preference */
10565 struct sipdns_tport const *
outgoing_naptr_tport(nta_outgoing_t * orq,sres_record_t * answers[])10566 outgoing_naptr_tport(nta_outgoing_t *orq, sres_record_t *answers[])
10567 {
10568 int i, j, order, pref;
10569 int orders[SIPDNS_TRANSPORTS] = {0}, prefs[SIPDNS_TRANSPORTS] = {0};
10570 struct sipdns_tport const *tport;
10571
10572 struct sipdns_resolver *sr = orq->orq_resolver;
10573
10574 prefs[0] = 0;
10575 for (j = 0; sr->sr_tports[j]; j++) {
10576 tport = sr->sr_tports[j];
10577
10578 orders[j] = 65536, prefs[j] = 65536;
10579
10580 /* Find transport order */
10581 for (i = 0; answers && answers[i]; i++) {
10582 sres_naptr_record_t const *na = answers[i]->sr_naptr;
10583 if (na->na_record->r_status)
10584 continue;
10585 if (na->na_record->r_type != sres_type_naptr)
10586 continue;
10587 /* Check if NAPTR matches transport */
10588 if (!su_casematch(na->na_services, tport->service))
10589 continue;
10590 orders[j] = na->na_order;
10591 prefs[j] = na->na_prefer;
10592 break;
10593 }
10594 }
10595
10596 tport = sr->sr_tports[0], order = orders[0], pref = prefs[0];
10597
10598 for (j = 1; sr->sr_tports[j]; j++) {
10599 if (orders[j] <= order && prefs[j] < pref) {
10600 tport = sr->sr_tports[j], order = orders[j], pref = prefs[j];
10601 }
10602 }
10603
10604 return tport;
10605 }
10606
10607
10608 /* Query SRV records */
10609 static
outgoing_query_srv(nta_outgoing_t * orq,struct sipdns_query * sq)10610 int outgoing_query_srv(nta_outgoing_t *orq,
10611 struct sipdns_query *sq)
10612 {
10613 struct sipdns_resolver *sr = orq->orq_resolver;
10614
10615 sres_record_t **answers;
10616
10617 sr->sr_target = sq->sq_domain;
10618 sr->sr_current = sq;
10619
10620 answers = sres_cached_answers(orq->orq_agent->sa_resolver,
10621 sres_type_srv, sq->sq_domain);
10622
10623 SU_DEBUG_5(("nta: for \"%s\" query \"%s\" %s%s\n",
10624 orq->orq_tpn->tpn_host, sq->sq_domain, "SRV",
10625 answers ? " (cached)" : ""));
10626
10627 if (answers) {
10628 outgoing_answer_srv(orq, NULL, answers);
10629 return 0;
10630 }
10631 else {
10632 sr->sr_query = sres_query(orq->orq_agent->sa_resolver,
10633 outgoing_answer_srv, orq,
10634 sres_type_srv, sq->sq_domain);
10635 return outgoing_resolving(orq);
10636 }
10637 }
10638
10639 /* Process SRV records */
10640 static
10641 void
outgoing_answer_srv(sres_context_t * orq,sres_query_t * q,sres_record_t * answers[])10642 outgoing_answer_srv(sres_context_t *orq, sres_query_t *q,
10643 sres_record_t *answers[])
10644 {
10645 struct sipdns_resolver *sr = orq->orq_resolver;
10646 su_home_t *home = msg_home(orq->orq_request);
10647 struct sipdns_query *sq0, *sq, *selected = NULL, **tail = &selected, **at;
10648 int i;
10649 size_t tlen;
10650
10651 sr->sr_query = NULL;
10652
10653 sq0 = sr->sr_current;
10654 assert(sq0 && sq0->sq_type == sres_type_srv);
10655 assert(sq0->sq_domain); assert(sq0->sq_proto);
10656
10657 /* Sort by priority, weight? */
10658 sres_sort_answers(orq->orq_agent->sa_resolver, answers);
10659
10660 for (i = 0; answers && answers[i]; i++) {
10661 sres_srv_record_t const *srv = answers[i]->sr_srv;
10662
10663 if (srv->srv_record->r_status /* There was an error */ ||
10664 srv->srv_record->r_type != sres_type_srv)
10665 continue;
10666
10667 tlen = strlen(srv->srv_target) + 1;
10668
10669 sq = su_zalloc(home, (sizeof *sq) + tlen);
10670
10671 if (sq) {
10672 *tail = sq, tail = &sq->sq_next;
10673
10674 sq->sq_otype = sres_type_srv;
10675 sq->sq_type = sr->sr_a_aaaa1;
10676 sq->sq_proto = sq0->sq_proto;
10677 sq->sq_domain = memcpy(sq + 1, srv->srv_target, tlen);
10678 snprintf(sq->sq_port, sizeof(sq->sq_port), "%u", srv->srv_port);
10679 sq->sq_priority = srv->srv_priority;
10680 sq->sq_weight = srv->srv_weight;
10681 }
10682 }
10683
10684 sres_free_answers(orq->orq_agent->sa_resolver, answers);
10685
10686 at = &sr->sr_head;
10687
10688 /* Insert sorted by priority, randomly select by weigth */
10689 while (selected) {
10690 unsigned long weight = 0;
10691 unsigned N = 0;
10692 uint16_t priority = selected->sq_priority;
10693
10694 /* Total weight of entries with same priority */
10695 for (sq = selected; sq && priority == sq->sq_priority; sq = sq->sq_next) {
10696 weight += sq->sq_weight;
10697 N ++;
10698 }
10699
10700 tail = &selected;
10701
10702 /* Select by weighted random. Entries with weight 0 are kept in order */
10703 if (N > 1 && weight > 0) {
10704 unsigned rand = su_randint(0, weight - 1);
10705
10706 while (*tail && rand >= (*tail)->sq_weight) {
10707 rand -= (*tail)->sq_weight;
10708 tail = &(*tail)->sq_next;
10709 }
10710 }
10711
10712 /* Remove selected */
10713 if (*tail) {
10714 sq = *tail; *tail = sq->sq_next; assert(sq->sq_priority == priority);
10715
10716 /* Append at *at */
10717 sq->sq_next = *at; *at = sq; at = &sq->sq_next; if (!*at) sr->sr_tail = at;
10718
10719 SU_DEBUG_5(("nta: %s IN SRV %u %u %s %s (%s)\n",
10720 sq0->sq_domain,
10721 (unsigned)sq->sq_priority, (unsigned)sq->sq_weight,
10722 sq->sq_port, sq->sq_domain, sq->sq_proto));
10723 }
10724 }
10725
10726 /* This is not needed anymore (?) */
10727 sr->sr_current = NULL;
10728 sq0->sq_next = sr->sr_done; sr->sr_done = sq0;
10729
10730 outgoing_resolve_next(orq);
10731 }
10732
10733 #if SU_HAVE_IN6
10734 /* Query AAAA records */
10735 static
outgoing_query_aaaa(nta_outgoing_t * orq,struct sipdns_query * sq)10736 int outgoing_query_aaaa(nta_outgoing_t *orq, struct sipdns_query *sq)
10737 {
10738 struct sipdns_resolver *sr = orq->orq_resolver;
10739 sres_record_t **answers;
10740
10741 sr->sr_target = sq->sq_domain;
10742 sr->sr_current = sq;
10743
10744 answers = sres_cached_answers(orq->orq_agent->sa_resolver,
10745 sres_type_aaaa, sq->sq_domain);
10746
10747 SU_DEBUG_5(("nta: for \"%s\" query \"%s\" %s%s\n",
10748 orq->orq_tpn->tpn_host, sq->sq_domain, "AAAA",
10749 answers ? " (cached)" : ""));
10750
10751 if (answers) {
10752 outgoing_answer_aaaa(orq, NULL, answers);
10753 return 0;
10754 }
10755
10756 sr->sr_query = sres_query(orq->orq_agent->sa_resolver,
10757 outgoing_answer_aaaa, orq,
10758 sres_type_aaaa, sq->sq_domain);
10759
10760 return outgoing_resolving(orq);
10761 }
10762
10763 /* Process AAAA records */
10764 static
outgoing_answer_aaaa(sres_context_t * orq,sres_query_t * q,sres_record_t * answers[])10765 void outgoing_answer_aaaa(sres_context_t *orq, sres_query_t *q,
10766 sres_record_t *answers[])
10767 {
10768 struct sipdns_resolver *sr = orq->orq_resolver;
10769 su_home_t *home = msg_home(orq->orq_request);
10770 struct sipdns_query *sq = sr->sr_current;
10771
10772 size_t i, j, found;
10773 char *result, **results = NULL;
10774
10775 assert(sq); assert(sq->sq_type == sres_type_aaaa);
10776
10777 sr->sr_query = NULL;
10778
10779 for (i = 0, found = 0; answers && answers[i]; i++) {
10780 sres_aaaa_record_t const *aaaa = answers[i]->sr_aaaa;
10781 if (aaaa->aaaa_record->r_status == 0 &&
10782 aaaa->aaaa_record->r_type == sres_type_aaaa)
10783 found++;
10784 }
10785
10786 if (found > 1)
10787 results = su_zalloc(home, (found + 1) * (sizeof *results));
10788 else if (found)
10789 results = &result;
10790
10791 for (i = j = 0; results && answers && answers[i]; i++) {
10792 char addr[SU_ADDRSIZE];
10793 sres_aaaa_record_t const *aaaa = answers[i]->sr_aaaa;
10794
10795 if (aaaa->aaaa_record->r_status ||
10796 aaaa->aaaa_record->r_type != sres_type_aaaa)
10797 continue; /* There was an error */
10798
10799 su_inet_ntop(AF_INET6, &aaaa->aaaa_addr, addr, sizeof(addr));
10800
10801 if (j == 0)
10802 SU_DEBUG_5(("nta(%p): %s IN AAAA %s\n", (void *)orq,
10803 aaaa->aaaa_record->r_name, addr));
10804 else
10805 SU_DEBUG_5(("nta(%p): AAAA %s\n", (void *)orq, addr));
10806
10807 assert(j < found);
10808 results[j++] = su_strdup(home, addr);
10809 }
10810
10811 sres_free_answers(orq->orq_agent->sa_resolver, answers);
10812
10813 if (results)
10814 outgoing_query_results(orq, sq, results, found);
10815 }
10816 #endif /* SU_HAVE_IN6 */
10817
10818 /* Query A records */
10819 static
outgoing_query_a(nta_outgoing_t * orq,struct sipdns_query * sq)10820 int outgoing_query_a(nta_outgoing_t *orq, struct sipdns_query *sq)
10821 {
10822 struct sipdns_resolver *sr = orq->orq_resolver;
10823 sres_record_t **answers;
10824
10825 sr->sr_target = sq->sq_domain;
10826 sr->sr_current = sq;
10827
10828 answers = sres_cached_answers(orq->orq_agent->sa_resolver,
10829 sres_type_a, sq->sq_domain);
10830
10831 SU_DEBUG_5(("nta: for \"%s\" query \"%s\" %s%s\n",
10832 orq->orq_tpn->tpn_host, sq->sq_domain, "A",
10833 answers ? " (cached)" : ""));
10834
10835 if (answers) {
10836 outgoing_answer_a(orq, NULL, answers);
10837 return 0;
10838 }
10839
10840 sr->sr_query = sres_query(orq->orq_agent->sa_resolver,
10841 outgoing_answer_a, orq,
10842 sres_type_a, sq->sq_domain);
10843
10844 return outgoing_resolving(orq);
10845 }
10846
10847 /* Process A records */
10848 static
outgoing_answer_a(sres_context_t * orq,sres_query_t * q,sres_record_t * answers[])10849 void outgoing_answer_a(sres_context_t *orq, sres_query_t *q,
10850 sres_record_t *answers[])
10851 {
10852 struct sipdns_resolver *sr = orq->orq_resolver;
10853 su_home_t *home = msg_home(orq->orq_request);
10854 struct sipdns_query *sq = sr->sr_current;
10855
10856 int i, j, found;
10857 char *result, **results = NULL;
10858
10859 assert(sq); assert(sq->sq_type == sres_type_a);
10860
10861 sr->sr_query = NULL;
10862
10863 for (i = 0, found = 0; answers && answers[i]; i++) {
10864 sres_a_record_t const *a = answers[i]->sr_a;
10865 if (a->a_record->r_status == 0 &&
10866 a->a_record->r_type == sres_type_a)
10867 found++;
10868 }
10869
10870 if (found > 1)
10871 results = su_zalloc(home, (found + 1) * (sizeof *results));
10872 else if (found)
10873 results = &result;
10874
10875 for (i = j = 0; answers && answers[i]; i++) {
10876 char addr[SU_ADDRSIZE];
10877 sres_a_record_t const *a = answers[i]->sr_a;
10878
10879 if (a->a_record->r_status ||
10880 a->a_record->r_type != sres_type_a)
10881 continue; /* There was an error */
10882
10883 su_inet_ntop(AF_INET, &a->a_addr, addr, sizeof(addr));
10884
10885 if (j == 0)
10886 SU_DEBUG_5(("nta: %s IN A %s\n", a->a_record->r_name, addr));
10887 else
10888 SU_DEBUG_5(("nta(%p): A %s\n", (void *)orq, addr));
10889
10890 assert(j < found);
10891 results[j++] = su_strdup(home, addr);
10892 }
10893
10894 sres_free_answers(orq->orq_agent->sa_resolver, answers);
10895
10896 if (results)
10897 outgoing_query_results(orq, sq, results, found);
10898 else if (!q)
10899 outgoing_resolving_error(orq, SIPDNS_503_ERROR);
10900 }
10901
10902 /** Store A/AAAA query results */
10903 static void
outgoing_query_results(nta_outgoing_t * orq,struct sipdns_query * sq,char * results[],size_t rlen)10904 outgoing_query_results(nta_outgoing_t *orq,
10905 struct sipdns_query *sq,
10906 char *results[],
10907 size_t rlen)
10908 {
10909 struct sipdns_resolver *sr = orq->orq_resolver;
10910
10911 if (sq->sq_type == sr->sr_a_aaaa1 &&
10912 sq->sq_type != sr->sr_a_aaaa2) {
10913 sq->sq_type = sr->sr_a_aaaa2;
10914
10915 SU_DEBUG_7(("nta(%p): %s %s record still unresolved\n", (void *)orq,
10916 sq->sq_domain, sq->sq_type == sres_type_a ? "A" : "AAAA"));
10917
10918 /*
10919 * Three possible policies:
10920 * 1) try each host for AAAA/A, then A/AAAA
10921 * 2) try everything first for AAAA/A, then everything for A/AAAA
10922 * 3) try one SRV record results for AAAA/A, then for A/AAAA,
10923 * then next SRV record
10924 */
10925
10926 /* We use now policy #1 */
10927 if (!(sq->sq_next = sr->sr_head))
10928 sr->sr_tail = &sq->sq_next;
10929 sr->sr_head = sq;
10930 }
10931 else {
10932 sq->sq_next = sr->sr_done, sr->sr_done = sq;
10933
10934 if (rlen == 0 && sq->sq_grayish)
10935 outgoing_graylist(orq, sq);
10936 }
10937
10938 if (rlen > 1)
10939 sr->sr_results = results;
10940 else
10941 sr->sr_current = NULL;
10942
10943 if (rlen > 0) {
10944 orq->orq_resolved = 1;
10945 orq->orq_tpn->tpn_host = results[0];
10946 if (sq->sq_proto) orq->orq_tpn->tpn_proto = sq->sq_proto;
10947 if (sq->sq_port[0]) orq->orq_tpn->tpn_port = sq->sq_port;
10948 outgoing_prepare_send(orq);
10949 } else {
10950 outgoing_resolve_next(orq);
10951 }
10952 }
10953
10954
10955 #endif
10956
10957 /* ====================================================================== */
10958 /* 10) Reliable responses */
10959
10960 static nta_prack_f nta_reliable_destroyed;
10961
10962 /**
10963 * Check that server transaction can be used to send reliable provisional
10964 * responses.
10965 */
10966 su_inline
reliable_check(nta_incoming_t * irq)10967 int reliable_check(nta_incoming_t *irq)
10968 {
10969 if (irq == NULL || irq->irq_status >= 200 || !irq->irq_agent)
10970 return 0;
10971
10972 if (irq->irq_reliable && irq->irq_reliable->rel_status >= 200)
10973 return 0;
10974
10975 /* @RSeq is initialized to nonzero when request requires/supports 100rel */
10976 if (irq->irq_rseq == 0)
10977 return 0;
10978
10979 if (irq->irq_rseq == 0xffffffffU) /* already sent >> 2**31 responses */
10980 return 0;
10981
10982 return 1;
10983 }
10984
10985 /** Respond reliably.
10986 *
10987 * @param irq
10988 * @param callback
10989 * @param rmagic
10990 * @param status
10991 * @param phrase
10992 * @param tag, value, ..
10993 */
nta_reliable_treply(nta_incoming_t * irq,nta_prack_f * callback,nta_reliable_magic_t * rmagic,int status,char const * phrase,tag_type_t tag,tag_value_t value,...)10994 nta_reliable_t *nta_reliable_treply(nta_incoming_t *irq,
10995 nta_prack_f *callback,
10996 nta_reliable_magic_t *rmagic,
10997 int status, char const *phrase,
10998 tag_type_t tag,
10999 tag_value_t value, ...)
11000 {
11001 ta_list ta;
11002 msg_t *msg;
11003 sip_t *sip;
11004 nta_reliable_t *retval = NULL;
11005
11006 if (!reliable_check(irq) || (status <= 100 || status >= 200))
11007 return NULL;
11008
11009 msg = nta_msg_create(irq->irq_agent, 0);
11010 sip = sip_object(msg);
11011
11012 if (!sip)
11013 return NULL;
11014
11015 ta_start(ta, tag, value);
11016
11017 if (0 > nta_incoming_complete_response(irq, msg, status, phrase,
11018 ta_tags(ta)))
11019 msg_destroy(msg);
11020 else if (!(retval = reliable_mreply(irq, callback, rmagic, msg, sip)))
11021 msg_destroy(msg);
11022
11023 ta_end(ta);
11024
11025 return retval;
11026 }
11027
11028 /** Respond reliably with @a msg.
11029 *
11030 * @note
11031 * The stack takes over the ownership of @a msg. (It is destroyed even if
11032 * sending the response fails.)
11033 *
11034 * @param irq
11035 * @param callback
11036 * @param rmagic
11037 * @param msg
11038 */
nta_reliable_mreply(nta_incoming_t * irq,nta_prack_f * callback,nta_reliable_magic_t * rmagic,msg_t * msg)11039 nta_reliable_t *nta_reliable_mreply(nta_incoming_t *irq,
11040 nta_prack_f *callback,
11041 nta_reliable_magic_t *rmagic,
11042 msg_t *msg)
11043 {
11044 sip_t *sip = sip_object(msg);
11045
11046 if (!reliable_check(irq)) {
11047 msg_destroy(msg);
11048 return NULL;
11049 }
11050
11051 if (sip == NULL || !sip->sip_status || sip->sip_status->st_status <= 100) {
11052 msg_destroy(msg);
11053 return NULL;
11054 }
11055
11056 if (sip->sip_status->st_status >= 200) {
11057 incoming_final_failed(irq, msg);
11058 return NULL;
11059 }
11060
11061 return reliable_mreply(irq, callback, rmagic, msg, sip);
11062 }
11063
11064 static
reliable_mreply(nta_incoming_t * irq,nta_prack_f * callback,nta_reliable_magic_t * rmagic,msg_t * msg,sip_t * sip)11065 nta_reliable_t *reliable_mreply(nta_incoming_t *irq,
11066 nta_prack_f *callback,
11067 nta_reliable_magic_t *rmagic,
11068 msg_t *msg,
11069 sip_t *sip)
11070 {
11071 nta_reliable_t *rel;
11072 nta_agent_t *agent;
11073
11074 agent = irq->irq_agent;
11075
11076 if (callback == NULL)
11077 callback = nta_reliable_destroyed;
11078
11079 rel = su_zalloc(agent->sa_home, sizeof(*rel));
11080 if (rel) {
11081 rel->rel_irq = irq;
11082 rel->rel_callback = callback;
11083 rel->rel_magic = rmagic;
11084 rel->rel_unsent = msg;
11085 rel->rel_status = sip->sip_status->st_status;
11086 rel->rel_precious = sip->sip_payload != NULL;
11087 rel->rel_next = irq->irq_reliable;
11088
11089 /*
11090 * If there already is a un-pr-acknowledged response, queue this one
11091 * until at least one response is pr-acknowledged.
11092 */
11093 if (irq->irq_reliable &&
11094 (irq->irq_reliable->rel_next == NULL ||
11095 irq->irq_reliable->rel_rseq == 0)) {
11096 return irq->irq_reliable = rel;
11097 }
11098
11099 if (reliable_send(irq, rel, msg_ref_create(msg), sip) < 0) {
11100 msg_destroy(msg);
11101 su_free(agent->sa_home, rel);
11102 return NULL;
11103 }
11104
11105 irq->irq_reliable = rel;
11106
11107 return callback ? rel : (nta_reliable_t *)-1;
11108 }
11109
11110 msg_destroy(msg);
11111 return NULL;
11112 }
11113
11114 static
reliable_send(nta_incoming_t * irq,nta_reliable_t * rel,msg_t * msg,sip_t * sip)11115 int reliable_send(nta_incoming_t *irq,
11116 nta_reliable_t *rel,
11117 msg_t *msg,
11118 sip_t *sip)
11119 {
11120 nta_agent_t *sa = irq->irq_agent;
11121 su_home_t *home = msg_home(msg);
11122 sip_rseq_t rseq[1];
11123 sip_rseq_init(rseq);
11124
11125 if (sip->sip_require)
11126 msg_header_replace_param(home, sip->sip_require->k_common, "100rel");
11127 else
11128 sip_add_make(msg, sip, sip_require_class, "100rel");
11129
11130 rel->rel_rseq = rseq->rs_response = irq->irq_rseq;
11131 sip_add_dup(msg, sip, (sip_header_t *)rseq);
11132
11133 if (!sip->sip_rseq || incoming_reply(irq, msg, sip) < 0) {
11134 msg_destroy(msg);
11135 return -1;
11136 }
11137
11138 irq->irq_rseq++;
11139
11140 if (irq->irq_queue == sa->sa_in.preliminary)
11141 /* Make sure we are moved to the tail */
11142 incoming_remove(irq);
11143
11144 incoming_queue(sa->sa_in.preliminary, irq); /* P1 */
11145 incoming_set_timer(irq, sa->sa_t1); /* P2 */
11146
11147 return 0;
11148 }
11149
11150 /** Queue final response when there are unsent precious preliminary responses */
11151 static
reliable_final(nta_incoming_t * irq,msg_t * msg,sip_t * sip)11152 int reliable_final(nta_incoming_t *irq, msg_t *msg, sip_t *sip)
11153 {
11154 nta_reliable_t *r;
11155 unsigned already_in_callback;
11156 /*
11157 * We delay sending final response if it's 2XX and
11158 * an unpracked reliable response contains session description
11159 */
11160 /* Get last unpracked response from queue */
11161 if (sip->sip_status->st_status < 300)
11162 for (r = irq->irq_reliable; r; r = r->rel_next)
11163 if (r->rel_unsent && r->rel_precious) {
11164 /* Delay sending 2XX */
11165 reliable_mreply(irq, NULL, NULL, msg, sip);
11166 return 0;
11167 }
11168
11169 /* Flush unsent responses. */
11170 already_in_callback = irq->irq_in_callback;
11171 irq->irq_in_callback = 1;
11172 reliable_flush(irq);
11173 irq->irq_in_callback = already_in_callback;
11174
11175 if (!already_in_callback && irq->irq_terminated && irq->irq_destroyed) {
11176 incoming_free(irq);
11177 msg_destroy(msg);
11178 return 0;
11179 }
11180
11181 return 1;
11182 }
11183
11184 /** Get latest reliably sent response */
11185 static
reliable_response(nta_incoming_t * irq)11186 msg_t *reliable_response(nta_incoming_t *irq)
11187 {
11188 nta_reliable_t *r, *rel;
11189
11190 /* Get last unpracked response from queue */
11191 for (rel = NULL, r = irq->irq_reliable; r; r = r->rel_next)
11192 if (!r->rel_pracked)
11193 rel = r;
11194
11195 assert(rel);
11196
11197 return rel->rel_unsent;
11198 }
11199
11200 /* Find un-PRACKed responses */
11201 static
reliable_find(nta_agent_t const * agent,sip_t const * sip)11202 nta_reliable_t *reliable_find(nta_agent_t const *agent,
11203 sip_t const *sip)
11204 {
11205 incoming_htable_t const *iht = agent->sa_incoming;
11206 nta_incoming_t *irq, **ii;
11207 sip_call_id_t const *i = sip->sip_call_id;
11208 sip_rack_t const *rack = sip->sip_rack;
11209 hash_value_t hash = NTA_HASH(i, rack->ra_cseq);
11210
11211 /* XXX - add own hash table for 100rel */
11212
11213 for (ii = incoming_htable_hash(iht, hash);
11214 (irq = *ii);
11215 ii = incoming_htable_next(iht, ii)) {
11216
11217 if (hash == irq->irq_hash &&
11218 irq->irq_call_id->i_hash == i->i_hash &&
11219 irq->irq_cseq->cs_seq == rack->ra_cseq &&
11220 irq->irq_method == sip_method_invite &&
11221 strcmp(irq->irq_call_id->i_id, i->i_id) == 0 &&
11222 (irq->irq_to->a_tag == NULL ||
11223 su_casematch(irq->irq_to->a_tag, sip->sip_to->a_tag)) &&
11224 su_casematch(irq->irq_from->a_tag, sip->sip_from->a_tag)) {
11225
11226 nta_reliable_t const *rel;
11227
11228 /* Found matching INVITE */
11229 for (rel = irq->irq_reliable; rel; rel = rel->rel_next)
11230 if (rel->rel_rseq == rack->ra_response)
11231 return (nta_reliable_t *)rel;
11232
11233 }
11234 }
11235
11236 return NULL;
11237 }
11238
11239 /** Process incoming PRACK with matching @RAck field */
11240 static
reliable_recv(nta_reliable_t * rel,msg_t * msg,sip_t * sip,tport_t * tp)11241 int reliable_recv(nta_reliable_t *rel, msg_t *msg, sip_t *sip, tport_t *tp)
11242 {
11243 nta_incoming_t *irq = rel->rel_irq;
11244 nta_incoming_t *pr_irq;
11245 int status;
11246
11247 rel->rel_pracked = 1;
11248 msg_ref_destroy(rel->rel_unsent), rel->rel_unsent = NULL;
11249
11250 pr_irq = incoming_create(irq->irq_agent, msg, sip, tp, irq->irq_tag);
11251 if (!pr_irq) {
11252 mreply(irq->irq_agent, NULL,
11253 SIP_500_INTERNAL_SERVER_ERROR, msg,
11254 tp, 0, 0, NULL,
11255 TAG_END());
11256 return 0;
11257 }
11258
11259 if (irq->irq_status < 200) {
11260 incoming_queue(irq->irq_agent->sa_in.proceeding, irq); /* Reset P1 */
11261 incoming_reset_timer(irq); /* Reset P2 */
11262 }
11263
11264 irq->irq_in_callback = pr_irq->irq_in_callback = 1;
11265 status = rel->rel_callback(rel->rel_magic, rel, pr_irq, sip); rel = NULL;
11266 irq->irq_in_callback = pr_irq->irq_in_callback = 0;
11267
11268 if (pr_irq->irq_completed) { /* Already sent final response */
11269 if (pr_irq->irq_terminated && pr_irq->irq_destroyed)
11270 incoming_free(pr_irq);
11271 }
11272 else if (status != 0) {
11273 if (status < 200 || status > 299) {
11274 SU_DEBUG_3(("nta_reliable(): invalid status %03d from callback\n",
11275 status));
11276 status = 200;
11277 }
11278 nta_incoming_treply(pr_irq, status, "OK", TAG_END());
11279 nta_incoming_destroy(pr_irq);
11280 }
11281
11282 /* If there are queued unsent reliable responses, send them all. */
11283 while (irq->irq_reliable && irq->irq_reliable->rel_rseq == 0) {
11284 nta_reliable_t *r;
11285
11286 for (r = irq->irq_reliable; r; r = r->rel_next)
11287 if (r->rel_rseq == 0)
11288 rel = r;
11289
11290 msg = rel->rel_unsent, sip = sip_object(msg);
11291
11292 if (sip->sip_status->st_status < 200) {
11293 if (reliable_send(irq, rel, msg_ref_create(msg), sip) < 0) {
11294 assert(!"send reliable response");
11295 }
11296 }
11297 else {
11298 /*
11299 * XXX
11300 * Final response should be delayed until a reliable provisional
11301 * response has been pracked
11302 */
11303 rel->rel_unsent = NULL, rel->rel_rseq = (uint32_t)-1;
11304 if (incoming_reply(irq, msg, sip) < 0) {
11305 assert(!"send delayed final response");
11306 }
11307 }
11308 }
11309
11310 return 0;
11311 }
11312
11313 /** Flush unacknowledged and unsent reliable responses */
reliable_flush(nta_incoming_t * irq)11314 void reliable_flush(nta_incoming_t *irq)
11315 {
11316 nta_reliable_t *r, *rel;
11317
11318 do {
11319 for (r = irq->irq_reliable, rel = NULL; r; r = r->rel_next)
11320 if (r->rel_unsent)
11321 rel = r;
11322
11323 if (rel) {
11324 rel->rel_pracked = 1;
11325 msg_ref_destroy(rel->rel_unsent), rel->rel_unsent = NULL;
11326 rel->rel_callback(rel->rel_magic, rel, NULL, NULL);
11327 }
11328 } while (rel);
11329 }
11330
reliable_timeout(nta_incoming_t * irq,int timeout)11331 void reliable_timeout(nta_incoming_t *irq, int timeout)
11332 {
11333 if (timeout)
11334 SU_DEBUG_5(("nta: response timeout with %u\n", irq->irq_status));
11335
11336 irq->irq_in_callback = 1;
11337
11338 reliable_flush(irq);
11339
11340 if (irq->irq_callback)
11341 irq->irq_callback(irq->irq_magic, irq, NULL);
11342
11343 irq->irq_in_callback = 0;
11344
11345 if (!timeout)
11346 return;
11347
11348 if (irq->irq_completed && irq->irq_destroyed)
11349 incoming_free(irq), irq = NULL;
11350 else if (irq->irq_status < 200)
11351 nta_incoming_treply(irq, 503, "Reliable Response Time-Out", TAG_END());
11352 }
11353
11354 #if 0 /* Not needed, yet. */
11355 /** Use this callback when normal leg callback is supposed to
11356 * process incoming PRACK requests
11357 */
11358 int nta_reliable_leg_prack(nta_reliable_magic_t *magic,
11359 nta_reliable_t *rel,
11360 nta_incoming_t *irq,
11361 sip_t const *sip)
11362 {
11363 nta_agent_t *agent;
11364 nta_leg_t *leg;
11365 char const *method_name;
11366 url_t url[1];
11367 int retval;
11368
11369 if (irq == NULL || sip == NULL || rel == NULL ||
11370 sip_object(irq->irq_request) != sip)
11371 return 500;
11372
11373 agent = irq->irq_agent;
11374 method_name = sip->sip_request->rq_method_name;
11375 *url = *sip->sip_request->rq_url; url->url_params = NULL;
11376 agent_aliases(agent, url, irq->irq_tport); /* canonize urls */
11377
11378 if ((leg = leg_find(irq->irq_agent,
11379 method_name, url,
11380 sip->sip_call_id,
11381 sip->sip_from->a_tag,
11382 sip->sip_to->a_tag))) {
11383 /* Use existing dialog */
11384 SU_DEBUG_5(("nta: %s (%u) %s\n",
11385 method_name, sip->sip_cseq->cs_seq,
11386 "PRACK processed by default callback, too"));
11387 retval = leg->leg_callback(leg->leg_magic, leg, irq, sip);
11388 }
11389 else {
11390 retval = 500;
11391 }
11392
11393 nta_reliable_destroy(rel);
11394
11395 return retval;
11396 }
11397 #endif
11398
11399 /** Destroy a reliable response.
11400 *
11401 * Mark a reliable response object for destroyal and free it if possible.
11402 */
nta_reliable_destroy(nta_reliable_t * rel)11403 void nta_reliable_destroy(nta_reliable_t *rel)
11404 {
11405 if (rel == NULL || rel == NONE)
11406 return;
11407
11408 if (rel->rel_callback == nta_reliable_destroyed)
11409 SU_DEBUG_1(("%s(%p): %s\n", __func__, (void *)rel, "already destroyed"));
11410
11411 rel->rel_callback = nta_reliable_destroyed;
11412
11413 if (rel->rel_response)
11414 return;
11415
11416 nta_reliable_destroyed(NULL, rel, NULL, NULL);
11417 }
11418
11419 /** Free and unallocate the nta_reliable_t structure. */
11420 static
nta_reliable_destroyed(nta_reliable_magic_t * rmagic,nta_reliable_t * rel,nta_incoming_t * prack,sip_t const * sip)11421 int nta_reliable_destroyed(nta_reliable_magic_t *rmagic,
11422 nta_reliable_t *rel,
11423 nta_incoming_t *prack,
11424 sip_t const *sip)
11425 {
11426 nta_reliable_t **prev;
11427
11428 assert(rel); assert(rel->rel_irq);
11429
11430 for (prev = &rel->rel_irq->irq_reliable; *prev; prev = &(*prev)->rel_next)
11431 if (*prev == rel)
11432 break;
11433
11434 if (!*prev) {
11435 assert(*prev);
11436 SU_DEBUG_1(("%s(%p): %s\n", __func__, (void *)rel, "not linked"));
11437 return 200;
11438 }
11439
11440 *prev = rel->rel_next;
11441
11442 if (rel->rel_unsent)
11443 msg_destroy(rel->rel_unsent), rel->rel_unsent = NULL;
11444
11445 su_free(rel->rel_irq->irq_agent->sa_home, rel);
11446
11447 return 200;
11448 }
11449
11450 /** Validate a reliable response. */
outgoing_recv_reliable(nta_outgoing_t * orq,msg_t * msg,sip_t * sip)11451 int outgoing_recv_reliable(nta_outgoing_t *orq,
11452 msg_t *msg,
11453 sip_t *sip)
11454 {
11455 short status = sip->sip_status->st_status;
11456 char const *phrase = sip->sip_status->st_phrase;
11457 uint32_t rseq = sip->sip_rseq->rs_response;
11458
11459 SU_DEBUG_7(("nta: %03u %s is reliably received with RSeq: %u\n",
11460 status, phrase, rseq));
11461
11462 /* Cannot handle reliable responses unless we have a full dialog */
11463 if (orq->orq_rseq == 0 && !orq->orq_to->a_tag) {
11464 SU_DEBUG_5(("nta: %03u %s with initial RSeq: %u outside dialog\n",
11465 status, phrase, rseq));
11466 return 0;
11467 }
11468
11469 if (rseq <= orq->orq_rseq) {
11470 SU_DEBUG_3(("nta: %03u %s already received (RSeq: %u, expecting %u)\n",
11471 status, phrase, rseq, orq->orq_rseq + 1));
11472 return -1;
11473 }
11474
11475 if (orq->orq_rseq && orq->orq_rseq + 1 != rseq) {
11476 SU_DEBUG_3(("nta: %03d %s is not expected (RSeq: %u, expecting %u)\n",
11477 status, sip->sip_status->st_phrase,
11478 rseq, orq->orq_rseq + 1));
11479 return -1;
11480 }
11481
11482 return 0;
11483 }
11484
11485 /** Create a tagged fork of outgoing request.
11486 *
11487 * When a dialog-creating INVITE request is forked, each response from
11488 * diffent fork will create an early dialog with a distinct tag in @To
11489 * header. When each fork should be handled separately, a tagged INVITE
11490 * request can be used. It will only receive responses from the specified
11491 * fork. Please note that the tagged transaction should be terminated with
11492 * the final response from another fork, too.
11493 *
11494 * @param orq
11495 * @param callback
11496 * @param magic
11497 * @param to_tag
11498 * @param rseq
11499 *
11500 * @bug Fix the memory leak - either one of the requests is left unreleased
11501 * for ever.
11502 */
nta_outgoing_tagged(nta_outgoing_t * orq,nta_response_f * callback,nta_outgoing_magic_t * magic,char const * to_tag,sip_rseq_t const * rseq)11503 nta_outgoing_t *nta_outgoing_tagged(nta_outgoing_t *orq,
11504 nta_response_f *callback,
11505 nta_outgoing_magic_t *magic,
11506 char const *to_tag,
11507 sip_rseq_t const *rseq)
11508 {
11509 nta_agent_t *agent;
11510 su_home_t *home;
11511 nta_outgoing_t *tagged;
11512 sip_to_t *to;
11513
11514 if (orq == NULL || to_tag == NULL)
11515 return NULL;
11516
11517 if (orq->orq_to->a_tag) {
11518 SU_DEBUG_1(("%s: transaction %p (CSeq: %s %u) already in dialog\n", __func__,
11519 (void *)orq, orq->orq_cseq->cs_method_name, orq->orq_cseq->cs_seq));
11520 return NULL;
11521 }
11522 if (orq->orq_method != sip_method_invite) {
11523 SU_DEBUG_1(("%s: transaction %p (CSeq: %s %u) cannot be tagged\n", __func__,
11524 (void *)orq, orq->orq_cseq->cs_method_name, orq->orq_cseq->cs_seq));
11525 return NULL;
11526 }
11527 if (orq->orq_status < 100) {
11528 SU_DEBUG_1(("%s: transaction %p (CSeq: %s %u) still calling\n", __func__,
11529 (void *)orq, orq->orq_cseq->cs_method_name, orq->orq_cseq->cs_seq));
11530 return NULL;
11531 }
11532
11533 assert(orq->orq_agent); assert(orq->orq_request);
11534
11535 agent = orq->orq_agent;
11536 tagged = su_zalloc(agent->sa_home, sizeof(*tagged));
11537
11538 home = msg_home((msg_t *)orq->orq_request);
11539
11540 tagged->orq_hash = orq->orq_hash;
11541 tagged->orq_agent = orq->orq_agent;
11542 tagged->orq_callback = callback;
11543 tagged->orq_magic = magic;
11544
11545 tagged->orq_method = orq->orq_method;
11546 tagged->orq_method_name = orq->orq_method_name;
11547 tagged->orq_url = orq->orq_url;
11548 tagged->orq_from = orq->orq_from;
11549
11550 sip_to_tag(home, to = sip_to_copy(home, orq->orq_to), to_tag);
11551
11552 tagged->orq_to = to;
11553 tagged->orq_tag = to->a_tag;
11554 tagged->orq_cseq = orq->orq_cseq;
11555 tagged->orq_call_id = orq->orq_call_id;
11556
11557 tagged->orq_request = msg_ref_create(orq->orq_request);
11558 tagged->orq_response = msg_ref_create(orq->orq_response);
11559
11560 tagged->orq_status = orq->orq_status;
11561 tagged->orq_via_added = orq->orq_via_added;
11562 tagged->orq_prepared = orq->orq_prepared;
11563 tagged->orq_reliable = orq->orq_reliable;
11564 tagged->orq_sips = orq->orq_sips;
11565 tagged->orq_uas = orq->orq_uas;
11566 tagged->orq_pass_100 = orq->orq_pass_100;
11567 tagged->orq_must_100rel = orq->orq_must_100rel;
11568 tagged->orq_100rel = orq->orq_100rel;
11569 tagged->orq_route = orq->orq_route;
11570 *tagged->orq_tpn = *orq->orq_tpn;
11571 tagged->orq_tport = tport_ref(orq->orq_tport);
11572 if (orq->orq_cc)
11573 tagged->orq_cc = nta_compartment_ref(orq->orq_cc);
11574 tagged->orq_branch = orq->orq_branch;
11575 tagged->orq_via_branch = orq->orq_via_branch;
11576
11577 if (tagged->orq_uas) {
11578 tagged->orq_forking = orq;
11579 tagged->orq_forks = orq->orq_forks;
11580 tagged->orq_forked = 1;
11581 orq->orq_forks = tagged;
11582 }
11583
11584 outgoing_insert(agent, tagged);
11585
11586 return tagged;
11587 }
11588
11589 /**PRACK a provisional response.
11590 *
11591 * Create and send a PRACK request used to acknowledge a provisional
11592 * response.
11593 *
11594 * The request is sent using the route of the original request @a oorq.
11595 *
11596 * When NTA receives response to the prack request, it invokes the @a
11597 * callback function.
11598 *
11599 * @param leg dialog object
11600 * @param oorq original transaction request
11601 * @param callback callback function (may be @c NULL)
11602 * @param magic application context pointer
11603 * @param route_url optional URL used to route transaction requests
11604 * @param resp (optional) response message to be acknowledged
11605 * @param tag,value,... optional
11606 *
11607 * @return
11608 * If successful, return a pointer to newly created client transaction
11609 * object for PRACK request, NULL otherwise.
11610 *
11611 * @sa
11612 * nta_outgoing_tcreate(), nta_outgoing_tcancel(), nta_outgoing_destroy().
11613 */
nta_outgoing_prack(nta_leg_t * leg,nta_outgoing_t * oorq,nta_response_f * callback,nta_outgoing_magic_t * magic,url_string_t const * route_url,sip_t const * resp,tag_type_t tag,tag_value_t value,...)11614 nta_outgoing_t *nta_outgoing_prack(nta_leg_t *leg,
11615 nta_outgoing_t *oorq,
11616 nta_response_f *callback,
11617 nta_outgoing_magic_t *magic,
11618 url_string_t const *route_url,
11619 sip_t const *resp,
11620 tag_type_t tag, tag_value_t value, ...)
11621 {
11622 ta_list ta;
11623 msg_t *msg;
11624 su_home_t *home;
11625 sip_t *sip;
11626 sip_to_t const *to = NULL;
11627 sip_route_t *route = NULL, r0[1];
11628 nta_outgoing_t *orq = NULL;
11629 sip_rack_t *rack = NULL, rack0[1];
11630
11631 if (!leg || !oorq) {
11632 SU_DEBUG_1(("%s: invalid arguments\n", __func__));
11633 return NULL;
11634 }
11635
11636 sip_rack_init(rack0);
11637
11638 if (resp) {
11639 if (!resp->sip_status) {
11640 SU_DEBUG_1(("%s: invalid arguments\n", __func__));
11641 return NULL;
11642 }
11643
11644 if (resp->sip_status->st_status <= 100 ||
11645 resp->sip_status->st_status >= 200) {
11646 SU_DEBUG_1(("%s: %u response cannot be PRACKed\n",
11647 __func__, resp->sip_status->st_status));
11648 return NULL;
11649 }
11650
11651 if (!resp->sip_rseq) {
11652 SU_DEBUG_1(("%s: %u response missing RSeq\n",
11653 __func__, resp->sip_status->st_status));
11654 return NULL;
11655 }
11656
11657 if (resp->sip_rseq->rs_response <= oorq->orq_rseq) {
11658 SU_DEBUG_1(("%s: %u response RSeq does not match received RSeq\n",
11659 __func__, resp->sip_status->st_status));
11660 return NULL;
11661 }
11662 if (!oorq->orq_must_100rel &&
11663 !sip_has_feature(resp->sip_require, "100rel")) {
11664 SU_DEBUG_1(("%s: %u response does not require 100rel\n",
11665 __func__, resp->sip_status->st_status));
11666 return NULL;
11667 }
11668
11669 if (!resp->sip_to->a_tag) {
11670 SU_DEBUG_1(("%s: %u response has no To tag\n",
11671 __func__, resp->sip_status->st_status));
11672 return NULL;
11673 }
11674 if (su_strcasecmp(resp->sip_to->a_tag, leg->leg_remote->a_tag) ||
11675 su_strcasecmp(resp->sip_to->a_tag, oorq->orq_to->a_tag)) {
11676 SU_DEBUG_1(("%s: %u response To tag does not agree with dialog tag\n",
11677 __func__, resp->sip_status->st_status));
11678 return NULL;
11679 }
11680
11681 to = resp->sip_to;
11682 rack = rack0;
11683
11684 rack->ra_response = resp->sip_rseq->rs_response;
11685 rack->ra_cseq = resp->sip_cseq->cs_seq;
11686 rack->ra_method = resp->sip_cseq->cs_method;
11687 rack->ra_method_name = resp->sip_cseq->cs_method_name;
11688 }
11689
11690 msg = nta_msg_create(leg->leg_agent, 0);
11691 sip = sip_object(msg); home = msg_home(msg);
11692
11693 if (!sip)
11694 return NULL;
11695
11696 if (!leg->leg_route && resp) {
11697 /* Insert contact into route */
11698 if (resp->sip_contact) {
11699 sip_route_init(r0)->r_url[0] = resp->sip_contact->m_url[0];
11700 route = sip_route_dup(home, r0);
11701 }
11702
11703 /* Reverse record route */
11704 if (resp->sip_record_route) {
11705 sip_route_t *r, *r_next;
11706 for (r = sip_route_dup(home, resp->sip_record_route); r; r = r_next) {
11707 r_next = r->r_next, r->r_next = route, route = r;
11708 }
11709 }
11710 }
11711
11712 ta_start(ta, tag, value);
11713
11714 if (!resp) {
11715 tagi_t const *t;
11716
11717 if ((t = tl_find(ta_args(ta), ntatag_rseq)) && t->t_value) {
11718 rack = rack0;
11719 rack->ra_response = (uint32_t)t->t_value;
11720 }
11721
11722 if (rack) {
11723 rack->ra_cseq = oorq->orq_cseq->cs_seq;
11724 rack->ra_method = oorq->orq_cseq->cs_method;
11725 rack->ra_method_name = oorq->orq_cseq->cs_method_name;
11726 }
11727 }
11728
11729 if (sip_add_tl(msg, sip,
11730 TAG_IF(rack, SIPTAG_RACK(rack)),
11731 TAG_IF(to, SIPTAG_TO(to)),
11732 ta_tags(ta)) < 0)
11733 ;
11734 else if (route && sip_add_dup(msg, sip, (sip_header_t *)route) < 0)
11735 ;
11736 else if (!sip->sip_rack)
11737 SU_DEBUG_1(("%s: RAck header missing\n", __func__));
11738 else if (nta_msg_request_complete(msg, leg,
11739 SIP_METHOD_PRACK,
11740 (url_string_t *)oorq->orq_url) < 0)
11741 ;
11742 else
11743 orq = outgoing_create(leg->leg_agent, callback, magic,
11744 route_url, NULL, msg, ta_tags(ta));
11745
11746 ta_end(ta);
11747
11748 if (!orq)
11749 msg_destroy(msg);
11750 else if (rack)
11751 oorq->orq_rseq = rack->ra_response;
11752 else if (sip->sip_rack)
11753 oorq->orq_rseq = sip->sip_rack->ra_response;
11754
11755 return orq;
11756 }
11757
11758 /** Get @RSeq value stored with client transaction. */
nta_outgoing_rseq(nta_outgoing_t const * orq)11759 uint32_t nta_outgoing_rseq(nta_outgoing_t const *orq)
11760 {
11761 return orq ? orq->orq_rseq : 0;
11762 }
11763
11764 /** Set @RSeq value stored with client transaction.
11765 *
11766 * @return 0 if rseq was set successfully
11767 * @return -1 if rseq is invalid or orq is NULL.
11768 */
nta_outgoing_setrseq(nta_outgoing_t * orq,uint32_t rseq)11769 int nta_outgoing_setrseq(nta_outgoing_t *orq, uint32_t rseq)
11770 {
11771 if (orq && orq->orq_rseq <= rseq) {
11772 orq->orq_rseq = rseq;
11773 return 0;
11774 }
11775
11776 return -1;
11777 }
11778
11779 /* ------------------------------------------------------------------------ */
11780 /* 11) SigComp handling and public transport interface */
11781
11782 #include <sofia-sip/nta_tport.h>
11783
11784 /** Return the master transport for the agent.
11785 *
11786 * @NEW_1_12_11
11787 */
11788 tport_t *
nta_agent_tports(nta_agent_t * agent)11789 nta_agent_tports(nta_agent_t *agent)
11790 {
11791 return agent ? agent->sa_tports : NULL;
11792 }
11793
11794 su_inline tport_t *
nta_transport_(nta_agent_t * agent,nta_incoming_t * irq,msg_t * msg)11795 nta_transport_(nta_agent_t *agent,
11796 nta_incoming_t *irq,
11797 msg_t *msg)
11798 {
11799 if (irq)
11800 return irq->irq_tport;
11801 else if (agent && msg)
11802 return tport_delivered_by(agent->sa_tports, msg);
11803
11804 errno = EINVAL;
11805 return NULL;
11806 }
11807
11808
11809 /** Return a new reference to the transaction transport.
11810 *
11811 * @note The referenced transport must be unreferenced with tport_unref()
11812 */
11813 tport_t *
nta_incoming_transport(nta_agent_t * agent,nta_incoming_t * irq,msg_t * msg)11814 nta_incoming_transport(nta_agent_t *agent,
11815 nta_incoming_t *irq,
11816 msg_t *msg)
11817 {
11818 return tport_ref(nta_transport_(agent, irq, msg));
11819 }
11820
nta_agent_init_sigcomp(nta_agent_t * sa)11821 nta_compressor_t *nta_agent_init_sigcomp(nta_agent_t *sa)
11822 {
11823 if (!nta_compressor_vtable || !sa)
11824 return NULL;
11825
11826 if (sa->sa_compressor == NULL) {
11827 char const * const *l = sa->sa_sigcomp_option_list;
11828 nta_compressor_t *comp;
11829 comp = nta_compressor_vtable->ncv_init_agent(sa, l);
11830 sa->sa_compressor = comp;
11831 }
11832
11833 return sa->sa_compressor;
11834 }
11835
nta_agent_deinit_sigcomp(nta_agent_t * sa)11836 void nta_agent_deinit_sigcomp(nta_agent_t *sa)
11837 {
11838 if (nta_compressor_vtable && sa && sa->sa_compressor) {
11839 nta_compressor_vtable->ncv_deinit_agent(sa, sa->sa_compressor);
11840 sa->sa_compressor = NULL;
11841 }
11842 }
11843
11844 struct sigcomp_compartment *
nta_incoming_compartment(nta_incoming_t * irq)11845 nta_incoming_compartment(nta_incoming_t *irq)
11846 {
11847 if (nta_compressor_vtable && irq && irq->irq_cc)
11848 return nta_compressor_vtable->ncv_compartment_ref(irq->irq_cc);
11849 else
11850 return NULL;
11851 }
11852
11853 tport_t *
nta_outgoing_transport(nta_outgoing_t * orq)11854 nta_outgoing_transport(nta_outgoing_t *orq)
11855 {
11856 if (orq)
11857 return tport_ref(orq->orq_tport);
11858 else
11859 return NULL;
11860 }
11861
11862
11863 struct sigcomp_compartment *
nta_outgoing_compartment(nta_outgoing_t * orq)11864 nta_outgoing_compartment(nta_outgoing_t *orq)
11865 {
11866 if (nta_compressor_vtable && orq && orq->orq_cc)
11867 return nta_compressor_vtable->ncv_compartment_ref(orq->orq_cc);
11868 else
11869 return NULL;
11870 }
11871
11872
11873 struct sigcomp_compartment *
nta_compartment_ref(struct sigcomp_compartment * cc)11874 nta_compartment_ref(struct sigcomp_compartment *cc)
11875 {
11876 if (nta_compressor_vtable)
11877 return nta_compressor_vtable->ncv_compartment_ref(cc);
11878 else
11879 return NULL;
11880 }
11881
11882 void
nta_compartment_decref(struct sigcomp_compartment ** pcc)11883 nta_compartment_decref(struct sigcomp_compartment **pcc)
11884 {
11885 if (nta_compressor_vtable && pcc && *pcc)
11886 nta_compressor_vtable->ncv_compartment_unref(*pcc), *pcc = NULL;
11887 }
11888
11889
11890 /** Get compartment for connection, create it when needed. */
11891 static
11892 struct sigcomp_compartment *
agent_compression_compartment(nta_agent_t * sa,tport_t * tp,tp_name_t const * tpn,int new_if_needed)11893 agent_compression_compartment(nta_agent_t *sa,
11894 tport_t *tp,
11895 tp_name_t const *tpn,
11896 int new_if_needed)
11897 {
11898 if (nta_compressor_vtable) {
11899 char const * const *l = sa->sa_sigcomp_option_list;
11900 return nta_compressor_vtable->
11901 ncv_compartment(sa, tp, sa->sa_compressor, tpn, l, new_if_needed);
11902 }
11903 else
11904 return NULL;
11905 }
11906
11907 static
agent_accept_compressed(nta_agent_t * sa,msg_t * msg,struct sigcomp_compartment * cc)11908 int agent_accept_compressed(nta_agent_t *sa, msg_t *msg,
11909 struct sigcomp_compartment *cc)
11910 {
11911 if (nta_compressor_vtable) {
11912 nta_compressor_t *msc = sa->sa_compressor;
11913 tport_compressor_t *sc = NULL;
11914 if (tport_delivered_with_comp(sa->sa_tports, msg, &sc) < 0)
11915 return 0;
11916 return nta_compressor_vtable->ncv_accept_compressed(sa, msc, sc, msg, cc);
11917 }
11918 else
11919 return 0;
11920 }
11921
11922 /** Close compressor (lose its state). */
11923 static
agent_close_compressor(nta_agent_t * sa,struct sigcomp_compartment * cc)11924 int agent_close_compressor(nta_agent_t *sa,
11925 struct sigcomp_compartment *cc)
11926 {
11927 if (nta_compressor_vtable)
11928 return nta_compressor_vtable->ncv_close_compressor(sa, cc);
11929 return 0;
11930 }
11931
11932 /** Close both compressor and decompressor */
11933 static
agent_zap_compressor(nta_agent_t * sa,struct sigcomp_compartment * cc)11934 int agent_zap_compressor(nta_agent_t *sa,
11935 struct sigcomp_compartment *cc)
11936 {
11937 if (nta_compressor_vtable)
11938 return nta_compressor_vtable->ncv_zap_compressor(sa, cc);
11939 return 0;
11940 }
11941
11942 /** Bind transport update callback */
nta_agent_bind_tport_update(nta_agent_t * agent,nta_update_magic_t * magic,nta_update_tport_f * callback)11943 int nta_agent_bind_tport_update(nta_agent_t *agent,
11944 nta_update_magic_t *magic,
11945 nta_update_tport_f *callback)
11946 {
11947 if (!agent)
11948 return su_seterrno(EFAULT), -1;
11949 agent->sa_update_magic = magic;
11950 agent->sa_update_tport = callback;
11951 return 0;
11952 }
11953
11954 /** Bind transport error callback */
nta_agent_bind_tport_error(nta_agent_t * agent,nta_error_magic_t * magic,nta_error_tport_f * callback)11955 int nta_agent_bind_tport_error(nta_agent_t *agent,
11956 nta_error_magic_t *magic,
11957 nta_error_tport_f *callback)
11958 {
11959 if (!agent)
11960 return su_seterrno(EFAULT), -1;
11961 agent->sa_error_magic = magic;
11962 agent->sa_error_tport = callback;
11963 return 0;
11964 }
11965
11966 /** Check if public transport binding is in progress */
nta_agent_tport_is_updating(nta_agent_t * agent)11967 int nta_agent_tport_is_updating(nta_agent_t *agent)
11968 {
11969 return agent && tport_is_updating(agent->sa_tports);
11970 }
11971
11972 /** Initiate STUN keepalive controller to TPORT */
nta_tport_keepalive(nta_outgoing_t * orq)11973 int nta_tport_keepalive(nta_outgoing_t *orq)
11974 {
11975 assert(orq);
11976
11977 #if HAVE_SOFIA_STUN
11978 return tport_keepalive(orq->orq_tport, msg_addrinfo(orq->orq_request),
11979 TAG_END());
11980 #else
11981 return -1;
11982 #endif
11983 }
11984
11985 /** Close all transports. @since Experimental in @VERSION_1_12_2. */
nta_agent_close_tports(nta_agent_t * agent)11986 int nta_agent_close_tports(nta_agent_t *agent)
11987 {
11988 size_t i;
11989 outgoing_htable_t *oht = agent->sa_outgoing;
11990 incoming_htable_t *iht = agent->sa_incoming;
11991
11992 for (i = oht->oht_size; i-- > 0;)
11993 /* while */ if (oht->oht_table[i]) {
11994 nta_outgoing_t *orq = oht->oht_table[i];
11995
11996 if (orq->orq_pending && orq->orq_tport)
11997 tport_release(orq->orq_tport, orq->orq_pending, orq->orq_request,
11998 NULL, orq, 0);
11999
12000 orq->orq_pending = 0;
12001 tport_unref(orq->orq_tport), orq->orq_tport = NULL;
12002 }
12003
12004
12005 for (i = iht->iht_size; i-- > 0;)
12006 /* while */ if (iht->iht_table[i]) {
12007 nta_incoming_t *irq = iht->iht_table[i];
12008 tport_unref(irq->irq_tport), irq->irq_tport = NULL;
12009 }
12010
12011 tport_destroy(agent->sa_tports), agent->sa_tports = NULL;
12012
12013 msg_header_free(agent->sa_home, (void *)agent->sa_vias);
12014 agent->sa_vias = NULL;
12015 msg_header_free(agent->sa_home, (void *)agent->sa_public_vias);
12016 agent->sa_public_vias = NULL;
12017
12018 return 0;
12019 }
12020