On 31.05.19 at 11:34 Joshua C. Colp wrote:
On Fri, May 31, 2019, at 3:38 AM, Michael Maier wrote:
On 30.05.19 at 10:24 Michael Maier wrote:
[...]
Another yet missing point is the qualify OPTIONS package. I'm not sure where to 
add the mediasec headers exactly (which function?). At the
moment, the Response after OPTION request is (if already registered):

SIP/2.0 494 Security Agreement Required
CSeq: 21671 OPTIONS
Security-Server: msrp-tls;mediasec
Security-Server: sdes-srtp;mediasec
Security-Server: dtls-srtp;mediasec

If you are not already registered, you get a 403 Forbidden.

I managed to add the necessary headers statically in
sip_options_qualify_contact() and they are working as expected. But this
isn't a good solution. I would like to handle those additions
dynamically like that:

- sending the usual OPTIONS request
- acting on the 494 Security Agreement Required response
- resend the correct OPTIONS request

Where is the OPTIONS response handled (from a client view) - means,
where can I check the response code and act on it?

The qualify_contact_cb function is called in res/res_pjsip/pjsip_options.c on 
received responses. It doesn't currently examine or care about the response so 
you would have to figure out how (I don't recall off the top of my head) and do 
what is needed.


Thanks Joshua!

I added the attached changes. Afterwards, I could see one SIGSEGV so far which I can't understand. I would be very happy, if you could take a look at it - maybe you have an idea? Most probably I'm doing something I shouldn't do (locking problem)?

What I'm doing:
In qualify_contact_cb, I'm checking for the status code of the received response. If the status code is 494, I'm again calling sip_options_qualify_contact() with the flag 494. In sip_options_qualify_contact, I'm checking for the flag == 494 to add the additional mediasec headers.


Strangely, suddenly I could see one SIGSEGV (seems not (easily) to be 
reproducible) in
qualify_contact_cb(void *token, pjsip_event e) at

if (e->body.tsx_state.src.rdata->msg_info.msg->line.status.code == 494) {

according core dump.

The crash directly happened after a successful sequence of mediasec relevant 
endpoint (endpoint2):

- request OPTIONS
- response 494
- request OPTIONS w/ MEDIASEC
- response 200 OK
- Crash

Obviously, there has been a problem with the processing of the received 200 OK. 
But why?

Directly before (about 1s) the mentioned sequence, another OPTIONS request for a not mediasec relevant endpoint (endpoint1) was started, which didn't receive a response.

The complete sequence at this moment looks like this:

- request OPTIONS endpoint1

- request OPTIONS endpoint2
- response 494 endpoint2
- request OPTIONS w/ MEDIASEC endpoint2
- response 200 OK endpoint2

- Crash

It would already help, if you could say, which part of the e->body.tsx_state.src.rdata->msg_info.msg->line.status.code could have been null so I could check for it.



Thanks!
Michael
diff -urN asterisk-16.3.0.orig/res/res_pjsip/pjsip_options.c asterisk-16.3.0/res/res_pjsip/pjsip_options.c
--- asterisk-16.3.0.orig/res/res_pjsip/pjsip_options.c	2019-04-04 16:49:57.000000000 +0200
+++ asterisk-16.3.0/res/res_pjsip/pjsip_options.c	2019-05-31 16:30:22.589000000 +0200
@@ -212,6 +212,8 @@
  */
 static struct ast_taskprocessor *management_serializer;
 
+static int sip_options_qualify_contact(void *obj, void *arg, int flags);
+
 static pj_status_t send_options_response(pjsip_rx_data *rdata, int code)
 {
 	pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
@@ -788,6 +790,15 @@
 	struct sip_options_contact_callback_data *contact_callback_data = token;
 	enum ast_sip_contact_status_type status;
 
+	/* check for 494 */
+	if (e->body.tsx_state.src.rdata->msg_info.msg->line.status.code == 494) {
+		/* need to resend the options request with mediasec headers */
+		ast_verb(3,"detected 494 - call sip_options_qualify_contact again with mediasec header\n");
+		sip_options_qualify_contact(contact_callback_data->contact, contact_callback_data->aor_options, 494);
+		return;
+	}
+
+
 	switch(e->body.tsx_state.type) {
 	default:
 		ast_log(LOG_ERROR, "Unexpected PJSIP event %u\n", e->body.tsx_state.type);
@@ -905,6 +916,14 @@
 		return 0;
 	}
 
+	if (flags && flags == 494) {
+		/* add mediasec header */
+		ast_verb(3,"OPTIONS: adding MEDIASEC headers\n");
+		ast_sip_add_header(tdata,"Security-Verify","msrp-tls;mediasec");
+		ast_sip_add_header(tdata,"Security-Verify","sdes-srtp;mediasec");
+		ast_sip_add_header(tdata,"Security-Verify","dtls-srtp;mediasec");
+	}
+
 	if (ast_sip_send_out_of_dialog_request(tdata, endpoint,
 		(int)(aor_options->qualify_timeout * 1000), contact_callback_data,
 		qualify_contact_cb)) {
!@!@!@! thread1.txt !@!@!@!

$1 = {si_signo = 11, si_errno = 0, si_code = 1, _sifields = {_pad = {8, 0 
<repeats 27 times>}, _kill = {si_pid = 8, si_uid = 0}, _timer = {si_tid = 8, 
si_overrun = 0, si_sigval = {sival_int = 0, sival_ptr = 0x0}}, _rt = {si_pid = 
8, si_uid = 0, si_sigval = {sival_int = 0, sival_ptr = 0x0}}, _sigchld = 
{si_pid = 8, si_uid = 0, si_status = 0, si_utime = 0, si_stime = 0}, _sigfault 
= {si_addr = 0x8}, _sigpoll = {si_band = 8, si_fd = 0}}}
Signal        Stop      Print   Pass to program Description
SIGSEGV       Yes       Yes     Yes             Segmentation fault

Thread 1 (Thread 0x7f9363f20700 (LWP 23951)):
#0  0x00007f936bf7b8ae in qualify_contact_cb (token=0x3cb55d8, 
e=0x7f9363f1fbe0) at res_pjsip/pjsip_options.c:794
        contact_callback_data = 0x3cb55d8
        status = 32659
        __PRETTY_FUNCTION__ = "qualify_contact_cb"
#1  0x00007f936bf76678 in send_request_cb (token=0x3cb5628, e=0x7f9363f1fbe0) 
at res_pjsip.c:4408
        req_data = 0x3cb5628
        challenge = 0x388b458
        supplement = 0x388b458
        __PRETTY_FUNCTION__ = "send_request_cb"
#2  0x00007f936bf75abb in send_request_timer_callback (theap=0x331f5c0, 
entry=0x3d01278) at res_pjsip.c:4156
        event = {prev = 0x7f9363f1fc10, next = 0x7f93d7b31741 
<pj_mutex_unlock+84>, type = PJSIP_EVENT_TX_MSG, body = {timer = {entry = 
0x3cffe38}, tsx_state = {src = {rdata = 0x3cffe38, tdata = 0x3cffe38, timer = 
0x3cffe38, status = 63962680, data = 0x3cffe38}, tsx = 0x38d9b00, prev_state = 
53605824, type = PJSIP_EVENT_TIMER}, tx_msg = {tdata = 0x3cffe38}, tx_error = 
{tdata = 0x3cffe38, tsx = 0x38d9b00}, rx_msg = {rdata = 0x3cffe38}, user = 
{user1 = 0x3cffe38, user2 = 0x38d9b00, user3 = 0x10331f5c0, user4 = 
0x7f9363f1fc30}}}
        req_wrapper = 0x388b470
        cb_called = 0
        __PRETTY_FUNCTION__ = "send_request_timer_callback"
#3  0x00007f93d7b49630 in pj_timer_heap_poll (ht=0x331f5c0, 
next_delay=0x7f9363f1fcd0) at ../src/pj/timer.c:649
        node = 0x3d01278
        node_timer_id = 2
        grp_lock = 0x0
        now = {sec = 190946, msec = 48}
        count = 1
#4  0x00007f93d7a97a3d in pjsip_endpt_handle_events2 (endpt=0x331f2d8, 
max_timeout=0x7f9363f1fd40, p_count=0x0) at ../src/pjsip/sip_endpoint.c:715
        timeout = {sec = 0, msec = 0}
        count = 0
        net_event_count = 0
        c = 0
#5  0x00007f93d7a97b82 in pjsip_endpt_handle_events (endpt=0x331f2d8, 
max_timeout=0x7f9363f1fd40) at ../src/pjsip/sip_endpoint.c:776
No locals.
#6  0x00007f936bf77436 in monitor_thread_exec (endpt=0x0) at res_pjsip.c:4758
        delay = {sec = 0, msec = 10}
#7  0x00007f93d7b30be7 in thread_main (param=0x3324a08) at 
../src/pj/os_core_unix.c:541
        rec = 0x3324a08
        result = 0x7f93d4fb0642 <__libc_thread_freeres+34>
        rc = 0
#8  0x00007f93d5e9ddd5 in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
#9  0x00007f93d4f3dead in clone () from /lib64/libc.so.6
No symbol table info available.
-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Reply via email to