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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/pjsip/src/pjsip/sip_transport.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: sip_transport.c 4775 2014-03-04 02:18:51Z nanang $ */
 
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_transport.h>
 
21
#include <pjsip/sip_endpoint.h>
 
22
#include <pjsip/sip_parser.h>
 
23
#include <pjsip/sip_msg.h>
 
24
#include <pjsip/sip_private.h>
 
25
#include <pjsip/sip_errno.h>
 
26
#include <pjsip/sip_module.h>
 
27
#include <pj/addr_resolv.h>
 
28
#include <pj/except.h>
 
29
#include <pj/os.h>
 
30
#include <pj/log.h>
 
31
#include <pj/ioqueue.h>
 
32
#include <pj/hash.h>
 
33
#include <pj/string.h>
 
34
#include <pj/pool.h>
 
35
#include <pj/assert.h>
 
36
#include <pj/lock.h>
 
37
#include <pj/list.h>
 
38
 
 
39
 
 
40
#define THIS_FILE    "sip_transport.c"
 
41
 
 
42
#if 0
 
43
#   define TRACE_(x)    PJ_LOG(5,x)
 
44
 
 
45
static const char *addr_string(const pj_sockaddr_t *addr)
 
46
{
 
47
    static char str[PJ_INET6_ADDRSTRLEN];
 
48
    pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family, 
 
49
                 pj_sockaddr_get_addr(addr),
 
50
                 str, sizeof(str));
 
51
    return str;
 
52
}
 
53
#else
 
54
#   define TRACE_(x)
 
55
#endif
 
56
 
 
57
/* Prototype. */
 
58
static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata);
 
59
 
 
60
/* This module has sole purpose to print transmit data to contigous buffer
 
61
 * before actually transmitted to the wire. 
 
62
 */
 
63
static pjsip_module mod_msg_print = 
 
64
{
 
65
    NULL, NULL,                         /* prev and next                    */
 
66
    { "mod-msg-print", 13},             /* Name.                            */
 
67
    -1,                                 /* Id                               */
 
68
    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER, /* Priority                         */
 
69
    NULL,                               /* load()                           */
 
70
    NULL,                               /* start()                          */
 
71
    NULL,                               /* stop()                           */
 
72
    NULL,                               /* unload()                         */
 
73
    NULL,                               /* on_rx_request()                  */
 
74
    NULL,                               /* on_rx_response()                 */
 
75
    &mod_on_tx_msg,                     /* on_tx_request()                  */
 
76
    &mod_on_tx_msg,                     /* on_tx_response()                 */
 
77
    NULL,                               /* on_tsx_state()                   */
 
78
};
 
79
 
 
80
/*
 
81
 * Transport manager.
 
82
 */
 
83
struct pjsip_tpmgr 
 
84
{
 
85
    pj_hash_table_t *table;
 
86
    pj_lock_t       *lock;
 
87
    pjsip_endpoint  *endpt;
 
88
    pjsip_tpfactory  factory_list;
 
89
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
90
    pj_atomic_t     *tdata_counter;
 
91
#endif
 
92
    void           (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*);
 
93
    pj_status_t    (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*);
 
94
    pjsip_tp_state_callback tp_state_cb;
 
95
 
 
96
    /* Transmit data list, for transmit data cleanup when transport manager
 
97
     * is destroyed.
 
98
     */
 
99
    pjsip_tx_data    tdata_list;
 
100
};
 
101
 
 
102
 
 
103
/* Transport state listener list type */
 
104
typedef struct tp_state_listener
 
105
{
 
106
    PJ_DECL_LIST_MEMBER(struct tp_state_listener);
 
107
 
 
108
    pjsip_tp_state_callback  cb;
 
109
    void *user_data;
 
110
} tp_state_listener;
 
111
 
 
112
 
 
113
/*
 
114
 * Transport data.
 
115
 */
 
116
typedef struct transport_data
 
117
{
 
118
    /* Transport listeners */
 
119
    tp_state_listener       st_listeners;
 
120
    tp_state_listener       st_listeners_empty;
 
121
} transport_data;
 
122
 
 
123
 
 
124
/*****************************************************************************
 
125
 *
 
126
 * GENERAL TRANSPORT (NAMES, TYPES, ETC.)
 
127
 *
 
128
 *****************************************************************************/
 
129
 
 
130
/*
 
131
 * Transport names.
 
132
 */
 
133
static struct transport_names_t
 
134
{
 
135
    pjsip_transport_type_e type;            /* Transport type       */
 
136
    pj_uint16_t            port;            /* Default port number  */
 
137
    pj_str_t               name;            /* Id tag               */
 
138
    const char            *description;     /* Longer description   */
 
139
    unsigned               flag;            /* Flags                */
 
140
    char                   name_buf[16];    /* For user's transport */
 
141
} transport_names[16] = 
 
142
{
 
143
    { 
 
144
        PJSIP_TRANSPORT_UNSPECIFIED, 
 
145
        0, 
 
146
        {"Unspecified", 11}, 
 
147
        "Unspecified", 
 
148
        0
 
149
    },
 
150
    { 
 
151
        PJSIP_TRANSPORT_UDP, 
 
152
        5060, 
 
153
        {"UDP", 3}, 
 
154
        "UDP transport", 
 
155
        PJSIP_TRANSPORT_DATAGRAM
 
156
    },
 
157
    { 
 
158
        PJSIP_TRANSPORT_TCP, 
 
159
        5060, 
 
160
        {"TCP", 3}, 
 
161
        "TCP transport", 
 
162
        PJSIP_TRANSPORT_RELIABLE
 
163
    },
 
164
    { 
 
165
        PJSIP_TRANSPORT_TLS, 
 
166
        5061, 
 
167
        {"TLS", 3}, 
 
168
        "TLS transport", 
 
169
        PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
 
170
    },
 
171
    { 
 
172
        PJSIP_TRANSPORT_SCTP, 
 
173
        5060, 
 
174
        {"SCTP", 4}, 
 
175
        "SCTP transport", 
 
176
        PJSIP_TRANSPORT_RELIABLE
 
177
    },
 
178
    { 
 
179
        PJSIP_TRANSPORT_LOOP, 
 
180
        15060, 
 
181
        {"LOOP", 4}, 
 
182
        "Loopback transport", 
 
183
        PJSIP_TRANSPORT_RELIABLE
 
184
    }, 
 
185
    { 
 
186
        PJSIP_TRANSPORT_LOOP_DGRAM, 
 
187
        15060, 
 
188
        {"LOOP-DGRAM", 10}, 
 
189
        "Loopback datagram transport", 
 
190
        PJSIP_TRANSPORT_DATAGRAM
 
191
    },
 
192
    { 
 
193
        PJSIP_TRANSPORT_UDP6, 
 
194
        5060, 
 
195
        {"UDP", 3}, 
 
196
        "UDP IPv6 transport", 
 
197
        PJSIP_TRANSPORT_DATAGRAM
 
198
    },
 
199
    { 
 
200
        PJSIP_TRANSPORT_TCP6, 
 
201
        5060, 
 
202
        {"TCP", 3}, 
 
203
        "TCP IPv6 transport", 
 
204
        PJSIP_TRANSPORT_RELIABLE
 
205
    },
 
206
    {
 
207
        PJSIP_TRANSPORT_TLS6,
 
208
        5061,
 
209
        {"TLS", 3},
 
210
        "TLS IPv6 transport",
 
211
        PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
 
212
    },
 
213
};
 
214
 
 
215
static void tp_state_callback(pjsip_transport *tp,
 
216
                              pjsip_transport_state state,
 
217
                              const pjsip_transport_state_info *info);
 
218
 
 
219
 
 
220
static struct transport_names_t *get_tpname(pjsip_transport_type_e type)
 
221
{
 
222
    unsigned i;
 
223
    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
 
224
        if (transport_names[i].type == type)
 
225
            return &transport_names[i];
 
226
    }
 
227
    pj_assert(!"Invalid transport type!");
 
228
    return NULL;
 
229
}
 
230
 
 
231
 
 
232
 
 
233
/*
 
234
 * Register new transport type to PJSIP.
 
235
 */
 
236
PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
 
237
                                                   const char *tp_name,
 
238
                                                   int def_port,
 
239
                                                   int *p_tp_type)
 
240
{
 
241
    unsigned i;
 
242
 
 
243
    PJ_ASSERT_RETURN(tp_flag && tp_name && def_port, PJ_EINVAL);
 
244
    PJ_ASSERT_RETURN(pj_ansi_strlen(tp_name) < 
 
245
                        PJ_ARRAY_SIZE(transport_names[0].name_buf), 
 
246
                     PJ_ENAMETOOLONG);
 
247
 
 
248
    for (i=1; i<PJ_ARRAY_SIZE(transport_names); ++i) {
 
249
        if (transport_names[i].type == 0)
 
250
            break;
 
251
    }
 
252
 
 
253
    if (i == PJ_ARRAY_SIZE(transport_names))
 
254
        return PJ_ETOOMANY;
 
255
 
 
256
    transport_names[i].type = (pjsip_transport_type_e)i;
 
257
    transport_names[i].port = (pj_uint16_t)def_port;
 
258
    pj_ansi_strcpy(transport_names[i].name_buf, tp_name);
 
259
    transport_names[i].name = pj_str(transport_names[i].name_buf);
 
260
    transport_names[i].flag = tp_flag;
 
261
 
 
262
    if (p_tp_type)
 
263
        *p_tp_type = i;
 
264
 
 
265
    return PJ_SUCCESS;
 
266
}
 
267
 
 
268
 
 
269
/*
 
270
 * Get transport type from name.
 
271
 */
 
272
PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_name(const pj_str_t *name)
 
273
{
 
274
    unsigned i;
 
275
 
 
276
    if (name->slen == 0)
 
277
        return PJSIP_TRANSPORT_UNSPECIFIED;
 
278
 
 
279
    /* Get transport type from name. */
 
280
    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
 
281
        if (pj_stricmp(name, &transport_names[i].name) == 0) {
 
282
            return transport_names[i].type;
 
283
        }
 
284
    }
 
285
 
 
286
    pj_assert(!"Invalid transport name");
 
287
    return PJSIP_TRANSPORT_UNSPECIFIED;
 
288
}
 
289
 
 
290
 
 
291
/*
 
292
 * Get the transport type for the specified flags.
 
293
 */
 
294
PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_flag(unsigned flag)
 
295
{
 
296
    unsigned i;
 
297
 
 
298
    /* Get the transport type for the specified flags. */
 
299
    for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
 
300
        if (transport_names[i].flag == flag) {
 
301
            return transport_names[i].type;
 
302
        }
 
303
    }
 
304
 
 
305
    pj_assert(!"Invalid transport type");
 
306
    return PJSIP_TRANSPORT_UNSPECIFIED;
 
307
}
 
308
 
 
309
/*
 
310
 * Get the socket address family of a given transport type.
 
311
 */
 
312
PJ_DEF(int) pjsip_transport_type_get_af(pjsip_transport_type_e type)
 
313
{
 
314
    if (type & PJSIP_TRANSPORT_IPV6)
 
315
        return pj_AF_INET6();
 
316
    else
 
317
        return pj_AF_INET();
 
318
}
 
319
 
 
320
PJ_DEF(unsigned) pjsip_transport_get_flag_from_type(pjsip_transport_type_e type)
 
321
{
 
322
    /* Return transport flag. */
 
323
    return get_tpname(type)->flag;
 
324
}
 
325
 
 
326
/*
 
327
 * Get the default SIP port number for the specified type.
 
328
 */
 
329
PJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type)
 
330
{
 
331
    /* Return the port. */
 
332
    return get_tpname(type)->port;
 
333
}
 
334
 
 
335
/*
 
336
 * Get transport name.
 
337
 */
 
338
PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type)
 
339
{
 
340
    /* Return the name. */
 
341
    return get_tpname(type)->name.ptr;
 
342
}
 
343
 
 
344
/*
 
345
 * Get transport description.
 
346
 */
 
347
PJ_DEF(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e type)
 
348
{
 
349
    /* Return the description. */
 
350
    return get_tpname(type)->description;
 
351
}
 
352
 
 
353
 
 
354
/*****************************************************************************
 
355
 *
 
356
 * TRANSPORT SELECTOR
 
357
 *
 
358
 *****************************************************************************/
 
359
 
 
360
/*
 
361
 * Add transport/listener reference in the selector.
 
362
 */
 
363
PJ_DEF(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel)
 
364
{
 
365
    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
 
366
        pjsip_transport_add_ref(sel->u.transport);
 
367
    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
 
368
        ; /* Hmm.. looks like we don't have reference counter for listener */
 
369
}
 
370
 
 
371
 
 
372
/*
 
373
 * Decrement transport/listener reference in the selector.
 
374
 */
 
375
PJ_DEF(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel)
 
376
{
 
377
    if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
 
378
        pjsip_transport_dec_ref(sel->u.transport);
 
379
    else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
 
380
        ; /* Hmm.. looks like we don't have reference counter for listener */
 
381
}
 
382
 
 
383
 
 
384
/*****************************************************************************
 
385
 *
 
386
 * TRANSMIT DATA BUFFER MANIPULATION.
 
387
 *
 
388
 *****************************************************************************/
 
389
 
 
390
/*
 
391
 * Create new transmit buffer.
 
392
 */
 
393
PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
 
394
                                          pjsip_tx_data **p_tdata )
 
395
{
 
396
    pj_pool_t *pool;
 
397
    pjsip_tx_data *tdata;
 
398
    pj_status_t status;
 
399
 
 
400
    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);
 
401
 
 
402
    pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p",
 
403
                                    PJSIP_POOL_LEN_TDATA,
 
404
                                    PJSIP_POOL_INC_TDATA );
 
405
    if (!pool)
 
406
        return PJ_ENOMEM;
 
407
 
 
408
    tdata = PJ_POOL_ZALLOC_T(pool, pjsip_tx_data);
 
409
    tdata->pool = pool;
 
410
    tdata->mgr = mgr;
 
411
    pj_memcpy(tdata->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME);
 
412
 
 
413
    status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);
 
414
    if (status != PJ_SUCCESS) {
 
415
        pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
 
416
        return status;
 
417
    }
 
418
    
 
419
    //status = pj_lock_create_simple_mutex(pool, "tdta%p", &tdata->lock);
 
420
    status = pj_lock_create_null_mutex(pool, "tdta%p", &tdata->lock);
 
421
    if (status != PJ_SUCCESS) {
 
422
        pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
 
423
        return status;
 
424
    }
 
425
 
 
426
    pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key));
 
427
    pj_list_init(tdata);
 
428
 
 
429
#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0
 
430
    /* Append this just created tdata to transmit buffer list */
 
431
    pj_lock_acquire(mgr->lock);
 
432
    pj_list_push_back(&mgr->tdata_list, tdata);
 
433
    pj_lock_release(mgr->lock);
 
434
#endif
 
435
 
 
436
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
437
    pj_atomic_inc( tdata->mgr->tdata_counter );
 
438
#endif
 
439
 
 
440
    *p_tdata = tdata;
 
441
    return PJ_SUCCESS;
 
442
}
 
443
 
 
444
 
 
445
/*
 
446
 * Add reference to tx buffer.
 
447
 */
 
448
PJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata )
 
449
{
 
450
    pj_atomic_inc(tdata->ref_cnt);
 
451
}
 
452
 
 
453
static void tx_data_destroy(pjsip_tx_data *tdata)
 
454
{
 
455
    PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s",
 
456
              pjsip_tx_data_get_info(tdata)));
 
457
    pjsip_tpselector_dec_ref(&tdata->tp_sel);
 
458
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
459
    pj_atomic_dec( tdata->mgr->tdata_counter );
 
460
#endif
 
461
 
 
462
#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0
 
463
    /* Remove this tdata from transmit buffer list */
 
464
    pj_lock_acquire(tdata->mgr->lock);
 
465
    pj_list_erase(tdata);
 
466
    pj_lock_release(tdata->mgr->lock);
 
467
#endif
 
468
 
 
469
    pj_atomic_destroy( tdata->ref_cnt );
 
470
    pj_lock_destroy( tdata->lock );
 
471
    pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool );
 
472
}
 
473
 
 
474
/*
 
475
 * Decrease transport data reference, destroy it when the reference count
 
476
 * reaches zero.
 
477
 */
 
478
PJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata )
 
479
{
 
480
    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0);
 
481
    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) {
 
482
        tx_data_destroy(tdata);
 
483
        return PJSIP_EBUFDESTROYED;
 
484
    } else {
 
485
        return PJ_SUCCESS;
 
486
    }
 
487
}
 
488
 
 
489
/*
 
490
 * Invalidate the content of the print buffer to force the message to be
 
491
 * re-printed when sent.
 
492
 */
 
493
PJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata )
 
494
{
 
495
    tdata->buf.cur = tdata->buf.start;
 
496
    tdata->info = NULL;
 
497
}
 
498
 
 
499
/*
 
500
 * Print the SIP message to transmit data buffer's internal buffer.
 
501
 */
 
502
PJ_DEF(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata)
 
503
{
 
504
    /* Allocate buffer if necessary. */
 
505
    if (tdata->buf.start == NULL) {
 
506
        PJ_USE_EXCEPTION;
 
507
 
 
508
        PJ_TRY {
 
509
            tdata->buf.start = (char*) 
 
510
                               pj_pool_alloc(tdata->pool, PJSIP_MAX_PKT_LEN);
 
511
        }
 
512
        PJ_CATCH_ANY {
 
513
            return PJ_ENOMEM;
 
514
        }
 
515
        PJ_END
 
516
 
 
517
        tdata->buf.cur = tdata->buf.start;
 
518
        tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN;
 
519
    }
 
520
 
 
521
    /* Do we need to reprint? */
 
522
    if (!pjsip_tx_data_is_valid(tdata)) {
 
523
        pj_ssize_t size;
 
524
 
 
525
        size = pjsip_msg_print( tdata->msg, tdata->buf.start, 
 
526
                                tdata->buf.end - tdata->buf.start);
 
527
        if (size < 0) {
 
528
            return PJSIP_EMSGTOOLONG;
 
529
        }
 
530
        pj_assert(size != 0);
 
531
        tdata->buf.cur[size] = '\0';
 
532
        tdata->buf.cur += size;
 
533
    }
 
534
 
 
535
    return PJ_SUCCESS;
 
536
}
 
537
 
 
538
PJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata )
 
539
{
 
540
    return tdata->buf.cur != tdata->buf.start;
 
541
}
 
542
 
 
543
static char *get_msg_info(pj_pool_t *pool, const char *obj_name,
 
544
                          const pjsip_msg *msg)
 
545
{
 
546
    char info_buf[128], *info;
 
547
    const pjsip_cseq_hdr *cseq;
 
548
    int len;
 
549
 
 
550
    cseq = (const pjsip_cseq_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);
 
551
    PJ_ASSERT_RETURN(cseq != NULL, "INVALID MSG");
 
552
 
 
553
    if (msg->type == PJSIP_REQUEST_MSG) {
 
554
        len = pj_ansi_snprintf(info_buf, sizeof(info_buf), 
 
555
                               "Request msg %.*s/cseq=%d (%s)",
 
556
                               (int)msg->line.req.method.name.slen,
 
557
                               msg->line.req.method.name.ptr,
 
558
                               cseq->cseq, obj_name);
 
559
    } else {
 
560
        len = pj_ansi_snprintf(info_buf, sizeof(info_buf),
 
561
                               "Response msg %d/%.*s/cseq=%d (%s)",
 
562
                               msg->line.status.code,
 
563
                               (int)cseq->method.name.slen,
 
564
                               cseq->method.name.ptr,
 
565
                               cseq->cseq, obj_name);
 
566
    }
 
567
 
 
568
    if (len < 1 || len >= (int)sizeof(info_buf)) {
 
569
        return (char*)obj_name;
 
570
    }
 
571
 
 
572
    info = (char*) pj_pool_alloc(pool, len+1);
 
573
    pj_memcpy(info, info_buf, len+1);
 
574
 
 
575
    return info;
 
576
}
 
577
 
 
578
PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata )
 
579
{
 
580
    PJ_ASSERT_RETURN(tdata, "NULL");
 
581
 
 
582
    /* tdata->info may be assigned by application so if it exists
 
583
     * just return it.
 
584
     */
 
585
    if (tdata->info)
 
586
        return tdata->info;
 
587
 
 
588
    if (tdata->msg==NULL)
 
589
        return "NULL";
 
590
 
 
591
    pj_lock_acquire(tdata->lock);
 
592
    tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg);
 
593
    pj_lock_release(tdata->lock);
 
594
 
 
595
    return tdata->info;
 
596
}
 
597
 
 
598
PJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
 
599
                                                const pjsip_tpselector *sel)
 
600
{
 
601
    PJ_ASSERT_RETURN(tdata && sel, PJ_EINVAL);
 
602
 
 
603
    pj_lock_acquire(tdata->lock);
 
604
 
 
605
    pjsip_tpselector_dec_ref(&tdata->tp_sel);
 
606
 
 
607
    pj_memcpy(&tdata->tp_sel, sel, sizeof(*sel));
 
608
    pjsip_tpselector_add_ref(&tdata->tp_sel);
 
609
 
 
610
    pj_lock_release(tdata->lock);
 
611
 
 
612
    return PJ_SUCCESS;
 
613
}
 
614
 
 
615
 
 
616
PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata)
 
617
{
 
618
    char obj_name[PJ_MAX_OBJ_NAME];
 
619
 
 
620
    PJ_ASSERT_RETURN(rdata->msg_info.msg, "INVALID MSG");
 
621
 
 
622
    if (rdata->msg_info.info)
 
623
        return rdata->msg_info.info;
 
624
 
 
625
    pj_ansi_strcpy(obj_name, "rdata");
 
626
    pj_ansi_snprintf(obj_name+5, sizeof(obj_name)-5, "%p", rdata);
 
627
 
 
628
    rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name,
 
629
                                        rdata->msg_info.msg);
 
630
    return rdata->msg_info.info;
 
631
}
 
632
 
 
633
/* Clone pjsip_rx_data. */
 
634
PJ_DEF(pj_status_t) pjsip_rx_data_clone( const pjsip_rx_data *src,
 
635
                                         unsigned flags,
 
636
                                         pjsip_rx_data **p_rdata)
 
637
{
 
638
    pj_pool_t *pool;
 
639
    pjsip_rx_data *dst;
 
640
    pjsip_hdr *hdr;
 
641
 
 
642
    PJ_ASSERT_RETURN(src && flags==0 && p_rdata, PJ_EINVAL);
 
643
 
 
644
    pool = pj_pool_create(src->tp_info.pool->factory,
 
645
                          "rtd%p",
 
646
                          PJSIP_POOL_RDATA_LEN,
 
647
                          PJSIP_POOL_RDATA_INC,
 
648
                          NULL);
 
649
    if (!pool)
 
650
        return PJ_ENOMEM;
 
651
 
 
652
    dst = PJ_POOL_ZALLOC_T(pool, pjsip_rx_data);
 
653
 
 
654
    /* Parts of tp_info */
 
655
    dst->tp_info.pool = pool;
 
656
    dst->tp_info.transport = (pjsip_transport*)src->tp_info.transport;
 
657
 
 
658
    /* pkt_info can be memcopied */
 
659
    pj_memcpy(&dst->pkt_info, &src->pkt_info, sizeof(src->pkt_info));
 
660
 
 
661
    /* msg_info needs deep clone */
 
662
    dst->msg_info.msg_buf = dst->pkt_info.packet;
 
663
    dst->msg_info.len = src->msg_info.len;
 
664
    dst->msg_info.msg = pjsip_msg_clone(pool, src->msg_info.msg);
 
665
    pj_list_init(&dst->msg_info.parse_err);
 
666
 
 
667
#define GET_MSG_HDR2(TYPE, type, var)   \
 
668
                        case PJSIP_H_##TYPE: \
 
669
                            if (!dst->msg_info.var) { \
 
670
                                dst->msg_info.var = (pjsip_##type##_hdr*)hdr; \
 
671
                            } \
 
672
                            break
 
673
#define GET_MSG_HDR(TYPE, var_type)     GET_MSG_HDR2(TYPE, var_type, var_type)
 
674
 
 
675
    hdr = dst->msg_info.msg->hdr.next;
 
676
    while (hdr != &dst->msg_info.msg->hdr) {
 
677
        switch (hdr->type) {
 
678
        GET_MSG_HDR(CALL_ID, cid);
 
679
        GET_MSG_HDR(FROM, from);
 
680
        GET_MSG_HDR(TO, to);
 
681
        GET_MSG_HDR(VIA, via);
 
682
        GET_MSG_HDR(CSEQ, cseq);
 
683
        GET_MSG_HDR(MAX_FORWARDS, max_fwd);
 
684
        GET_MSG_HDR(ROUTE, route);
 
685
        GET_MSG_HDR2(RECORD_ROUTE, rr, record_route);
 
686
        GET_MSG_HDR(CONTENT_TYPE, ctype);
 
687
        GET_MSG_HDR(CONTENT_LENGTH, clen);
 
688
        GET_MSG_HDR(REQUIRE, require);
 
689
        GET_MSG_HDR(SUPPORTED, supported);
 
690
        default:
 
691
            break;
 
692
        }
 
693
        hdr = hdr->next;
 
694
    }
 
695
 
 
696
#undef GET_MSG_HDR
 
697
#undef GET_MSG_HDR2
 
698
 
 
699
    *p_rdata = dst;
 
700
 
 
701
    /* Finally add transport ref */
 
702
    return pjsip_transport_add_ref(dst->tp_info.transport);
 
703
}
 
704
 
 
705
/* Free previously cloned pjsip_rx_data. */
 
706
PJ_DEF(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata)
 
707
{
 
708
    PJ_ASSERT_RETURN(rdata, PJ_EINVAL);
 
709
 
 
710
    pjsip_transport_dec_ref(rdata->tp_info.transport);
 
711
    pj_pool_release(rdata->tp_info.pool);
 
712
 
 
713
    return PJ_SUCCESS;
 
714
}
 
715
 
 
716
/*****************************************************************************
 
717
 *
 
718
 * TRANSPORT KEY
 
719
 *
 
720
 *****************************************************************************/
 
721
 
 
722
 
 
723
/*****************************************************************************
 
724
 *
 
725
 * TRANSPORT
 
726
 *
 
727
 *****************************************************************************/
 
728
 
 
729
static void transport_send_callback(pjsip_transport *transport,
 
730
                                    void *token,
 
731
                                    pj_ssize_t size)
 
732
{
 
733
    pjsip_tx_data *tdata = (pjsip_tx_data*) token;
 
734
 
 
735
    PJ_UNUSED_ARG(transport);
 
736
 
 
737
    /* Mark pending off so that app can resend/reuse txdata from inside
 
738
     * the callback.
 
739
     */
 
740
    tdata->is_pending = 0;
 
741
 
 
742
    /* Call callback, if any. */
 
743
    if (tdata->cb) {
 
744
        (*tdata->cb)(tdata->token, tdata, size);
 
745
    }
 
746
 
 
747
    /* Decrement reference count. */
 
748
    pjsip_tx_data_dec_ref(tdata);
 
749
}
 
750
 
 
751
/* This function is called by endpoint for on_tx_request() and on_tx_response()
 
752
 * notification.
 
753
 */
 
754
static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata)
 
755
{
 
756
    return pjsip_tx_data_encode(tdata);
 
757
}
 
758
 
 
759
/*
 
760
 * Send a SIP message using the specified transport.
 
761
 */
 
762
PJ_DEF(pj_status_t) pjsip_transport_send(  pjsip_transport *tr, 
 
763
                                           pjsip_tx_data *tdata,
 
764
                                           const pj_sockaddr_t *addr,
 
765
                                           int addr_len,
 
766
                                           void *token,
 
767
                                           pjsip_tp_send_callback cb)
 
768
{
 
769
    pj_status_t status;
 
770
 
 
771
    PJ_ASSERT_RETURN(tr && tdata && addr, PJ_EINVAL);
 
772
 
 
773
    /* Is it currently being sent? */
 
774
    if (tdata->is_pending) {
 
775
        pj_assert(!"Invalid operation step!");
 
776
        PJ_LOG(2,(THIS_FILE, "Unable to send %s: message is pending", 
 
777
                             pjsip_tx_data_get_info(tdata)));
 
778
        return PJSIP_EPENDINGTX;
 
779
    }
 
780
 
 
781
    /* Add reference to prevent deletion, and to cancel idle timer if
 
782
     * it's running.
 
783
     */
 
784
    pjsip_transport_add_ref(tr);
 
785
 
 
786
    /* Fill in tp_info. */
 
787
    tdata->tp_info.transport = tr;
 
788
    pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len);
 
789
    tdata->tp_info.dst_addr_len = addr_len;
 
790
 
 
791
    pj_inet_ntop(((pj_sockaddr*)addr)->addr.sa_family,
 
792
                 pj_sockaddr_get_addr(addr),
 
793
                 tdata->tp_info.dst_name,
 
794
                 sizeof(tdata->tp_info.dst_name));
 
795
    tdata->tp_info.dst_port = pj_sockaddr_get_port(addr);
 
796
 
 
797
    /* Distribute to modules. 
 
798
     * When the message reach mod_msg_print, the contents of the message will
 
799
     * be "printed" to contiguous buffer.
 
800
     */
 
801
    if (tr->tpmgr->on_tx_msg) {
 
802
        status = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata);
 
803
        if (status != PJ_SUCCESS) {
 
804
            pjsip_transport_dec_ref(tr);
 
805
            return status;
 
806
        }
 
807
    }
 
808
 
 
809
    /* Save callback data. */
 
810
    tdata->token = token;
 
811
    tdata->cb = cb;
 
812
 
 
813
    /* Add reference counter. */
 
814
    pjsip_tx_data_add_ref(tdata);
 
815
 
 
816
    /* Mark as pending. */
 
817
    tdata->is_pending = 1;
 
818
 
 
819
    /* Send to transport. */
 
820
    status = (*tr->send_msg)(tr, tdata,  addr, addr_len, (void*)tdata, 
 
821
                             &transport_send_callback);
 
822
 
 
823
    if (status != PJ_EPENDING) {
 
824
        tdata->is_pending = 0;
 
825
        pjsip_tx_data_dec_ref(tdata);
 
826
    }
 
827
 
 
828
    pjsip_transport_dec_ref(tr);
 
829
    return status;
 
830
}
 
831
 
 
832
 
 
833
/* send_raw() callback */
 
834
static void send_raw_callback(pjsip_transport *transport,
 
835
                              void *token,
 
836
                              pj_ssize_t size)
 
837
{
 
838
    pjsip_tx_data *tdata = (pjsip_tx_data*) token;
 
839
 
 
840
    /* Mark pending off so that app can resend/reuse txdata from inside
 
841
     * the callback.
 
842
     */
 
843
    tdata->is_pending = 0;
 
844
 
 
845
    /* Call callback, if any. */
 
846
    if (tdata->cb) {
 
847
        (*tdata->cb)(tdata->token, tdata, size);
 
848
    }
 
849
 
 
850
    /* Decrement tdata reference count. */
 
851
    pjsip_tx_data_dec_ref(tdata);
 
852
 
 
853
    /* Decrement transport reference count */
 
854
    pjsip_transport_dec_ref(transport);
 
855
}
 
856
 
 
857
 
 
858
/* Send raw data */
 
859
PJ_DEF(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
 
860
                                         pjsip_transport_type_e tp_type,
 
861
                                         const pjsip_tpselector *sel,
 
862
                                         pjsip_tx_data *tdata,
 
863
                                         const void *raw_data,
 
864
                                         pj_size_t data_len,
 
865
                                         const pj_sockaddr_t *addr,
 
866
                                         int addr_len,
 
867
                                         void *token,
 
868
                                         pjsip_tp_send_callback cb)
 
869
{
 
870
    pjsip_transport *tr;
 
871
    pj_status_t status;
 
872
 
 
873
    /* Acquire the transport */
 
874
    status = pjsip_tpmgr_acquire_transport(mgr, tp_type, addr, addr_len,
 
875
                                           sel, &tr);
 
876
    if (status != PJ_SUCCESS)
 
877
        return status;
 
878
 
 
879
    /* Create transmit data buffer if one is not specified */
 
880
    if (tdata == NULL) {
 
881
        status = pjsip_endpt_create_tdata(tr->endpt, &tdata);
 
882
        if (status != PJ_SUCCESS) {
 
883
            pjsip_transport_dec_ref(tr);
 
884
            return status;
 
885
        }
 
886
 
 
887
        tdata->info = "raw";
 
888
 
 
889
        /* Add reference counter. */
 
890
        pjsip_tx_data_add_ref(tdata);
 
891
    }
 
892
 
 
893
    /* Allocate buffer */
 
894
    if (tdata->buf.start == NULL ||
 
895
        (tdata->buf.end - tdata->buf.start) < (int)data_len)
 
896
    {
 
897
        /* Note: data_len may be zero, so allocate +1 */
 
898
        tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
 
899
        tdata->buf.end = tdata->buf.start + data_len + 1;
 
900
    }
 
901
 
 
902
    /* Copy data, if any! (application may send zero len packet) */
 
903
    if (data_len) {
 
904
        pj_memcpy(tdata->buf.start, raw_data, data_len);
 
905
    }
 
906
    tdata->buf.cur = tdata->buf.start + data_len;
 
907
 
 
908
    /* Save callback data. */
 
909
    tdata->token = token;
 
910
    tdata->cb = cb;
 
911
 
 
912
    /* Mark as pending. */
 
913
    tdata->is_pending = 1;
 
914
 
 
915
    /* Send to transport */
 
916
    status = tr->send_msg(tr, tdata, addr, addr_len,
 
917
                          tdata, &send_raw_callback);
 
918
 
 
919
    if (status != PJ_EPENDING) {
 
920
        /* callback will not be called, so destroy tdata now. */
 
921
        pjsip_tx_data_dec_ref(tdata);
 
922
        pjsip_transport_dec_ref(tr);
 
923
    }
 
924
 
 
925
    return status;
 
926
}
 
927
 
 
928
 
 
929
static void transport_idle_callback(pj_timer_heap_t *timer_heap,
 
930
                                    struct pj_timer_entry *entry)
 
931
{
 
932
    pjsip_transport *tp = (pjsip_transport*) entry->user_data;
 
933
    pj_assert(tp != NULL);
 
934
 
 
935
    PJ_UNUSED_ARG(timer_heap);
 
936
 
 
937
    entry->id = PJ_FALSE;
 
938
    pjsip_transport_destroy(tp);
 
939
}
 
940
 
 
941
/*
 
942
 * Add ref.
 
943
 */
 
944
PJ_DEF(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp )
 
945
{
 
946
    PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);
 
947
 
 
948
    if (pj_atomic_inc_and_get(tp->ref_cnt) == 1) {
 
949
        pj_lock_acquire(tp->tpmgr->lock);
 
950
        /* Verify again. */
 
951
        if (pj_atomic_get(tp->ref_cnt) == 1) {
 
952
            if (tp->idle_timer.id != PJ_FALSE) {
 
953
                pjsip_endpt_cancel_timer(tp->tpmgr->endpt, &tp->idle_timer);
 
954
                tp->idle_timer.id = PJ_FALSE;
 
955
            }
 
956
        }
 
957
        pj_lock_release(tp->tpmgr->lock);
 
958
    }
 
959
 
 
960
    return PJ_SUCCESS;
 
961
}
 
962
 
 
963
/*
 
964
 * Dec ref.
 
965
 */
 
966
PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
 
967
{
 
968
    PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);
 
969
 
 
970
    pj_assert(pj_atomic_get(tp->ref_cnt) > 0);
 
971
 
 
972
    if (pj_atomic_dec_and_get(tp->ref_cnt) == 0) {
 
973
        pj_lock_acquire(tp->tpmgr->lock);
 
974
        /* Verify again. Do not register timer if the transport is
 
975
         * being destroyed.
 
976
         */
 
977
        if (pj_atomic_get(tp->ref_cnt) == 0 && !tp->is_destroying) {
 
978
            pj_time_val delay;
 
979
            
 
980
            /* If transport is in graceful shutdown, then this is the
 
981
             * last user who uses the transport. Schedule to destroy the
 
982
             * transport immediately. Otherwise schedule idle timer.
 
983
             */
 
984
            if (tp->is_shutdown) {
 
985
                delay.sec = delay.msec = 0;
 
986
            } else {
 
987
                delay.sec = (tp->dir==PJSIP_TP_DIR_OUTGOING) ?
 
988
                                PJSIP_TRANSPORT_IDLE_TIME :
 
989
                                PJSIP_TRANSPORT_SERVER_IDLE_TIME;
 
990
                delay.msec = 0;
 
991
            }
 
992
 
 
993
            pj_assert(tp->idle_timer.id == 0);
 
994
            tp->idle_timer.id = PJ_TRUE;
 
995
            pjsip_endpt_schedule_timer(tp->tpmgr->endpt, &tp->idle_timer, 
 
996
                                       &delay);
 
997
        }
 
998
        pj_lock_release(tp->tpmgr->lock);
 
999
    }
 
1000
 
 
1001
    return PJ_SUCCESS;
 
1002
}
 
1003
 
 
1004
 
 
1005
/**
 
1006
 * Register a transport.
 
1007
 */
 
1008
PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
 
1009
                                              pjsip_transport *tp )
 
1010
{
 
1011
    int key_len;
 
1012
    pj_uint32_t hval;
 
1013
    void *entry;
 
1014
 
 
1015
    /* Init. */
 
1016
    tp->tpmgr = mgr;
 
1017
    pj_bzero(&tp->idle_timer, sizeof(tp->idle_timer));
 
1018
    tp->idle_timer.user_data = tp;
 
1019
    tp->idle_timer.cb = &transport_idle_callback;
 
1020
 
 
1021
    /* 
 
1022
     * Register to hash table (see Trac ticket #42).
 
1023
     */
 
1024
    key_len = sizeof(tp->key.type) + tp->addr_len;
 
1025
    pj_lock_acquire(mgr->lock);
 
1026
 
 
1027
    /* If entry already occupied, unregister previous entry */
 
1028
    hval = 0;
 
1029
    entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
 
1030
    if (entry != NULL)
 
1031
        pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);
 
1032
 
 
1033
    /* Register new entry */
 
1034
    pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, hval, tp);
 
1035
 
 
1036
    pj_lock_release(mgr->lock);
 
1037
 
 
1038
    TRACE_((THIS_FILE,"Transport %s registered: type=%s, remote=%s:%d",
 
1039
                       tp->obj_name,
 
1040
                       pjsip_transport_get_type_name(tp->key.type),
 
1041
                       addr_string(&tp->key.rem_addr),
 
1042
                       pj_sockaddr_get_port(&tp->key.rem_addr)));
 
1043
 
 
1044
    return PJ_SUCCESS;
 
1045
}
 
1046
 
 
1047
/* Force destroy transport (e.g. during transport manager shutdown. */
 
1048
static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
 
1049
                                      pjsip_transport *tp )
 
1050
{
 
1051
    int key_len;
 
1052
    pj_uint32_t hval;
 
1053
    void *entry;
 
1054
 
 
1055
    TRACE_((THIS_FILE, "Transport %s is being destroyed", tp->obj_name));
 
1056
 
 
1057
    pj_lock_acquire(tp->lock);
 
1058
    pj_lock_acquire(mgr->lock);
 
1059
 
 
1060
    tp->is_destroying = PJ_TRUE;
 
1061
 
 
1062
    /*
 
1063
     * Unregister timer, if any.
 
1064
     */
 
1065
    //pj_assert(tp->idle_timer.id == PJ_FALSE);
 
1066
    if (tp->idle_timer.id != PJ_FALSE) {
 
1067
        pjsip_endpt_cancel_timer(mgr->endpt, &tp->idle_timer);
 
1068
        tp->idle_timer.id = PJ_FALSE;
 
1069
    }
 
1070
 
 
1071
    /*
 
1072
     * Unregister from hash table (see Trac ticket #42).
 
1073
     */
 
1074
    key_len = sizeof(tp->key.type) + tp->addr_len;
 
1075
    hval = 0;
 
1076
    entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
 
1077
    if (entry == (void*)tp)
 
1078
        pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);
 
1079
 
 
1080
    pj_lock_release(mgr->lock);
 
1081
 
 
1082
    /* Destroy. */
 
1083
    return tp->destroy(tp);
 
1084
}
 
1085
 
 
1086
 
 
1087
/*
 
1088
 * Start graceful shutdown procedure for this transport. 
 
1089
 */
 
1090
PJ_DEF(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp)
 
1091
{
 
1092
    pjsip_tpmgr *mgr;
 
1093
    pj_status_t status;
 
1094
    pjsip_tp_state_callback state_cb;
 
1095
 
 
1096
    TRACE_((THIS_FILE, "Transport %s shutting down", tp->obj_name));
 
1097
 
 
1098
    pj_lock_acquire(tp->lock);
 
1099
 
 
1100
    mgr = tp->tpmgr;
 
1101
    pj_lock_acquire(mgr->lock);
 
1102
 
 
1103
    /* Do nothing if transport is being shutdown already */
 
1104
    if (tp->is_shutdown) {
 
1105
        pj_lock_release(tp->lock);
 
1106
        pj_lock_release(mgr->lock);
 
1107
        return PJ_SUCCESS;
 
1108
    }
 
1109
 
 
1110
    status = PJ_SUCCESS;
 
1111
 
 
1112
    /* Instruct transport to shutdown itself */
 
1113
    if (tp->do_shutdown)
 
1114
        status = tp->do_shutdown(tp);
 
1115
 
 
1116
    /* Notify application of transport shutdown */
 
1117
    state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);
 
1118
    if (state_cb) {
 
1119
        pjsip_transport_state_info state_info;
 
1120
 
 
1121
        pj_bzero(&state_info, sizeof(state_info));
 
1122
        state_info.status = status;
 
1123
        (*state_cb)(tp, PJSIP_TP_STATE_SHUTDOWN, &state_info);
 
1124
    }
 
1125
 
 
1126
    if (status == PJ_SUCCESS)
 
1127
        tp->is_shutdown = PJ_TRUE;
 
1128
 
 
1129
    /* If transport reference count is zero, start timer count-down */
 
1130
    if (pj_atomic_get(tp->ref_cnt) == 0) {
 
1131
        pjsip_transport_add_ref(tp);
 
1132
        pjsip_transport_dec_ref(tp);
 
1133
    }
 
1134
 
 
1135
    pj_lock_release(tp->lock);
 
1136
    pj_lock_release(mgr->lock);
 
1137
 
 
1138
    return status;
 
1139
}
 
1140
 
 
1141
 
 
1142
/**
 
1143
 * Unregister transport.
 
1144
 */
 
1145
PJ_DEF(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp)
 
1146
{
 
1147
    pjsip_tp_state_callback state_cb;
 
1148
 
 
1149
    /* Must have no user. */
 
1150
    PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);
 
1151
 
 
1152
    /* Notify application of transport destroy */
 
1153
    state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);
 
1154
    if (state_cb) {
 
1155
        pjsip_transport_state_info state_info;
 
1156
 
 
1157
        pj_bzero(&state_info, sizeof(state_info));
 
1158
        (*state_cb)(tp, PJSIP_TP_STATE_DESTROY, &state_info);
 
1159
    }
 
1160
 
 
1161
    /* Destroy. */
 
1162
    return destroy_transport(tp->tpmgr, tp);
 
1163
}
 
1164
 
 
1165
 
 
1166
 
 
1167
/*****************************************************************************
 
1168
 *
 
1169
 * TRANSPORT FACTORY
 
1170
 *
 
1171
 *****************************************************************************/
 
1172
 
 
1173
 
 
1174
PJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr,
 
1175
                                                    pjsip_tpfactory *tpf)
 
1176
{
 
1177
    pjsip_tpfactory *p;
 
1178
    pj_status_t status;
 
1179
 
 
1180
    pj_lock_acquire(mgr->lock);
 
1181
 
 
1182
    /* Check that no factory with the same type has been registered. */
 
1183
    status = PJ_SUCCESS;
 
1184
    for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
 
1185
        if (p->type == tpf->type) {
 
1186
            status = PJSIP_ETYPEEXISTS;
 
1187
            break;
 
1188
        }
 
1189
        if (p == tpf) {
 
1190
            status = PJ_EEXISTS;
 
1191
            break;
 
1192
        }
 
1193
    }
 
1194
 
 
1195
    if (status != PJ_SUCCESS) {
 
1196
        pj_lock_release(mgr->lock);
 
1197
        return status;
 
1198
    }
 
1199
 
 
1200
    pj_list_insert_before(&mgr->factory_list, tpf);
 
1201
 
 
1202
    pj_lock_release(mgr->lock);
 
1203
 
 
1204
    return PJ_SUCCESS;
 
1205
}
 
1206
 
 
1207
 
 
1208
/**
 
1209
 * Unregister factory.
 
1210
 */
 
1211
PJ_DEF(pj_status_t) pjsip_tpmgr_unregister_tpfactory( pjsip_tpmgr *mgr,
 
1212
                                                      pjsip_tpfactory *tpf)
 
1213
{
 
1214
    pj_lock_acquire(mgr->lock);
 
1215
 
 
1216
    pj_assert(pj_list_find_node(&mgr->factory_list, tpf) == tpf);
 
1217
    pj_list_erase(tpf);
 
1218
 
 
1219
    pj_lock_release(mgr->lock);
 
1220
 
 
1221
    return PJ_SUCCESS;
 
1222
}
 
1223
 
 
1224
PJ_DECL(void) pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param *prm)
 
1225
{
 
1226
    pj_bzero(prm, sizeof(*prm));
 
1227
}
 
1228
 
 
1229
/*****************************************************************************
 
1230
 *
 
1231
 * TRANSPORT MANAGER
 
1232
 *
 
1233
 *****************************************************************************/
 
1234
 
 
1235
/*
 
1236
 * Create a new transport manager.
 
1237
 */
 
1238
PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
 
1239
                                        pjsip_endpoint *endpt,
 
1240
                                        pjsip_rx_callback rx_cb,
 
1241
                                        pjsip_tx_callback tx_cb,
 
1242
                                        pjsip_tpmgr **p_mgr)
 
1243
{
 
1244
    pjsip_tpmgr *mgr;
 
1245
    pj_status_t status;
 
1246
 
 
1247
    PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL);
 
1248
 
 
1249
    /* Register mod_msg_print module. */
 
1250
    status = pjsip_endpt_register_module(endpt, &mod_msg_print);
 
1251
    if (status != PJ_SUCCESS)
 
1252
        return status;
 
1253
 
 
1254
    /* Create and initialize transport manager. */
 
1255
    mgr = PJ_POOL_ZALLOC_T(pool, pjsip_tpmgr);
 
1256
    mgr->endpt = endpt;
 
1257
    mgr->on_rx_msg = rx_cb;
 
1258
    mgr->on_tx_msg = tx_cb;
 
1259
    pj_list_init(&mgr->factory_list);
 
1260
    pj_list_init(&mgr->tdata_list);
 
1261
 
 
1262
    mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE);
 
1263
    if (!mgr->table)
 
1264
        return PJ_ENOMEM;
 
1265
 
 
1266
    status = pj_lock_create_recursive_mutex(pool, "tmgr%p", &mgr->lock);
 
1267
    if (status != PJ_SUCCESS)
 
1268
        return status;
 
1269
 
 
1270
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
1271
    status = pj_atomic_create(pool, 0, &mgr->tdata_counter);
 
1272
    if (status != PJ_SUCCESS) {
 
1273
        pj_lock_destroy(mgr->lock);
 
1274
        return status;
 
1275
    }
 
1276
#endif
 
1277
 
 
1278
    /* Set transport state callback */
 
1279
    pjsip_tpmgr_set_state_cb(mgr, &tp_state_callback);
 
1280
 
 
1281
    PJ_LOG(5, (THIS_FILE, "Transport manager created."));
 
1282
 
 
1283
    *p_mgr = mgr;
 
1284
    return PJ_SUCCESS;
 
1285
}
 
1286
 
 
1287
/* Get the interface to send packet to the specified address */
 
1288
static pj_status_t get_net_interface(pjsip_transport_type_e tp_type,
 
1289
                                     const pj_str_t *dst,
 
1290
                                     pj_str_t *itf_str_addr)
 
1291
{
 
1292
    int af;
 
1293
    pj_sockaddr itf_addr;
 
1294
    pj_status_t status;
 
1295
 
 
1296
    af = (tp_type & PJSIP_TRANSPORT_IPV6)? PJ_AF_INET6 : PJ_AF_INET;
 
1297
    status = pj_getipinterface(af, dst, &itf_addr, PJ_FALSE, NULL);
 
1298
    if (status != PJ_SUCCESS) {
 
1299
        /* If it fails, e.g: on WM6 (http://support.microsoft.com/kb/129065),
 
1300
         * just fallback using pj_gethostip(), see ticket #1660.
 
1301
         */
 
1302
        PJ_LOG(5,(THIS_FILE,"Warning: unable to determine local "
 
1303
                            "interface, fallback to default interface!"));
 
1304
        status = pj_gethostip(af, &itf_addr);
 
1305
        if (status != PJ_SUCCESS)
 
1306
            return status;
 
1307
    }
 
1308
 
 
1309
    /* Print address */
 
1310
    pj_sockaddr_print(&itf_addr, itf_str_addr->ptr,
 
1311
                      PJ_INET6_ADDRSTRLEN, 0);
 
1312
    itf_str_addr->slen = pj_ansi_strlen(itf_str_addr->ptr);
 
1313
 
 
1314
    return PJ_SUCCESS;
 
1315
}
 
1316
 
 
1317
/*
 
1318
 * Find out the appropriate local address info (IP address and port) to
 
1319
 * advertise in Contact header based on the remote address to be 
 
1320
 * contacted. The local address info would be the address name of the
 
1321
 * transport or listener which will be used to send the request.
 
1322
 *
 
1323
 * In this implementation, it will only select the transport based on
 
1324
 * the transport type in the request.
 
1325
 */
 
1326
PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr2(pjsip_tpmgr *tpmgr,
 
1327
                                                 pj_pool_t *pool,
 
1328
                                                 pjsip_tpmgr_fla2_param *prm)
 
1329
{
 
1330
    char tmp_buf[PJ_INET6_ADDRSTRLEN+10];
 
1331
    pj_str_t tmp_str;
 
1332
    pj_status_t status = PJSIP_EUNSUPTRANSPORT;
 
1333
    unsigned flag;
 
1334
 
 
1335
    /* Sanity checks */
 
1336
    PJ_ASSERT_RETURN(tpmgr && pool && prm, PJ_EINVAL);
 
1337
 
 
1338
    pj_strset(&tmp_str, tmp_buf, 0);
 
1339
    prm->ret_addr.slen = 0;
 
1340
    prm->ret_port = 0;
 
1341
    prm->ret_tp = NULL;
 
1342
 
 
1343
    flag = pjsip_transport_get_flag_from_type(prm->tp_type);
 
1344
 
 
1345
    if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
 
1346
        prm->tp_sel->u.transport)
 
1347
    {
 
1348
        const pjsip_transport *tp = prm->tp_sel->u.transport;
 
1349
        if (prm->local_if) {
 
1350
            status = get_net_interface((pjsip_transport_type_e)tp->key.type,
 
1351
                                       &prm->dst_host, &tmp_str);
 
1352
            if (status != PJ_SUCCESS)
 
1353
                goto on_return;
 
1354
            pj_strdup(pool, &prm->ret_addr, &tmp_str);
 
1355
            prm->ret_port = pj_sockaddr_get_port(&tp->local_addr);
 
1356
            prm->ret_tp = tp;
 
1357
        } else {
 
1358
            pj_strdup(pool, &prm->ret_addr, &tp->local_name.host);
 
1359
            prm->ret_port = (pj_uint16_t)tp->local_name.port;
 
1360
        }
 
1361
        status = PJ_SUCCESS;
 
1362
 
 
1363
    } else if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_LISTENER &&
 
1364
               prm->tp_sel->u.listener)
 
1365
    {
 
1366
        if (prm->local_if) {
 
1367
            status = get_net_interface(prm->tp_sel->u.listener->type,
 
1368
                                       &prm->dst_host, &tmp_str);
 
1369
            if (status != PJ_SUCCESS)
 
1370
                goto on_return;
 
1371
            pj_strdup(pool, &prm->ret_addr, &tmp_str);
 
1372
        } else {
 
1373
            pj_strdup(pool, &prm->ret_addr,
 
1374
                      &prm->tp_sel->u.listener->addr_name.host);
 
1375
        }
 
1376
        prm->ret_port = (pj_uint16_t)prm->tp_sel->u.listener->addr_name.port;
 
1377
        status = PJ_SUCCESS;
 
1378
 
 
1379
    } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) {
 
1380
        pj_sockaddr remote;
 
1381
        int addr_len;
 
1382
        pjsip_transport *tp;
 
1383
 
 
1384
        pj_bzero(&remote, sizeof(remote));
 
1385
        if (prm->tp_type & PJSIP_TRANSPORT_IPV6) {
 
1386
            addr_len = sizeof(pj_sockaddr_in6);
 
1387
            remote.addr.sa_family = pj_AF_INET6();
 
1388
        } else {
 
1389
            addr_len = sizeof(pj_sockaddr_in);
 
1390
            remote.addr.sa_family = pj_AF_INET();
 
1391
        }
 
1392
 
 
1393
        status = pjsip_tpmgr_acquire_transport(tpmgr, prm->tp_type, &remote,
 
1394
                                               addr_len, NULL, &tp);
 
1395
 
 
1396
        if (status == PJ_SUCCESS) {
 
1397
            if (prm->local_if) {
 
1398
                status = get_net_interface((pjsip_transport_type_e)
 
1399
                                           tp->key.type,
 
1400
                                           &prm->dst_host, &tmp_str);
 
1401
                if (status != PJ_SUCCESS)
 
1402
                    goto on_return;
 
1403
                pj_strdup(pool, &prm->ret_addr, &tmp_str);
 
1404
                prm->ret_port = pj_sockaddr_get_port(&tp->local_addr);
 
1405
                prm->ret_tp = tp;
 
1406
            } else {
 
1407
                pj_strdup(pool, &prm->ret_addr, &tp->local_name.host);
 
1408
                prm->ret_port = (pj_uint16_t)tp->local_name.port;
 
1409
            }
 
1410
 
 
1411
            pjsip_transport_dec_ref(tp);
 
1412
        }
 
1413
 
 
1414
    } else {
 
1415
        /* For connection oriented transport, enum the factories */
 
1416
        pjsip_tpfactory *f;
 
1417
 
 
1418
        pj_lock_acquire(tpmgr->lock);
 
1419
 
 
1420
        f = tpmgr->factory_list.next;
 
1421
        while (f != &tpmgr->factory_list) {
 
1422
            if (f->type == prm->tp_type)
 
1423
                break;
 
1424
            f = f->next;
 
1425
        }
 
1426
 
 
1427
        if (f != &tpmgr->factory_list) {
 
1428
            if (prm->local_if) {
 
1429
                status = get_net_interface(f->type, &prm->dst_host,
 
1430
                                           &tmp_str);
 
1431
                if (status == PJ_SUCCESS) {
 
1432
                    pj_strdup(pool, &prm->ret_addr, &tmp_str);
 
1433
                } else {
 
1434
                    /* It could fail "normally" on certain cases, e.g.
 
1435
                     * when connecting to IPv6 link local address, it
 
1436
                     * will wail with EINVAL.
 
1437
                     * In this case, fallback to use the default interface
 
1438
                     * rather than failing the call.
 
1439
                     */
 
1440
                    PJ_PERROR(5,(THIS_FILE, status, "Warning: unable to "
 
1441
                                 "determine local interface"));
 
1442
                    pj_strdup(pool, &prm->ret_addr, &f->addr_name.host);
 
1443
                    status = PJ_SUCCESS;
 
1444
                }
 
1445
            } else {
 
1446
                pj_strdup(pool, &prm->ret_addr, &f->addr_name.host);
 
1447
            }
 
1448
            prm->ret_port = (pj_uint16_t)f->addr_name.port;
 
1449
            status = PJ_SUCCESS;
 
1450
        }
 
1451
        pj_lock_release(tpmgr->lock);
 
1452
    }
 
1453
 
 
1454
on_return:
 
1455
    return status;
 
1456
}
 
1457
 
 
1458
PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,
 
1459
                                                 pj_pool_t *pool,
 
1460
                                                 pjsip_transport_type_e type,
 
1461
                                                 const pjsip_tpselector *sel,
 
1462
                                                 pj_str_t *ip_addr,
 
1463
                                                 int *port)
 
1464
{
 
1465
    pjsip_tpmgr_fla2_param prm;
 
1466
    pj_status_t status;
 
1467
 
 
1468
    pjsip_tpmgr_fla2_param_default(&prm);
 
1469
    prm.tp_type = type;
 
1470
    prm.tp_sel = sel;
 
1471
 
 
1472
    status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &prm);
 
1473
    if (status != PJ_SUCCESS)
 
1474
        return status;
 
1475
 
 
1476
    *ip_addr = prm.ret_addr;
 
1477
    *port = prm.ret_port;
 
1478
 
 
1479
    return PJ_SUCCESS;
 
1480
}
 
1481
 
 
1482
/*
 
1483
 * Return number of transports currently registered to the transport
 
1484
 * manager.
 
1485
 */
 
1486
PJ_DEF(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr)
 
1487
{
 
1488
    pj_hash_iterator_t itr_val;
 
1489
    pj_hash_iterator_t *itr;
 
1490
    int nr_of_transports = 0;
 
1491
    
 
1492
    pj_lock_acquire(mgr->lock);
 
1493
    
 
1494
    itr = pj_hash_first(mgr->table, &itr_val);
 
1495
    while (itr) {
 
1496
        nr_of_transports++;
 
1497
        itr = pj_hash_next(mgr->table, itr);
 
1498
    }
 
1499
    
 
1500
    pj_lock_release(mgr->lock);
 
1501
 
 
1502
    return nr_of_transports;
 
1503
}
 
1504
 
 
1505
/*
 
1506
 * pjsip_tpmgr_destroy()
 
1507
 *
 
1508
 * Destroy transport manager.
 
1509
 */
 
1510
PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )
 
1511
{
 
1512
    pj_hash_iterator_t itr_val;
 
1513
    pj_hash_iterator_t *itr;
 
1514
    pjsip_tpfactory *factory;
 
1515
    pjsip_endpoint *endpt = mgr->endpt;
 
1516
    
 
1517
    PJ_LOG(5, (THIS_FILE, "Destroying transport manager"));
 
1518
 
 
1519
    pj_lock_acquire(mgr->lock);
 
1520
 
 
1521
    /*
 
1522
     * Destroy all transports.
 
1523
     */
 
1524
    itr = pj_hash_first(mgr->table, &itr_val);
 
1525
    while (itr != NULL) {
 
1526
        pj_hash_iterator_t *next;
 
1527
        pjsip_transport *transport;
 
1528
        
 
1529
        transport = (pjsip_transport*) pj_hash_this(mgr->table, itr);
 
1530
 
 
1531
        next = pj_hash_next(mgr->table, itr);
 
1532
 
 
1533
        destroy_transport(mgr, transport);
 
1534
 
 
1535
        itr = next;
 
1536
    }
 
1537
 
 
1538
    /*
 
1539
     * Destroy all factories/listeners.
 
1540
     */
 
1541
    factory = mgr->factory_list.next;
 
1542
    while (factory != &mgr->factory_list) {
 
1543
        pjsip_tpfactory *next = factory->next;
 
1544
        
 
1545
        factory->destroy(factory);
 
1546
 
 
1547
        factory = next;
 
1548
    }
 
1549
 
 
1550
    pj_lock_release(mgr->lock);
 
1551
 
 
1552
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
1553
    /* If you encounter assert error on this line, it means there are
 
1554
     * leakings in transmit data (i.e. some transmit data have not been
 
1555
     * destroyed).
 
1556
     */
 
1557
    //pj_assert(pj_atomic_get(mgr->tdata_counter) == 0);
 
1558
    if (pj_atomic_get(mgr->tdata_counter) != 0) {
 
1559
        PJ_LOG(3,(THIS_FILE, "Warning: %d transmit buffer(s) not freed!",
 
1560
                  pj_atomic_get(mgr->tdata_counter)));
 
1561
    }
 
1562
#endif
 
1563
 
 
1564
    /*
 
1565
     * Destroy any dangling transmit buffer.
 
1566
     */
 
1567
    if (!pj_list_empty(&mgr->tdata_list)) {
 
1568
        pjsip_tx_data *tdata = mgr->tdata_list.next;
 
1569
        while (tdata != &mgr->tdata_list) {
 
1570
            pjsip_tx_data *next = tdata->next;
 
1571
            tx_data_destroy(tdata);
 
1572
            tdata = next;
 
1573
        }
 
1574
        PJ_LOG(3,(THIS_FILE, "Cleaned up dangling transmit buffer(s)."));
 
1575
    }
 
1576
 
 
1577
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
1578
    pj_atomic_destroy(mgr->tdata_counter);
 
1579
#endif
 
1580
 
 
1581
    pj_lock_destroy(mgr->lock);
 
1582
 
 
1583
    /* Unregister mod_msg_print. */
 
1584
    if (mod_msg_print.id != -1) {
 
1585
        pjsip_endpt_unregister_module(endpt, &mod_msg_print);
 
1586
    }
 
1587
 
 
1588
    return PJ_SUCCESS;
 
1589
}
 
1590
 
 
1591
 
 
1592
/*
 
1593
 * pjsip_tpmgr_receive_packet()
 
1594
 *
 
1595
 * Called by tranports when they receive a new packet.
 
1596
 */
 
1597
PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
 
1598
                                               pjsip_rx_data *rdata)
 
1599
{
 
1600
    pjsip_transport *tr = rdata->tp_info.transport;
 
1601
 
 
1602
    char *current_pkt;
 
1603
    pj_size_t remaining_len;
 
1604
    pj_size_t total_processed = 0;
 
1605
 
 
1606
    /* Check size. */
 
1607
    pj_assert(rdata->pkt_info.len > 0);
 
1608
    if (rdata->pkt_info.len <= 0)
 
1609
        return -1;
 
1610
 
 
1611
    current_pkt = rdata->pkt_info.packet;
 
1612
    remaining_len = rdata->pkt_info.len;
 
1613
 
 
1614
    tr->last_recv_len = rdata->pkt_info.len;
 
1615
    pj_get_timestamp(&tr->last_recv_ts);
 
1616
    
 
1617
    /* Must NULL terminate buffer. This is the requirement of the 
 
1618
     * parser etc. 
 
1619
     */
 
1620
    current_pkt[remaining_len] = '\0';
 
1621
 
 
1622
    /* Process all message fragments. */
 
1623
    while (remaining_len > 0) {
 
1624
 
 
1625
        pjsip_msg *msg;
 
1626
        char *p, *end;
 
1627
        char saved;
 
1628
        pj_size_t msg_fragment_size;
 
1629
 
 
1630
        /* Skip leading newlines as pjsip_find_msg() currently can't
 
1631
         * handle leading newlines.
 
1632
         */
 
1633
        for (p=current_pkt, end=p+remaining_len; p!=end; ++p) {
 
1634
            if (*p != '\r' && *p != '\n')
 
1635
                break;
 
1636
        }
 
1637
        if (p!=current_pkt) {
 
1638
            remaining_len -= (p - current_pkt);
 
1639
            total_processed += (p - current_pkt);
 
1640
            current_pkt = p;
 
1641
            if (remaining_len == 0) {
 
1642
                return total_processed;
 
1643
            }
 
1644
        }
 
1645
 
 
1646
        /* Initialize default fragment size. */
 
1647
        msg_fragment_size = remaining_len;
 
1648
 
 
1649
        /* Clear and init msg_info in rdata. 
 
1650
         * Endpoint might inspect the values there when we call the callback
 
1651
         * to report some errors.
 
1652
         */
 
1653
        pj_bzero(&rdata->msg_info, sizeof(rdata->msg_info));
 
1654
        pj_list_init(&rdata->msg_info.parse_err);
 
1655
        rdata->msg_info.msg_buf = current_pkt;
 
1656
        rdata->msg_info.len = (int)remaining_len;
 
1657
 
 
1658
        /* For TCP transport, check if the whole message has been received. */
 
1659
        if ((tr->flag & PJSIP_TRANSPORT_DATAGRAM) == 0) {
 
1660
            pj_status_t msg_status;
 
1661
            msg_status = pjsip_find_msg(current_pkt, remaining_len, PJ_FALSE, 
 
1662
                                        &msg_fragment_size);
 
1663
            if (msg_status != PJ_SUCCESS) {
 
1664
                if (remaining_len == PJSIP_MAX_PKT_LEN) {
 
1665
                    mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);
 
1666
                    /* Exhaust all data. */
 
1667
                    return rdata->pkt_info.len;
 
1668
                } else {
 
1669
                    /* Not enough data in packet. */
 
1670
                    return total_processed;
 
1671
                }
 
1672
            }
 
1673
        }
 
1674
 
 
1675
        /* Update msg_info. */
 
1676
        rdata->msg_info.len = (int)msg_fragment_size;
 
1677
 
 
1678
        /* Null terminate packet */
 
1679
        saved = current_pkt[msg_fragment_size];
 
1680
        current_pkt[msg_fragment_size] = '\0';
 
1681
 
 
1682
        /* Parse the message. */
 
1683
        rdata->msg_info.msg = msg = 
 
1684
            pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata);
 
1685
 
 
1686
        /* Restore null termination */
 
1687
        current_pkt[msg_fragment_size] = saved;
 
1688
 
 
1689
        /* Check for parsing syntax error */
 
1690
        if (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) {
 
1691
            pjsip_parser_err_report *err;
 
1692
            char buf[128];
 
1693
            pj_str_t tmp;
 
1694
 
 
1695
            /* Gather syntax error information */
 
1696
            tmp.ptr = buf; tmp.slen = 0;
 
1697
            err = rdata->msg_info.parse_err.next;
 
1698
            while (err != &rdata->msg_info.parse_err) {
 
1699
                int len;
 
1700
                len = pj_ansi_snprintf(tmp.ptr+tmp.slen, sizeof(buf)-tmp.slen,
 
1701
                                       ": %s exception when parsing '%.*s' "
 
1702
                                       "header on line %d col %d",
 
1703
                                       pj_exception_id_name(err->except_code),
 
1704
                                       (int)err->hname.slen, err->hname.ptr,
 
1705
                                       err->line, err->col);
 
1706
                if (len > 0 && len < (int) (sizeof(buf)-tmp.slen)) {
 
1707
                    tmp.slen += len;
 
1708
                }
 
1709
                err = err->next;
 
1710
            }
 
1711
 
 
1712
            /* Only print error message if there's error.
 
1713
             * Sometimes we receive blank packets (packets with only CRLF)
 
1714
             * which were sent to keep NAT bindings.
 
1715
             */
 
1716
            if (tmp.slen) {
 
1717
                PJ_LOG(1, (THIS_FILE, 
 
1718
                      "Error processing %d bytes packet from %s %s:%d %.*s:\n"
 
1719
                      "%.*s\n"
 
1720
                      "-- end of packet.",
 
1721
                      msg_fragment_size,
 
1722
                      rdata->tp_info.transport->type_name,
 
1723
                      rdata->pkt_info.src_name, 
 
1724
                      rdata->pkt_info.src_port,
 
1725
                      (int)tmp.slen, tmp.ptr,
 
1726
                      (int)msg_fragment_size,
 
1727
                      rdata->msg_info.msg_buf));
 
1728
            }
 
1729
 
 
1730
            goto finish_process_fragment;
 
1731
        }
 
1732
 
 
1733
        /* Perform basic header checking. */
 
1734
        if (rdata->msg_info.cid == NULL ||
 
1735
            rdata->msg_info.cid->id.slen == 0 || 
 
1736
            rdata->msg_info.from == NULL || 
 
1737
            rdata->msg_info.to == NULL || 
 
1738
            rdata->msg_info.via == NULL || 
 
1739
            rdata->msg_info.cseq == NULL) 
 
1740
        {
 
1741
            mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata);
 
1742
            goto finish_process_fragment;
 
1743
        }
 
1744
 
 
1745
        /* For request: */
 
1746
        if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
 
1747
            /* always add received parameter to the via. */
 
1748
            pj_strdup2(rdata->tp_info.pool, 
 
1749
                       &rdata->msg_info.via->recvd_param, 
 
1750
                       rdata->pkt_info.src_name);
 
1751
 
 
1752
            /* RFC 3581:
 
1753
             * If message contains "rport" param, put the received port there.
 
1754
             */
 
1755
            if (rdata->msg_info.via->rport_param == 0) {
 
1756
                rdata->msg_info.via->rport_param = rdata->pkt_info.src_port;
 
1757
            }
 
1758
        } else {
 
1759
            /* Drop malformed responses */
 
1760
            if (rdata->msg_info.msg->line.status.code < 100 ||
 
1761
                rdata->msg_info.msg->line.status.code >= 700)
 
1762
            {
 
1763
                mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDSTATUS, rdata);
 
1764
                goto finish_process_fragment;
 
1765
            }
 
1766
        }
 
1767
 
 
1768
        /* Drop response message if it has more than one Via.
 
1769
        */
 
1770
        /* This is wrong. Proxy DOES receive responses with multiple
 
1771
         * Via headers! Thanks Aldo <acampi at deis.unibo.it> for pointing
 
1772
         * this out.
 
1773
 
 
1774
        if (msg->type == PJSIP_RESPONSE_MSG) {
 
1775
            pjsip_hdr *hdr;
 
1776
            hdr = (pjsip_hdr*)rdata->msg_info.via->next;
 
1777
            if (hdr != &msg->hdr) {
 
1778
                hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr);
 
1779
                if (hdr) {
 
1780
                    mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata);
 
1781
                    goto finish_process_fragment;
 
1782
                }
 
1783
            }
 
1784
        }
 
1785
        */
 
1786
 
 
1787
        /* Call the transport manager's upstream message callback.
 
1788
         */
 
1789
        mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata);
 
1790
 
 
1791
 
 
1792
finish_process_fragment:
 
1793
        total_processed += msg_fragment_size;
 
1794
        current_pkt += msg_fragment_size;
 
1795
        remaining_len -= msg_fragment_size;
 
1796
 
 
1797
    }   /* while (rdata->pkt_info.len > 0) */
 
1798
 
 
1799
 
 
1800
    return total_processed;
 
1801
}
 
1802
 
 
1803
 
 
1804
/*
 
1805
 * pjsip_tpmgr_acquire_transport()
 
1806
 *
 
1807
 * Get transport suitable to communicate to remote. Create a new one
 
1808
 * if necessary.
 
1809
 */
 
1810
PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
 
1811
                                                  pjsip_transport_type_e type,
 
1812
                                                  const pj_sockaddr_t *remote,
 
1813
                                                  int addr_len,
 
1814
                                                  const pjsip_tpselector *sel,
 
1815
                                                  pjsip_transport **tp)
 
1816
{
 
1817
    return pjsip_tpmgr_acquire_transport2(mgr, type, remote, addr_len, sel,
 
1818
                                          NULL, tp);
 
1819
}
 
1820
 
 
1821
/*
 
1822
 * pjsip_tpmgr_acquire_transport2()
 
1823
 *
 
1824
 * Get transport suitable to communicate to remote. Create a new one
 
1825
 * if necessary.
 
1826
 */
 
1827
PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
 
1828
                                                   pjsip_transport_type_e type,
 
1829
                                                   const pj_sockaddr_t *remote,
 
1830
                                                   int addr_len,
 
1831
                                                   const pjsip_tpselector *sel,
 
1832
                                                   pjsip_tx_data *tdata,
 
1833
                                                   pjsip_transport **tp)
 
1834
{
 
1835
    pjsip_tpfactory *factory;
 
1836
    pj_status_t status;
 
1837
 
 
1838
    TRACE_((THIS_FILE,"Acquiring transport type=%s, remote=%s:%d",
 
1839
                       pjsip_transport_get_type_name(type),
 
1840
                       addr_string(remote),
 
1841
                       pj_sockaddr_get_port(remote)));
 
1842
 
 
1843
    pj_lock_acquire(mgr->lock);
 
1844
 
 
1845
    /* If transport is specified, then just use it if it is suitable
 
1846
     * for the destination.
 
1847
     */
 
1848
    if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
 
1849
        sel->u.transport) 
 
1850
    {
 
1851
        pjsip_transport *seltp = sel->u.transport;
 
1852
 
 
1853
        /* See if the transport is (not) suitable */
 
1854
        if (seltp->key.type != type) {
 
1855
            pj_lock_release(mgr->lock);
 
1856
            return PJSIP_ETPNOTSUITABLE;
 
1857
        }
 
1858
 
 
1859
        /* We could also verify that the destination address is reachable
 
1860
         * from this transport (i.e. both are equal), but if application
 
1861
         * has requested a specific transport to be used, assume that
 
1862
         * it knows what to do.
 
1863
         *
 
1864
         * In other words, I don't think destination verification is a good
 
1865
         * idea for now.
 
1866
         */
 
1867
 
 
1868
        /* Transport looks to be suitable to use, so just use it. */
 
1869
        pjsip_transport_add_ref(seltp);
 
1870
        pj_lock_release(mgr->lock);
 
1871
        *tp = seltp;
 
1872
 
 
1873
        TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name));
 
1874
        return PJ_SUCCESS;
 
1875
 
 
1876
 
 
1877
    } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
 
1878
               sel->u.listener)
 
1879
    {
 
1880
        /* Application has requested that a specific listener is to
 
1881
         * be used. In this case, skip transport hash table lookup.
 
1882
         */
 
1883
 
 
1884
        /* Verify that the listener type matches the destination type */
 
1885
        if (sel->u.listener->type != type) {
 
1886
            pj_lock_release(mgr->lock);
 
1887
            return PJSIP_ETPNOTSUITABLE;
 
1888
        }
 
1889
 
 
1890
        /* We'll use this listener to create transport */
 
1891
        factory = sel->u.listener;
 
1892
 
 
1893
    } else {
 
1894
 
 
1895
        /*
 
1896
         * This is the "normal" flow, where application doesn't specify
 
1897
         * specific transport/listener to be used to send message to.
 
1898
         * In this case, lookup the transport from the hash table.
 
1899
         */
 
1900
        pjsip_transport_key key;
 
1901
        int key_len;
 
1902
        pjsip_transport *transport;
 
1903
 
 
1904
        pj_bzero(&key, sizeof(key));
 
1905
        key_len = sizeof(key.type) + addr_len;
 
1906
 
 
1907
        /* First try to get exact destination. */
 
1908
        key.type = type;
 
1909
        pj_memcpy(&key.rem_addr, remote, addr_len);
 
1910
 
 
1911
        transport = (pjsip_transport*)
 
1912
                    pj_hash_get(mgr->table, &key, key_len, NULL);
 
1913
 
 
1914
        if (transport == NULL) {
 
1915
            unsigned flag = pjsip_transport_get_flag_from_type(type);
 
1916
            const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
 
1917
 
 
1918
 
 
1919
            /* Ignore address for loop transports. */
 
1920
            if (type == PJSIP_TRANSPORT_LOOP ||
 
1921
                     type == PJSIP_TRANSPORT_LOOP_DGRAM)
 
1922
            {
 
1923
                pj_sockaddr *addr = &key.rem_addr;
 
1924
 
 
1925
                pj_bzero(addr, addr_len);
 
1926
                key_len = sizeof(key.type) + addr_len;
 
1927
                transport = (pjsip_transport*) 
 
1928
                            pj_hash_get(mgr->table, &key, key_len, NULL);
 
1929
            }
 
1930
            /* For datagram transports, try lookup with zero address.
 
1931
             */
 
1932
            else if (flag & PJSIP_TRANSPORT_DATAGRAM)
 
1933
            {
 
1934
                pj_sockaddr *addr = &key.rem_addr;
 
1935
 
 
1936
                pj_bzero(addr, addr_len);
 
1937
                addr->addr.sa_family = remote_addr->addr.sa_family;
 
1938
 
 
1939
                key_len = sizeof(key.type) + addr_len;
 
1940
                transport = (pjsip_transport*)
 
1941
                            pj_hash_get(mgr->table, &key, key_len, NULL);
 
1942
            }
 
1943
        }
 
1944
 
 
1945
        if (transport!=NULL && !transport->is_shutdown) {
 
1946
            /*
 
1947
             * Transport found!
 
1948
             */
 
1949
            pjsip_transport_add_ref(transport);
 
1950
            pj_lock_release(mgr->lock);
 
1951
            *tp = transport;
 
1952
 
 
1953
            TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name));
 
1954
            return PJ_SUCCESS;
 
1955
        }
 
1956
 
 
1957
        /*
 
1958
         * Transport not found!
 
1959
         * Find factory that can create such transport.
 
1960
         */
 
1961
        factory = mgr->factory_list.next;
 
1962
        while (factory != &mgr->factory_list) {
 
1963
            if (factory->type == type)
 
1964
                break;
 
1965
            factory = factory->next;
 
1966
        }
 
1967
 
 
1968
        if (factory == &mgr->factory_list) {
 
1969
            /* No factory can create the transport! */
 
1970
            pj_lock_release(mgr->lock);
 
1971
            TRACE_((THIS_FILE, "No suitable factory was found either"));
 
1972
            return PJSIP_EUNSUPTRANSPORT;
 
1973
        }
 
1974
    }
 
1975
 
 
1976
    TRACE_((THIS_FILE, "Creating new transport from factory"));
 
1977
 
 
1978
    /* Request factory to create transport. */
 
1979
    if (factory->create_transport2) {
 
1980
        status = factory->create_transport2(factory, mgr, mgr->endpt,
 
1981
                                            (const pj_sockaddr*) remote, 
 
1982
                                            addr_len, tdata, tp);
 
1983
    } else {
 
1984
        status = factory->create_transport(factory, mgr, mgr->endpt,
 
1985
                                           (const pj_sockaddr*) remote, 
 
1986
                                           addr_len, tp);
 
1987
    }
 
1988
    if (status == PJ_SUCCESS) {
 
1989
        PJ_ASSERT_ON_FAIL(tp!=NULL, 
 
1990
            {pj_lock_release(mgr->lock); return PJ_EBUG;});
 
1991
        pjsip_transport_add_ref(*tp);
 
1992
    }
 
1993
    pj_lock_release(mgr->lock);
 
1994
    return status;
 
1995
}
 
1996
 
 
1997
/**
 
1998
 * Dump transport info.
 
1999
 */
 
2000
PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr)
 
2001
{
 
2002
#if PJ_LOG_MAX_LEVEL >= 3
 
2003
    pj_hash_iterator_t itr_val;
 
2004
    pj_hash_iterator_t *itr;
 
2005
    pjsip_tpfactory *factory;
 
2006
 
 
2007
    pj_lock_acquire(mgr->lock);
 
2008
 
 
2009
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
 
2010
    PJ_LOG(3,(THIS_FILE, " Outstanding transmit buffers: %d",
 
2011
              pj_atomic_get(mgr->tdata_counter)));
 
2012
#endif
 
2013
 
 
2014
    PJ_LOG(3, (THIS_FILE, " Dumping listeners:"));
 
2015
    factory = mgr->factory_list.next;
 
2016
    while (factory != &mgr->factory_list) {
 
2017
        PJ_LOG(3, (THIS_FILE, "  %s %s:%.*s:%d", 
 
2018
                   factory->obj_name,
 
2019
                   factory->type_name,
 
2020
                   (int)factory->addr_name.host.slen,
 
2021
                   factory->addr_name.host.ptr,
 
2022
                   (int)factory->addr_name.port));
 
2023
        factory = factory->next;
 
2024
    }
 
2025
 
 
2026
    itr = pj_hash_first(mgr->table, &itr_val);
 
2027
    if (itr) {
 
2028
        PJ_LOG(3, (THIS_FILE, " Dumping transports:"));
 
2029
 
 
2030
        do {
 
2031
            pjsip_transport *t = (pjsip_transport*) 
 
2032
                                 pj_hash_this(mgr->table, itr);
 
2033
 
 
2034
            PJ_LOG(3, (THIS_FILE, "  %s %s (refcnt=%d%s)", 
 
2035
                       t->obj_name,
 
2036
                       t->info,
 
2037
                       pj_atomic_get(t->ref_cnt),
 
2038
                       (t->idle_timer.id ? " [idle]" : "")));
 
2039
 
 
2040
            itr = pj_hash_next(mgr->table, itr);
 
2041
        } while (itr);
 
2042
    }
 
2043
 
 
2044
    pj_lock_release(mgr->lock);
 
2045
#else
 
2046
    PJ_UNUSED_ARG(mgr);
 
2047
#endif
 
2048
}
 
2049
 
 
2050
/**
 
2051
 * Set callback of global transport state notification.
 
2052
 */
 
2053
PJ_DEF(pj_status_t) pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr,
 
2054
                                             pjsip_tp_state_callback cb)
 
2055
{
 
2056
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
 
2057
 
 
2058
    mgr->tp_state_cb = cb;
 
2059
 
 
2060
    return PJ_SUCCESS;
 
2061
}
 
2062
 
 
2063
/**
 
2064
 * Get callback of global transport state notification.
 
2065
 */
 
2066
PJ_DEF(pjsip_tp_state_callback) pjsip_tpmgr_get_state_cb(
 
2067
                                             const pjsip_tpmgr *mgr)
 
2068
{
 
2069
    PJ_ASSERT_RETURN(mgr, NULL);
 
2070
 
 
2071
    return mgr->tp_state_cb;
 
2072
}
 
2073
 
 
2074
 
 
2075
/**
 
2076
 * Allocate and init transport data.
 
2077
 */
 
2078
static void init_tp_data(pjsip_transport *tp)
 
2079
{
 
2080
    transport_data *tp_data;
 
2081
 
 
2082
    pj_assert(tp && !tp->data);
 
2083
 
 
2084
    tp_data = PJ_POOL_ZALLOC_T(tp->pool, transport_data);
 
2085
    pj_list_init(&tp_data->st_listeners);
 
2086
    pj_list_init(&tp_data->st_listeners_empty);
 
2087
    tp->data = tp_data;
 
2088
}
 
2089
 
 
2090
 
 
2091
static void tp_state_callback(pjsip_transport *tp,
 
2092
                              pjsip_transport_state state,
 
2093
                              const pjsip_transport_state_info *info)
 
2094
{
 
2095
    transport_data *tp_data;
 
2096
 
 
2097
    pj_lock_acquire(tp->lock);
 
2098
 
 
2099
    tp_data = (transport_data*)tp->data;
 
2100
 
 
2101
    /* Notify the transport state listeners, if any. */
 
2102
    if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {
 
2103
        goto on_return;
 
2104
    } else {
 
2105
        pjsip_transport_state_info st_info;
 
2106
        tp_state_listener *st_listener = tp_data->st_listeners.next;
 
2107
 
 
2108
        /* As we need to put the user data into the transport state info,
 
2109
         * let's use a copy of transport state info.
 
2110
         */
 
2111
        pj_memcpy(&st_info, info, sizeof(st_info));
 
2112
        while (st_listener != &tp_data->st_listeners) {
 
2113
            st_info.user_data = st_listener->user_data;
 
2114
            (*st_listener->cb)(tp, state, &st_info);
 
2115
 
 
2116
            st_listener = st_listener->next;
 
2117
        }
 
2118
    }
 
2119
 
 
2120
on_return:
 
2121
    pj_lock_release(tp->lock);
 
2122
}
 
2123
 
 
2124
 
 
2125
/**
 
2126
 * Add a listener to the specified transport for transport state notification.
 
2127
 */
 
2128
PJ_DEF(pj_status_t) pjsip_transport_add_state_listener (
 
2129
                                            pjsip_transport *tp,
 
2130
                                            pjsip_tp_state_callback cb,
 
2131
                                            void *user_data,
 
2132
                                            pjsip_tp_state_listener_key **key)
 
2133
{
 
2134
    transport_data *tp_data;
 
2135
    tp_state_listener *entry;
 
2136
 
 
2137
    PJ_ASSERT_RETURN(tp && cb && key, PJ_EINVAL);
 
2138
 
 
2139
    pj_lock_acquire(tp->lock);
 
2140
 
 
2141
    /* Init transport data, if it hasn't */
 
2142
    if (!tp->data)
 
2143
        init_tp_data(tp);
 
2144
 
 
2145
    tp_data = (transport_data*)tp->data;
 
2146
 
 
2147
    /* Init the new listener entry. Use available empty slot, if any,
 
2148
     * otherwise allocate it using the transport pool.
 
2149
     */
 
2150
    if (!pj_list_empty(&tp_data->st_listeners_empty)) {
 
2151
        entry = tp_data->st_listeners_empty.next;
 
2152
        pj_list_erase(entry);
 
2153
    } else {
 
2154
        entry = PJ_POOL_ZALLOC_T(tp->pool, tp_state_listener);
 
2155
    }
 
2156
    entry->cb = cb;
 
2157
    entry->user_data = user_data;
 
2158
 
 
2159
    /* Add the new listener entry to the listeners list */
 
2160
    pj_list_push_back(&tp_data->st_listeners, entry);
 
2161
 
 
2162
    *key = entry;
 
2163
 
 
2164
    pj_lock_release(tp->lock);
 
2165
 
 
2166
    return PJ_SUCCESS;
 
2167
}
 
2168
 
 
2169
/**
 
2170
 * Remove a listener from the specified transport for transport state 
 
2171
 * notification.
 
2172
 */
 
2173
PJ_DEF(pj_status_t) pjsip_transport_remove_state_listener (
 
2174
                                    pjsip_transport *tp,
 
2175
                                    pjsip_tp_state_listener_key *key,
 
2176
                                    const void *user_data)
 
2177
{
 
2178
    transport_data *tp_data;
 
2179
    tp_state_listener *entry;
 
2180
 
 
2181
    PJ_ASSERT_RETURN(tp && key, PJ_EINVAL);
 
2182
 
 
2183
    pj_lock_acquire(tp->lock);
 
2184
 
 
2185
    tp_data = (transport_data*)tp->data;
 
2186
 
 
2187
    /* Transport data is NULL or no registered listener? */
 
2188
    if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {
 
2189
        pj_lock_release(tp->lock);
 
2190
        return PJ_ENOTFOUND;
 
2191
    }
 
2192
 
 
2193
    entry = (tp_state_listener*)key;
 
2194
 
 
2195
    /* Validate the user data */
 
2196
    if (entry->user_data != user_data) {
 
2197
        pj_assert(!"Invalid transport state listener key");
 
2198
        pj_lock_release(tp->lock);
 
2199
        return PJ_EBUG;
 
2200
    }
 
2201
 
 
2202
    /* Reset the entry and move it to the empty list */
 
2203
    entry->cb = NULL;
 
2204
    entry->user_data = NULL;
 
2205
    pj_list_erase(entry);
 
2206
    pj_list_push_back(&tp_data->st_listeners_empty, entry);
 
2207
 
 
2208
    pj_lock_release(tp->lock);
 
2209
 
 
2210
    return PJ_SUCCESS;
 
2211
}