[Siproxd-users] Patch: Handling NAT between clients and siproxd
Status: Beta
Brought to you by:
tries
From: Srinivas M.A. <sri...@gm...> - 2013-06-03 10:51:55
|
Hi, My setup is as follows: SIP-Phone ----- NAT Firewall ----- Siproxd ----- VOIP Provider Both Siproxd and the VOIP Provider are outside the firewall, but the fIrewall rules only allow the SIP-Phone to talk to Siproxd but not to the VOIP Provider. Siproxd worked well in this setup when the SIP-Phone was a Grandstream HT-286, since this used STUN to determine the public side host and port for its UDP SIP server and used that port for all traffic and also used the public IP and port number within all SIP messages. When the SIP-Phone was Linphone, things didn't work so well. Linphone does not use STUN for its SIP portion, but only for mapping its RTP ports. (See http://lists.gnu.org/archive/html/linphone-developers/2009-07/msg00017.html) It uses the VIa rport parameter for handling NAT issues in SIP. I had to make some changes to siproxd to make it work in this case. I have included a patch of the changes I used. They are the following: 1. Handling rport parameter from the client even in the case of UDP, according to RFC 3581 2. Modifying sip_find_direction() to treat an unknown incoming REGISTER as REQTYP_INCOMING. This was needed since the contact information in the REGISTER is a private IP behind the NAT, so it does not match the registered client information that is saved. Linphone then sends a second REGISTER using the received and rport values in the response, but without this change, the first REGISTER gets dropped and things don't go any further. Do you think this use case deserves to be handled by siproxd? And if so, what do you think of the changes. I myself think that the rport handling is okay, though maybe it needs work to not break TCP. The sip_find_direction change is a hack but I am not sure how to do it right. Regards, Srinivas ----------- Patch -------------------------------- diff -aur siproxd-0.8.1/src/proxy.c siproxd-0.8.1-patch/src/proxy.c --- siproxd-0.8.1/src/proxy.c 2011-05-28 21:17:15.000000000 +0530 +++ siproxd-0.8.1-patch/src/proxy.c 2013-06-01 00:36:42.000000000 +0530 @@ -96,14 +96,13 @@ request=ticket->sipmsg; /* - * RFC&&&& - * add a received= parameter to the topmost Via header. Used for TCP - * connections - send answer within the existing TCP connection back + * RFC3261 Section 18.2.1 + RFC3581 Section 4: + * Add a received= parameter to the topmost Via header. If client + * sent an rport parameter, set that to the right value too. + * Used to send answer within the existing TCP/UDP connection back * to client. */ - if (ticket->protocol == PROTO_TCP) { - sip_add_received_param(ticket); - } + sip_add_received_param(ticket); /* * RFC 3261, Section 16.4 @@ -667,16 +666,15 @@ * Determine Next-Hop Address */ /*&&&& priority probably should be: - * 0) rport=;received= header (TCP only for now) + * 0) rport=;received= header * 1) Route header * 2) fixed outbound proxy * 3) Via header */ /* - * IF TCP, check for rport=x;received=y parameters in VIA + * check for rport=x;received=y parameters in VIA */ - if ((ticket->protocol == PROTO_TCP) && - (sip_get_received_param(ticket, &sendto_addr, &port) == STS_SUCCESS)) { + if ((sip_get_received_param(ticket, &sendto_addr, &port) == STS_SUCCESS)) { DEBUGC(DBCLASS_PROXY, "proxy_response: have received/rport to %s:%i", utils_inet_ntoa(sendto_addr), port); /* diff -aur siproxd-0.8.1/src/sip_utils.c siproxd-0.8.1-patch/src/sip_utils.c --- siproxd-0.8.1/src/sip_utils.c 2011-05-28 21:17:15.000000000 +0530 +++ siproxd-0.8.1-patch/src/sip_utils.c 2013-06-01 02:26:26.000000000 +0530 @@ -1173,6 +1173,10 @@ } } /* if type == DIRTYP_UNKNOWN */ + if (type == DIRTYP_UNKNOWN) { + if (MSG_IS_REQUEST(ticket->sipmsg) && MSG_IS_REGISTER(request)) + type=REQTYP_INCOMING; + } if (type == DIRTYP_UNKNOWN) { DEBUGC(DBCLASS_SIP, "sip_find_direction: unable to determine " @@ -1399,13 +1403,18 @@ int sip_add_received_param(sip_ticket_t *ticket){ osip_via_t *via; char tmp[6]; + osip_generic_param_t *rport=NULL; DEBUGC(DBCLASS_PROXY,"adding received= param to topmost via"); via = osip_list_get (&(ticket->sipmsg->vias), 0); + + osip_via_param_get_byname (via, "rport", &rport); /* set rport=xxx;received=1.2.3.4 */ - snprintf(tmp, sizeof(tmp), "%i", ntohs(ticket->from.sin_port)); - osip_via_param_add(via,osip_strdup("rport"),osip_strdup(tmp)); + if (rport!=NULL) { + snprintf(tmp, sizeof(tmp), "%i", ntohs(ticket->from.sin_port)); + osip_generic_param_set_value(rport,osip_strdup(tmp)); + } osip_via_param_add(via,osip_strdup("received"), osip_strdup(utils_inet_ntoa(ticket->from.sin_addr))); |