Joshua, Harry, Thanks for the clarifications. Indeed, res/res_pjsip/config_global.c manages somehow max_fwd option and it looks like it adds it to all requests, but not to the responses (simply adding ast_sip_add_global_response_header("Max-Forwards", max_forwards, 1); into global_apply() doesn't work). And it looks like the same happens in the pjsip_endpt_create: max_fwd is added to the endpt->req_hdr, but not to the response headers. Actually, it's just my guess and I may be wrong thinking about pjsip's request and response concepts as being actual requests and responses, I need to have much better understanding of pjsip code and its integration with asterisk to continue the investigations, so for now I'll stop here and submit an issue to the asterisk issues tracker. Regards, Anatoli From: pjsip [mailto:pjsip-bounces@xxxxxxxxxxxxxxx] On Behalf Of Harald Radke Sent: Wednesday, February 18, 2015 12:19 To: pjsip at lists.pjsip.org Subject: Re: Possible bug - missing mandatory field Max-Forwards if you look into -> pjsip_endpt_create_request_from_hdr() you will see that it calls -> init_request_throw() which in turn gets additional headers from the sip endpoint via -> pjsip_endpt_get_request_headers() [ basically endpt->req_hdr] in -> pjsip_endpt_create() now, the Max-Forwards header had been added to the request headers at creation time: [...] mf_hdr = pjsip_max_fwd_hdr_create(endpt->pool, PJSIP_MAX_FORWARDS_VALUE); pj_list_insert_before( &endpt->req_hdr, mf_hdr); so the Max-Forwards header should be put in by default Regards, Harry Gesendet: Mittwoch, 18. Februar 2015 um 15:54 Uhr Von: Anatoli <me at anatoli.ws> An: "'pjsip list'" <pjsip at lists.pjsip.org> Betreff: Re: [pjsip] Possible bug - missing mandatory field Max-Forwards Hi Harold, Are you sure your UA is not adding this header somehow outside the pjsip code? If I understand it correctly (and I may perfectly not as I just started analyzing SIP internals and pjsip code when I found this problem 2 days ago) pjsip handles almost everything SIP-related in asterisk by itself without much intervention from asterisk. I've also continued pjsip code research a bit more and (I guess) I can confirm that the function where all outgoing requests from pjsip/asterisk originate is pjsip_endpt_create_request_from_hdr. I created a better patch (than the one I've sent with the first mail) that could be an acceptable workaround for everyone who encounters the same problem until a definitive fix is implemented. Here it is: --- pjproject-2.3/pjsip/src/pjsip/sip_util.c.orig 2014-08-18 05:54:43.000000000 -0300 +++ pjproject-2.3/pjsip/src/pjsip/sip_util.c 2015-02-17 10:52:23.839673699 -0300 @@ -465,6 +465,8 @@ PJ_DEF(pj_status_t) pjsip_endpt_create_r } PJ_END; + pjsip_msg_add_hdr(tdata->msg, pjsip_max_fwd_hdr_create(tdata->pool, 70)); + *p_tdata = tdata; return PJ_SUCCESS; To apply it (for those who don't know how), cd to pjproject-2.3 source files folder, and there: patch -p1 < <path_to_the_patch>/max_fwd.patch This patch doesn't implement a proper decrement of max_fwd field as, according to SIP RFC, when relaying a request, max_fwd should be decremented by 1 and if it reaches 0, the request should be dropped to avoid infinite relaying loops (the same way TTL works in IP packets). Also it's initialized with a hardcoded (70) value but should be taking it from [general] max_forwards option. But, nevertheless, with this patch I haven't found any problems using 2 (Linphone) softphones, so my guess is that this functionality is part of pjsip rather than asterisk, but again I may be completely wrong. I guess we could ask for a comment about this on asterisk-dev mailing list. Regards, Anatoli From: pjsip [mailto:pjsip-bounces@xxxxxxxxxxxxxxx] On Behalf Of Harald Radke Sent: Wednesday, February 18, 2015 06:05 To: pjsip at lists.pjsip.org Subject: Re: Possible bug - missing mandatory field Max-Forwards Hi Anatoli, Hm, right now this looks to me more like an asterisk than an pjsip problem. Over here, my user agent creates headers with the Max-Forwards field, so I take it the bug is more in the asterisk module that is using PJSIP than the lib itself. Regards, Harry Gesendet: Mittwoch, 18. Februar 2015 um 02:35 Uhr Von: Anatoli <me at anatoli.ws> An: pjsip at lists.pjsip.org Betreff: [pjsip] Possible bug - missing mandatory field Max-Forwards Hi All, I was trying to make work the latest asterisk (13.2.0) with the latest pjproject (2.3) both compiled from sources. They work pretty well, but when calling to/from softphones (in particular the latest Linphone v.3.7.0) the INVITE messages from asterisk are rejected due to the specification violation. Here are more people having the same problem: http://comments.gmane.org/gmane.comp.telephony.pbx.asterisk.user/281228 and http://lists.digium.com/pipermail/asterisk-dev/2003-July/001114.html. Linphone has a debug option: linphone.exe --logfile "c:\Temp\logs.txt" and in the generated logfile one can see something like: [error] Missing mandatory header [Max-Forwards] for message [INVITE] And this is what pjsip at asterisk sends to it: INVITE sip:6002 at 192.168.56.102 SIP/2.0 Via: SIP/2.0/UDP 192.168.56.3:5060;rport;branch=z9hG4bKPjbf53c93c-a424-4b9e-9e6a-b50d0e606965 From: <sip:6001@192.168.56.3>;tag=deeff9b9-50ab-410e-b683-94fdeb9f87b3 To: <sip:6002 at 192.168.56.102> Contact: <sip:9426fd27-7ccd-4e1e-ab7a-e6c27fc59a5c at 192.168.56.3:5060> Call-ID: 5b517cda-634b-4036-bb81-95a43379c09d CSeq: 6848 INVITE Allow: OPTIONS, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, REGISTER, MESSAGE, REFER Supported: 100rel, timer, replaces, norefersub Session-Expires: 1800 Min-SE: 90 Content-Type: application/sdp Content-Length: 254 So indeed, there is no "Max-Forwards" header send with the INVITE requests, but, according to the SIP RFC 3261: "A valid SIP request formulated by a UAC MUST, at a minimum, contain the following header fields: To, From, CSeq, Call-ID, Max-Forwards, and Via; all of these header fields are mandatory in all SIP requests." After researching a bit the source code of pjsip, I found that actually almost all messages originating from it don't have Max-Forwards fields. As a proof-of-concept, here is a patch that adds this header to the INVITE and ACK packets and with it the softphones work almost well. Almost, because there are more types of packets involved in a communication (like hanging up that doesn't work) and I've just patched 2 of them. Also, this patch doesn't decrease the value of the header as it should to when the message is relayed (Max-Forwards in SIP is like TTL field in IP), it's just a proof-of-concept. IMO, the better way would be to modify accordingly the functions like pjsip_endpt_create_request_from_hdr where the messages are created initially and where other mandatory fields are set, but it requires a better understanding of the project's code and SIP protocol in general than mine is (it's almost 0). As a side note, it would be great to have the initial Max-Forwards value configurable with the (already existing, but ignored) max_forwards option in [general] section. This problem is actually a show-stopper when there are softphones among the endpoints; so as for me for example, I have to stay with the old asterisk sip driver until this issue is solved. Regards, Anatoli A *demo* patch: --- pjproject-2.3/pjsip/src/pjsip-ua/sip_inv.c.orig 2014-08-21 04:20:34.000000000 -0300 +++ pjproject-2.3/pjsip/src/pjsip-ua/sip_inv.c 2015-02-16 14:55:29.683566529 -0300 @@ -1679,6 +1679,15 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pj } } + + + // PATCH + if (!pjsip_msg_find_hdr(tdata->msg, PJSIP_H_MAX_FORWARDS, NULL)) + pjsip_msg_add_hdr(tdata->msg, pjsip_max_fwd_hdr_create(tdata->pool, 70)); + // PATCH + + + /* See if we have SDP to send. */ if (inv->neg) { pjmedia_sdp_neg_state neg_state; @@ -2986,6 +2995,12 @@ PJ_DEF(pj_status_t) pjsip_inv_create_ack return status; } + + // PATCH + pjsip_msg_add_hdr(inv->last_ack->msg, pjsip_max_fwd_hdr_create(inv->last_ack->pool, 70)); + // PATCH + + /* See if we have pending SDP answer to send */ sdp = inv_has_pending_answer(inv, inv->invite_tsx); if (sdp) { STEPS TO REPRODUCE: extensions.conf: [general] language=en static=yes writeprotect=no autofallthrough=yes [internal] exten => 6001,1,Answer() same => 2,Dial(PJSIP/6001,20) same => 3,Hangup() exten => 6002,1,Answer() same => 2,Dial(PJSIP/6002,20) same => 3,Hangup() pjsip.conf: [transport-udp] type=transport protocol=udp bind=192.168.56.3 [6001] type=endpoint transport=transport-udp context=internal allow=ulaw allow=gsm auth=6001 aors=6001 device_state_busy_at=1 allow_subscribe=yes sub_min_expiry=30 [6001] type=auth auth_type=userpass password=6001 username=6001 [6001] type=aor max_contacts=1 contact=sip:6001 at 192.168.56.101 [6002] type=endpoint transport=transport-udp context=internal allow=ulaw allow=gsm auth=6002 aors=6002 device_state_busy_at=1 allow_subscribe=yes sub_min_expiry=30 [6002] type=auth auth_type=userpass password=6002 username=6002 [6002] type=aor max_contacts=1 contact=sip:6002 at 192.168.56.102 Start asterisk: # /usr/sbin/asterisk Then configure the extensions in 2 Linphones (in wizard: user/pass = 600x/600x and domain: 192.168.56.3) and try to make a call from one Linphone to another. _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip at lists.pjsip.org http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip at lists.pjsip.org http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20150218/ca51bbb4/attachment.html>