1 /* $Id$ */
2 /*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include <pjsip/sip_util.h>
21 #include <pjsip/sip_transport.h>
22 #include <pjsip/sip_msg.h>
23 #include <pjsip/sip_endpoint.h>
24 #include <pjsip/sip_event.h>
25 #include <pjsip/sip_transaction.h>
26 #include <pjsip/sip_module.h>
27 #include <pjsip/sip_errno.h>
28 #include <pj/log.h>
29 #include <pj/string.h>
30 #include <pj/guid.h>
31 #include <pj/pool.h>
32 #include <pj/except.h>
33 #include <pj/rand.h>
34 #include <pj/assert.h>
35 #include <pj/errno.h>
36
37 #define THIS_FILE "endpoint"
38
39 static const char *event_str[] =
40 {
41 "UNIDENTIFIED",
42 "TIMER",
43 "TX_MSG",
44 "RX_MSG",
45 "TRANSPORT_ERROR",
46 "TSX_STATE",
47 "USER",
48 };
49
50 static pj_str_t str_TEXT = { "text", 4},
51 str_PLAIN = { "plain", 5 };
52
53 /* Add URI to target-set */
pjsip_target_set_add_uri(pjsip_target_set * tset,pj_pool_t * pool,const pjsip_uri * uri,int q1000)54 PJ_DEF(pj_status_t) pjsip_target_set_add_uri( pjsip_target_set *tset,
55 pj_pool_t *pool,
56 const pjsip_uri *uri,
57 int q1000)
58 {
59 pjsip_target *t, *pos = NULL;
60
61 PJ_ASSERT_RETURN(tset && pool && uri, PJ_EINVAL);
62
63 /* Set q-value to 1 if it is not set */
64 if (q1000 <= 0)
65 q1000 = 1000;
66
67 /* Scan all the elements to see for duplicates, and at the same time
68 * get the position where the new element should be inserted to
69 * based on the q-value.
70 */
71 t = tset->head.next;
72 while (t != &tset->head) {
73 if (pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, t->uri, uri)==PJ_SUCCESS)
74 return PJ_EEXISTS;
75 if (pos==NULL && t->q1000 < q1000)
76 pos = t;
77 t = t->next;
78 }
79
80 /* Create new element */
81 t = PJ_POOL_ZALLOC_T(pool, pjsip_target);
82 t->uri = (pjsip_uri*)pjsip_uri_clone(pool, uri);
83 t->q1000 = q1000;
84
85 /* Insert */
86 if (pos == NULL)
87 pj_list_push_back(&tset->head, t);
88 else
89 pj_list_insert_before(pos, t);
90
91 /* Set current target if this is the first URI */
92 if (tset->current == NULL)
93 tset->current = t;
94
95 return PJ_SUCCESS;
96 }
97
98 /* Add URI's in the Contact header in the message to target-set */
pjsip_target_set_add_from_msg(pjsip_target_set * tset,pj_pool_t * pool,const pjsip_msg * msg)99 PJ_DEF(pj_status_t) pjsip_target_set_add_from_msg( pjsip_target_set *tset,
100 pj_pool_t *pool,
101 const pjsip_msg *msg)
102 {
103 const pjsip_hdr *hdr;
104 unsigned added = 0;
105
106 PJ_ASSERT_RETURN(tset && pool && msg, PJ_EINVAL);
107
108 /* Scan for Contact headers and add the URI */
109 hdr = msg->hdr.next;
110 while (hdr != &msg->hdr) {
111 if (hdr->type == PJSIP_H_CONTACT) {
112 const pjsip_contact_hdr *cn_hdr = (const pjsip_contact_hdr*)hdr;
113
114 if (!cn_hdr->star) {
115 pj_status_t rc;
116 rc = pjsip_target_set_add_uri(tset, pool, cn_hdr->uri,
117 cn_hdr->q1000);
118 if (rc == PJ_SUCCESS)
119 ++added;
120 }
121 }
122 hdr = hdr->next;
123 }
124
125 return added ? PJ_SUCCESS : PJ_EEXISTS;
126 }
127
128
129 /* Get next target, if any */
pjsip_target_set_get_next(const pjsip_target_set * tset)130 PJ_DEF(pjsip_target*) pjsip_target_set_get_next(const pjsip_target_set *tset)
131 {
132 const pjsip_target *t, *next = NULL;
133
134 t = tset->head.next;
135 while (t != &tset->head) {
136 if (PJSIP_IS_STATUS_IN_CLASS(t->code, 200)) {
137 /* No more target since one target has been successful */
138 return NULL;
139 }
140 if (PJSIP_IS_STATUS_IN_CLASS(t->code, 600)) {
141 /* No more target since one target returned global error */
142 return NULL;
143 }
144 if (t->code==0 && next==NULL) {
145 /* This would be the next target as long as we don't find
146 * targets with 2xx or 6xx status after this.
147 */
148 next = t;
149 }
150 t = t->next;
151 }
152
153 return (pjsip_target*)next;
154 }
155
156
157 /* Set current target */
pjsip_target_set_set_current(pjsip_target_set * tset,pjsip_target * target)158 PJ_DEF(pj_status_t) pjsip_target_set_set_current( pjsip_target_set *tset,
159 pjsip_target *target)
160 {
161 PJ_ASSERT_RETURN(tset && target, PJ_EINVAL);
162 PJ_ASSERT_RETURN(pj_list_find_node(tset, target) != NULL, PJ_ENOTFOUND);
163
164 tset->current = target;
165
166 return PJ_SUCCESS;
167 }
168
169
170 /* Assign status to a target */
pjsip_target_assign_status(pjsip_target * target,pj_pool_t * pool,int status_code,const pj_str_t * reason)171 PJ_DEF(pj_status_t) pjsip_target_assign_status( pjsip_target *target,
172 pj_pool_t *pool,
173 int status_code,
174 const pj_str_t *reason)
175 {
176 PJ_ASSERT_RETURN(target && pool && status_code && reason, PJ_EINVAL);
177
178 target->code = (pjsip_status_code)status_code;
179 pj_strdup(pool, &target->reason, reason);
180
181 return PJ_SUCCESS;
182 }
183
184
185
186 /*
187 * Initialize transmit data (msg) with the headers and optional body.
188 * This will just put the headers in the message as it is. Be carefull
189 * when calling this function because once a header is put in a message,
190 * it CAN NOT be put in other message until the first message is deleted,
191 * because the way the header is put in the list.
192 * That's why the session will shallow_clone it's headers before calling
193 * this function.
194 */
init_request_throw(pjsip_endpoint * endpt,pjsip_tx_data * tdata,pjsip_method * method,pjsip_uri * param_target,pjsip_from_hdr * param_from,pjsip_to_hdr * param_to,pjsip_contact_hdr * param_contact,pjsip_cid_hdr * param_call_id,pjsip_cseq_hdr * param_cseq,const pj_str_t * param_text)195 static void init_request_throw( pjsip_endpoint *endpt,
196 pjsip_tx_data *tdata,
197 pjsip_method *method,
198 pjsip_uri *param_target,
199 pjsip_from_hdr *param_from,
200 pjsip_to_hdr *param_to,
201 pjsip_contact_hdr *param_contact,
202 pjsip_cid_hdr *param_call_id,
203 pjsip_cseq_hdr *param_cseq,
204 const pj_str_t *param_text)
205 {
206 pjsip_msg *msg;
207 pjsip_msg_body *body;
208 pjsip_via_hdr *via;
209 const pjsip_hdr *endpt_hdr;
210
211 /* Create the message. */
212 msg = tdata->msg = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG);
213
214 /* Init request URI. */
215 pj_memcpy(&msg->line.req.method, method, sizeof(*method));
216 msg->line.req.uri = param_target;
217
218 /* Add additional request headers from endpoint. */
219 endpt_hdr = pjsip_endpt_get_request_headers(endpt)->next;
220 while (endpt_hdr != pjsip_endpt_get_request_headers(endpt)) {
221 pjsip_hdr *hdr = (pjsip_hdr*)
222 pjsip_hdr_shallow_clone(tdata->pool, endpt_hdr);
223 pjsip_msg_add_hdr( tdata->msg, hdr );
224 endpt_hdr = endpt_hdr->next;
225 }
226
227 /* Add From header. */
228 if (param_from->tag.slen == 0)
229 pj_create_unique_string(tdata->pool, ¶m_from->tag);
230 pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_from);
231
232 /* Add To header. */
233 pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_to);
234
235 /* Add Contact header. */
236 if (param_contact) {
237 pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_contact);
238 }
239
240 /* Add Call-ID header. */
241 pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_call_id);
242
243 /* Add CSeq header. */
244 pjsip_msg_add_hdr(msg, (pjsip_hdr*)param_cseq);
245
246 /* Add a blank Via header in the front of the message. */
247 via = pjsip_via_hdr_create(tdata->pool);
248 via->rport_param = pjsip_cfg()->endpt.disable_rport ? -1 : 0;
249 pjsip_msg_insert_first_hdr(msg, (pjsip_hdr*)via);
250
251 /* Add header params as request headers */
252 if (PJSIP_URI_SCHEME_IS_SIP(param_target) ||
253 PJSIP_URI_SCHEME_IS_SIPS(param_target))
254 {
255 pjsip_sip_uri *uri = (pjsip_sip_uri*) pjsip_uri_get_uri(param_target);
256 pjsip_param *hparam;
257
258 hparam = uri->header_param.next;
259 while (hparam != &uri->header_param) {
260 pjsip_generic_string_hdr *hdr;
261
262 hdr = pjsip_generic_string_hdr_create(tdata->pool,
263 &hparam->name,
264 &hparam->value);
265 pjsip_msg_add_hdr(msg, (pjsip_hdr*)hdr);
266 hparam = hparam->next;
267 }
268 }
269
270 /* Create message body. */
271 if (param_text) {
272 body = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_msg_body);
273 body->content_type.type = str_TEXT;
274 body->content_type.subtype = str_PLAIN;
275 body->data = pj_pool_alloc(tdata->pool, param_text->slen );
276 pj_memcpy(body->data, param_text->ptr, param_text->slen);
277 body->len = (unsigned)param_text->slen;
278 body->print_body = &pjsip_print_text_body;
279 msg->body = body;
280 }
281
282 PJ_LOG(5,(THIS_FILE, "%s created.",
283 pjsip_tx_data_get_info(tdata)));
284
285 }
286
287 /*
288 * Create arbitrary request.
289 */
pjsip_endpt_create_request(pjsip_endpoint * endpt,const pjsip_method * method,const pj_str_t * param_target,const pj_str_t * param_from,const pj_str_t * param_to,const pj_str_t * param_contact,const pj_str_t * param_call_id,int param_cseq,const pj_str_t * param_text,pjsip_tx_data ** p_tdata)290 PJ_DEF(pj_status_t) pjsip_endpt_create_request( pjsip_endpoint *endpt,
291 const pjsip_method *method,
292 const pj_str_t *param_target,
293 const pj_str_t *param_from,
294 const pj_str_t *param_to,
295 const pj_str_t *param_contact,
296 const pj_str_t *param_call_id,
297 int param_cseq,
298 const pj_str_t *param_text,
299 pjsip_tx_data **p_tdata)
300 {
301 pjsip_uri *target;
302 pjsip_tx_data *tdata;
303 pjsip_from_hdr *from;
304 pjsip_to_hdr *to;
305 pjsip_contact_hdr *contact;
306 pjsip_cseq_hdr *cseq = NULL; /* = NULL, warning in VC6 */
307 pjsip_cid_hdr *call_id;
308 pj_str_t tmp;
309 pj_status_t status;
310 const pj_str_t STR_CONTACT = { "Contact", 7 };
311 PJ_USE_EXCEPTION;
312
313 status = pjsip_endpt_create_tdata(endpt, &tdata);
314 if (status != PJ_SUCCESS)
315 return status;
316
317 /* Init reference counter to 1. */
318 pjsip_tx_data_add_ref(tdata);
319
320 PJ_TRY {
321 /* Request target. */
322 pj_strdup_with_null(tdata->pool, &tmp, param_target);
323 target = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 0);
324 if (target == NULL) {
325 status = PJSIP_EINVALIDREQURI;
326 goto on_error;
327 }
328
329 /* From */
330 from = pjsip_from_hdr_create(tdata->pool);
331 pj_strdup_with_null(tdata->pool, &tmp, param_from);
332 from->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen,
333 PJSIP_PARSE_URI_AS_NAMEADDR);
334 if (from->uri == NULL) {
335 status = PJSIP_EINVALIDHDR;
336 goto on_error;
337 }
338 pj_create_unique_string(tdata->pool, &from->tag);
339
340 /* To */
341 to = pjsip_to_hdr_create(tdata->pool);
342 pj_strdup_with_null(tdata->pool, &tmp, param_to);
343 to->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen,
344 PJSIP_PARSE_URI_AS_NAMEADDR);
345 if (to->uri == NULL) {
346 status = PJSIP_EINVALIDHDR;
347 goto on_error;
348 }
349
350 /* Contact. */
351 if (param_contact) {
352 pj_strdup_with_null(tdata->pool, &tmp, param_contact);
353 contact = (pjsip_contact_hdr*)
354 pjsip_parse_hdr(tdata->pool, &STR_CONTACT, tmp.ptr,
355 tmp.slen, NULL);
356 if (contact == NULL) {
357 status = PJSIP_EINVALIDHDR;
358 goto on_error;
359 }
360 } else {
361 contact = NULL;
362 }
363
364 /* Call-ID */
365 call_id = pjsip_cid_hdr_create(tdata->pool);
366 if (param_call_id != NULL && param_call_id->slen)
367 pj_strdup(tdata->pool, &call_id->id, param_call_id);
368 else
369 pj_create_unique_string(tdata->pool, &call_id->id);
370
371 /* CSeq */
372 cseq = pjsip_cseq_hdr_create(tdata->pool);
373 if (param_cseq >= 0)
374 cseq->cseq = param_cseq;
375 else
376 cseq->cseq = pj_rand() & 0xFFFF;
377
378 /* Method */
379 pjsip_method_copy(tdata->pool, &cseq->method, method);
380
381 /* Create the request. */
382 init_request_throw( endpt, tdata, &cseq->method, target, from, to,
383 contact, call_id, cseq, param_text);
384 }
385 PJ_CATCH_ANY {
386 status = PJ_ENOMEM;
387 goto on_error;
388 }
389 PJ_END
390
391 *p_tdata = tdata;
392 return PJ_SUCCESS;
393
394 on_error:
395 pjsip_tx_data_dec_ref(tdata);
396 return status;
397 }
398
pjsip_endpt_create_request_from_hdr(pjsip_endpoint * endpt,const pjsip_method * method,const pjsip_uri * param_target,const pjsip_from_hdr * param_from,const pjsip_to_hdr * param_to,const pjsip_contact_hdr * param_contact,const pjsip_cid_hdr * param_call_id,int param_cseq,const pj_str_t * param_text,pjsip_tx_data ** p_tdata)399 PJ_DEF(pj_status_t) pjsip_endpt_create_request_from_hdr( pjsip_endpoint *endpt,
400 const pjsip_method *method,
401 const pjsip_uri *param_target,
402 const pjsip_from_hdr *param_from,
403 const pjsip_to_hdr *param_to,
404 const pjsip_contact_hdr *param_contact,
405 const pjsip_cid_hdr *param_call_id,
406 int param_cseq,
407 const pj_str_t *param_text,
408 pjsip_tx_data **p_tdata)
409 {
410 pjsip_uri *target;
411 pjsip_tx_data *tdata;
412 pjsip_from_hdr *from;
413 pjsip_to_hdr *to;
414 pjsip_contact_hdr *contact;
415 pjsip_cid_hdr *call_id;
416 pjsip_cseq_hdr *cseq = NULL; /* The NULL because warning in VC6 */
417 pj_status_t status;
418 PJ_USE_EXCEPTION;
419
420 /* Check arguments. */
421 PJ_ASSERT_RETURN(endpt && method && param_target && param_from &&
422 param_to && p_tdata, PJ_EINVAL);
423
424 /* Create new transmit data. */
425 status = pjsip_endpt_create_tdata(endpt, &tdata);
426 if (status != PJ_SUCCESS)
427 return status;
428
429 /* Set initial reference counter to 1. */
430 pjsip_tx_data_add_ref(tdata);
431
432 PJ_TRY {
433 /* Duplicate target URI and headers. */
434 target = (pjsip_uri*) pjsip_uri_clone(tdata->pool, param_target);
435 from = (pjsip_from_hdr*) pjsip_hdr_clone(tdata->pool, param_from);
436 pjsip_fromto_hdr_set_from(from);
437 to = (pjsip_to_hdr*) pjsip_hdr_clone(tdata->pool, param_to);
438 pjsip_fromto_hdr_set_to(to);
439 if (param_contact) {
440 contact = (pjsip_contact_hdr*)
441 pjsip_hdr_clone(tdata->pool, param_contact);
442 } else {
443 contact = NULL;
444 }
445 call_id = pjsip_cid_hdr_create(tdata->pool);
446 if (param_call_id != NULL && param_call_id->id.slen)
447 pj_strdup(tdata->pool, &call_id->id, ¶m_call_id->id);
448 else
449 pj_create_unique_string(tdata->pool, &call_id->id);
450
451 cseq = pjsip_cseq_hdr_create(tdata->pool);
452 if (param_cseq >= 0)
453 cseq->cseq = param_cseq;
454 else
455 cseq->cseq = pj_rand() % 0xFFFF;
456 pjsip_method_copy(tdata->pool, &cseq->method, method);
457
458 /* Copy headers to the request. */
459 init_request_throw(endpt, tdata, &cseq->method, target, from, to,
460 contact, call_id, cseq, param_text);
461 }
462 PJ_CATCH_ANY {
463 status = PJ_ENOMEM;
464 goto on_error;
465 }
466 PJ_END;
467
468 *p_tdata = tdata;
469 return PJ_SUCCESS;
470
471 on_error:
472 pjsip_tx_data_dec_ref(tdata);
473 return status;
474 }
475
476 /*
477 * Construct a minimal response message for the received request.
478 */
pjsip_endpt_create_response(pjsip_endpoint * endpt,const pjsip_rx_data * rdata,int st_code,const pj_str_t * st_text,pjsip_tx_data ** p_tdata)479 PJ_DEF(pj_status_t) pjsip_endpt_create_response( pjsip_endpoint *endpt,
480 const pjsip_rx_data *rdata,
481 int st_code,
482 const pj_str_t *st_text,
483 pjsip_tx_data **p_tdata)
484 {
485 pjsip_tx_data *tdata;
486 pjsip_msg *msg, *req_msg;
487 pjsip_hdr *hdr;
488 pjsip_to_hdr *to_hdr;
489 pjsip_via_hdr *top_via = NULL, *via;
490 pjsip_rr_hdr *rr;
491 pj_status_t status;
492
493 /* Check arguments. */
494 PJ_ASSERT_RETURN(endpt && rdata && p_tdata, PJ_EINVAL);
495
496 /* Check status code. */
497 PJ_ASSERT_RETURN(st_code >= 100 && st_code <= 699, PJ_EINVAL);
498
499 /* rdata must be a request message. */
500 req_msg = rdata->msg_info.msg;
501 pj_assert(req_msg->type == PJSIP_REQUEST_MSG);
502
503 /* Request MUST NOT be ACK request! */
504 PJ_ASSERT_RETURN(req_msg->line.req.method.id != PJSIP_ACK_METHOD,
505 PJ_EINVALIDOP);
506
507 /* Create a new transmit buffer. */
508 status = pjsip_endpt_create_tdata( endpt, &tdata);
509 if (status != PJ_SUCCESS)
510 return status;
511
512 /* Set initial reference count to 1. */
513 pjsip_tx_data_add_ref(tdata);
514
515 /* Create new response message. */
516 tdata->msg = msg = pjsip_msg_create(tdata->pool, PJSIP_RESPONSE_MSG);
517
518 /* Set status code and reason text. */
519 msg->line.status.code = st_code;
520 if (st_text)
521 pj_strdup(tdata->pool, &msg->line.status.reason, st_text);
522 else
523 msg->line.status.reason = *pjsip_get_status_text(st_code);
524
525 /* Set TX data attributes. */
526 tdata->rx_timestamp = rdata->pkt_info.timestamp;
527
528 /* Copy all the via headers, in order. */
529 via = rdata->msg_info.via;
530 while (via) {
531 pjsip_via_hdr *new_via;
532
533 new_via = (pjsip_via_hdr*)pjsip_hdr_clone(tdata->pool, via);
534 if (top_via == NULL)
535 top_via = new_via;
536
537 pjsip_msg_add_hdr( msg, (pjsip_hdr*)new_via);
538 via = via->next;
539 if (via != (void*)&req_msg->hdr)
540 via = (pjsip_via_hdr*)
541 pjsip_msg_find_hdr(req_msg, PJSIP_H_VIA, via);
542 else
543 break;
544 }
545
546 /* Copy all Record-Route headers, in order. */
547 rr = (pjsip_rr_hdr*)
548 pjsip_msg_find_hdr(req_msg, PJSIP_H_RECORD_ROUTE, NULL);
549 while (rr) {
550 pjsip_msg_add_hdr(msg, (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, rr));
551 rr = rr->next;
552 if (rr != (void*)&req_msg->hdr)
553 rr = (pjsip_rr_hdr*) pjsip_msg_find_hdr(req_msg,
554 PJSIP_H_RECORD_ROUTE, rr);
555 else
556 break;
557 }
558
559 /* Copy Call-ID header. */
560 hdr = (pjsip_hdr*) pjsip_msg_find_hdr( req_msg, PJSIP_H_CALL_ID, NULL);
561 pjsip_msg_add_hdr(msg, (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr));
562
563 /* Copy From header. */
564 hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, rdata->msg_info.from);
565 pjsip_msg_add_hdr( msg, hdr);
566
567 /* Copy To header. */
568 to_hdr = (pjsip_to_hdr*) pjsip_hdr_clone(tdata->pool, rdata->msg_info.to);
569 pjsip_msg_add_hdr( msg, (pjsip_hdr*)to_hdr);
570
571 /* Must add To tag in the response (Section 8.2.6.2), except if this is
572 * 100 (Trying) response. Same tag must be created for the same request
573 * (e.g. same tag in provisional and final response). The easiest way
574 * to do this is to derive the tag from Via branch parameter (or to
575 * use it directly).
576 */
577 if (to_hdr->tag.slen==0 && st_code > 100 && top_via) {
578 to_hdr->tag = top_via->branch_param;
579 }
580
581 /* Copy CSeq header. */
582 hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, rdata->msg_info.cseq);
583 pjsip_msg_add_hdr( msg, hdr);
584
585 /* All done. */
586 *p_tdata = tdata;
587
588 PJ_LOG(5,(THIS_FILE, "%s created", pjsip_tx_data_get_info(tdata)));
589 return PJ_SUCCESS;
590 }
591
592
593 /*
594 * Construct ACK for 3xx-6xx final response (according to chapter 17.1.1 of
595 * RFC3261). Note that the generation of ACK for 2xx response is different,
596 * and one must not use this function to generate such ACK.
597 */
pjsip_endpt_create_ack(pjsip_endpoint * endpt,const pjsip_tx_data * tdata,const pjsip_rx_data * rdata,pjsip_tx_data ** ack_tdata)598 PJ_DEF(pj_status_t) pjsip_endpt_create_ack( pjsip_endpoint *endpt,
599 const pjsip_tx_data *tdata,
600 const pjsip_rx_data *rdata,
601 pjsip_tx_data **ack_tdata)
602 {
603 pjsip_tx_data *ack = NULL;
604 const pjsip_msg *invite_msg;
605 const pjsip_from_hdr *from_hdr;
606 const pjsip_to_hdr *to_hdr;
607 const pjsip_cid_hdr *cid_hdr;
608 const pjsip_cseq_hdr *cseq_hdr;
609 const pjsip_hdr *hdr;
610 pjsip_hdr *via;
611 pjsip_to_hdr *to;
612 pj_status_t status;
613
614 /* rdata must be a non-2xx final response. */
615 pj_assert(rdata->msg_info.msg->type==PJSIP_RESPONSE_MSG &&
616 rdata->msg_info.msg->line.status.code >= 300);
617
618 /* Initialize return value to NULL. */
619 *ack_tdata = NULL;
620
621 /* The original INVITE message. */
622 invite_msg = tdata->msg;
623
624 /* Get the headers from original INVITE request. */
625 # define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL)
626
627 from_hdr = (const pjsip_from_hdr*) FIND_HDR(invite_msg, FROM);
628 PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr);
629
630 to_hdr = (const pjsip_to_hdr*) FIND_HDR(invite_msg, TO);
631 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);
632
633 cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(invite_msg, CALL_ID);
634 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);
635
636 cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(invite_msg, CSEQ);
637 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);
638
639 # undef FIND_HDR
640
641 /* Create new request message from the headers. */
642 status = pjsip_endpt_create_request_from_hdr(endpt,
643 pjsip_get_ack_method(),
644 tdata->msg->line.req.uri,
645 from_hdr, to_hdr,
646 NULL, cid_hdr,
647 cseq_hdr->cseq, NULL,
648 &ack);
649
650 if (status != PJ_SUCCESS)
651 return status;
652
653 /* Update tag in To header with the one from the response (if any). */
654 to = (pjsip_to_hdr*) pjsip_msg_find_hdr(ack->msg, PJSIP_H_TO, NULL);
655 pj_strdup(ack->pool, &to->tag, &rdata->msg_info.to->tag);
656
657
658 /* Clear Via headers in the new request. */
659 while ((via=(pjsip_hdr*)pjsip_msg_find_hdr(ack->msg, PJSIP_H_VIA, NULL)) != NULL)
660 pj_list_erase(via);
661
662 /* Must contain single Via, just as the original INVITE. */
663 hdr = (pjsip_hdr*) pjsip_msg_find_hdr( invite_msg, PJSIP_H_VIA, NULL);
664 pjsip_msg_insert_first_hdr( ack->msg,
665 (pjsip_hdr*) pjsip_hdr_clone(ack->pool,hdr) );
666
667 /* If the original INVITE has Route headers, those header fields MUST
668 * appear in the ACK.
669 */
670 hdr = (pjsip_hdr*) pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, NULL);
671 while (hdr != NULL) {
672 pjsip_msg_add_hdr( ack->msg,
673 (pjsip_hdr*) pjsip_hdr_clone(ack->pool, hdr) );
674 hdr = hdr->next;
675 if (hdr == &invite_msg->hdr)
676 break;
677 hdr = (pjsip_hdr*) pjsip_msg_find_hdr( invite_msg, PJSIP_H_ROUTE, hdr);
678 }
679
680 /* We're done.
681 * "tdata" parameter now contains the ACK message.
682 */
683 *ack_tdata = ack;
684 return PJ_SUCCESS;
685
686 on_missing_hdr:
687 if (ack)
688 pjsip_tx_data_dec_ref(ack);
689 return PJSIP_EMISSINGHDR;
690 }
691
692
693 /*
694 * Construct CANCEL request for the previously sent request, according to
695 * chapter 9.1 of RFC3261.
696 */
pjsip_endpt_create_cancel(pjsip_endpoint * endpt,const pjsip_tx_data * req_tdata,pjsip_tx_data ** p_tdata)697 PJ_DEF(pj_status_t) pjsip_endpt_create_cancel( pjsip_endpoint *endpt,
698 const pjsip_tx_data *req_tdata,
699 pjsip_tx_data **p_tdata)
700 {
701 pjsip_tx_data *cancel_tdata = NULL;
702 const pjsip_from_hdr *from_hdr;
703 const pjsip_to_hdr *to_hdr;
704 const pjsip_cid_hdr *cid_hdr;
705 const pjsip_cseq_hdr *cseq_hdr;
706 const pjsip_hdr *hdr;
707 pjsip_hdr *via;
708 pj_status_t status;
709
710 /* The transmit buffer must INVITE request. */
711 PJ_ASSERT_RETURN(req_tdata->msg->type == PJSIP_REQUEST_MSG &&
712 req_tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD,
713 PJ_EINVAL);
714
715 /* Get the headers from original INVITE request. */
716 # define FIND_HDR(m,HNAME) pjsip_msg_find_hdr(m, PJSIP_H_##HNAME, NULL)
717
718 from_hdr = (const pjsip_from_hdr*) FIND_HDR(req_tdata->msg, FROM);
719 PJ_ASSERT_ON_FAIL(from_hdr != NULL, goto on_missing_hdr);
720
721 to_hdr = (const pjsip_to_hdr*) FIND_HDR(req_tdata->msg, TO);
722 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);
723
724 cid_hdr = (const pjsip_cid_hdr*) FIND_HDR(req_tdata->msg, CALL_ID);
725 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);
726
727 cseq_hdr = (const pjsip_cseq_hdr*) FIND_HDR(req_tdata->msg, CSEQ);
728 PJ_ASSERT_ON_FAIL(to_hdr != NULL, goto on_missing_hdr);
729
730 # undef FIND_HDR
731
732 /* Create new request message from the headers. */
733 status = pjsip_endpt_create_request_from_hdr(endpt,
734 pjsip_get_cancel_method(),
735 req_tdata->msg->line.req.uri,
736 from_hdr, to_hdr,
737 NULL, cid_hdr,
738 cseq_hdr->cseq, NULL,
739 &cancel_tdata);
740
741 if (status != PJ_SUCCESS)
742 return status;
743
744 /* Clear Via headers in the new request. */
745 while ((via=(pjsip_hdr*)pjsip_msg_find_hdr(cancel_tdata->msg, PJSIP_H_VIA, NULL)) != NULL)
746 pj_list_erase(via);
747
748
749 /* Must only have single Via which matches the top-most Via in the
750 * request being cancelled.
751 */
752 hdr = (pjsip_hdr*) pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_VIA, NULL);
753 if (hdr) {
754 pjsip_msg_insert_first_hdr(cancel_tdata->msg,
755 (pjsip_hdr*)pjsip_hdr_clone(cancel_tdata->pool, hdr));
756 }
757
758 /* If the original request has Route header, the CANCEL request must also
759 * has exactly the same.
760 * Copy "Route" header from the request.
761 */
762 hdr = (pjsip_hdr*) pjsip_msg_find_hdr(req_tdata->msg, PJSIP_H_ROUTE, NULL);
763 while (hdr != NULL) {
764 pjsip_msg_add_hdr(cancel_tdata->msg,
765 (pjsip_hdr*) pjsip_hdr_clone(cancel_tdata->pool, hdr));
766 hdr = hdr->next;
767 if (hdr != &req_tdata->msg->hdr)
768 hdr = (pjsip_hdr*) pjsip_msg_find_hdr(req_tdata->msg,
769 PJSIP_H_ROUTE, hdr);
770 else
771 break;
772 }
773
774 /* Must also copy the saved strict route header, otherwise CANCEL will be
775 * sent with swapped Route and request URI!
776 */
777 if (req_tdata->saved_strict_route) {
778 cancel_tdata->saved_strict_route = (pjsip_route_hdr*)
779 pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route);
780 }
781
782 /* Copy the destination info from the original request */
783 pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,
784 sizeof(req_tdata->dest_info));
785
786 /* Finally, copy the destination host name from the original request */
787 pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
788 &req_tdata->dest_info.name);
789
790 /* Done.
791 * Return the transmit buffer containing the CANCEL request.
792 */
793 *p_tdata = cancel_tdata;
794 return PJ_SUCCESS;
795
796 on_missing_hdr:
797 if (cancel_tdata)
798 pjsip_tx_data_dec_ref(cancel_tdata);
799 return PJSIP_EMISSINGHDR;
800 }
801
802
803 /* Fill-up destination information from a target URI */
pjsip_get_dest_info(const pjsip_uri * target_uri,const pjsip_uri * request_uri,pj_pool_t * pool,pjsip_host_info * dest_info)804 PJ_DEF(pj_status_t) pjsip_get_dest_info(const pjsip_uri *target_uri,
805 const pjsip_uri *request_uri,
806 pj_pool_t *pool,
807 pjsip_host_info *dest_info)
808 {
809 /* The target URI must be a SIP/SIPS URL so we can resolve it's address.
810 * Otherwise we're in trouble (i.e. there's no host part in tel: URL).
811 */
812 pj_bzero(dest_info, sizeof(*dest_info));
813
814 /* When request URI uses sips scheme, TLS must always be used regardless
815 * of the target scheme or transport type (see ticket #1740).
816 */
817 if (PJSIP_URI_SCHEME_IS_SIPS(target_uri) ||
818 (pjsip_cfg()->endpt.disable_tls_switch == 0 && request_uri &&
819 PJSIP_URI_SCHEME_IS_SIPS(request_uri)))
820 {
821 pjsip_uri *uri = (pjsip_uri*) target_uri;
822 const pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);
823 unsigned flag;
824
825 if (!PJSIP_URI_SCHEME_IS_SIPS(target_uri)) {
826 PJ_LOG(4,(THIS_FILE, "Automatic switch to TLS transport as "
827 "request-URI uses ""sips"" scheme."));
828 }
829
830 dest_info->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE);
831 if (url->maddr_param.slen)
832 pj_strdup(pool, &dest_info->addr.host, &url->maddr_param);
833 else
834 pj_strdup(pool, &dest_info->addr.host, &url->host);
835 dest_info->addr.port = url->port;
836 dest_info->type =
837 pjsip_transport_get_type_from_name(&url->transport_param);
838 /* Double-check that the transport parameter match.
839 * Sample case: sips:host;transport=tcp
840 * See https://trac.pjsip.org/repos/ticket/1319
841 */
842 flag = pjsip_transport_get_flag_from_type(dest_info->type);
843 if ((flag & dest_info->flag) != dest_info->flag) {
844 pjsip_transport_type_e t;
845
846 t = pjsip_transport_get_type_from_flag(dest_info->flag);
847 if (t != PJSIP_TRANSPORT_UNSPECIFIED)
848 dest_info->type = t;
849 }
850
851 } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) {
852 pjsip_uri *uri = (pjsip_uri*) target_uri;
853 const pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);
854 if (url->maddr_param.slen)
855 pj_strdup(pool, &dest_info->addr.host, &url->maddr_param);
856 else
857 pj_strdup(pool, &dest_info->addr.host, &url->host);
858 dest_info->addr.port = url->port;
859 dest_info->type =
860 pjsip_transport_get_type_from_name(&url->transport_param);
861 dest_info->flag =
862 pjsip_transport_get_flag_from_type(dest_info->type);
863 } else {
864 /* Should have never reached here; app should have configured route
865 * set when sending to tel: URI
866 pj_assert(!"Unsupported URI scheme!");
867 */
868 PJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI);
869 return PJSIP_ENOROUTESET;
870 }
871
872 /* Handle IPv6 (http://trac.pjsip.org/repos/ticket/861) */
873 if (dest_info->type != PJSIP_TRANSPORT_UNSPECIFIED &&
874 pj_strchr(&dest_info->addr.host, ':'))
875 {
876 dest_info->type = (pjsip_transport_type_e)
877 ((int)dest_info->type | PJSIP_TRANSPORT_IPV6);
878 }
879
880 return PJ_SUCCESS;
881 }
882
883
884 /*
885 * Find which destination to be used to send the request message, based
886 * on the request URI and Route headers in the message. The procedure
887 * used here follows the guidelines on sending the request in RFC 3261
888 * chapter 8.1.2.
889 */
pjsip_get_request_dest(const pjsip_tx_data * tdata,pjsip_host_info * dest_info)890 PJ_DEF(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
891 pjsip_host_info *dest_info )
892 {
893 const pjsip_uri *target_uri;
894 const pjsip_route_hdr *first_route_hdr;
895
896 PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
897 PJSIP_ENOTREQUESTMSG);
898 PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
899
900 /* Get the first "Route" header from the message.
901 */
902 first_route_hdr = (const pjsip_route_hdr*)
903 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
904 if (first_route_hdr) {
905 target_uri = first_route_hdr->name_addr.uri;
906 } else {
907 target_uri = tdata->msg->line.req.uri;
908 }
909
910 return pjsip_get_dest_info(target_uri, tdata->msg->line.req.uri,
911 (pj_pool_t*)tdata->pool, dest_info);
912 }
913
914
915 /*
916 * Process route-set found in the request and calculate
917 * the destination to be used to send the request message, based
918 * on the request URI and Route headers in the message. The procedure
919 * used here follows the guidelines on sending the request in RFC 3261
920 * chapter 8.1.2.
921 */
pjsip_process_route_set(pjsip_tx_data * tdata,pjsip_host_info * dest_info)922 PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
923 pjsip_host_info *dest_info )
924 {
925 const pjsip_uri *new_request_uri, *target_uri;
926 const pjsip_name_addr *topmost_route_uri;
927 pjsip_route_hdr *first_route_hdr, *last_route_hdr;
928 pj_status_t status;
929
930 PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
931 PJSIP_ENOTREQUESTMSG);
932 PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
933
934 /* If the request contains strict route, check that the strict route
935 * has been restored to its original values before processing the
936 * route set. The strict route is restored to the original values
937 * with pjsip_restore_strict_route_set(). If caller did not restore
938 * the strict route before calling this function, we need to call it
939 * here, or otherwise the strict-route and Request-URI will be swapped
940 * twice!
941 */
942 if (tdata->saved_strict_route != NULL) {
943 pjsip_restore_strict_route_set(tdata);
944 }
945 PJ_ASSERT_RETURN(tdata->saved_strict_route==NULL, PJ_EBUG);
946
947 /* Find the first and last "Route" headers from the message. */
948 last_route_hdr = first_route_hdr = (pjsip_route_hdr*)
949 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
950 if (first_route_hdr) {
951 topmost_route_uri = &first_route_hdr->name_addr;
952 while (last_route_hdr->next != (void*)&tdata->msg->hdr) {
953 pjsip_route_hdr *hdr;
954 hdr = (pjsip_route_hdr*)
955 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE,
956 last_route_hdr->next);
957 if (!hdr)
958 break;
959 last_route_hdr = hdr;
960 }
961 } else {
962 topmost_route_uri = NULL;
963 }
964
965 /* If Route headers exist, and the first element indicates loose-route,
966 * the URI is taken from the Request-URI, and we keep all existing Route
967 * headers intact.
968 * If Route headers exist, and the first element DOESN'T indicate loose
969 * route, the URI is taken from the first Route header, and remove the
970 * first Route header from the message.
971 * Otherwise if there's no Route headers, the URI is taken from the
972 * Request-URI.
973 */
974 if (topmost_route_uri) {
975 pj_bool_t has_lr_param;
976
977 if (PJSIP_URI_SCHEME_IS_SIP(topmost_route_uri) ||
978 PJSIP_URI_SCHEME_IS_SIPS(topmost_route_uri))
979 {
980 const pjsip_sip_uri *url = (const pjsip_sip_uri*)
981 pjsip_uri_get_uri((const void*)topmost_route_uri);
982 has_lr_param = url->lr_param;
983 } else {
984 has_lr_param = 0;
985 }
986
987 if (has_lr_param) {
988 new_request_uri = tdata->msg->line.req.uri;
989 /* We shouldn't need to delete topmost Route if it has lr param.
990 * But seems like it breaks some proxy implementation, so we
991 * delete it anyway.
992 */
993 /*
994 pj_list_erase(first_route_hdr);
995 if (first_route_hdr == last_route_hdr)
996 last_route_hdr = NULL;
997 */
998 } else {
999 new_request_uri = (const pjsip_uri*)
1000 pjsip_uri_get_uri((pjsip_uri*)topmost_route_uri);
1001 pj_list_erase(first_route_hdr);
1002 tdata->saved_strict_route = first_route_hdr;
1003 if (first_route_hdr == last_route_hdr)
1004 first_route_hdr = last_route_hdr = NULL;
1005 }
1006
1007 target_uri = (pjsip_uri*)topmost_route_uri;
1008
1009 } else {
1010 target_uri = new_request_uri = tdata->msg->line.req.uri;
1011 }
1012
1013 /* Fill up the destination host/port from the URI. */
1014 status = pjsip_get_dest_info(target_uri, new_request_uri, tdata->pool,
1015 dest_info);
1016 if (status != PJ_SUCCESS)
1017 return status;
1018
1019 /* If transport selector is set, set destination type accordingly */
1020 if (tdata->tp_sel.type != PJSIP_TPSELECTOR_NONE && tdata->tp_sel.u.ptr) {
1021 if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT)
1022 dest_info->type = tdata->tp_sel.u.transport->key.type;
1023 else if (tdata->tp_sel.type == PJSIP_TPSELECTOR_LISTENER)
1024 dest_info->type = tdata->tp_sel.u.listener->type;
1025 }
1026
1027 /* If target URI is different than request URI, replace
1028 * request URI add put the original URI in the last Route header.
1029 */
1030 if (new_request_uri && new_request_uri!=tdata->msg->line.req.uri) {
1031 pjsip_route_hdr *route = pjsip_route_hdr_create(tdata->pool);
1032 route->name_addr.uri = (pjsip_uri*)
1033 pjsip_uri_get_uri(tdata->msg->line.req.uri);
1034 if (last_route_hdr)
1035 pj_list_insert_after(last_route_hdr, route);
1036 else
1037 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route);
1038 tdata->msg->line.req.uri = (pjsip_uri*)new_request_uri;
1039 }
1040
1041 /* Success. */
1042 return PJ_SUCCESS;
1043 }
1044
1045
1046 /*
1047 * Swap the request URI and strict route back to the original position
1048 * before #pjsip_process_route_set() function is called. This function
1049 * should only used internally by PJSIP client authentication module.
1050 */
pjsip_restore_strict_route_set(pjsip_tx_data * tdata)1051 PJ_DEF(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata)
1052 {
1053 pjsip_route_hdr *first_route_hdr, *last_route_hdr;
1054
1055 /* Check if we have found strict route before */
1056 if (tdata->saved_strict_route == NULL) {
1057 /* This request doesn't contain strict route */
1058 return;
1059 }
1060
1061 /* Find the first "Route" headers from the message. */
1062 first_route_hdr = (pjsip_route_hdr*)
1063 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
1064
1065 if (first_route_hdr == NULL) {
1066 /* User has modified message route? We don't expect this! */
1067 pj_assert(!"Message route was modified?");
1068 tdata->saved_strict_route = NULL;
1069 return;
1070 }
1071
1072 /* Find last Route header */
1073 last_route_hdr = first_route_hdr;
1074 while (last_route_hdr->next != (void*)&tdata->msg->hdr) {
1075 pjsip_route_hdr *hdr;
1076 hdr = (pjsip_route_hdr*)
1077 pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE,
1078 last_route_hdr->next);
1079 if (!hdr)
1080 break;
1081 last_route_hdr = hdr;
1082 }
1083
1084 /* Put the last Route header as request URI, delete last Route
1085 * header, and insert the saved strict route as the first Route.
1086 */
1087 tdata->msg->line.req.uri = last_route_hdr->name_addr.uri;
1088 pj_list_insert_before(first_route_hdr, tdata->saved_strict_route);
1089 pj_list_erase(last_route_hdr);
1090
1091 /* Reset */
1092 tdata->saved_strict_route = NULL;
1093 }
1094
1095
1096 /* Transport callback for sending stateless request.
1097 * This is one of the most bizzare function in pjsip, so
1098 * good luck if you happen to debug this function!!
1099 */
stateless_send_transport_cb(void * token,pjsip_tx_data * tdata,pj_ssize_t sent)1100 static void stateless_send_transport_cb( void *token,
1101 pjsip_tx_data *tdata,
1102 pj_ssize_t sent )
1103 {
1104 pjsip_send_state *stateless_data = (pjsip_send_state*) token;
1105 pj_status_t need_update_via = PJ_TRUE;
1106
1107 PJ_UNUSED_ARG(tdata);
1108 pj_assert(tdata == stateless_data->tdata);
1109
1110 for (;;) {
1111 pj_status_t status;
1112 pj_bool_t cont;
1113
1114 pj_sockaddr_t *cur_addr;
1115 pjsip_transport_type_e cur_addr_type;
1116 int cur_addr_len;
1117
1118 pjsip_via_hdr *via;
1119
1120 if (sent == -PJ_EPENDING) {
1121 /* This is the initial process.
1122 * When the process started, this function will be called by
1123 * stateless_send_resolver_callback() with sent argument set to
1124 * -PJ_EPENDING.
1125 */
1126 cont = PJ_TRUE;
1127 } else {
1128 /* There are two conditions here:
1129 * (1) Message is sent (i.e. sent > 0),
1130 * (2) Failure (i.e. sent <= 0)
1131 */
1132 cont = (sent > 0) ? PJ_FALSE :
1133 (tdata->dest_info.cur_addr<tdata->dest_info.addr.count-1);
1134 if (stateless_data->app_cb) {
1135 (*stateless_data->app_cb)(stateless_data, sent, &cont);
1136 } else {
1137 /* Doesn't have application callback.
1138 * Terminate the process.
1139 */
1140 cont = PJ_FALSE;
1141 }
1142 }
1143
1144 /* Finished with this transport. */
1145 if (stateless_data->cur_transport) {
1146 pjsip_transport_dec_ref(stateless_data->cur_transport);
1147 stateless_data->cur_transport = NULL;
1148 }
1149
1150 /* Done if application doesn't want to continue. */
1151 if (sent > 0 || !cont) {
1152 pjsip_tx_data_dec_ref(tdata);
1153 return;
1154 }
1155
1156 /* Try next address, if any, and only when this is not the
1157 * first invocation.
1158 */
1159 if (sent != -PJ_EPENDING) {
1160 tdata->dest_info.cur_addr++;
1161 }
1162
1163 /* Have next address? */
1164 if (tdata->dest_info.cur_addr >= tdata->dest_info.addr.count) {
1165 /* This only happens when a rather buggy application has
1166 * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE.
1167 * In this case just stop the processing; we don't need to
1168 * call the callback again as application has been informed
1169 * before.
1170 */
1171 pjsip_tx_data_dec_ref(tdata);
1172 return;
1173 }
1174
1175 /* Keep current server address information handy. */
1176 cur_addr = &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr;
1177 cur_addr_type = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].type;
1178 cur_addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;
1179
1180 /* Acquire transport. */
1181 status = pjsip_endpt_acquire_transport2(stateless_data->endpt,
1182 cur_addr_type,
1183 cur_addr,
1184 cur_addr_len,
1185 &tdata->tp_sel,
1186 tdata,
1187 &stateless_data->cur_transport);
1188 if (status != PJ_SUCCESS) {
1189 sent = -status;
1190 continue;
1191 }
1192
1193 /* Modify Via header. */
1194 via = (pjsip_via_hdr*) pjsip_msg_find_hdr( tdata->msg,
1195 PJSIP_H_VIA, NULL);
1196 if (!via) {
1197 /* Shouldn't happen if request was created with PJSIP API!
1198 * But we handle the case anyway for robustness.
1199 */
1200 pj_assert(!"Via header not found!");
1201 via = pjsip_via_hdr_create(tdata->pool);
1202 pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)via);
1203 }
1204
1205 if (tdata->msg->line.req.method.id == PJSIP_CANCEL_METHOD) {
1206 if (via->sent_by.host.slen > 0) {
1207 /* Don't update Via header on a CANCEL request if the sent-by
1208 * parameter is already set since it needs to match the
1209 * original request. */
1210 need_update_via = PJ_FALSE;
1211 }
1212 }
1213
1214 if (via->branch_param.slen == 0) {
1215 pj_str_t tmp;
1216 via->branch_param.ptr = (char*)pj_pool_alloc(tdata->pool,
1217 PJSIP_MAX_BRANCH_LEN);
1218 via->branch_param.slen = PJSIP_MAX_BRANCH_LEN;
1219 pj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID,
1220 PJSIP_RFC3261_BRANCH_LEN);
1221 tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;
1222 *(tmp.ptr-2) = 80; *(tmp.ptr-1) = 106;
1223 pj_generate_unique_string(&tmp);
1224 }
1225
1226 if (need_update_via) {
1227 via->transport = pj_str(stateless_data->cur_transport->type_name);
1228
1229 if (tdata->via_addr.host.slen > 0 &&
1230 (!tdata->via_tp ||
1231 tdata->via_tp == (void *)stateless_data->cur_transport))
1232 {
1233 via->sent_by = tdata->via_addr;
1234
1235 /* Better also update tdata via_tp, e.g: CANCEL may need to
1236 * refer to original INVITE tdata.
1237 */
1238 tdata->via_tp = stateless_data->cur_transport;
1239 } else {
1240 via->sent_by = stateless_data->cur_transport->local_name;
1241
1242 /* Better also update tdata via_tp & via_addr, e.g: CANCEL
1243 * may need to refer to original INVITE tdata.
1244 */
1245 tdata->via_tp = stateless_data->cur_transport;
1246 tdata->via_addr = via->sent_by;
1247 }
1248
1249 via->rport_param = pjsip_cfg()->endpt.disable_rport ? -1 : 0;
1250
1251 /* Add/remove "alias" param to/from Via header on connection
1252 * oriented/less transport, if configured.
1253 */
1254 if (pjsip_cfg()->endpt.req_has_via_alias &&
1255 tdata->msg->type == PJSIP_REQUEST_MSG)
1256 {
1257 const pj_str_t ALIAS_STR = {"alias", 5};
1258 pjsip_param *alias_param;
1259 pj_bool_t is_datagram;
1260
1261 alias_param = pjsip_param_find(&via->other_param, &ALIAS_STR);
1262 is_datagram = (stateless_data->cur_transport->flag &
1263 PJSIP_TRANSPORT_DATAGRAM);
1264 if (!is_datagram && !alias_param) {
1265 alias_param = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_param);
1266 alias_param->name = ALIAS_STR;
1267 pj_list_push_back(&via->other_param, alias_param);
1268 } else if (is_datagram && alias_param) {
1269 pj_list_erase(alias_param);
1270 }
1271 }
1272 }
1273
1274 pjsip_tx_data_invalidate_msg(tdata);
1275
1276 /* Send message using this transport. */
1277 status = pjsip_transport_send( stateless_data->cur_transport,
1278 tdata,
1279 cur_addr,
1280 cur_addr_len,
1281 stateless_data,
1282 &stateless_send_transport_cb);
1283 if (status == PJ_SUCCESS) {
1284 /* Recursively call this function. */
1285 sent = tdata->buf.cur - tdata->buf.start;
1286 stateless_send_transport_cb( stateless_data, tdata, sent );
1287 return;
1288 } else if (status == PJ_EPENDING) {
1289 /* This callback will be called later. */
1290 return;
1291 } else {
1292 /* Recursively call this function. */
1293 sent = -status;
1294 stateless_send_transport_cb( stateless_data, tdata, sent );
1295 return;
1296 }
1297 }
1298
1299 }
1300
1301 /* Resolver callback for sending stateless request. */
1302 static void
stateless_send_resolver_callback(pj_status_t status,void * token,const struct pjsip_server_addresses * addr)1303 stateless_send_resolver_callback( pj_status_t status,
1304 void *token,
1305 const struct pjsip_server_addresses *addr)
1306 {
1307 pjsip_send_state *stateless_data = (pjsip_send_state*) token;
1308 pjsip_tx_data *tdata = stateless_data->tdata;
1309
1310 /* Fail on server resolution. */
1311 if (status != PJ_SUCCESS) {
1312 if (stateless_data->app_cb) {
1313 pj_bool_t cont = PJ_FALSE;
1314 (*stateless_data->app_cb)(stateless_data, -status, &cont);
1315 }
1316 pjsip_tx_data_dec_ref(tdata);
1317 return;
1318 }
1319
1320 /* Copy server addresses */
1321 if (addr && addr != &tdata->dest_info.addr) {
1322 pj_memcpy( &tdata->dest_info.addr, addr,
1323 sizeof(pjsip_server_addresses));
1324 }
1325 pj_assert(tdata->dest_info.addr.count != 0);
1326
1327 /* RFC 3261 section 18.1.1:
1328 * If a request is within 200 bytes of the path MTU, or if it is larger
1329 * than 1300 bytes and the path MTU is unknown, the request MUST be sent
1330 * using an RFC 2914 [43] congestion controlled transport protocol, such
1331 * as TCP.
1332 */
1333 if (pjsip_cfg()->endpt.disable_tcp_switch==0 &&
1334 tdata->msg->type == PJSIP_REQUEST_MSG &&
1335 tdata->dest_info.addr.count > 0 &&
1336 tdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP)
1337 {
1338 int len;
1339
1340 /* Encode the request */
1341 status = pjsip_tx_data_encode(tdata);
1342 if (status != PJ_SUCCESS) {
1343 if (stateless_data->app_cb) {
1344 pj_bool_t cont = PJ_FALSE;
1345 (*stateless_data->app_cb)(stateless_data, -status, &cont);
1346 }
1347 pjsip_tx_data_dec_ref(tdata);
1348 return;
1349 }
1350
1351 /* Check if request message is larger than 1300 bytes. */
1352 len = (int)(tdata->buf.cur - tdata->buf.start);
1353 if (len >= PJSIP_UDP_SIZE_THRESHOLD) {
1354 int i;
1355 int count = tdata->dest_info.addr.count;
1356
1357 PJ_LOG(5,(THIS_FILE, "%s exceeds UDP size threshold (%u), "
1358 "sending with TCP",
1359 pjsip_tx_data_get_info(tdata),
1360 PJSIP_UDP_SIZE_THRESHOLD));
1361
1362 /* Insert "TCP version" of resolved UDP addresses at the
1363 * beginning.
1364 */
1365 if (count * 2 > PJSIP_MAX_RESOLVED_ADDRESSES)
1366 count = PJSIP_MAX_RESOLVED_ADDRESSES / 2;
1367 for (i = 0; i < count; ++i) {
1368 pj_memcpy(&tdata->dest_info.addr.entry[i+count],
1369 &tdata->dest_info.addr.entry[i],
1370 sizeof(tdata->dest_info.addr.entry[0]));
1371 tdata->dest_info.addr.entry[i].type = PJSIP_TRANSPORT_TCP;
1372 }
1373 tdata->dest_info.addr.count = count * 2;
1374 }
1375 }
1376
1377 /* Process the addresses. */
1378 stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING);
1379 }
1380
1381 /*
1382 * Send stateless request.
1383 * The sending process consists of several stages:
1384 * - determine which host to contact (#pjsip_get_request_addr).
1385 * - resolve the host (#pjsip_endpt_resolve)
1386 * - establish transport (#pjsip_endpt_acquire_transport)
1387 * - send the message (#pjsip_transport_send)
1388 */
pjsip_endpt_send_request_stateless(pjsip_endpoint * endpt,pjsip_tx_data * tdata,void * token,pjsip_send_callback cb)1389 PJ_DEF(pj_status_t) pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,
1390 pjsip_tx_data *tdata,
1391 void *token,
1392 pjsip_send_callback cb)
1393 {
1394 pjsip_host_info dest_info;
1395 pjsip_send_state *stateless_data;
1396 pj_status_t status;
1397
1398 PJ_ASSERT_RETURN(endpt && tdata, PJ_EINVAL);
1399
1400 /* Get destination name to contact. */
1401 status = pjsip_process_route_set(tdata, &dest_info);
1402 if (status != PJ_SUCCESS)
1403 return status;
1404
1405 /* Keep stateless data. */
1406 stateless_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_send_state);
1407 stateless_data->token = token;
1408 stateless_data->endpt = endpt;
1409 stateless_data->tdata = tdata;
1410 stateless_data->app_cb = cb;
1411
1412 /* If destination info has not been initialized (this applies for most
1413 * all requests except CANCEL), resolve destination host. The processing
1414 * then resumed when the resolving callback is called. For CANCEL, the
1415 * destination info must have been copied from the original INVITE so
1416 * proceed to sending the request directly.
1417 */
1418 if (tdata->dest_info.addr.count == 0) {
1419 /* Copy the destination host name to TX data */
1420 if (!tdata->dest_info.name.slen) {
1421 pj_strdup(tdata->pool, &tdata->dest_info.name,
1422 &dest_info.addr.host);
1423 }
1424
1425 pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data,
1426 &stateless_send_resolver_callback);
1427 } else {
1428 PJ_LOG(5,(THIS_FILE, "%s: skipping target resolution because "
1429 "address is already set",
1430 pjsip_tx_data_get_info(tdata)));
1431 stateless_send_resolver_callback(PJ_SUCCESS, stateless_data,
1432 &tdata->dest_info.addr);
1433 }
1434 return PJ_SUCCESS;
1435 }
1436
1437
1438 /*
1439 * Send raw data to a destination.
1440 */
pjsip_endpt_send_raw(pjsip_endpoint * endpt,pjsip_transport_type_e tp_type,const pjsip_tpselector * sel,const void * raw_data,pj_size_t data_len,const pj_sockaddr_t * addr,int addr_len,void * token,pjsip_tp_send_callback cb)1441 PJ_DEF(pj_status_t) pjsip_endpt_send_raw( pjsip_endpoint *endpt,
1442 pjsip_transport_type_e tp_type,
1443 const pjsip_tpselector *sel,
1444 const void *raw_data,
1445 pj_size_t data_len,
1446 const pj_sockaddr_t *addr,
1447 int addr_len,
1448 void *token,
1449 pjsip_tp_send_callback cb)
1450 {
1451 return pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(endpt), tp_type, sel,
1452 NULL, raw_data, data_len, addr, addr_len,
1453 token, cb);
1454 }
1455
1456
1457 /* Callback data for sending raw data */
1458 struct send_raw_data
1459 {
1460 pjsip_endpoint *endpt;
1461 pjsip_tx_data *tdata;
1462 pjsip_tpselector *sel;
1463 void *app_token;
1464 pjsip_tp_send_callback app_cb;
1465 };
1466
1467
1468 /* Resolver callback for sending raw data. */
send_raw_resolver_callback(pj_status_t status,void * token,const pjsip_server_addresses * addr)1469 static void send_raw_resolver_callback( pj_status_t status,
1470 void *token,
1471 const pjsip_server_addresses *addr)
1472 {
1473 struct send_raw_data *sraw_data = (struct send_raw_data*) token;
1474
1475 if (status != PJ_SUCCESS) {
1476 if (sraw_data->app_cb) {
1477 (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
1478 -status);
1479 }
1480 } else {
1481 pj_size_t data_len;
1482
1483 pj_assert(addr->count != 0);
1484
1485 /* Avoid tdata destroyed by pjsip_tpmgr_send_raw(). */
1486 pjsip_tx_data_add_ref(sraw_data->tdata);
1487
1488 data_len = sraw_data->tdata->buf.cur - sraw_data->tdata->buf.start;
1489 status = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(sraw_data->endpt),
1490 addr->entry[0].type,
1491 sraw_data->sel, sraw_data->tdata,
1492 sraw_data->tdata->buf.start, data_len,
1493 &addr->entry[0].addr,
1494 addr->entry[0].addr_len,
1495 sraw_data->app_token,
1496 sraw_data->app_cb);
1497 if (status == PJ_SUCCESS) {
1498 (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
1499 data_len);
1500 } else if (status != PJ_EPENDING) {
1501 (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
1502 -status);
1503 }
1504 }
1505
1506 if (sraw_data->sel) {
1507 pjsip_tpselector_dec_ref(sraw_data->sel);
1508 }
1509 pjsip_tx_data_dec_ref(sraw_data->tdata);
1510 }
1511
1512
1513 /*
1514 * Send raw data to the specified destination URI.
1515 */
pjsip_endpt_send_raw_to_uri(pjsip_endpoint * endpt,const pj_str_t * p_dst_uri,const pjsip_tpselector * sel,const void * raw_data,pj_size_t data_len,void * token,pjsip_tp_send_callback cb)1516 PJ_DEF(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
1517 const pj_str_t *p_dst_uri,
1518 const pjsip_tpselector *sel,
1519 const void *raw_data,
1520 pj_size_t data_len,
1521 void *token,
1522 pjsip_tp_send_callback cb)
1523 {
1524 pjsip_tx_data *tdata;
1525 struct send_raw_data *sraw_data;
1526 pj_str_t dst_uri;
1527 pjsip_uri *uri;
1528 pjsip_host_info dest_info;
1529 pj_status_t status;
1530
1531 /* Allocate buffer */
1532 status = pjsip_endpt_create_tdata(endpt, &tdata);
1533 if (status != PJ_SUCCESS)
1534 return status;
1535
1536 pjsip_tx_data_add_ref(tdata);
1537
1538 /* Duplicate URI since parser requires URI to be NULL terminated */
1539 pj_strdup_with_null(tdata->pool, &dst_uri, p_dst_uri);
1540
1541 /* Parse URI */
1542 uri = pjsip_parse_uri(tdata->pool, dst_uri.ptr, dst_uri.slen, 0);
1543 if (uri == NULL) {
1544 pjsip_tx_data_dec_ref(tdata);
1545 return PJSIP_EINVALIDURI;
1546 }
1547
1548 /* Build destination info. */
1549 status = pjsip_get_dest_info(uri, NULL, tdata->pool, &dest_info);
1550 if (status != PJ_SUCCESS) {
1551 pjsip_tx_data_dec_ref(tdata);
1552 return status;
1553 }
1554
1555 /* Copy data (note: data_len may be zero!) */
1556 tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
1557 tdata->buf.end = tdata->buf.start + data_len + 1;
1558 if (data_len)
1559 pj_memcpy(tdata->buf.start, raw_data, data_len);
1560 tdata->buf.cur = tdata->buf.start + data_len;
1561
1562 /* Init send_raw_data */
1563 sraw_data = PJ_POOL_ZALLOC_T(tdata->pool, struct send_raw_data);
1564 sraw_data->endpt = endpt;
1565 sraw_data->tdata = tdata;
1566 sraw_data->app_token = token;
1567 sraw_data->app_cb = cb;
1568
1569 if (sel) {
1570 sraw_data->sel = PJ_POOL_ALLOC_T(tdata->pool, pjsip_tpselector);
1571 pj_memcpy(sraw_data->sel, sel, sizeof(pjsip_tpselector));
1572 pjsip_tpselector_add_ref(sraw_data->sel);
1573 }
1574
1575 /* Copy the destination host name to TX data */
1576 pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);
1577
1578 /* Resolve destination host.
1579 * The processing then resumed when the resolving callback is called.
1580 */
1581 pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, sraw_data,
1582 &send_raw_resolver_callback);
1583 return PJ_SUCCESS;
1584 }
1585
1586
1587 /*
1588 * Determine which address (and transport) to use to send response message
1589 * based on the received request. This function follows the specification
1590 * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination
1591 * address and transport.
1592 */
pjsip_get_response_addr(pj_pool_t * pool,pjsip_rx_data * rdata,pjsip_response_addr * res_addr)1593 PJ_DEF(pj_status_t) pjsip_get_response_addr( pj_pool_t *pool,
1594 pjsip_rx_data *rdata,
1595 pjsip_response_addr *res_addr )
1596 {
1597 pjsip_transport *src_transport = rdata->tp_info.transport;
1598
1599 /* Check arguments. */
1600 PJ_ASSERT_RETURN(pool && rdata && res_addr, PJ_EINVAL);
1601
1602 /* rdata must be a request message! */
1603 PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
1604 PJ_EINVAL);
1605
1606 /* All requests must have "received" parameter.
1607 * This must always be done in transport layer.
1608 */
1609 pj_assert(rdata->msg_info.via->recvd_param.slen != 0);
1610
1611 /* Do the calculation based on RFC 3261 Section 18.2.2 and RFC 3581 */
1612
1613 if (PJSIP_TRANSPORT_IS_RELIABLE(src_transport)) {
1614 /* For reliable protocol such as TCP or SCTP, or TLS over those, the
1615 * response MUST be sent using the existing connection to the source
1616 * of the original request that created the transaction, if that
1617 * connection is still open.
1618 * If that connection is no longer open, the server SHOULD open a
1619 * connection to the IP address in the received parameter, if present,
1620 * using the port in the sent-by value, or the default port for that
1621 * transport, if no port is specified.
1622 * If that connection attempt fails, the server SHOULD use the
1623 * procedures in [4] for servers in order to determine the IP address
1624 * and port to open the connection and send the response to.
1625 */
1626 res_addr->transport = rdata->tp_info.transport;
1627 pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr,
1628 rdata->pkt_info.src_addr_len);
1629 res_addr->addr_len = rdata->pkt_info.src_addr_len;
1630 res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1631 res_addr->dst_host.flag = src_transport->flag;
1632 pj_strdup( pool, &res_addr->dst_host.addr.host,
1633 &rdata->msg_info.via->recvd_param);
1634 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1635 if (res_addr->dst_host.addr.port == 0) {
1636 res_addr->dst_host.addr.port =
1637 pjsip_transport_get_default_port_for_type(res_addr->dst_host.type);
1638 }
1639
1640 } else if (rdata->msg_info.via->maddr_param.slen) {
1641 /* Otherwise, if the Via header field value contains a maddr parameter,
1642 * the response MUST be forwarded to the address listed there, using
1643 * the port indicated in sent-by, or port 5060 if none is present.
1644 * If the address is a multicast address, the response SHOULD be sent
1645 * using the TTL indicated in the ttl parameter, or with a TTL of 1 if
1646 * that parameter is not present.
1647 */
1648 res_addr->transport = NULL;
1649 res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1650 res_addr->dst_host.flag = src_transport->flag;
1651 pj_strdup( pool, &res_addr->dst_host.addr.host,
1652 &rdata->msg_info.via->maddr_param);
1653 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1654 if (res_addr->dst_host.addr.port == 0)
1655 res_addr->dst_host.addr.port = 5060;
1656
1657 } else if (rdata->msg_info.via->rport_param >= 0) {
1658 /* There is both a "received" parameter and an "rport" parameter,
1659 * the response MUST be sent to the IP address listed in the "received"
1660 * parameter, and the port in the "rport" parameter.
1661 * The response MUST be sent from the same address and port that the
1662 * corresponding request was received on.
1663 */
1664 res_addr->transport = rdata->tp_info.transport;
1665 pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr,
1666 rdata->pkt_info.src_addr_len);
1667 res_addr->addr_len = rdata->pkt_info.src_addr_len;
1668 res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1669 res_addr->dst_host.flag = src_transport->flag;
1670 pj_strdup( pool, &res_addr->dst_host.addr.host,
1671 &rdata->msg_info.via->recvd_param);
1672 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1673 if (res_addr->dst_host.addr.port == 0) {
1674 res_addr->dst_host.addr.port =
1675 pjsip_transport_get_default_port_for_type(res_addr->dst_host.type);
1676 }
1677
1678 } else {
1679 res_addr->transport = NULL;
1680 res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1681 res_addr->dst_host.flag = src_transport->flag;
1682 pj_strdup( pool, &res_addr->dst_host.addr.host,
1683 &rdata->msg_info.via->recvd_param);
1684 res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1685 if (res_addr->dst_host.addr.port == 0) {
1686 res_addr->dst_host.addr.port =
1687 pjsip_transport_get_default_port_for_type(res_addr->dst_host.type);
1688 }
1689 }
1690
1691 return PJ_SUCCESS;
1692 }
1693
1694 /*
1695 * Callback called by transport during send_response.
1696 */
send_response_transport_cb(void * token,pjsip_tx_data * tdata,pj_ssize_t sent)1697 static void send_response_transport_cb(void *token, pjsip_tx_data *tdata,
1698 pj_ssize_t sent)
1699 {
1700 pjsip_send_state *send_state = (pjsip_send_state*) token;
1701 pj_bool_t cont = PJ_FALSE;
1702
1703 /* Call callback, if any. */
1704 if (send_state->app_cb)
1705 (*send_state->app_cb)(send_state, sent, &cont);
1706
1707 /* Decrement transport reference counter. */
1708 pjsip_transport_dec_ref(send_state->cur_transport);
1709
1710 /* Decrement transmit data ref counter. */
1711 pjsip_tx_data_dec_ref(tdata);
1712 }
1713
1714 /*
1715 * Resolver calback during send_response.
1716 */
send_response_resolver_cb(pj_status_t status,void * token,const pjsip_server_addresses * addr)1717 static void send_response_resolver_cb( pj_status_t status, void *token,
1718 const pjsip_server_addresses *addr )
1719 {
1720 pjsip_send_state *send_state = (pjsip_send_state*) token;
1721
1722 if (status != PJ_SUCCESS) {
1723 if (send_state->app_cb) {
1724 pj_bool_t cont = PJ_FALSE;
1725 (*send_state->app_cb)(send_state, -status, &cont);
1726 }
1727 pjsip_tx_data_dec_ref(send_state->tdata);
1728 return;
1729 }
1730
1731 /* Only handle the first address resolved. */
1732
1733 /* Acquire transport. */
1734 status = pjsip_endpt_acquire_transport2(send_state->endpt,
1735 addr->entry[0].type,
1736 &addr->entry[0].addr,
1737 addr->entry[0].addr_len,
1738 &send_state->tdata->tp_sel,
1739 send_state->tdata,
1740 &send_state->cur_transport);
1741 if (status != PJ_SUCCESS) {
1742 if (send_state->app_cb) {
1743 pj_bool_t cont = PJ_FALSE;
1744 (*send_state->app_cb)(send_state, -status, &cont);
1745 }
1746 pjsip_tx_data_dec_ref(send_state->tdata);
1747 return;
1748 }
1749
1750 /* Update address in send_state. */
1751 pj_memcpy(&send_state->tdata->dest_info.addr, addr, sizeof(*addr));
1752
1753 /* Send response using the transoprt. */
1754 status = pjsip_transport_send( send_state->cur_transport,
1755 send_state->tdata,
1756 &addr->entry[0].addr,
1757 addr->entry[0].addr_len,
1758 send_state,
1759 &send_response_transport_cb);
1760 if (status == PJ_SUCCESS) {
1761 pj_ssize_t sent = send_state->tdata->buf.cur -
1762 send_state->tdata->buf.start;
1763 send_response_transport_cb(send_state, send_state->tdata, sent);
1764
1765 } else if (status == PJ_EPENDING) {
1766 /* Transport callback will be called later. */
1767 } else {
1768 send_response_transport_cb(send_state, send_state->tdata, -status);
1769 }
1770 }
1771
1772 /*
1773 * Send response.
1774 */
pjsip_endpt_send_response(pjsip_endpoint * endpt,pjsip_response_addr * res_addr,pjsip_tx_data * tdata,void * token,pjsip_send_callback cb)1775 PJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,
1776 pjsip_response_addr *res_addr,
1777 pjsip_tx_data *tdata,
1778 void *token,
1779 pjsip_send_callback cb)
1780 {
1781 /* Determine which transports and addresses to send the response,
1782 * based on Section 18.2.2 of RFC 3261.
1783 */
1784 pjsip_send_state *send_state;
1785 pj_status_t status;
1786
1787 /* Create structure to keep the sending state. */
1788 send_state = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_send_state);
1789 send_state->endpt = endpt;
1790 send_state->tdata = tdata;
1791 send_state->token = token;
1792 send_state->app_cb = cb;
1793
1794 if (res_addr->transport != NULL) {
1795 send_state->cur_transport = res_addr->transport;
1796 pjsip_transport_add_ref(send_state->cur_transport);
1797
1798 status = pjsip_transport_send( send_state->cur_transport, tdata,
1799 &res_addr->addr,
1800 res_addr->addr_len,
1801 send_state,
1802 &send_response_transport_cb );
1803 if (status == PJ_SUCCESS) {
1804 pj_ssize_t sent = tdata->buf.cur - tdata->buf.start;
1805 send_response_transport_cb(send_state, tdata, sent);
1806 return PJ_SUCCESS;
1807 } else if (status == PJ_EPENDING) {
1808 /* Callback will be called later. */
1809 return PJ_SUCCESS;
1810 } else {
1811 pjsip_transport_dec_ref(send_state->cur_transport);
1812 return status;
1813 }
1814 } else {
1815 /* Copy the destination host name to TX data */
1816 if (!tdata->dest_info.name.slen) {
1817 pj_strdup(tdata->pool, &tdata->dest_info.name,
1818 &res_addr->dst_host.addr.host);
1819 }
1820
1821 pjsip_endpt_resolve(endpt, tdata->pool, &res_addr->dst_host,
1822 send_state, &send_response_resolver_cb);
1823 return PJ_SUCCESS;
1824 }
1825 }
1826
1827 /*
1828 * Send response combo
1829 */
pjsip_endpt_send_response2(pjsip_endpoint * endpt,pjsip_rx_data * rdata,pjsip_tx_data * tdata,void * token,pjsip_send_callback cb)1830 PJ_DEF(pj_status_t) pjsip_endpt_send_response2( pjsip_endpoint *endpt,
1831 pjsip_rx_data *rdata,
1832 pjsip_tx_data *tdata,
1833 void *token,
1834 pjsip_send_callback cb)
1835 {
1836 pjsip_response_addr res_addr;
1837 pj_status_t status;
1838
1839 status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
1840 if (status != PJ_SUCCESS) {
1841 pjsip_tx_data_dec_ref(tdata);
1842 return PJ_SUCCESS;
1843 }
1844
1845 status = pjsip_endpt_send_response(endpt, &res_addr, tdata, token, cb);
1846 return status;
1847 }
1848
1849
1850 /*
1851 * Send response
1852 */
pjsip_endpt_respond_stateless(pjsip_endpoint * endpt,pjsip_rx_data * rdata,int st_code,const pj_str_t * st_text,const pjsip_hdr * hdr_list,const pjsip_msg_body * body)1853 PJ_DEF(pj_status_t) pjsip_endpt_respond_stateless( pjsip_endpoint *endpt,
1854 pjsip_rx_data *rdata,
1855 int st_code,
1856 const pj_str_t *st_text,
1857 const pjsip_hdr *hdr_list,
1858 const pjsip_msg_body *body)
1859 {
1860 pj_status_t status;
1861 pjsip_response_addr res_addr;
1862 pjsip_tx_data *tdata;
1863
1864 /* Verify arguments. */
1865 PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL);
1866 PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
1867 PJSIP_ENOTREQUESTMSG);
1868
1869 /* Check that no UAS transaction has been created for this request.
1870 * If UAS transaction has been created for this request, application
1871 * MUST send the response statefully using that transaction.
1872 */
1873 PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata)==NULL, PJ_EINVALIDOP);
1874
1875 /* Create response message */
1876 status = pjsip_endpt_create_response( endpt, rdata, st_code, st_text,
1877 &tdata);
1878 if (status != PJ_SUCCESS)
1879 return status;
1880
1881 /* Add the message headers, if any */
1882 if (hdr_list) {
1883 const pjsip_hdr *hdr = hdr_list->next;
1884 while (hdr != hdr_list) {
1885 pjsip_msg_add_hdr(tdata->msg,
1886 (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr) );
1887 hdr = hdr->next;
1888 }
1889 }
1890
1891 /* Add the message body, if any. */
1892 if (body) {
1893 tdata->msg->body = pjsip_msg_body_clone( tdata->pool, body );
1894 if (tdata->msg->body == NULL) {
1895 pjsip_tx_data_dec_ref(tdata);
1896 return status;
1897 }
1898 }
1899
1900 /* Get where to send request. */
1901 status = pjsip_get_response_addr( tdata->pool, rdata, &res_addr );
1902 if (status != PJ_SUCCESS) {
1903 pjsip_tx_data_dec_ref(tdata);
1904 return status;
1905 }
1906
1907 /* Send! */
1908 status = pjsip_endpt_send_response( endpt, &res_addr, tdata, NULL, NULL );
1909 if (status != PJ_SUCCESS) {
1910 pjsip_tx_data_dec_ref(tdata);
1911 return status;
1912 }
1913
1914 return PJ_SUCCESS;
1915 }
1916
1917
1918 /*
1919 * Get the event string from the event ID.
1920 */
pjsip_event_str(pjsip_event_id_e e)1921 PJ_DEF(const char *) pjsip_event_str(pjsip_event_id_e e)
1922 {
1923 return event_str[e];
1924 }
1925
1926