Coverage Report

Created: 2026-07-30 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/tests/fuzz/fuzz-sip.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
3
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
#include <stdio.h>
20
#include <stdint.h>
21
#include <stdlib.h>
22
23
#include <pjlib.h>
24
#include <pjlib-util.h>
25
#include <pjsip.h>
26
#include <pjsip/sip_types.h>
27
#include <pjsip/sip_multipart.h>
28
#include <pjsip/sip_tel_uri.h>
29
#include <pjsip/sip_auth.h>
30
#include <pjsip/sip_transaction.h>
31
#include <pjsip/sip_dialog.h>
32
#include <pjsip-simple/evsub.h>
33
#include <pjsip-ua/sip_replaces.h>
34
#include <pjsip-ua/sip_timer.h>
35
36
pjsip_endpoint *endpt;
37
pj_caching_pool caching_pool;
38
39
15.2k
#define POOL_SIZE       8000
40
1
#define PJSIP_TEST_MEM_SIZE         (2*1024*1024)
41
42
15.2k
#define kMinInputLength 10
43
7.60k
#define kMaxInputLength 5120
44
45
/* Transaction user module */
46
static pjsip_module tsx_user_module;
47
48
/* Transaction state callback */
49
static void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
50
0
{
51
0
    PJ_UNUSED_ARG(tsx);
52
0
    PJ_UNUSED_ARG(event);
53
0
}
54
55
/* Standard header types to test */
56
static const pjsip_hdr_e hdr_types[] = {
57
    PJSIP_H_AUTHORIZATION,
58
    PJSIP_H_PROXY_AUTHORIZATION,
59
    PJSIP_H_WWW_AUTHENTICATE,
60
    PJSIP_H_PROXY_AUTHENTICATE,
61
    PJSIP_H_ROUTE,
62
    PJSIP_H_RECORD_ROUTE,
63
    PJSIP_H_CONTACT
64
};
65
66
static pjsip_msg* parse_message(pj_pool_t *pool, char *data, size_t size)
67
7.60k
{
68
7.60k
    pjsip_parser_err_report err_list;
69
7.60k
    pj_list_init(&err_list);
70
7.60k
    return pjsip_parse_msg(pool, data, size, &err_list);
71
7.60k
}
72
73
/* Multipart body parsing */
74
static void do_test_multipart(pj_pool_t *pool, pjsip_msg *msg)
75
4.48k
{
76
4.48k
    if (!msg->body)
77
4.31k
        return;
78
79
165
    pjsip_msg_body *body = msg->body;
80
81
165
    if (body->content_type.type.slen > 0 &&
82
165
        pj_stricmp2(&body->content_type.type, "multipart") == 0)
83
60
    {
84
60
        pjsip_msg_body *multipart_body = NULL;
85
60
        if (body->data && body->len > 0) {
86
0
            multipart_body = pjsip_multipart_parse(pool, (char *)body->data,
87
0
                                                   body->len, &body->content_type, 0);
88
0
            if (!multipart_body)
89
0
                return;
90
60
        } else {
91
60
            multipart_body = body;
92
60
        }
93
94
60
        pjsip_multipart_part *part = pjsip_multipart_get_first_part(multipart_body);
95
96
3.58k
        while (part) {
97
3.52k
            pjsip_media_type ctype_app, ctype_text;
98
99
3.52k
            ctype_app.type = pj_str("application");
100
3.52k
            ctype_app.subtype = pj_str("sdp");
101
3.52k
            ctype_text.type = pj_str("text");
102
3.52k
            ctype_text.subtype = pj_str("plain");
103
104
3.52k
            pjsip_multipart_find_part(multipart_body, &ctype_app, NULL);
105
3.52k
            pjsip_multipart_find_part(multipart_body, &ctype_text, NULL);
106
107
3.52k
            part = pjsip_multipart_get_next_part(multipart_body, part);
108
3.52k
        }
109
110
60
        pjsip_media_type search_type;
111
60
        search_type.type = pj_str("application");
112
60
        search_type.subtype = pj_str("sdp");
113
60
        pjsip_multipart_find_part(multipart_body, &search_type, NULL);
114
60
    }
115
165
}
116
117
/* Tel URI parsing */
118
static void do_test_tel_uri(pj_pool_t *pool, char *data, size_t size)
119
7.60k
{
120
7.60k
    pj_str_t uri_str;
121
7.60k
    pjsip_uri *uri;
122
123
7.60k
    if (size < 4 || size > 256)
124
1.64k
        return;
125
126
5.95k
    uri_str.ptr = data;
127
5.95k
    uri_str.slen = (pj_ssize_t)size;
128
129
5.95k
    uri = pjsip_parse_uri(pool, uri_str.ptr, uri_str.slen, 0);
130
131
5.95k
    if (uri && size > 20) {
132
655
        pj_str_t uri2_str;
133
655
        pjsip_uri *uri2;
134
135
655
        uri2_str.ptr = data + 10;
136
655
        uri2_str.slen = (pj_ssize_t)(size - 10);
137
138
655
        uri2 = pjsip_parse_uri(pool, uri2_str.ptr, uri2_str.slen, 0);
139
655
        if (uri2) {
140
585
            pjsip_uri_cmp(PJSIP_URI_IN_FROMTO_HDR, uri, uri2);
141
585
            pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, uri, uri2);
142
585
        }
143
655
    }
144
5.95k
}
145
146
/* Test UAS transaction creation and message feeding */
147
static void do_test_transaction_layer(pjsip_msg *msg, pjsip_rx_data *rdata)
148
4.48k
{
149
4.48k
    pj_str_t tsx_key;
150
4.48k
    pjsip_via_hdr *via_hdr;
151
152
4.48k
    if (!msg || msg->type != PJSIP_REQUEST_MSG || !rdata)
153
2.88k
        return;
154
155
1.59k
    if (!rdata->msg_info.via || !rdata->msg_info.cseq ||
156
1.42k
        !rdata->msg_info.from || !rdata->msg_info.cid)
157
172
        return;
158
159
1.42k
    via_hdr = rdata->msg_info.via;
160
161
    /* Skip transaction creation if transport not available */
162
1.42k
    if (!rdata->tp_info.transport)
163
0
        return;
164
165
    /* Ensure From/To headers have tags */
166
1.42k
    pjsip_from_hdr *from_hdr = (pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL);
167
1.42k
    pjsip_to_hdr *to_hdr = (pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL);
168
169
1.42k
    if (from_hdr && pj_stricmp2(&from_hdr->tag, "") == 0)
170
1.38k
        from_hdr->tag = pj_str("from-tag-123");
171
172
1.42k
    if (to_hdr && pj_stricmp2(&to_hdr->tag, "") == 0)
173
1.40k
        to_hdr->tag = pj_str("to-tag-456");
174
175
    /* Ensure Via header has valid host/port for response addressing */
176
1.42k
    if (via_hdr->sent_by.host.slen == 0) {
177
0
        via_hdr->sent_by.host = pj_str("127.0.0.1");
178
0
        via_hdr->sent_by.port = 5060;
179
0
    }
180
181
    /* Test transaction key generation */
182
1.42k
    if (pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAS,
183
1.42k
                             &msg->line.req.method, rdata) == PJ_SUCCESS) {
184
1.42k
        pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE);
185
1.42k
    }
186
1.42k
}
187
188
/* Test synthetic transaction creation */
189
static void do_test_transaction_synthetic(void)
190
1
{
191
1
    pj_str_t target_uri_str = pj_str("sip:test@example.com");
192
1
    pj_str_t from_str = pj_str("sip:caller@example.com");
193
1
    pj_str_t to_str = pj_str("sip:callee@example.com");
194
1
    pj_str_t call_id_str = pj_str("call-id-fuzz-test@example.com");
195
1
    pjsip_tx_data *tdata;
196
197
1
    if (pjsip_endpt_create_request(endpt, &pjsip_invite_method,
198
1
                                   &target_uri_str, &from_str, &to_str,
199
1
                                   NULL, &call_id_str, -1, NULL, &tdata) == PJ_SUCCESS) {
200
1
        pjsip_tx_data_dec_ref(tdata);
201
1
    }
202
1
}
203
204
/* Test UAC transaction response handling */
205
static void do_test_transaction_uac(pjsip_msg *msg, pjsip_rx_data *rdata)
206
2.88k
{
207
2.88k
    pj_str_t tsx_key;
208
209
2.88k
    if (!msg || msg->type != PJSIP_RESPONSE_MSG || !rdata)
210
0
        return;
211
212
2.88k
    if (!rdata->msg_info.via || !rdata->msg_info.cseq ||
213
54
        !rdata->msg_info.from || !rdata->msg_info.cid)
214
2.83k
        return;
215
216
    /* Skip if no transport available */
217
50
    if (!rdata->tp_info.transport)
218
0
        return;
219
220
    /* Test transaction key generation for responses */
221
50
    if (pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC,
222
50
                             &rdata->msg_info.cseq->method, rdata) == PJ_SUCCESS) {
223
50
        pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE);
224
50
    }
225
50
}
226
227
/* Test authentication client */
228
static void do_test_auth_client(pj_pool_t *pool, pjsip_msg *msg)
229
4.48k
{
230
4.48k
    pjsip_auth_clt_sess auth_sess;
231
4.48k
    pjsip_hdr *hdr = NULL;
232
4.48k
    pj_status_t status;
233
234
    /* Only test with 401/407 responses */
235
4.48k
    if (!msg || msg->type != PJSIP_RESPONSE_MSG)
236
1.59k
        return;
237
238
2.88k
    if (msg->line.status.code != 401 && msg->line.status.code != 407)
239
2.16k
        return;
240
241
    /* Initialize auth client session */
242
721
    if (pjsip_auth_clt_init(&auth_sess, endpt, pool, 0) != PJ_SUCCESS)
243
0
        return;
244
245
    /* Set up credentials */
246
721
    pjsip_cred_info cred;
247
721
    pj_bzero(&cred, sizeof(cred));
248
721
    cred.realm = pj_str("test");
249
721
    cred.username = pj_str("user");
250
721
    cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
251
721
    cred.data = pj_str("password");
252
253
721
    if (pjsip_auth_clt_set_credentials(&auth_sess, 1, &cred) != PJ_SUCCESS)
254
0
        goto cleanup;
255
256
    /* Parse authentication headers */
257
721
    if (msg->line.status.code == 401)
258
707
        hdr = pjsip_msg_find_hdr(msg, PJSIP_H_WWW_AUTHENTICATE, NULL);
259
14
    else
260
14
        hdr = pjsip_msg_find_hdr(msg, PJSIP_H_PROXY_AUTHENTICATE, NULL);
261
262
721
    if (hdr) {
263
        /* Create a dummy request to test reinit */
264
591
        pjsip_tx_data *tdata = NULL;
265
591
        pjsip_method method;
266
591
        pj_str_t target_uri = pj_str("sip:server.com");
267
591
        pj_str_t from_uri = pj_str("sip:client@local");
268
591
        pj_str_t to_uri = pj_str("sip:server.com");
269
591
        pj_str_t contact = pj_str("sip:client@local");
270
271
591
        pjsip_method_set(&method, PJSIP_REGISTER_METHOD);
272
273
591
        status = pjsip_endpt_create_request(endpt, &method, &target_uri,
274
591
                                           &from_uri, &to_uri, &contact,
275
591
                                           NULL, -1, NULL, &tdata);
276
591
        if (status != PJ_SUCCESS || !tdata)
277
0
            goto cleanup;
278
279
        /* Initialize request with auth */
280
591
        pjsip_auth_clt_init_req(&auth_sess, tdata);
281
282
        /* Create rx_data from the 401/407 message */
283
591
        pjsip_rx_data rdata;
284
591
        pj_bzero(&rdata, sizeof(rdata));
285
591
        rdata.msg_info.msg = msg;
286
591
        rdata.msg_info.info = NULL;
287
591
        rdata.msg_info.len = 1024;
288
289
        /* Try to reinit with the challenge */
290
591
        pjsip_tx_data *new_tdata = NULL;
291
591
        if (pjsip_auth_clt_reinit_req(&auth_sess, &rdata, tdata, &new_tdata) == PJ_SUCCESS && new_tdata) {
292
256
            pjsip_tx_data_dec_ref(new_tdata);
293
256
        }
294
295
591
        pjsip_tx_data_dec_ref(tdata);
296
591
    }
297
298
721
cleanup:
299
721
    pjsip_auth_clt_deinit(&auth_sess);
300
721
}
301
302
/* Test dialog creation */
303
static void do_test_dialog(pjsip_msg *msg)
304
4.48k
{
305
4.48k
    pjsip_dialog *dlg = NULL;
306
4.48k
    pjsip_to_hdr *to;
307
4.48k
    pjsip_from_hdr *from;
308
4.48k
    pj_str_t local_uri = pj_str("sip:local@test.com");
309
4.48k
    pj_str_t remote_uri = pj_str("sip:remote@test.com");
310
4.48k
    pj_str_t target = pj_str("sip:remote@test.com");
311
312
4.48k
    if (!msg || msg->type != PJSIP_REQUEST_MSG)
313
2.88k
        return;
314
315
1.59k
    if (msg->line.req.method.id != PJSIP_INVITE_METHOD)
316
1.27k
        return;
317
318
    /* Get To and From headers */
319
326
    to = (pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL);
320
326
    from = (pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL);
321
326
    if (!to || !from)
322
4
        return;
323
324
    /* Create UAC dialog */
325
322
    if (pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL,
326
322
                             &remote_uri, &target, &dlg) == PJ_SUCCESS && dlg) {
327
322
        pjsip_dlg_inc_lock(dlg);
328
329
        /* Build route set from all Route headers */
330
322
        pjsip_route_hdr route_set;
331
322
        pjsip_route_hdr *route;
332
322
        pj_list_init(&route_set);
333
322
        route = (pjsip_route_hdr*)
334
322
                pjsip_msg_find_hdr(msg, PJSIP_H_ROUTE, NULL);
335
3.44k
        while (route) {
336
3.12k
            pjsip_route_hdr *route_clone = (pjsip_route_hdr*)
337
3.12k
                    pjsip_hdr_clone(dlg->pool, route);
338
3.12k
            pj_list_push_back(&route_set, route_clone);
339
3.12k
            route = (pjsip_route_hdr*)
340
3.12k
                    pjsip_msg_find_hdr(msg, PJSIP_H_ROUTE,
341
3.12k
                                        route->next);
342
3.12k
        }
343
322
        if (!pj_list_empty(&route_set)) {
344
92
            pjsip_dlg_set_route_set(dlg, &route_set);
345
92
        }
346
347
322
        pjsip_dlg_dec_lock(dlg);
348
322
    }
349
322
}
350
351
extern int
352
LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
353
7.61k
{
354
7.61k
    char *DataFx;
355
7.61k
    pj_pool_t *pool;
356
7.61k
    pjsip_msg *msg;
357
7.61k
    static int initialized = 0;
358
359
7.61k
    if (Size < kMinInputLength || Size > kMaxInputLength)
360
10
        return 1;
361
362
7.60k
    DataFx = (char *)calloc((Size+1), sizeof(char));
363
7.60k
    if (DataFx == NULL)
364
0
        return 0;
365
7.60k
    memcpy((void *)DataFx, (void *)Data, Size);
366
367
7.60k
    if (!initialized) {
368
1
        pj_log_set_level(0);
369
370
1
        if (pj_init() != PJ_SUCCESS || pjlib_util_init() != PJ_SUCCESS) {
371
0
            free(DataFx);
372
0
            return 0;
373
0
        }
374
375
1
        pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy,
376
1
                            PJSIP_TEST_MEM_SIZE);
377
378
1
        if (pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt) != PJ_SUCCESS || !endpt) {
379
0
            free(DataFx);
380
0
            return 0;
381
0
        }
382
383
1
        if (pjsip_tsx_layer_init_module(endpt) != PJ_SUCCESS ||
384
1
            pjsip_loop_start(endpt, NULL) != PJ_SUCCESS) {
385
0
            free(DataFx);
386
0
            return 0;
387
0
        }
388
389
1
        pjsip_ua_init_module(endpt, NULL);
390
391
        /* Register the specialised SIP header parsers. The core SIP parser
392
         * only installs grammars for headers whose owning module has been
393
         * initialised; without these calls the headers below are parsed as
394
         * generic string headers and the hand-written grammars in
395
         * evsub_msg.c (Event/Subscription-State/Allow-Events),
396
         * sip_replaces.c (Replaces) and sip_timer.c (Session-Expires/Min-SE)
397
         * are never exercised even when present in the input message. */
398
1
        if (pjsip_evsub_init_module(endpt) != PJ_SUCCESS ||
399
1
            pjsip_replaces_init_module(endpt) != PJ_SUCCESS ||
400
1
            pjsip_timer_init_module(endpt) != PJ_SUCCESS) {
401
0
            free(DataFx);
402
0
            return 0;
403
0
        }
404
405
        /* Initialize transaction user module */
406
1
        pj_bzero(&tsx_user_module, sizeof(tsx_user_module));
407
1
        tsx_user_module.name = pj_str("tsx-user");
408
1
        tsx_user_module.id = -1;
409
1
        tsx_user_module.priority = PJSIP_MOD_PRIORITY_APPLICATION;
410
1
        tsx_user_module.on_tsx_state = &on_tsx_state;
411
1
        pjsip_endpt_register_module(endpt, &tsx_user_module);
412
413
1
        do_test_transaction_synthetic();
414
415
1
        initialized = 1;
416
1
    }
417
418
7.60k
    pool = pjsip_endpt_create_pool(endpt, NULL, POOL_SIZE, POOL_SIZE);
419
7.60k
    msg = parse_message(pool, DataFx, Size);
420
421
7.60k
    if (msg) {
422
4.48k
        pjsip_rx_data rdata;
423
4.48k
        pj_sockaddr remote_addr;
424
4.48k
        pjsip_transport *fake_transport = NULL;
425
4.48k
        int i;
426
427
4.48k
        do_test_multipart(pool, msg);
428
429
        /* Test named headers */
430
4.48k
        const char *hdr_names[] = {
431
4.48k
            "Replaces", "Refer-To", "Refer-Sub", "Subscription-State",
432
4.48k
            "Session-Expires", "Min-SE", "RSeq", "RAck"
433
4.48k
        };
434
40.3k
        for (i = 0; i < (int)(sizeof(hdr_names) / sizeof(hdr_names[0])); i++) {
435
35.8k
            pj_str_t hdr_name = pj_str((char *)hdr_names[i]);
436
35.8k
            pjsip_msg_find_hdr_by_name(msg, &hdr_name, NULL);
437
35.8k
        }
438
439
        /* Test standard header types */
440
35.8k
        for (i = 0; i < (int)(sizeof(hdr_types) / sizeof(hdr_types[0])); i++) {
441
31.3k
            pjsip_msg_find_hdr(msg, hdr_types[i], NULL);
442
31.3k
        }
443
444
        /* Setup rx_data for transaction testing */
445
4.48k
        pj_bzero(&rdata, sizeof(rdata));
446
4.48k
        rdata.msg_info.msg = msg;
447
4.48k
        rdata.msg_info.len = Size;
448
4.48k
        rdata.msg_info.info = DataFx;
449
4.48k
        rdata.tp_info.pool = pool;
450
451
        /* Populate header shortcuts */
452
4.48k
        rdata.msg_info.from = (pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL);
453
4.48k
        rdata.msg_info.to = (pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL);
454
4.48k
        rdata.msg_info.via = (pjsip_via_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL);
455
4.48k
        rdata.msg_info.cseq = (pjsip_cseq_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);
456
4.48k
        rdata.msg_info.cid = (pjsip_cid_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CALL_ID, NULL);
457
4.48k
        rdata.msg_info.max_fwd = (pjsip_max_fwd_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_MAX_FORWARDS, NULL);
458
459
        /* Setup transport info */
460
4.48k
        pj_sockaddr_init(pj_AF_INET(), &remote_addr, NULL, 5060);
461
4.48k
        remote_addr.ipv4.sin_addr.s_addr = pj_htonl(0x7F000001);
462
463
4.48k
        pj_memcpy(&rdata.pkt_info.src_addr, &remote_addr,
464
4.48k
                  sizeof(remote_addr.ipv4));
465
4.48k
        rdata.pkt_info.src_addr_len = sizeof(remote_addr.ipv4);
466
4.48k
        pj_ansi_snprintf(rdata.pkt_info.src_name, sizeof(rdata.pkt_info.src_name),
467
4.48k
                         "127.0.0.1");
468
4.48k
        rdata.pkt_info.src_port = 5060;
469
4.48k
        if (Size < sizeof(rdata.pkt_info.packet)) {
470
4.39k
            pj_memcpy(rdata.pkt_info.packet, DataFx, Size);
471
4.39k
            rdata.pkt_info.len = Size;
472
4.39k
        } else {
473
84
            pj_memcpy(rdata.pkt_info.packet, DataFx, sizeof(rdata.pkt_info.packet));
474
84
            rdata.pkt_info.len = sizeof(rdata.pkt_info.packet);
475
84
        }
476
477
        /* Acquire loop datagram transport */
478
4.48k
        if (pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
479
4.48k
                                          &remote_addr,
480
4.48k
                                          sizeof(remote_addr.ipv4),
481
4.48k
                                          NULL, &fake_transport) == PJ_SUCCESS) {
482
4.48k
            rdata.tp_info.transport = fake_transport;
483
4.48k
        }
484
485
4.48k
        do_test_transaction_layer(msg, &rdata);
486
487
4.48k
        if (msg->type == PJSIP_RESPONSE_MSG) {
488
2.88k
            do_test_transaction_uac(msg, &rdata);
489
2.88k
        }
490
491
4.48k
        do_test_auth_client(pool, msg);
492
4.48k
        do_test_dialog(msg);
493
494
4.48k
        if (msg->type == PJSIP_REQUEST_MSG && rdata.msg_info.via) {
495
1.44k
            pj_strdup2(pool, &rdata.msg_info.via->recvd_param,
496
1.44k
                       rdata.pkt_info.src_name);
497
1.44k
            if (rdata.msg_info.via->rport_param == 0) {
498
26
                rdata.msg_info.via->rport_param = rdata.pkt_info.src_port;
499
26
            }
500
1.44k
        }
501
502
        /* Route through the full endpoint module pipeline */
503
4.48k
        if (rdata.tp_info.transport &&
504
4.48k
            rdata.msg_info.from && rdata.msg_info.to &&
505
1.55k
            rdata.msg_info.via && rdata.msg_info.cseq &&
506
1.44k
            rdata.msg_info.cid && rdata.msg_info.cid->id.slen != 0) {
507
1.44k
            pjsip_transaction *tsx;
508
1.44k
            pj_time_val timeout = {0, 0};
509
1.44k
            unsigned i;
510
511
1.44k
            pjsip_endpt_process_rx_data(endpt, &rdata, NULL, NULL);
512
513
1.44k
            tsx = pjsip_rdata_get_tsx(&rdata);
514
1.44k
            if (tsx) {
515
0
                pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
516
0
            }
517
518
            /* Pump events repeatedly */
519
13.0k
            for (i = 0; i < 8; ++i) {
520
11.5k
                pjsip_endpt_handle_events(endpt, &timeout);
521
11.5k
            }
522
1.44k
        }
523
524
        /* Release transport */
525
4.48k
        if (fake_transport) {
526
4.48k
            pjsip_transport_dec_ref(fake_transport);
527
4.48k
        }
528
4.48k
    }
529
530
7.60k
    do_test_tel_uri(pool, DataFx, Size);
531
532
7.60k
    pjsip_endpt_release_pool(endpt, pool);
533
7.60k
    free(DataFx);
534
535
7.60k
    return 0;
536
7.60k
}
537