/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 | | |
33 | | pjsip_endpoint *endpt; |
34 | | pj_caching_pool caching_pool; |
35 | | |
36 | 14.5k | #define POOL_SIZE 8000 |
37 | 1 | #define PJSIP_TEST_MEM_SIZE (2*1024*1024) |
38 | | |
39 | 14.5k | #define kMinInputLength 10 |
40 | 7.26k | #define kMaxInputLength 5120 |
41 | | |
42 | | /* Transaction user module */ |
43 | | static pjsip_module tsx_user_module; |
44 | | |
45 | | /* Transaction state callback */ |
46 | | static void on_tsx_state(pjsip_transaction *tsx, pjsip_event *event) |
47 | 0 | { |
48 | 0 | PJ_UNUSED_ARG(tsx); |
49 | 0 | PJ_UNUSED_ARG(event); |
50 | 0 | } |
51 | | |
52 | | /* Standard header types to test */ |
53 | | static const pjsip_hdr_e hdr_types[] = { |
54 | | PJSIP_H_AUTHORIZATION, |
55 | | PJSIP_H_PROXY_AUTHORIZATION, |
56 | | PJSIP_H_WWW_AUTHENTICATE, |
57 | | PJSIP_H_PROXY_AUTHENTICATE, |
58 | | PJSIP_H_ROUTE, |
59 | | PJSIP_H_RECORD_ROUTE, |
60 | | PJSIP_H_CONTACT |
61 | | }; |
62 | | |
63 | | static pjsip_msg* parse_message(pj_pool_t *pool, char *data, size_t size) |
64 | 7.25k | { |
65 | 7.25k | pjsip_parser_err_report err_list; |
66 | 7.25k | pj_list_init(&err_list); |
67 | 7.25k | return pjsip_parse_msg(pool, data, size, &err_list); |
68 | 7.25k | } |
69 | | |
70 | | /* Multipart body parsing */ |
71 | | static void do_test_multipart(pj_pool_t *pool, pjsip_msg *msg) |
72 | 4.10k | { |
73 | 4.10k | if (!msg->body) |
74 | 3.92k | return; |
75 | | |
76 | 181 | pjsip_msg_body *body = msg->body; |
77 | | |
78 | 181 | if (body->content_type.type.slen > 0 && |
79 | 181 | pj_stricmp2(&body->content_type.type, "multipart") == 0) |
80 | 66 | { |
81 | 66 | pjsip_msg_body *multipart_body = NULL; |
82 | 66 | if (body->data && body->len > 0) { |
83 | 0 | multipart_body = pjsip_multipart_parse(pool, (char *)body->data, |
84 | 0 | body->len, &body->content_type, 0); |
85 | 0 | if (!multipart_body) |
86 | 0 | return; |
87 | 66 | } else { |
88 | 66 | multipart_body = body; |
89 | 66 | } |
90 | | |
91 | 66 | pjsip_multipart_part *part = pjsip_multipart_get_first_part(multipart_body); |
92 | | |
93 | 4.92k | while (part) { |
94 | 4.85k | pjsip_media_type ctype_app, ctype_text; |
95 | | |
96 | 4.85k | ctype_app.type = pj_str("application"); |
97 | 4.85k | ctype_app.subtype = pj_str("sdp"); |
98 | 4.85k | ctype_text.type = pj_str("text"); |
99 | 4.85k | ctype_text.subtype = pj_str("plain"); |
100 | | |
101 | 4.85k | pjsip_multipart_find_part(multipart_body, &ctype_app, NULL); |
102 | 4.85k | pjsip_multipart_find_part(multipart_body, &ctype_text, NULL); |
103 | | |
104 | 4.85k | part = pjsip_multipart_get_next_part(multipart_body, part); |
105 | 4.85k | } |
106 | | |
107 | 66 | pjsip_media_type search_type; |
108 | 66 | search_type.type = pj_str("application"); |
109 | 66 | search_type.subtype = pj_str("sdp"); |
110 | 66 | pjsip_multipart_find_part(multipart_body, &search_type, NULL); |
111 | 66 | } |
112 | 181 | } |
113 | | |
114 | | /* Tel URI parsing */ |
115 | | static void do_test_tel_uri(pj_pool_t *pool, char *data, size_t size) |
116 | 7.25k | { |
117 | 7.25k | pj_str_t uri_str; |
118 | 7.25k | pjsip_uri *uri; |
119 | | |
120 | 7.25k | if (size < 4 || size > 256) |
121 | 1.85k | return; |
122 | | |
123 | 5.40k | uri_str.ptr = data; |
124 | 5.40k | uri_str.slen = (pj_ssize_t)size; |
125 | | |
126 | 5.40k | uri = pjsip_parse_uri(pool, uri_str.ptr, uri_str.slen, 0); |
127 | | |
128 | 5.40k | if (uri && size > 20) { |
129 | 688 | pj_str_t uri2_str; |
130 | 688 | pjsip_uri *uri2; |
131 | | |
132 | 688 | uri2_str.ptr = data + 10; |
133 | 688 | uri2_str.slen = (pj_ssize_t)(size - 10); |
134 | | |
135 | 688 | uri2 = pjsip_parse_uri(pool, uri2_str.ptr, uri2_str.slen, 0); |
136 | 688 | if (uri2) { |
137 | 613 | pjsip_uri_cmp(PJSIP_URI_IN_FROMTO_HDR, uri, uri2); |
138 | 613 | pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, uri, uri2); |
139 | 613 | } |
140 | 688 | } |
141 | 5.40k | } |
142 | | |
143 | | /* Test UAS transaction creation and message feeding */ |
144 | | static void do_test_transaction_layer(pjsip_msg *msg, pjsip_rx_data *rdata) |
145 | 4.10k | { |
146 | 4.10k | pj_str_t tsx_key; |
147 | 4.10k | pjsip_via_hdr *via_hdr; |
148 | | |
149 | 4.10k | if (!msg || msg->type != PJSIP_REQUEST_MSG || !rdata) |
150 | 2.85k | return; |
151 | | |
152 | 1.25k | if (!rdata->msg_info.via || !rdata->msg_info.cseq || |
153 | 1.09k | !rdata->msg_info.from || !rdata->msg_info.cid) |
154 | 161 | return; |
155 | | |
156 | 1.09k | via_hdr = rdata->msg_info.via; |
157 | | |
158 | | /* Skip transaction creation if transport not available */ |
159 | 1.09k | if (!rdata->tp_info.transport) |
160 | 0 | return; |
161 | | |
162 | | /* Ensure From/To headers have tags */ |
163 | 1.09k | pjsip_from_hdr *from_hdr = (pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL); |
164 | 1.09k | pjsip_to_hdr *to_hdr = (pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL); |
165 | | |
166 | 1.09k | if (from_hdr && pj_stricmp2(&from_hdr->tag, "") == 0) |
167 | 827 | from_hdr->tag = pj_str("from-tag-123"); |
168 | | |
169 | 1.09k | if (to_hdr && pj_stricmp2(&to_hdr->tag, "") == 0) |
170 | 1.05k | to_hdr->tag = pj_str("to-tag-456"); |
171 | | |
172 | | /* Ensure Via header has valid host/port for response addressing */ |
173 | 1.09k | if (via_hdr->sent_by.host.slen == 0) { |
174 | 0 | via_hdr->sent_by.host = pj_str("127.0.0.1"); |
175 | 0 | via_hdr->sent_by.port = 5060; |
176 | 0 | } |
177 | | |
178 | | /* Test transaction key generation */ |
179 | 1.09k | if (pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAS, |
180 | 1.09k | &msg->line.req.method, rdata) == PJ_SUCCESS) { |
181 | 1.09k | pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE); |
182 | 1.09k | } |
183 | 1.09k | } |
184 | | |
185 | | /* Test synthetic transaction creation */ |
186 | | static void do_test_transaction_synthetic(void) |
187 | 1 | { |
188 | 1 | pj_str_t target_uri_str = pj_str("sip:test@example.com"); |
189 | 1 | pj_str_t from_str = pj_str("sip:caller@example.com"); |
190 | 1 | pj_str_t to_str = pj_str("sip:callee@example.com"); |
191 | 1 | pj_str_t call_id_str = pj_str("call-id-fuzz-test@example.com"); |
192 | 1 | pjsip_tx_data *tdata; |
193 | | |
194 | 1 | if (pjsip_endpt_create_request(endpt, &pjsip_invite_method, |
195 | 1 | &target_uri_str, &from_str, &to_str, |
196 | 1 | NULL, &call_id_str, -1, NULL, &tdata) == PJ_SUCCESS) { |
197 | 1 | pjsip_tx_data_dec_ref(tdata); |
198 | 1 | } |
199 | 1 | } |
200 | | |
201 | | /* Test UAC transaction response handling */ |
202 | | static void do_test_transaction_uac(pjsip_msg *msg, pjsip_rx_data *rdata) |
203 | 2.85k | { |
204 | 2.85k | pj_str_t tsx_key; |
205 | | |
206 | 2.85k | if (!msg || msg->type != PJSIP_RESPONSE_MSG || !rdata) |
207 | 0 | return; |
208 | | |
209 | 2.85k | if (!rdata->msg_info.via || !rdata->msg_info.cseq || |
210 | 27 | !rdata->msg_info.from || !rdata->msg_info.cid) |
211 | 2.82k | return; |
212 | | |
213 | | /* Skip if no transport available */ |
214 | 25 | if (!rdata->tp_info.transport) |
215 | 0 | return; |
216 | | |
217 | | /* Test transaction key generation for responses */ |
218 | 25 | if (pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC, |
219 | 25 | &rdata->msg_info.cseq->method, rdata) == PJ_SUCCESS) { |
220 | 25 | pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE); |
221 | 25 | } |
222 | 25 | } |
223 | | |
224 | | /* Test authentication client */ |
225 | | static void do_test_auth_client(pj_pool_t *pool, pjsip_msg *msg) |
226 | 4.10k | { |
227 | 4.10k | pjsip_auth_clt_sess auth_sess; |
228 | 4.10k | pjsip_hdr *hdr = NULL; |
229 | 4.10k | pj_status_t status; |
230 | | |
231 | | /* Only test with 401/407 responses */ |
232 | 4.10k | if (!msg || msg->type != PJSIP_RESPONSE_MSG) |
233 | 1.25k | return; |
234 | | |
235 | 2.85k | if (msg->line.status.code != 401 && msg->line.status.code != 407) |
236 | 2.12k | return; |
237 | | |
238 | | /* Initialize auth client session */ |
239 | 728 | if (pjsip_auth_clt_init(&auth_sess, endpt, pool, 0) != PJ_SUCCESS) |
240 | 0 | return; |
241 | | |
242 | | /* Set up credentials */ |
243 | 728 | pjsip_cred_info cred; |
244 | 728 | pj_bzero(&cred, sizeof(cred)); |
245 | 728 | cred.realm = pj_str("test"); |
246 | 728 | cred.username = pj_str("user"); |
247 | 728 | cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; |
248 | 728 | cred.data = pj_str("password"); |
249 | | |
250 | 728 | if (pjsip_auth_clt_set_credentials(&auth_sess, 1, &cred) != PJ_SUCCESS) |
251 | 0 | goto cleanup; |
252 | | |
253 | | /* Parse authentication headers */ |
254 | 728 | if (msg->line.status.code == 401) |
255 | 713 | hdr = pjsip_msg_find_hdr(msg, PJSIP_H_WWW_AUTHENTICATE, NULL); |
256 | 15 | else |
257 | 15 | hdr = pjsip_msg_find_hdr(msg, PJSIP_H_PROXY_AUTHENTICATE, NULL); |
258 | | |
259 | 728 | if (hdr) { |
260 | | /* Create a dummy request to test reinit */ |
261 | 636 | pjsip_tx_data *tdata = NULL; |
262 | 636 | pjsip_method method; |
263 | 636 | pj_str_t target_uri = pj_str("sip:server.com"); |
264 | 636 | pj_str_t from_uri = pj_str("sip:client@local"); |
265 | 636 | pj_str_t to_uri = pj_str("sip:server.com"); |
266 | 636 | pj_str_t contact = pj_str("sip:client@local"); |
267 | | |
268 | 636 | pjsip_method_set(&method, PJSIP_REGISTER_METHOD); |
269 | | |
270 | 636 | status = pjsip_endpt_create_request(endpt, &method, &target_uri, |
271 | 636 | &from_uri, &to_uri, &contact, |
272 | 636 | NULL, -1, NULL, &tdata); |
273 | 636 | if (status != PJ_SUCCESS || !tdata) |
274 | 0 | goto cleanup; |
275 | | |
276 | | /* Initialize request with auth */ |
277 | 636 | pjsip_auth_clt_init_req(&auth_sess, tdata); |
278 | | |
279 | | /* Create rx_data from the 401/407 message */ |
280 | 636 | pjsip_rx_data rdata; |
281 | 636 | pj_bzero(&rdata, sizeof(rdata)); |
282 | 636 | rdata.msg_info.msg = msg; |
283 | 636 | rdata.msg_info.info = NULL; |
284 | 636 | rdata.msg_info.len = 1024; |
285 | | |
286 | | /* Try to reinit with the challenge */ |
287 | 636 | pjsip_tx_data *new_tdata = NULL; |
288 | 636 | if (pjsip_auth_clt_reinit_req(&auth_sess, &rdata, tdata, &new_tdata) == PJ_SUCCESS && new_tdata) { |
289 | 309 | pjsip_tx_data_dec_ref(new_tdata); |
290 | 309 | } |
291 | | |
292 | 636 | pjsip_tx_data_dec_ref(tdata); |
293 | 636 | } |
294 | | |
295 | 728 | cleanup: |
296 | 728 | pjsip_auth_clt_deinit(&auth_sess); |
297 | 728 | } |
298 | | |
299 | | /* Test dialog creation */ |
300 | | static void do_test_dialog(pjsip_msg *msg) |
301 | 4.10k | { |
302 | 4.10k | pjsip_dialog *dlg = NULL; |
303 | 4.10k | pjsip_to_hdr *to; |
304 | 4.10k | pjsip_from_hdr *from; |
305 | 4.10k | pj_str_t local_uri = pj_str("sip:local@test.com"); |
306 | 4.10k | pj_str_t remote_uri = pj_str("sip:remote@test.com"); |
307 | 4.10k | pj_str_t target = pj_str("sip:remote@test.com"); |
308 | | |
309 | 4.10k | if (!msg || msg->type != PJSIP_REQUEST_MSG) |
310 | 2.85k | return; |
311 | | |
312 | 1.25k | if (msg->line.req.method.id != PJSIP_INVITE_METHOD) |
313 | 603 | return; |
314 | | |
315 | | /* Get To and From headers */ |
316 | 649 | to = (pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL); |
317 | 649 | from = (pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL); |
318 | 649 | if (!to || !from) |
319 | 20 | return; |
320 | | |
321 | | /* Create UAC dialog */ |
322 | 629 | if (pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, |
323 | 629 | &remote_uri, &target, &dlg) == PJ_SUCCESS && dlg) { |
324 | 629 | pjsip_dlg_inc_lock(dlg); |
325 | | |
326 | | /* Build route set from all Route headers */ |
327 | 629 | pjsip_route_hdr route_set; |
328 | 629 | pjsip_route_hdr *route; |
329 | 629 | pj_list_init(&route_set); |
330 | 629 | route = (pjsip_route_hdr*) |
331 | 629 | pjsip_msg_find_hdr(msg, PJSIP_H_ROUTE, NULL); |
332 | 3.81k | while (route) { |
333 | 3.18k | pjsip_route_hdr *route_clone = (pjsip_route_hdr*) |
334 | 3.18k | pjsip_hdr_clone(dlg->pool, route); |
335 | 3.18k | pj_list_push_back(&route_set, route_clone); |
336 | 3.18k | route = (pjsip_route_hdr*) |
337 | 3.18k | pjsip_msg_find_hdr(msg, PJSIP_H_ROUTE, |
338 | 3.18k | route->next); |
339 | 3.18k | } |
340 | 629 | if (!pj_list_empty(&route_set)) { |
341 | 102 | pjsip_dlg_set_route_set(dlg, &route_set); |
342 | 102 | } |
343 | | |
344 | 629 | pjsip_dlg_dec_lock(dlg); |
345 | 629 | } |
346 | 629 | } |
347 | | |
348 | | extern int |
349 | | LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) |
350 | 7.26k | { |
351 | 7.26k | char *DataFx; |
352 | 7.26k | pj_pool_t *pool; |
353 | 7.26k | pjsip_msg *msg; |
354 | 7.26k | static int initialized = 0; |
355 | | |
356 | 7.26k | if (Size < kMinInputLength || Size > kMaxInputLength) |
357 | 9 | return 1; |
358 | | |
359 | 7.25k | DataFx = (char *)calloc((Size+1), sizeof(char)); |
360 | 7.25k | if (DataFx == NULL) |
361 | 0 | return 0; |
362 | 7.25k | memcpy((void *)DataFx, (void *)Data, Size); |
363 | | |
364 | 7.25k | if (!initialized) { |
365 | 1 | pj_log_set_level(0); |
366 | | |
367 | 1 | if (pj_init() != PJ_SUCCESS || pjlib_util_init() != PJ_SUCCESS) { |
368 | 0 | free(DataFx); |
369 | 0 | return 0; |
370 | 0 | } |
371 | | |
372 | 1 | pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, |
373 | 1 | PJSIP_TEST_MEM_SIZE); |
374 | | |
375 | 1 | if (pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt) != PJ_SUCCESS || !endpt) { |
376 | 0 | free(DataFx); |
377 | 0 | return 0; |
378 | 0 | } |
379 | | |
380 | 1 | if (pjsip_tsx_layer_init_module(endpt) != PJ_SUCCESS || |
381 | 1 | pjsip_loop_start(endpt, NULL) != PJ_SUCCESS) { |
382 | 0 | free(DataFx); |
383 | 0 | return 0; |
384 | 0 | } |
385 | | |
386 | 1 | pjsip_ua_init_module(endpt, NULL); |
387 | | |
388 | | /* Initialize transaction user module */ |
389 | 1 | pj_bzero(&tsx_user_module, sizeof(tsx_user_module)); |
390 | 1 | tsx_user_module.name = pj_str("tsx-user"); |
391 | 1 | tsx_user_module.id = -1; |
392 | 1 | tsx_user_module.priority = PJSIP_MOD_PRIORITY_APPLICATION; |
393 | 1 | tsx_user_module.on_tsx_state = &on_tsx_state; |
394 | 1 | pjsip_endpt_register_module(endpt, &tsx_user_module); |
395 | | |
396 | 1 | do_test_transaction_synthetic(); |
397 | | |
398 | 1 | initialized = 1; |
399 | 1 | } |
400 | | |
401 | 7.25k | pool = pjsip_endpt_create_pool(endpt, NULL, POOL_SIZE, POOL_SIZE); |
402 | 7.25k | msg = parse_message(pool, DataFx, Size); |
403 | | |
404 | 7.25k | if (msg) { |
405 | 4.10k | pjsip_rx_data rdata; |
406 | 4.10k | pj_sockaddr remote_addr; |
407 | 4.10k | pjsip_transport *fake_transport = NULL; |
408 | 4.10k | int i; |
409 | | |
410 | 4.10k | do_test_multipart(pool, msg); |
411 | | |
412 | | /* Test named headers */ |
413 | 4.10k | const char *hdr_names[] = { |
414 | 4.10k | "Replaces", "Refer-To", "Refer-Sub", "Subscription-State", |
415 | 4.10k | "Session-Expires", "Min-SE", "RSeq", "RAck" |
416 | 4.10k | }; |
417 | 36.9k | for (i = 0; i < (int)(sizeof(hdr_names) / sizeof(hdr_names[0])); i++) { |
418 | 32.8k | pj_str_t hdr_name = pj_str((char *)hdr_names[i]); |
419 | 32.8k | pjsip_msg_find_hdr_by_name(msg, &hdr_name, NULL); |
420 | 32.8k | } |
421 | | |
422 | | /* Test standard header types */ |
423 | 32.8k | for (i = 0; i < (int)(sizeof(hdr_types) / sizeof(hdr_types[0])); i++) { |
424 | 28.7k | pjsip_msg_find_hdr(msg, hdr_types[i], NULL); |
425 | 28.7k | } |
426 | | |
427 | | /* Setup rx_data for transaction testing */ |
428 | 4.10k | pj_bzero(&rdata, sizeof(rdata)); |
429 | 4.10k | rdata.msg_info.msg = msg; |
430 | 4.10k | rdata.msg_info.len = Size; |
431 | 4.10k | rdata.msg_info.info = DataFx; |
432 | 4.10k | rdata.tp_info.pool = pool; |
433 | | |
434 | | /* Populate header shortcuts */ |
435 | 4.10k | rdata.msg_info.from = (pjsip_from_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL); |
436 | 4.10k | rdata.msg_info.to = (pjsip_to_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL); |
437 | 4.10k | rdata.msg_info.via = (pjsip_via_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_VIA, NULL); |
438 | 4.10k | rdata.msg_info.cseq = (pjsip_cseq_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); |
439 | 4.10k | rdata.msg_info.cid = (pjsip_cid_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_CALL_ID, NULL); |
440 | 4.10k | rdata.msg_info.max_fwd = (pjsip_max_fwd_hdr*)pjsip_msg_find_hdr(msg, PJSIP_H_MAX_FORWARDS, NULL); |
441 | | |
442 | | /* Setup transport info */ |
443 | 4.10k | pj_sockaddr_init(pj_AF_INET(), &remote_addr, NULL, 5060); |
444 | 4.10k | remote_addr.ipv4.sin_addr.s_addr = pj_htonl(0x7F000001); |
445 | | |
446 | 4.10k | pj_memcpy(&rdata.pkt_info.src_addr, &remote_addr, |
447 | 4.10k | sizeof(remote_addr.ipv4)); |
448 | 4.10k | rdata.pkt_info.src_addr_len = sizeof(remote_addr.ipv4); |
449 | 4.10k | pj_ansi_snprintf(rdata.pkt_info.src_name, sizeof(rdata.pkt_info.src_name), |
450 | 4.10k | "127.0.0.1"); |
451 | 4.10k | rdata.pkt_info.src_port = 5060; |
452 | 4.10k | if (Size < sizeof(rdata.pkt_info.packet)) { |
453 | 3.95k | pj_memcpy(rdata.pkt_info.packet, DataFx, Size); |
454 | 3.95k | rdata.pkt_info.len = Size; |
455 | 3.95k | } else { |
456 | 146 | pj_memcpy(rdata.pkt_info.packet, DataFx, sizeof(rdata.pkt_info.packet)); |
457 | 146 | rdata.pkt_info.len = sizeof(rdata.pkt_info.packet); |
458 | 146 | } |
459 | | |
460 | | /* Acquire loop datagram transport */ |
461 | 4.10k | if (pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM, |
462 | 4.10k | &remote_addr, |
463 | 4.10k | sizeof(remote_addr.ipv4), |
464 | 4.10k | NULL, &fake_transport) == PJ_SUCCESS) { |
465 | 4.10k | rdata.tp_info.transport = fake_transport; |
466 | 4.10k | } |
467 | | |
468 | 4.10k | do_test_transaction_layer(msg, &rdata); |
469 | | |
470 | 4.10k | if (msg->type == PJSIP_RESPONSE_MSG) { |
471 | 2.85k | do_test_transaction_uac(msg, &rdata); |
472 | 2.85k | } |
473 | | |
474 | 4.10k | do_test_auth_client(pool, msg); |
475 | 4.10k | do_test_dialog(msg); |
476 | | |
477 | 4.10k | if (msg->type == PJSIP_REQUEST_MSG && rdata.msg_info.via) { |
478 | 1.10k | pj_strdup2(pool, &rdata.msg_info.via->recvd_param, |
479 | 1.10k | rdata.pkt_info.src_name); |
480 | 1.10k | if (rdata.msg_info.via->rport_param == 0) { |
481 | 30 | rdata.msg_info.via->rport_param = rdata.pkt_info.src_port; |
482 | 30 | } |
483 | 1.10k | } |
484 | | |
485 | | /* Route through the full endpoint module pipeline */ |
486 | 4.10k | if (rdata.tp_info.transport && |
487 | 4.10k | rdata.msg_info.from && rdata.msg_info.to && |
488 | 1.19k | rdata.msg_info.via && rdata.msg_info.cseq && |
489 | 1.07k | rdata.msg_info.cid && rdata.msg_info.cid->id.slen != 0) { |
490 | 1.07k | pjsip_transaction *tsx; |
491 | 1.07k | pj_time_val timeout = {0, 0}; |
492 | 1.07k | unsigned i; |
493 | | |
494 | 1.07k | pjsip_endpt_process_rx_data(endpt, &rdata, NULL, NULL); |
495 | | |
496 | 1.07k | tsx = pjsip_rdata_get_tsx(&rdata); |
497 | 1.07k | if (tsx) { |
498 | 0 | pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); |
499 | 0 | } |
500 | | |
501 | | /* Pump events repeatedly */ |
502 | 9.70k | for (i = 0; i < 8; ++i) { |
503 | 8.62k | pjsip_endpt_handle_events(endpt, &timeout); |
504 | 8.62k | } |
505 | 1.07k | } |
506 | | |
507 | | /* Release transport */ |
508 | 4.10k | if (fake_transport) { |
509 | 4.10k | pjsip_transport_dec_ref(fake_transport); |
510 | 4.10k | } |
511 | 4.10k | } |
512 | | |
513 | 7.25k | do_test_tel_uri(pool, DataFx, Size); |
514 | | |
515 | 7.25k | pjsip_endpt_release_pool(endpt, pool); |
516 | 7.25k | free(DataFx); |
517 | | |
518 | 7.25k | return 0; |
519 | 7.25k | } |
520 | | |