freeswitch / sofia-sip

Sofia-SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
GNU Lesser General Public License v2.1
274 stars 182 forks source link

When DNS response is truncated sofia-sip should retry via TCP #281

Open ivanuschak opened 3 days ago

ivanuschak commented 3 days ago

When a DNS record has a big size then the DNS UDP reply can come truncated and DNS request should be re-sent over TCP, like for example nslookup does for this DNS name ca.nga911.com:

user@debian:~$ nslookup -type=NAPTR ca.nga911.com
;; Truncated, retrying in TCP mode.
Server:         192.168.0.1
Address:        192.168.0.1#53

Non-authoritative answer:
ca.nga911.com   naptr = 50 500 "S" "SIPS+D2W" "" _sips._ws.ca.nga911.com.
...

nslookup prints ;; Truncated, retrying in TCP mode. and then it retries the DNS request over TCP.

When FreeSwitch (sofia-sip library) receives a truncated UDP DNS reply then it does not retry over TCP and consider this DNS request as failed, hence it causes the call gets failed:

sres.c:3468 sres_resolver_receive() sres_resolver_receive(0xfffea80051f0, 25) called
sres.c:3782 sres_create_record() ANSWER RR received ca.nga911.com. NAPTR IN 3600 rdlen=102
sres.c:3782 sres_create_record() ANSWER RR received ca.nga911.com. NAPTR IN 3600 rdlen=82
sres.c:3782 sres_create_record() ANSWER RR received ca.nga911.com. NAPTR IN 3600 rdlen=104
sres.c:3782 sres_create_record() ANSWER RR received ca.nga911.com. NAPTR IN 3600 rdlen=53
sres.c:3782 sres_create_record() ANSWER RR received ca.nga911.com. NAPTR IN 3600 rdlen=40
sres.c:3573 sres_log_response() sres_resolver_receive(0xfffea80051f0, 0xfffea8073950) id=34567 (from [127.0.0.1]:53)
nta.c:10529 outgoing_answer_naptr() nta: ca.nga911.com. IN NAPTR 20 200 "S" "SIP+D2T" "" _sip._tcp.ca.nga911.com. (tport not used)
nua_stack.c:271 nua_stack_event() nua(0xfffe68007750): event r_invite 503 DNS Error
nua_session.c:4140 signal_call_state_change() nua(0xfffe68007750): call state changed: calling -> init
nua_stack.c:271 nua_stack_event() nua(0xfffe68007750): event i_state 503 DNS Error
nua_stack.c:271 nua_stack_event() nua(0xfffe68007750): event i_terminated 503 DNS Error
nua_dialog.c:397 nua_dialog_usage_remove_at() nua(0xfffe68007750): removing session usage
soa.c:356 soa_destroy() soa_destroy(static::0xfffea806cab0) called
nua_stack.c:359 nua_application_event() nua: nua_application_event: entering
nta.c:4485 nta_leg_destroy() nta_leg_destroy(0xfffea801e0c0)
nua_stack.c:359 nua_application_event() nua: nua_application_event: entering
nua_stack.c:359 nua_application_event() nua: nua_application_event: entering
nua.c:370 nua_handle_magic() nua: nua_handle_magic: entering
nua.c:370 nua_handle_magic() nua: nua_handle_magic: entering
nua.c:370 nua_handle_magic() nua: nua_handle_magic: entering
2021-10-13 19:47:34.407638 [DEBUG] sofia.c:7427 Channel sofia/sipinterface_1/911@psapb.cal911.net entering state [terminated][503]
2021-10-13 19:47:34.407638 [NOTICE] sofia.c:8660 Hangup sofia/sipinterface_1/911@psapb.cal911.net [CS_CONSUME_MEDIA] [NORMAL_TEMPORARY_FAILURE]
ivanuschak commented 3 days ago

I've implemented the fix for this issue in this branch, this fix works - the issue is not reproduced when this fix applied. However I don't like some parts of this implementation and I would appreciate if sofia-sip developers reviewed/adjusted this update. Thanks in advance.