~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjsip/src/pjsip/sip_util.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sip_util.c 4173 2012-06-20 10:39:05Z ming $ */
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 */
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 */
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 */
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 */
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 */
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
 
 */
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, &param_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 = 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
 
 */
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
 
 
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, &param_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
 
 */
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
 
 */
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
 
 */
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 host name from the original request */
783
 
    pj_strdup(cancel_tdata->pool, &cancel_tdata->dest_info.name,
784
 
              &req_tdata->dest_info.name);
785
 
 
786
 
    /* Finally copy the destination info from the original request */
787
 
    pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info,
788
 
              sizeof(req_tdata->dest_info));
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 */
804
 
static pj_status_t get_dest_info(const pjsip_uri *target_uri,
805
 
                                 pj_pool_t *pool,
806
 
                                 pjsip_host_info *dest_info)
807
 
{
808
 
    /* The target URI must be a SIP/SIPS URL so we can resolve it's address.
809
 
     * Otherwise we're in trouble (i.e. there's no host part in tel: URL).
810
 
     */
811
 
    pj_bzero(dest_info, sizeof(*dest_info));
812
 
 
813
 
    if (PJSIP_URI_SCHEME_IS_SIPS(target_uri)) {
814
 
        pjsip_uri *uri = (pjsip_uri*) target_uri;
815
 
        const pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);
816
 
        unsigned flag;
817
 
 
818
 
        dest_info->flag |= (PJSIP_TRANSPORT_SECURE | PJSIP_TRANSPORT_RELIABLE);
819
 
        if (url->maddr_param.slen)
820
 
            pj_strdup(pool, &dest_info->addr.host, &url->maddr_param);
821
 
        else
822
 
            pj_strdup(pool, &dest_info->addr.host, &url->host);
823
 
        dest_info->addr.port = url->port;
824
 
        dest_info->type =
825
 
            pjsip_transport_get_type_from_name(&url->transport_param);
826
 
        /* Double-check that the transport parameter match.
827
 
         * Sample case:     sips:host;transport=tcp
828
 
         * See https://trac.pjsip.org/repos/ticket/1319
829
 
         */
830
 
        flag = pjsip_transport_get_flag_from_type(dest_info->type);
831
 
        if ((flag & dest_info->flag) != dest_info->flag) {
832
 
            pjsip_transport_type_e t;
833
 
 
834
 
            t = pjsip_transport_get_type_from_flag(dest_info->flag);
835
 
            if (t != PJSIP_TRANSPORT_UNSPECIFIED)
836
 
                dest_info->type = t;
837
 
        }
838
 
 
839
 
    } else if (PJSIP_URI_SCHEME_IS_SIP(target_uri)) {
840
 
        pjsip_uri *uri = (pjsip_uri*) target_uri;
841
 
        const pjsip_sip_uri *url=(const pjsip_sip_uri*)pjsip_uri_get_uri(uri);
842
 
        if (url->maddr_param.slen)
843
 
            pj_strdup(pool, &dest_info->addr.host, &url->maddr_param);
844
 
        else
845
 
            pj_strdup(pool, &dest_info->addr.host, &url->host);
846
 
        dest_info->addr.port = url->port;
847
 
        dest_info->type =
848
 
            pjsip_transport_get_type_from_name(&url->transport_param);
849
 
        dest_info->flag =
850
 
            pjsip_transport_get_flag_from_type(dest_info->type);
851
 
    } else {
852
 
        /* Should have never reached here; app should have configured route
853
 
         * set when sending to tel: URI
854
 
        pj_assert(!"Unsupported URI scheme!");
855
 
         */
856
 
        PJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI);
857
 
        return PJSIP_ENOROUTESET;
858
 
    }
859
 
 
860
 
    /* Handle IPv6 (http://trac.pjsip.org/repos/ticket/861) */
861
 
    if (dest_info->type != PJSIP_TRANSPORT_UNSPECIFIED &&
862
 
        pj_strchr(&dest_info->addr.host, ':'))
863
 
    {
864
 
        dest_info->type = (pjsip_transport_type_e)
865
 
                          ((int)dest_info->type | PJSIP_TRANSPORT_IPV6);
866
 
    }
867
 
 
868
 
    return PJ_SUCCESS;
869
 
}
870
 
 
871
 
 
872
 
/*
873
 
 * Find which destination to be used to send the request message, based
874
 
 * on the request URI and Route headers in the message. The procedure
875
 
 * used here follows the guidelines on sending the request in RFC 3261
876
 
 * chapter 8.1.2.
877
 
 */
878
 
PJ_DEF(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
879
 
                                           pjsip_host_info *dest_info )
880
 
{
881
 
    const pjsip_uri *target_uri;
882
 
    const pjsip_route_hdr *first_route_hdr;
883
 
 
884
 
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
885
 
                     PJSIP_ENOTREQUESTMSG);
886
 
    PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
887
 
 
888
 
    /* Get the first "Route" header from the message.
889
 
     */
890
 
    first_route_hdr = (const pjsip_route_hdr*)
891
 
                      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
892
 
    if (first_route_hdr) {
893
 
        target_uri = first_route_hdr->name_addr.uri;
894
 
    } else {
895
 
        target_uri = tdata->msg->line.req.uri;
896
 
    }
897
 
 
898
 
    return get_dest_info(target_uri, (pj_pool_t*)tdata->pool, dest_info);
899
 
}
900
 
 
901
 
 
902
 
/*
903
 
 * Process route-set found in the request and calculate
904
 
 * the destination to be used to send the request message, based
905
 
 * on the request URI and Route headers in the message. The procedure
906
 
 * used here follows the guidelines on sending the request in RFC 3261
907
 
 * chapter 8.1.2.
908
 
 */
909
 
PJ_DEF(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
910
 
                                            pjsip_host_info *dest_info )
911
 
{
912
 
    const pjsip_uri *new_request_uri, *target_uri;
913
 
    const pjsip_name_addr *topmost_route_uri;
914
 
    pjsip_route_hdr *first_route_hdr, *last_route_hdr;
915
 
    pj_status_t status;
916
 
 
917
 
    PJ_ASSERT_RETURN(tdata->msg->type == PJSIP_REQUEST_MSG,
918
 
                     PJSIP_ENOTREQUESTMSG);
919
 
    PJ_ASSERT_RETURN(dest_info != NULL, PJ_EINVAL);
920
 
 
921
 
    /* If the request contains strict route, check that the strict route
922
 
     * has been restored to its original values before processing the
923
 
     * route set. The strict route is restored to the original values
924
 
     * with pjsip_restore_strict_route_set(). If caller did not restore
925
 
     * the strict route before calling this function, we need to call it
926
 
     * here, or otherwise the strict-route and Request-URI will be swapped
927
 
     * twice!
928
 
     */
929
 
    if (tdata->saved_strict_route != NULL) {
930
 
        pjsip_restore_strict_route_set(tdata);
931
 
    }
932
 
    PJ_ASSERT_RETURN(tdata->saved_strict_route==NULL, PJ_EBUG);
933
 
 
934
 
    /* Find the first and last "Route" headers from the message. */
935
 
    last_route_hdr = first_route_hdr = (pjsip_route_hdr*)
936
 
        pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
937
 
    if (first_route_hdr) {
938
 
        topmost_route_uri = &first_route_hdr->name_addr;
939
 
        while (last_route_hdr->next != (void*)&tdata->msg->hdr) {
940
 
            pjsip_route_hdr *hdr;
941
 
            hdr = (pjsip_route_hdr*)
942
 
                  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE,
943
 
                                     last_route_hdr->next);
944
 
            if (!hdr)
945
 
                break;
946
 
            last_route_hdr = hdr;
947
 
        }
948
 
    } else {
949
 
        topmost_route_uri = NULL;
950
 
    }
951
 
 
952
 
    /* If Route headers exist, and the first element indicates loose-route,
953
 
     * the URI is taken from the Request-URI, and we keep all existing Route
954
 
     * headers intact.
955
 
     * If Route headers exist, and the first element DOESN'T indicate loose
956
 
     * route, the URI is taken from the first Route header, and remove the
957
 
     * first Route header from the message.
958
 
     * Otherwise if there's no Route headers, the URI is taken from the
959
 
     * Request-URI.
960
 
     */
961
 
    if (topmost_route_uri) {
962
 
        pj_bool_t has_lr_param;
963
 
 
964
 
        if (PJSIP_URI_SCHEME_IS_SIP(topmost_route_uri) ||
965
 
            PJSIP_URI_SCHEME_IS_SIPS(topmost_route_uri))
966
 
        {
967
 
            const pjsip_sip_uri *url = (const pjsip_sip_uri*)
968
 
                pjsip_uri_get_uri((const void*)topmost_route_uri);
969
 
            has_lr_param = url->lr_param;
970
 
        } else {
971
 
            has_lr_param = 0;
972
 
        }
973
 
 
974
 
        if (has_lr_param) {
975
 
            new_request_uri = tdata->msg->line.req.uri;
976
 
            /* We shouldn't need to delete topmost Route if it has lr param.
977
 
             * But seems like it breaks some proxy implementation, so we
978
 
             * delete it anyway.
979
 
             */
980
 
            /*
981
 
            pj_list_erase(first_route_hdr);
982
 
            if (first_route_hdr == last_route_hdr)
983
 
                last_route_hdr = NULL;
984
 
            */
985
 
        } else {
986
 
            new_request_uri = (const pjsip_uri*)
987
 
                              pjsip_uri_get_uri((pjsip_uri*)topmost_route_uri);
988
 
            pj_list_erase(first_route_hdr);
989
 
            tdata->saved_strict_route = first_route_hdr;
990
 
            if (first_route_hdr == last_route_hdr)
991
 
                first_route_hdr = last_route_hdr = NULL;
992
 
        }
993
 
 
994
 
        target_uri = (pjsip_uri*)topmost_route_uri;
995
 
 
996
 
    } else {
997
 
        target_uri = new_request_uri = tdata->msg->line.req.uri;
998
 
    }
999
 
 
1000
 
    /* Fill up the destination host/port from the URI. */
1001
 
    status = get_dest_info(target_uri, tdata->pool, dest_info);
1002
 
    if (status != PJ_SUCCESS)
1003
 
        return status;
1004
 
 
1005
 
    /* If target URI is different than request URI, replace
1006
 
     * request URI add put the original URI in the last Route header.
1007
 
     */
1008
 
    if (new_request_uri && new_request_uri!=tdata->msg->line.req.uri) {
1009
 
        pjsip_route_hdr *route = pjsip_route_hdr_create(tdata->pool);
1010
 
        route->name_addr.uri = (pjsip_uri*)
1011
 
                               pjsip_uri_get_uri(tdata->msg->line.req.uri);
1012
 
        if (last_route_hdr)
1013
 
            pj_list_insert_after(last_route_hdr, route);
1014
 
        else
1015
 
            pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route);
1016
 
        tdata->msg->line.req.uri = (pjsip_uri*)new_request_uri;
1017
 
    }
1018
 
 
1019
 
    /* Success. */
1020
 
    return PJ_SUCCESS;
1021
 
}
1022
 
 
1023
 
 
1024
 
/*
1025
 
 * Swap the request URI and strict route back to the original position
1026
 
 * before #pjsip_process_route_set() function is called. This function
1027
 
 * should only used internally by PJSIP client authentication module.
1028
 
 */
1029
 
PJ_DEF(void) pjsip_restore_strict_route_set(pjsip_tx_data *tdata)
1030
 
{
1031
 
    pjsip_route_hdr *first_route_hdr, *last_route_hdr;
1032
 
 
1033
 
    /* Check if we have found strict route before */
1034
 
    if (tdata->saved_strict_route == NULL) {
1035
 
        /* This request doesn't contain strict route */
1036
 
        return;
1037
 
    }
1038
 
 
1039
 
    /* Find the first "Route" headers from the message. */
1040
 
    first_route_hdr = (pjsip_route_hdr*)
1041
 
                      pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
1042
 
 
1043
 
    if (first_route_hdr == NULL) {
1044
 
        /* User has modified message route? We don't expect this! */
1045
 
        pj_assert(!"Message route was modified?");
1046
 
        tdata->saved_strict_route = NULL;
1047
 
        return;
1048
 
    }
1049
 
 
1050
 
    /* Find last Route header */
1051
 
    last_route_hdr = first_route_hdr;
1052
 
    while (last_route_hdr->next != (void*)&tdata->msg->hdr) {
1053
 
        pjsip_route_hdr *hdr;
1054
 
        hdr = (pjsip_route_hdr*)
1055
 
              pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE,
1056
 
                                 last_route_hdr->next);
1057
 
        if (!hdr)
1058
 
            break;
1059
 
        last_route_hdr = hdr;
1060
 
    }
1061
 
 
1062
 
    /* Put the last Route header as request URI, delete last Route
1063
 
     * header, and insert the saved strict route as the first Route.
1064
 
     */
1065
 
    tdata->msg->line.req.uri = last_route_hdr->name_addr.uri;
1066
 
    pj_list_insert_before(first_route_hdr, tdata->saved_strict_route);
1067
 
    pj_list_erase(last_route_hdr);
1068
 
 
1069
 
    /* Reset */
1070
 
    tdata->saved_strict_route = NULL;
1071
 
}
1072
 
 
1073
 
 
1074
 
/* Transport callback for sending stateless request.
1075
 
 * This is one of the most bizzare function in pjsip, so
1076
 
 * good luck if you happen to debug this function!!
1077
 
 */
1078
 
static void stateless_send_transport_cb( void *token,
1079
 
                                         pjsip_tx_data *tdata,
1080
 
                                         pj_ssize_t sent )
1081
 
{
1082
 
    pjsip_send_state *stateless_data = (pjsip_send_state*) token;
1083
 
 
1084
 
    PJ_UNUSED_ARG(tdata);
1085
 
    pj_assert(tdata == stateless_data->tdata);
1086
 
 
1087
 
    for (;;) {
1088
 
        pj_status_t status;
1089
 
        pj_bool_t cont;
1090
 
 
1091
 
        pj_sockaddr_t *cur_addr;
1092
 
        pjsip_transport_type_e cur_addr_type;
1093
 
        int cur_addr_len;
1094
 
 
1095
 
        pjsip_via_hdr *via;
1096
 
 
1097
 
        if (sent == -PJ_EPENDING) {
1098
 
            /* This is the initial process.
1099
 
             * When the process started, this function will be called by
1100
 
             * stateless_send_resolver_callback() with sent argument set to
1101
 
             * -PJ_EPENDING.
1102
 
             */
1103
 
            cont = PJ_TRUE;
1104
 
        } else {
1105
 
            /* There are two conditions here:
1106
 
             * (1) Message is sent (i.e. sent > 0),
1107
 
             * (2) Failure (i.e. sent <= 0)
1108
 
             */
1109
 
            cont = (sent > 0) ? PJ_FALSE :
1110
 
                   (tdata->dest_info.cur_addr<tdata->dest_info.addr.count-1);
1111
 
            if (stateless_data->app_cb) {
1112
 
                (*stateless_data->app_cb)(stateless_data, sent, &cont);
1113
 
            } else {
1114
 
                /* Doesn't have application callback.
1115
 
                 * Terminate the process.
1116
 
                 */
1117
 
                cont = PJ_FALSE;
1118
 
            }
1119
 
        }
1120
 
 
1121
 
        /* Finished with this transport. */
1122
 
        if (stateless_data->cur_transport) {
1123
 
            pjsip_transport_dec_ref(stateless_data->cur_transport);
1124
 
            stateless_data->cur_transport = NULL;
1125
 
        }
1126
 
 
1127
 
        /* Done if application doesn't want to continue. */
1128
 
        if (sent > 0 || !cont) {
1129
 
            pjsip_tx_data_dec_ref(tdata);
1130
 
            return;
1131
 
        }
1132
 
 
1133
 
        /* Try next address, if any, and only when this is not the
1134
 
         * first invocation.
1135
 
         */
1136
 
        if (sent != -PJ_EPENDING) {
1137
 
            tdata->dest_info.cur_addr++;
1138
 
        }
1139
 
 
1140
 
        /* Have next address? */
1141
 
        if (tdata->dest_info.cur_addr >= tdata->dest_info.addr.count) {
1142
 
            /* This only happens when a rather buggy application has
1143
 
             * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE.
1144
 
             * In this case just stop the processing; we don't need to
1145
 
             * call the callback again as application has been informed
1146
 
             * before.
1147
 
             */
1148
 
            pjsip_tx_data_dec_ref(tdata);
1149
 
            return;
1150
 
        }
1151
 
 
1152
 
        /* Keep current server address information handy. */
1153
 
        cur_addr = &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr;
1154
 
        cur_addr_type = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].type;
1155
 
        cur_addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len;
1156
 
 
1157
 
        /* Acquire transport. */
1158
 
        status = pjsip_endpt_acquire_transport2(stateless_data->endpt,
1159
 
                                                cur_addr_type,
1160
 
                                                cur_addr,
1161
 
                                                cur_addr_len,
1162
 
                                                &tdata->tp_sel,
1163
 
                                                tdata,
1164
 
                                                &stateless_data->cur_transport);
1165
 
        if (status != PJ_SUCCESS) {
1166
 
            sent = -status;
1167
 
            continue;
1168
 
        }
1169
 
 
1170
 
        /* Modify Via header. */
1171
 
        via = (pjsip_via_hdr*) pjsip_msg_find_hdr( tdata->msg,
1172
 
                                                   PJSIP_H_VIA, NULL);
1173
 
        if (!via) {
1174
 
            /* Shouldn't happen if request was created with PJSIP API!
1175
 
             * But we handle the case anyway for robustness.
1176
 
             */
1177
 
            pj_assert(!"Via header not found!");
1178
 
            via = pjsip_via_hdr_create(tdata->pool);
1179
 
            pjsip_msg_insert_first_hdr(tdata->msg, (pjsip_hdr*)via);
1180
 
        }
1181
 
 
1182
 
        if (via->branch_param.slen == 0) {
1183
 
            pj_str_t tmp;
1184
 
            via->branch_param.ptr = (char*)pj_pool_alloc(tdata->pool,
1185
 
                                                         PJSIP_MAX_BRANCH_LEN);
1186
 
            via->branch_param.slen = PJSIP_MAX_BRANCH_LEN;
1187
 
            pj_memcpy(via->branch_param.ptr, PJSIP_RFC3261_BRANCH_ID,
1188
 
                      PJSIP_RFC3261_BRANCH_LEN);
1189
 
            tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;
1190
 
            *(tmp.ptr-2) = 80; *(tmp.ptr-1) = 106;
1191
 
            pj_generate_unique_string(&tmp);
1192
 
        }
1193
 
 
1194
 
        via->transport = pj_str(stateless_data->cur_transport->type_name);
1195
 
        if (tdata->via_addr.host.slen > 0 &&
1196
 
            tdata->via_tp == (void *)stateless_data->cur_transport)
1197
 
        {
1198
 
            via->sent_by = tdata->via_addr;
1199
 
        } else {
1200
 
            via->sent_by = stateless_data->cur_transport->local_name;
1201
 
        }
1202
 
        via->rport_param = pjsip_cfg()->endpt.disable_rport ? -1 : 0;
1203
 
 
1204
 
        pjsip_tx_data_invalidate_msg(tdata);
1205
 
 
1206
 
        /* Send message using this transport. */
1207
 
        status = pjsip_transport_send( stateless_data->cur_transport,
1208
 
                                       tdata,
1209
 
                                       cur_addr,
1210
 
                                       cur_addr_len,
1211
 
                                       stateless_data,
1212
 
                                       &stateless_send_transport_cb);
1213
 
        if (status == PJ_SUCCESS) {
1214
 
            /* Recursively call this function. */
1215
 
            sent = tdata->buf.cur - tdata->buf.start;
1216
 
            stateless_send_transport_cb( stateless_data, tdata, sent );
1217
 
            return;
1218
 
        } else if (status == PJ_EPENDING) {
1219
 
            /* This callback will be called later. */
1220
 
            return;
1221
 
        } else {
1222
 
            /* Recursively call this function. */
1223
 
            sent = -status;
1224
 
            stateless_send_transport_cb( stateless_data, tdata, sent );
1225
 
            return;
1226
 
        }
1227
 
    }
1228
 
 
1229
 
}
1230
 
 
1231
 
/* Resolver callback for sending stateless request. */
1232
 
static void
1233
 
stateless_send_resolver_callback( pj_status_t status,
1234
 
                                  void *token,
1235
 
                                  const struct pjsip_server_addresses *addr)
1236
 
{
1237
 
    pjsip_send_state *stateless_data = (pjsip_send_state*) token;
1238
 
    pjsip_tx_data *tdata = stateless_data->tdata;
1239
 
 
1240
 
    /* Fail on server resolution. */
1241
 
    if (status != PJ_SUCCESS) {
1242
 
        if (stateless_data->app_cb) {
1243
 
            pj_bool_t cont = PJ_FALSE;
1244
 
            (*stateless_data->app_cb)(stateless_data, -status, &cont);
1245
 
        }
1246
 
        pjsip_tx_data_dec_ref(tdata);
1247
 
        return;
1248
 
    }
1249
 
 
1250
 
    /* Copy server addresses */
1251
 
    if (addr && addr != &tdata->dest_info.addr) {
1252
 
        pj_memcpy( &tdata->dest_info.addr, addr,
1253
 
                   sizeof(pjsip_server_addresses));
1254
 
    }
1255
 
    pj_assert(tdata->dest_info.addr.count != 0);
1256
 
 
1257
 
    /* RFC 3261 section 18.1.1:
1258
 
     * If a request is within 200 bytes of the path MTU, or if it is larger
1259
 
     * than 1300 bytes and the path MTU is unknown, the request MUST be sent
1260
 
     * using an RFC 2914 [43] congestion controlled transport protocol, such
1261
 
     * as TCP.
1262
 
     */
1263
 
    if (pjsip_cfg()->endpt.disable_tcp_switch==0 &&
1264
 
        tdata->msg->type == PJSIP_REQUEST_MSG &&
1265
 
        tdata->dest_info.addr.count > 0 &&
1266
 
        tdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP)
1267
 
    {
1268
 
        int len;
1269
 
 
1270
 
        /* Encode the request */
1271
 
        status = pjsip_tx_data_encode(tdata);
1272
 
        if (status != PJ_SUCCESS) {
1273
 
            if (stateless_data->app_cb) {
1274
 
                pj_bool_t cont = PJ_FALSE;
1275
 
                (*stateless_data->app_cb)(stateless_data, -status, &cont);
1276
 
            }
1277
 
            pjsip_tx_data_dec_ref(tdata);
1278
 
            return;
1279
 
        }
1280
 
 
1281
 
        /* Check if request message is larger than 1300 bytes. */
1282
 
        len = tdata->buf.cur - tdata->buf.start;
1283
 
        if (len >= PJSIP_UDP_SIZE_THRESHOLD) {
1284
 
            int i;
1285
 
            int count = tdata->dest_info.addr.count;
1286
 
 
1287
 
            PJ_LOG(5,(THIS_FILE, "%s exceeds UDP size threshold (%u), "
1288
 
                                 "sending with TCP",
1289
 
                                 pjsip_tx_data_get_info(tdata),
1290
 
                                 PJSIP_UDP_SIZE_THRESHOLD));
1291
 
 
1292
 
            /* Insert "TCP version" of resolved UDP addresses at the
1293
 
             * beginning.
1294
 
             */
1295
 
            if (count * 2 > PJSIP_MAX_RESOLVED_ADDRESSES)
1296
 
                count = PJSIP_MAX_RESOLVED_ADDRESSES / 2;
1297
 
            for (i = 0; i < count; ++i) {
1298
 
                pj_memcpy(&tdata->dest_info.addr.entry[i+count],
1299
 
                          &tdata->dest_info.addr.entry[i],
1300
 
                          sizeof(tdata->dest_info.addr.entry[0]));
1301
 
                tdata->dest_info.addr.entry[i].type = PJSIP_TRANSPORT_TCP;
1302
 
            }
1303
 
            tdata->dest_info.addr.count = count * 2;
1304
 
        }
1305
 
    }
1306
 
 
1307
 
    /* Process the addresses. */
1308
 
    stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING);
1309
 
}
1310
 
 
1311
 
/*
1312
 
 * Send stateless request.
1313
 
 * The sending process consists of several stages:
1314
 
 *  - determine which host to contact (#pjsip_get_request_addr).
1315
 
 *  - resolve the host (#pjsip_endpt_resolve)
1316
 
 *  - establish transport (#pjsip_endpt_acquire_transport)
1317
 
 *  - send the message (#pjsip_transport_send)
1318
 
 */
1319
 
PJ_DEF(pj_status_t) pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,
1320
 
                                   pjsip_tx_data *tdata,
1321
 
                                   void *token,
1322
 
                                   pjsip_send_callback cb)
1323
 
{
1324
 
    pjsip_host_info dest_info;
1325
 
    pjsip_send_state *stateless_data;
1326
 
    pj_status_t status;
1327
 
 
1328
 
    PJ_ASSERT_RETURN(endpt && tdata, PJ_EINVAL);
1329
 
 
1330
 
    /* Get destination name to contact. */
1331
 
    status = pjsip_process_route_set(tdata, &dest_info);
1332
 
    if (status != PJ_SUCCESS)
1333
 
        return status;
1334
 
 
1335
 
    /* Keep stateless data. */
1336
 
    stateless_data = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_send_state);
1337
 
    stateless_data->token = token;
1338
 
    stateless_data->endpt = endpt;
1339
 
    stateless_data->tdata = tdata;
1340
 
    stateless_data->app_cb = cb;
1341
 
 
1342
 
    /* If destination info has not been initialized (this applies for most
1343
 
     * all requests except CANCEL), resolve destination host. The processing
1344
 
     * then resumed when the resolving callback is called. For CANCEL, the
1345
 
     * destination info must have been copied from the original INVITE so
1346
 
     * proceed to sending the request directly.
1347
 
     */
1348
 
    if (tdata->dest_info.addr.count == 0) {
1349
 
        /* Copy the destination host name to TX data */
1350
 
        pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);
1351
 
 
1352
 
        pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data,
1353
 
                             &stateless_send_resolver_callback);
1354
 
    } else {
1355
 
        PJ_LOG(5,(THIS_FILE, "%s: skipping target resolution because "
1356
 
                             "address is already set",
1357
 
                             pjsip_tx_data_get_info(tdata)));
1358
 
        stateless_send_resolver_callback(PJ_SUCCESS, stateless_data,
1359
 
                                         &tdata->dest_info.addr);
1360
 
    }
1361
 
    return PJ_SUCCESS;
1362
 
}
1363
 
 
1364
 
 
1365
 
/*
1366
 
 * Send raw data to a destination.
1367
 
 */
1368
 
PJ_DEF(pj_status_t) pjsip_endpt_send_raw( pjsip_endpoint *endpt,
1369
 
                                          pjsip_transport_type_e tp_type,
1370
 
                                          const pjsip_tpselector *sel,
1371
 
                                          const void *raw_data,
1372
 
                                          pj_size_t data_len,
1373
 
                                          const pj_sockaddr_t *addr,
1374
 
                                          int addr_len,
1375
 
                                          void *token,
1376
 
                                          pjsip_tp_send_callback cb)
1377
 
{
1378
 
    return pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(endpt), tp_type, sel,
1379
 
                                NULL, raw_data, data_len, addr, addr_len,
1380
 
                                token, cb);
1381
 
}
1382
 
 
1383
 
 
1384
 
/* Callback data for sending raw data */
1385
 
struct send_raw_data
1386
 
{
1387
 
    pjsip_endpoint          *endpt;
1388
 
    pjsip_tx_data           *tdata;
1389
 
    pjsip_tpselector        *sel;
1390
 
    void                    *app_token;
1391
 
    pjsip_tp_send_callback   app_cb;
1392
 
};
1393
 
 
1394
 
 
1395
 
/* Resolver callback for sending raw data. */
1396
 
static void send_raw_resolver_callback( pj_status_t status,
1397
 
                                        void *token,
1398
 
                                        const pjsip_server_addresses *addr)
1399
 
{
1400
 
    struct send_raw_data *sraw_data = (struct send_raw_data*) token;
1401
 
 
1402
 
    if (status != PJ_SUCCESS) {
1403
 
        if (sraw_data->app_cb) {
1404
 
            (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
1405
 
                                 -status);
1406
 
        }
1407
 
    } else {
1408
 
        pj_size_t data_len;
1409
 
 
1410
 
        pj_assert(addr->count != 0);
1411
 
 
1412
 
        /* Avoid tdata destroyed by pjsip_tpmgr_send_raw(). */
1413
 
        pjsip_tx_data_add_ref(sraw_data->tdata);
1414
 
 
1415
 
        data_len = sraw_data->tdata->buf.cur - sraw_data->tdata->buf.start;
1416
 
        status = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(sraw_data->endpt),
1417
 
                                      addr->entry[0].type,
1418
 
                                      sraw_data->sel, sraw_data->tdata,
1419
 
                                      sraw_data->tdata->buf.start, data_len,
1420
 
                                      &addr->entry[0].addr,
1421
 
                                      addr->entry[0].addr_len,
1422
 
                                      sraw_data->app_token,
1423
 
                                      sraw_data->app_cb);
1424
 
        if (status == PJ_SUCCESS) {
1425
 
            (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
1426
 
                                 data_len);
1427
 
        } else if (status != PJ_EPENDING) {
1428
 
            (*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
1429
 
                                 -status);
1430
 
        }
1431
 
    }
1432
 
 
1433
 
    if (sraw_data->sel) {
1434
 
        pjsip_tpselector_dec_ref(sraw_data->sel);
1435
 
    }
1436
 
    pjsip_tx_data_dec_ref(sraw_data->tdata);
1437
 
}
1438
 
 
1439
 
 
1440
 
/*
1441
 
 * Send raw data to the specified destination URI.
1442
 
 */
1443
 
PJ_DEF(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
1444
 
                                                const pj_str_t *p_dst_uri,
1445
 
                                                const pjsip_tpselector *sel,
1446
 
                                                const void *raw_data,
1447
 
                                                pj_size_t data_len,
1448
 
                                                void *token,
1449
 
                                                pjsip_tp_send_callback cb)
1450
 
{
1451
 
    pjsip_tx_data *tdata;
1452
 
    struct send_raw_data *sraw_data;
1453
 
    pj_str_t dst_uri;
1454
 
    pjsip_uri *uri;
1455
 
    pjsip_host_info dest_info;
1456
 
    pj_status_t status;
1457
 
 
1458
 
    /* Allocate buffer */
1459
 
    status = pjsip_endpt_create_tdata(endpt, &tdata);
1460
 
    if (status != PJ_SUCCESS)
1461
 
        return status;
1462
 
 
1463
 
    pjsip_tx_data_add_ref(tdata);
1464
 
 
1465
 
    /* Duplicate URI since parser requires URI to be NULL terminated */
1466
 
    pj_strdup_with_null(tdata->pool, &dst_uri, p_dst_uri);
1467
 
 
1468
 
    /* Parse URI */
1469
 
    uri = pjsip_parse_uri(tdata->pool, dst_uri.ptr, dst_uri.slen, 0);
1470
 
    if (uri == NULL) {
1471
 
        pjsip_tx_data_dec_ref(tdata);
1472
 
        return PJSIP_EINVALIDURI;
1473
 
    }
1474
 
 
1475
 
    /* Build destination info. */
1476
 
    status = get_dest_info(uri, tdata->pool, &dest_info);
1477
 
    if (status != PJ_SUCCESS) {
1478
 
        pjsip_tx_data_dec_ref(tdata);
1479
 
        return status;
1480
 
    }
1481
 
 
1482
 
    /* Copy data (note: data_len may be zero!) */
1483
 
    tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
1484
 
    tdata->buf.end = tdata->buf.start + data_len + 1;
1485
 
    if (data_len)
1486
 
        pj_memcpy(tdata->buf.start, raw_data, data_len);
1487
 
    tdata->buf.cur = tdata->buf.start + data_len;
1488
 
 
1489
 
    /* Init send_raw_data */
1490
 
    sraw_data = PJ_POOL_ZALLOC_T(tdata->pool, struct send_raw_data);
1491
 
    sraw_data->endpt = endpt;
1492
 
    sraw_data->tdata = tdata;
1493
 
    sraw_data->app_token = token;
1494
 
    sraw_data->app_cb = cb;
1495
 
 
1496
 
    if (sel) {
1497
 
        sraw_data->sel = PJ_POOL_ALLOC_T(tdata->pool, pjsip_tpselector);
1498
 
        pj_memcpy(sraw_data->sel, sel, sizeof(pjsip_tpselector));
1499
 
        pjsip_tpselector_add_ref(sraw_data->sel);
1500
 
    }
1501
 
 
1502
 
    /* Copy the destination host name to TX data */
1503
 
    pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);
1504
 
 
1505
 
    /* Resolve destination host.
1506
 
     * The processing then resumed when the resolving callback is called.
1507
 
     */
1508
 
    pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, sraw_data,
1509
 
                         &send_raw_resolver_callback);
1510
 
    return PJ_SUCCESS;
1511
 
}
1512
 
 
1513
 
 
1514
 
/*
1515
 
 * Determine which address (and transport) to use to send response message
1516
 
 * based on the received request. This function follows the specification
1517
 
 * in section 18.2.2 of RFC 3261 and RFC 3581 for calculating the destination
1518
 
 * address and transport.
1519
 
 */
1520
 
PJ_DEF(pj_status_t) pjsip_get_response_addr( pj_pool_t *pool,
1521
 
                                             pjsip_rx_data *rdata,
1522
 
                                             pjsip_response_addr *res_addr )
1523
 
{
1524
 
    pjsip_transport *src_transport = rdata->tp_info.transport;
1525
 
 
1526
 
    /* Check arguments. */
1527
 
    PJ_ASSERT_RETURN(pool && rdata && res_addr, PJ_EINVAL);
1528
 
 
1529
 
    /* rdata must be a request message! */
1530
 
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
1531
 
                     PJ_EINVAL);
1532
 
 
1533
 
    /* All requests must have "received" parameter.
1534
 
     * This must always be done in transport layer.
1535
 
     */
1536
 
    pj_assert(rdata->msg_info.via->recvd_param.slen != 0);
1537
 
 
1538
 
    /* Do the calculation based on RFC 3261 Section 18.2.2 and RFC 3581 */
1539
 
 
1540
 
    if (PJSIP_TRANSPORT_IS_RELIABLE(src_transport)) {
1541
 
        /* For reliable protocol such as TCP or SCTP, or TLS over those, the
1542
 
         * response MUST be sent using the existing connection to the source
1543
 
         * of the original request that created the transaction, if that
1544
 
         * connection is still open.
1545
 
         * If that connection is no longer open, the server SHOULD open a
1546
 
         * connection to the IP address in the received parameter, if present,
1547
 
         * using the port in the sent-by value, or the default port for that
1548
 
         * transport, if no port is specified.
1549
 
         * If that connection attempt fails, the server SHOULD use the
1550
 
         * procedures in [4] for servers in order to determine the IP address
1551
 
         * and port to open the connection and send the response to.
1552
 
         */
1553
 
        res_addr->transport = rdata->tp_info.transport;
1554
 
        pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr,
1555
 
                  rdata->pkt_info.src_addr_len);
1556
 
        res_addr->addr_len = rdata->pkt_info.src_addr_len;
1557
 
        res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1558
 
        res_addr->dst_host.flag = src_transport->flag;
1559
 
        pj_strdup( pool, &res_addr->dst_host.addr.host,
1560
 
                   &rdata->msg_info.via->recvd_param);
1561
 
        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1562
 
        if (res_addr->dst_host.addr.port == 0) {
1563
 
            res_addr->dst_host.addr.port =
1564
 
                pjsip_transport_get_default_port_for_type(res_addr->dst_host.type);
1565
 
        }
1566
 
 
1567
 
    } else if (rdata->msg_info.via->maddr_param.slen) {
1568
 
        /* Otherwise, if the Via header field value contains a maddr parameter,
1569
 
         * the response MUST be forwarded to the address listed there, using
1570
 
         * the port indicated in sent-by, or port 5060 if none is present.
1571
 
         * If the address is a multicast address, the response SHOULD be sent
1572
 
         * using the TTL indicated in the ttl parameter, or with a TTL of 1 if
1573
 
         * that parameter is not present.
1574
 
         */
1575
 
        res_addr->transport = NULL;
1576
 
        res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1577
 
        res_addr->dst_host.flag = src_transport->flag;
1578
 
        pj_strdup( pool, &res_addr->dst_host.addr.host,
1579
 
                   &rdata->msg_info.via->maddr_param);
1580
 
        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1581
 
        if (res_addr->dst_host.addr.port == 0)
1582
 
            res_addr->dst_host.addr.port = 5060;
1583
 
 
1584
 
    } else if (rdata->msg_info.via->rport_param >= 0) {
1585
 
        /* There is both a "received" parameter and an "rport" parameter,
1586
 
         * the response MUST be sent to the IP address listed in the "received"
1587
 
         * parameter, and the port in the "rport" parameter.
1588
 
         * The response MUST be sent from the same address and port that the
1589
 
         * corresponding request was received on.
1590
 
         */
1591
 
        res_addr->transport = rdata->tp_info.transport;
1592
 
        pj_memcpy(&res_addr->addr, &rdata->pkt_info.src_addr,
1593
 
                  rdata->pkt_info.src_addr_len);
1594
 
        res_addr->addr_len = rdata->pkt_info.src_addr_len;
1595
 
        res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1596
 
        res_addr->dst_host.flag = src_transport->flag;
1597
 
        pj_strdup( pool, &res_addr->dst_host.addr.host,
1598
 
                   &rdata->msg_info.via->recvd_param);
1599
 
        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1600
 
        if (res_addr->dst_host.addr.port == 0) {
1601
 
            res_addr->dst_host.addr.port =
1602
 
                pjsip_transport_get_default_port_for_type(res_addr->dst_host.type);
1603
 
        }
1604
 
 
1605
 
    } else {
1606
 
        res_addr->transport = NULL;
1607
 
        res_addr->dst_host.type=(pjsip_transport_type_e)src_transport->key.type;
1608
 
        res_addr->dst_host.flag = src_transport->flag;
1609
 
        pj_strdup( pool, &res_addr->dst_host.addr.host,
1610
 
                   &rdata->msg_info.via->recvd_param);
1611
 
        res_addr->dst_host.addr.port = rdata->msg_info.via->sent_by.port;
1612
 
        if (res_addr->dst_host.addr.port == 0) {
1613
 
            res_addr->dst_host.addr.port =
1614
 
                pjsip_transport_get_default_port_for_type(res_addr->dst_host.type);
1615
 
        }
1616
 
    }
1617
 
 
1618
 
    return PJ_SUCCESS;
1619
 
}
1620
 
 
1621
 
/*
1622
 
 * Callback called by transport during send_response.
1623
 
 */
1624
 
static void send_response_transport_cb(void *token, pjsip_tx_data *tdata,
1625
 
                                       pj_ssize_t sent)
1626
 
{
1627
 
    pjsip_send_state *send_state = (pjsip_send_state*) token;
1628
 
    pj_bool_t cont = PJ_FALSE;
1629
 
 
1630
 
    /* Call callback, if any. */
1631
 
    if (send_state->app_cb)
1632
 
        (*send_state->app_cb)(send_state, sent, &cont);
1633
 
 
1634
 
    /* Decrement transport reference counter. */
1635
 
    pjsip_transport_dec_ref(send_state->cur_transport);
1636
 
 
1637
 
    /* Decrement transmit data ref counter. */
1638
 
    pjsip_tx_data_dec_ref(tdata);
1639
 
}
1640
 
 
1641
 
/*
1642
 
 * Resolver calback during send_response.
1643
 
 */
1644
 
static void send_response_resolver_cb( pj_status_t status, void *token,
1645
 
                                       const pjsip_server_addresses *addr )
1646
 
{
1647
 
    pjsip_send_state *send_state = (pjsip_send_state*) token;
1648
 
 
1649
 
    if (status != PJ_SUCCESS) {
1650
 
        if (send_state->app_cb) {
1651
 
            pj_bool_t cont = PJ_FALSE;
1652
 
            (*send_state->app_cb)(send_state, -status, &cont);
1653
 
        }
1654
 
        pjsip_tx_data_dec_ref(send_state->tdata);
1655
 
        return;
1656
 
    }
1657
 
 
1658
 
    /* Only handle the first address resolved. */
1659
 
 
1660
 
    /* Acquire transport. */
1661
 
    status = pjsip_endpt_acquire_transport2(send_state->endpt,
1662
 
                                            addr->entry[0].type,
1663
 
                                            &addr->entry[0].addr,
1664
 
                                            addr->entry[0].addr_len,
1665
 
                                            &send_state->tdata->tp_sel,
1666
 
                                            send_state->tdata,
1667
 
                                            &send_state->cur_transport);
1668
 
    if (status != PJ_SUCCESS) {
1669
 
        if (send_state->app_cb) {
1670
 
            pj_bool_t cont = PJ_FALSE;
1671
 
            (*send_state->app_cb)(send_state, -status, &cont);
1672
 
        }
1673
 
        pjsip_tx_data_dec_ref(send_state->tdata);
1674
 
        return;
1675
 
    }
1676
 
 
1677
 
    /* Update address in send_state. */
1678
 
    pj_memcpy(&send_state->tdata->dest_info.addr, addr, sizeof(*addr));
1679
 
 
1680
 
    /* Send response using the transoprt. */
1681
 
    status = pjsip_transport_send( send_state->cur_transport,
1682
 
                                   send_state->tdata,
1683
 
                                   &addr->entry[0].addr,
1684
 
                                   addr->entry[0].addr_len,
1685
 
                                   send_state,
1686
 
                                   &send_response_transport_cb);
1687
 
    if (status == PJ_SUCCESS) {
1688
 
        pj_ssize_t sent = send_state->tdata->buf.cur -
1689
 
                          send_state->tdata->buf.start;
1690
 
        send_response_transport_cb(send_state, send_state->tdata, sent);
1691
 
 
1692
 
    } else if (status == PJ_EPENDING) {
1693
 
        /* Transport callback will be called later. */
1694
 
    } else {
1695
 
        send_response_transport_cb(send_state, send_state->tdata, -status);
1696
 
    }
1697
 
}
1698
 
 
1699
 
/*
1700
 
 * Send response.
1701
 
 */
1702
 
PJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,
1703
 
                                               pjsip_response_addr *res_addr,
1704
 
                                               pjsip_tx_data *tdata,
1705
 
                                               void *token,
1706
 
                                               pjsip_send_callback cb)
1707
 
{
1708
 
    /* Determine which transports and addresses to send the response,
1709
 
     * based on Section 18.2.2 of RFC 3261.
1710
 
     */
1711
 
    pjsip_send_state *send_state;
1712
 
    pj_status_t status;
1713
 
 
1714
 
    /* Create structure to keep the sending state. */
1715
 
    send_state = PJ_POOL_ZALLOC_T(tdata->pool, pjsip_send_state);
1716
 
    send_state->endpt = endpt;
1717
 
    send_state->tdata = tdata;
1718
 
    send_state->token = token;
1719
 
    send_state->app_cb = cb;
1720
 
 
1721
 
    if (res_addr->transport != NULL) {
1722
 
        send_state->cur_transport = res_addr->transport;
1723
 
        pjsip_transport_add_ref(send_state->cur_transport);
1724
 
 
1725
 
        status = pjsip_transport_send( send_state->cur_transport, tdata,
1726
 
                                       &res_addr->addr,
1727
 
                                       res_addr->addr_len,
1728
 
                                       send_state,
1729
 
                                       &send_response_transport_cb );
1730
 
        if (status == PJ_SUCCESS) {
1731
 
            pj_ssize_t sent = tdata->buf.cur - tdata->buf.start;
1732
 
            send_response_transport_cb(send_state, tdata, sent);
1733
 
            return PJ_SUCCESS;
1734
 
        } else if (status == PJ_EPENDING) {
1735
 
            /* Callback will be called later. */
1736
 
            return PJ_SUCCESS;
1737
 
        } else {
1738
 
            pjsip_transport_dec_ref(send_state->cur_transport);
1739
 
            return status;
1740
 
        }
1741
 
    } else {
1742
 
        /* Copy the destination host name to TX data */
1743
 
        pj_strdup(tdata->pool, &tdata->dest_info.name,
1744
 
                  &res_addr->dst_host.addr.host);
1745
 
 
1746
 
        pjsip_endpt_resolve(endpt, tdata->pool, &res_addr->dst_host,
1747
 
                            send_state, &send_response_resolver_cb);
1748
 
        return PJ_SUCCESS;
1749
 
    }
1750
 
}
1751
 
 
1752
 
/*
1753
 
 * Send response combo
1754
 
 */
1755
 
PJ_DEF(pj_status_t) pjsip_endpt_send_response2( pjsip_endpoint *endpt,
1756
 
                                                pjsip_rx_data *rdata,
1757
 
                                                pjsip_tx_data *tdata,
1758
 
                                                void *token,
1759
 
                                                pjsip_send_callback cb)
1760
 
{
1761
 
    pjsip_response_addr res_addr;
1762
 
    pj_status_t status;
1763
 
 
1764
 
    status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
1765
 
    if (status != PJ_SUCCESS) {
1766
 
        pjsip_tx_data_dec_ref(tdata);
1767
 
        return PJ_SUCCESS;
1768
 
    }
1769
 
 
1770
 
    status = pjsip_endpt_send_response(endpt, &res_addr, tdata, token, cb);
1771
 
    return status;
1772
 
}
1773
 
 
1774
 
 
1775
 
/*
1776
 
 * Send response
1777
 
 */
1778
 
PJ_DEF(pj_status_t) pjsip_endpt_respond_stateless( pjsip_endpoint *endpt,
1779
 
                                                   pjsip_rx_data *rdata,
1780
 
                                                   int st_code,
1781
 
                                                   const pj_str_t *st_text,
1782
 
                                                   const pjsip_hdr *hdr_list,
1783
 
                                                   const pjsip_msg_body *body)
1784
 
{
1785
 
    pj_status_t status;
1786
 
    pjsip_response_addr res_addr;
1787
 
    pjsip_tx_data *tdata;
1788
 
 
1789
 
    /* Verify arguments. */
1790
 
    PJ_ASSERT_RETURN(endpt && rdata, PJ_EINVAL);
1791
 
    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
1792
 
                     PJSIP_ENOTREQUESTMSG);
1793
 
 
1794
 
    /* Check that no UAS transaction has been created for this request.
1795
 
     * If UAS transaction has been created for this request, application
1796
 
     * MUST send the response statefully using that transaction.
1797
 
     */
1798
 
    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata)==NULL, PJ_EINVALIDOP);
1799
 
 
1800
 
    /* Create response message */
1801
 
    status = pjsip_endpt_create_response( endpt, rdata, st_code, st_text,
1802
 
                                          &tdata);
1803
 
    if (status != PJ_SUCCESS)
1804
 
        return status;
1805
 
 
1806
 
    /* Add the message headers, if any */
1807
 
    if (hdr_list) {
1808
 
        const pjsip_hdr *hdr = hdr_list->next;
1809
 
        while (hdr != hdr_list) {
1810
 
            pjsip_msg_add_hdr(tdata->msg,
1811
 
                              (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr) );
1812
 
            hdr = hdr->next;
1813
 
        }
1814
 
    }
1815
 
 
1816
 
    /* Add the message body, if any. */
1817
 
    if (body) {
1818
 
        tdata->msg->body = pjsip_msg_body_clone( tdata->pool, body );
1819
 
        if (tdata->msg->body == NULL) {
1820
 
            pjsip_tx_data_dec_ref(tdata);
1821
 
            return status;
1822
 
        }
1823
 
    }
1824
 
 
1825
 
    /* Get where to send request. */
1826
 
    status = pjsip_get_response_addr( tdata->pool, rdata, &res_addr );
1827
 
    if (status != PJ_SUCCESS) {
1828
 
        pjsip_tx_data_dec_ref(tdata);
1829
 
        return status;
1830
 
    }
1831
 
 
1832
 
    /* Send! */
1833
 
    status = pjsip_endpt_send_response( endpt, &res_addr, tdata, NULL, NULL );
1834
 
    if (status != PJ_SUCCESS) {
1835
 
        pjsip_tx_data_dec_ref(tdata);
1836
 
        return status;
1837
 
    }
1838
 
 
1839
 
    return PJ_SUCCESS;
1840
 
}
1841
 
 
1842
 
 
1843
 
/*
1844
 
 * Get the event string from the event ID.
1845
 
 */
1846
 
PJ_DEF(const char *) pjsip_event_str(pjsip_event_id_e e)
1847
 
{
1848
 
    return event_str[e];
1849
 
}