- allocate only even RTP port numbers
- started with own name lookup routines that honor SRV and NAPTR records
This commit is contained in:
parent
9e817ab1f9
commit
ab08d2febf
@ -1,5 +1,6 @@
|
||||
0.5.12
|
||||
======
|
||||
14-Jul-2005: - allocate only even port numbers for RTP traffic
|
||||
|
||||
0.5.11
|
||||
======
|
||||
|
||||
@ -87,6 +87,9 @@
|
||||
/* Define to 1 if you have the `osipparser2' library (-losipparser2). */
|
||||
#undef HAVE_LIBOSIPPARSER2
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
#undef HAVE_LIBRESOLV
|
||||
|
||||
/* Define to 1 if you have the `listen' function. */
|
||||
#undef HAVE_LISTEN
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ dnl 08-Jan-2005 tries FreeBSD: check for libgnugetopt before using it
|
||||
dnl Cygwin build support
|
||||
dnl 13-Feb-2005 tries check for # of args on libosip2 functions
|
||||
dnl 10-Apr-2005 tries check for docbook
|
||||
dnl 18-Apr-2005 tries added libresolv
|
||||
dnl
|
||||
dnl
|
||||
|
||||
@ -369,6 +370,12 @@ AC_CHECK_TYPE(socklen_t,
|
||||
)
|
||||
|
||||
|
||||
dnl
|
||||
dnl Checks for libraries
|
||||
dnl
|
||||
AC_CHECK_LIB(resolv,res_query,)
|
||||
|
||||
|
||||
dnl
|
||||
dnl Checks for library functions.
|
||||
dnl
|
||||
|
||||
89
doc/FAQ
89
doc/FAQ
@ -25,14 +25,14 @@ A: Scenario
|
||||
|
||||
private IP address range : Internet
|
||||
10.0.0.x : (public IP address range)
|
||||
:
|
||||
: foo.bar.org xxx.org
|
||||
+-------------+ +--------------+ +-------------+
|
||||
! !.10 .1 ! masquerading ! publicIP ! !
|
||||
:
|
||||
: foo.bar.org xxx.org
|
||||
+-------------+ +--------------+ +-------------+
|
||||
! !.10 .1 ! masquerading ! publicIP ! !
|
||||
! IntHost !-------------! Firewall !------------>>! externalHost!
|
||||
! ! eth0! !ppp0 ! !
|
||||
+-------------+ +--------------+ +-------------+
|
||||
user: johndoe user: test
|
||||
! ! eth0! !ppp0 ! !
|
||||
+-------------+ +--------------+ +-------------+
|
||||
user: johndoe user: test
|
||||
|
||||
- IntHost is running an SIP softphone (like linphone, kphone)
|
||||
|
||||
@ -244,20 +244,20 @@ A:
|
||||
Full Name: My Name
|
||||
User part of SIP URL: FWD_NUMBER
|
||||
Host Part of SIP URL: fwd.pulver.com
|
||||
Outbound Proxy: 192.168.1.1 <<-- local IP of siproxd
|
||||
Outbound Proxy: 192.168.1.1 <<-- local IP of siproxd
|
||||
Authentication Username: FWD_NUMBER
|
||||
q-value: <<-- empty
|
||||
q-value: <<-- empty
|
||||
|
||||
Preferences->SIP->Socket
|
||||
------------------------
|
||||
Socket Protocol: UDP
|
||||
Use STUN Server: No
|
||||
Symmetric Signalling: No (may also be 'Yes')
|
||||
Symmetric Media: No (may also be 'Yes')
|
||||
STUN Server: << n/a
|
||||
Request Period for STUN Server << n/a
|
||||
Media Min Port: 7070 << depend of siproxd config
|
||||
Media Max Port: 7080 (RTP ports)
|
||||
Symmetric Signalling: No (may also be 'Yes')
|
||||
Symmetric Media: No (may also be 'Yes')
|
||||
STUN Server: << n/a
|
||||
Request Period for STUN Server << n/a
|
||||
Media Min Port: 7070 << depend of siproxd config
|
||||
Media Max Port: 7080 (RTP ports)
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
Q: If I update both inbound and outbound to
|
||||
@ -276,64 +276,5 @@ A: Very likely this will not work properly. Siproxd does masquerade User
|
||||
If you just want a proxy located in the public IP range you should not
|
||||
use siproxd, but get a real SIP proxy server instead.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
...
|
||||
> Hier ist 40Mb logs mit overload problem. Wir haben auch probleme um neue
|
||||
> verbindung einzustellen. Es ist wie ob den RTP timeout fur alle UA
|
||||
> hinter den proxy bloquiert wenn eine bindung geschlossen wird. Nach 5 mn
|
||||
> (oder 3 in unsere buro) geht es wieder ok (oder eine restart von
|
||||
> siproxd). Manschmal, wenn eine von den beiden endpunkt die kommunikation
|
||||
> schlisst, ist die andere immer noch up und denkt das die verbingun
|
||||
> existiert. Wir haben den ganzen tag getestet mit lezte version von 17May:
|
||||
>
|
||||
> 2 intranet hinten siproxd, der eine ohne seine UA zu registrieren
|
||||
> (192.168.1.0/24). Der andere hat 1 BudgeTone, 1 HandyTone, 2 xlite ten
|
||||
> und 1 linphone als klient (192.168.10.0/24).
|
||||
|
||||
ACHTUNG!
|
||||
Siproxd unterstützt zur Zeit lediglich 1 internes Netz und ein externes
|
||||
Netz. ALLE lokalen UAs *müssen* sich:
|
||||
|
||||
- entweder bei SIPROXD registrieren
|
||||
|
||||
oder
|
||||
|
||||
- sich bei einem externen REGSITRAR registrieren (siproxd muss als
|
||||
OUTBOUND PROXY konfiguriert sein).
|
||||
|
||||
|
||||
Werden diese Spielregeln nicht eingehalten kommt es zu verschiedenen
|
||||
komischen Effekten, auch solche die Du beschrieben hast.
|
||||
|
||||
|
||||
|
||||
UA1--+
|
||||
|
|
||||
UA2--+
|
||||
|
|
||||
UA3--+ +-----------+
|
||||
| +-----------+ | externer |
|
||||
+---------| siproxd & |------>>Internet <<---| Registrar |
|
||||
| NAT | +-----------+
|
||||
+-----------+
|
||||
|
||||
Spielregeln:
|
||||
- ALLE UAs (UA1, UA2, UA3) benutzen siproxd also OUTBOUND proxy
|
||||
- ALLE UAs (UA1, UA2, UA3) registrieren sich entweder direkt bei
|
||||
siproxd ODER bei "externer Registrar"
|
||||
|
||||
Wenn Registrierung bei siproxd:
|
||||
- SIP URL (address of record) hat die form SIP:<user>@<host>
|
||||
- <user> ist frei wählbar
|
||||
- <host> MUSS einen DNS Eintrag haben, der auf die public IP
|
||||
von siproxd auflöst
|
||||
|
||||
|
||||
Wenn Registrierung bei "externer Registrar":
|
||||
- <user> und <domain> wird von "externer Registrar" definiert
|
||||
|
||||
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ rtp_proxy_enable = 1
|
||||
# This should be a range that is not blocked by the firewall
|
||||
#
|
||||
rtp_port_low = 7070
|
||||
rtp_port_high = 7079
|
||||
rtp_port_high = 7089
|
||||
|
||||
######################################################################
|
||||
# Timeout for RTP streams
|
||||
|
||||
@ -29,7 +29,7 @@ sbin_PROGRAMS = siproxd
|
||||
siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c \
|
||||
sip_utils.c sip_layer.c log.c readconf.c rtpproxy.c \
|
||||
rtpproxy_relay.c accessctl.c route_processing.c \
|
||||
security.c auth.c fwapi.c
|
||||
security.c auth.c fwapi.c resolve.c
|
||||
|
||||
#
|
||||
# an example for a custom firewall control module
|
||||
|
||||
42
src/proxy.c
42
src/proxy.c
@ -451,6 +451,8 @@ int proxy_request (sip_ticket_t *ticket) {
|
||||
/*
|
||||
* fixed or domain outbound proxy defined ?
|
||||
*/
|
||||
// let's try with Route header first
|
||||
#if 0
|
||||
if ((type == REQTYP_OUTGOING) &&
|
||||
(sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",
|
||||
@ -468,6 +470,25 @@ int proxy_request (sip_ticket_t *ticket) {
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have Route header to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
#else
|
||||
if ((type == REQTYP_OUTGOING) &&
|
||||
(request->routes && !osip_list_eol(request->routes, 0))) {
|
||||
sts=route_determine_nexthop(ticket, &sendto_addr, &port);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: route_determine_nexthop failed");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have Route header to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
} else if ((type == REQTYP_OUTGOING) &&
|
||||
(sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
/*
|
||||
* Route present?
|
||||
* If so, fetch address from topmost Route: header and remove it.
|
||||
*/
|
||||
#endif
|
||||
/*
|
||||
* destination from SIP URI
|
||||
*/
|
||||
@ -872,6 +893,8 @@ int proxy_response (sip_ticket_t *ticket) {
|
||||
/*
|
||||
* check if we need to send to an outbound proxy
|
||||
*/
|
||||
// let's try with Route header first
|
||||
#if 0
|
||||
if ((type == RESTYP_OUTGOING) &&
|
||||
(sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have outbound proxy %s:%i",
|
||||
@ -889,6 +912,25 @@ int proxy_response (sip_ticket_t *ticket) {
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have Route header to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
#else
|
||||
if ((type == RESTYP_OUTGOING) &&
|
||||
(response->routes && !osip_list_eol(response->routes, 0))) {
|
||||
sts=route_determine_nexthop(ticket, &sendto_addr, &port);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: route_determine_nexthop failed");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have Route header to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
} else if ((type == RESTYP_OUTGOING) &&
|
||||
(sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have outbound proxy %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
/*
|
||||
* Route present?
|
||||
* If so, fetch address from topmost Route: header and remove it.
|
||||
*/
|
||||
#endif
|
||||
} else {
|
||||
/* get target address and port from VIA header */
|
||||
via = (osip_via_t *) osip_list_get (response->vias, 0);
|
||||
|
||||
218
src/resolve.c
Normal file
218
src/resolve.c
Normal file
@ -0,0 +1,218 @@
|
||||
/* -*- Mode: C; c-basic-offset: 3 -*-
|
||||
Copyright (C) 2005 Thomas Ries <tries@gmx.net>
|
||||
|
||||
This file is part of Siproxd.
|
||||
|
||||
Siproxd is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Siproxd is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Siproxd; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
static char const ident[]="$Id$";
|
||||
|
||||
|
||||
/* local functions */
|
||||
static int _resolve(char *name, int proto, int type,
|
||||
char *dname, int dnamelen, int *port);
|
||||
|
||||
#define PROTO_UDP 1
|
||||
#define PROTO_TCP 2
|
||||
|
||||
/*
|
||||
* perform a SRV record lookup
|
||||
*/
|
||||
int resolve_SRV(char *name, int proto, char *dname, int dnamelen, int *port) {
|
||||
return _resolve(name, proto, T_SRV, dname, dnamelen, port);
|
||||
}
|
||||
|
||||
/*
|
||||
* perform a NAPTR lookup
|
||||
*/
|
||||
int resolve_NAPTR(char *name, char *dname, int dnamelen) {
|
||||
int port=0;
|
||||
return _resolve(name, 0, T_NAPTR, dname, dnamelen, &port);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* query the DNS for a specific record type
|
||||
*/
|
||||
static int _resolve(char *name, int proto, int type,
|
||||
char *dname, int dnamelen, int *port) {
|
||||
int sts;
|
||||
|
||||
int class=C_ANY;
|
||||
|
||||
// message buffer
|
||||
char msg[PACKETSZ];
|
||||
int msglen=PACKETSZ;
|
||||
|
||||
// response header
|
||||
HEADER *res_header;
|
||||
|
||||
// expanded name
|
||||
char exp_dn[MAXDNAME];
|
||||
int exp_dnlen=MAXDNAME;
|
||||
|
||||
int i, j, co;
|
||||
char *mptr, *xptr;
|
||||
unsigned short *usp,ty;
|
||||
unsigned int *uip;
|
||||
|
||||
u_short priority = 0;
|
||||
u_short weight = 0;
|
||||
|
||||
char tmpname[PACKETSZ];
|
||||
|
||||
dname[0]='\0';
|
||||
*port=0;
|
||||
|
||||
|
||||
// issue request
|
||||
sts=res_query(name, class, type, msg, msglen);
|
||||
if (sts<0) {
|
||||
ERROR("res_query failed sts=%i\n", sts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
res_header = (HEADER *)msg;
|
||||
DEBUGC(DBCLASS_DNS, "_resolve: name=[%s], type=%i, qdcount=%i, ancount=%i",
|
||||
name, type, ntohs(res_header->qdcount), ntohs(res_header->ancount));
|
||||
|
||||
mptr=msg+sizeof(HEADER);
|
||||
|
||||
// loop through query part
|
||||
co=ntohs(res_header->qdcount);
|
||||
for (i=0; i<co; i++) {
|
||||
j=dn_expand(msg,msg+PACKETSZ,mptr,exp_dn,exp_dnlen);
|
||||
DEBUGC(DBCLASS_DNS, "_resolve: Q - len=%i, name=[%s]", j, exp_dn);
|
||||
if( j < 0 ) {
|
||||
break;
|
||||
} else {
|
||||
mptr += j;
|
||||
usp = (unsigned short *)mptr;
|
||||
mptr += sizeof( short );
|
||||
usp = (unsigned short *)mptr;
|
||||
mptr += sizeof( short );
|
||||
}
|
||||
}
|
||||
|
||||
// loop through answer part
|
||||
co=ntohs(res_header->ancount);
|
||||
for (i=0; i<co; i++) {
|
||||
j=dn_expand(msg,msg+PACKETSZ,mptr,exp_dn,exp_dnlen);
|
||||
if( j < 0 ) {
|
||||
ERROR("_resolve: dn_expand error");
|
||||
break;
|
||||
} else {
|
||||
mptr += j;
|
||||
usp = (unsigned short *)mptr;
|
||||
ty = ntohs( *usp );
|
||||
mptr += sizeof( short );
|
||||
usp = (unsigned short *)mptr;
|
||||
mptr += sizeof(short);
|
||||
uip = (unsigned int *)mptr;
|
||||
mptr += sizeof(int);
|
||||
uip = (unsigned int *)mptr;
|
||||
j = ntohs( *uip );
|
||||
mptr += sizeof(short);
|
||||
xptr = mptr;
|
||||
mptr += j;
|
||||
if( ty == T_NAPTR ) {
|
||||
DEBUGC(DBCLASS_DNS, "_resolve: A - type NAPTR");
|
||||
usp = (unsigned short *)xptr;
|
||||
xptr += sizeof(short);
|
||||
usp = (unsigned short *)xptr;
|
||||
xptr += sizeof(short);
|
||||
j = (int)(*xptr);
|
||||
xptr += 1;
|
||||
while( j > 0 ) {
|
||||
xptr+=1;
|
||||
j--;
|
||||
}
|
||||
j = (int)(*xptr);
|
||||
xptr += 1;
|
||||
while( j > 0 ) {
|
||||
xptr += 1;
|
||||
j--;
|
||||
}
|
||||
j=(int)(*xptr);
|
||||
xptr+=1;
|
||||
while( j > 0 ) {
|
||||
xptr += 1;
|
||||
j--;
|
||||
}
|
||||
j = dn_expand( msg, msg + PACKETSZ, xptr, tmpname, MAXDNAME );
|
||||
if( j < 0 ) {
|
||||
break;
|
||||
} else {
|
||||
/*
|
||||
* there should be some REGEX magic, no?
|
||||
*/
|
||||
if( proto == PROTO_UDP ) {
|
||||
if( strstr(tmpname, "_udp" ) ) {
|
||||
strncpy(dname, tmpname, dnamelen);
|
||||
}
|
||||
} else {
|
||||
if( strstr(tmpname, "_tcp" ) ) {
|
||||
strncpy(dname, tmpname, dnamelen);
|
||||
}
|
||||
}
|
||||
DEBUGC(DBCLASS_DNS, "_resolve: A[%i] - type NAPTR: %s",
|
||||
i, tmpname);
|
||||
xptr+=j;
|
||||
}
|
||||
} else if( ty == T_SRV ) {
|
||||
u_short pr;
|
||||
u_short we;
|
||||
u_short po;
|
||||
usp = (unsigned short *)xptr;
|
||||
pr = ntohs( *usp );
|
||||
xptr += sizeof( short );
|
||||
usp = (unsigned short *)xptr;
|
||||
we = ntohs( *usp );
|
||||
xptr += sizeof( short );
|
||||
usp = (unsigned short *)xptr;
|
||||
po = ntohs( *usp );
|
||||
xptr += sizeof( short );
|
||||
j = dn_expand( msg, msg + PACKETSZ, xptr, tmpname, MAXDNAME );
|
||||
if( j < 0 ) {
|
||||
break;
|
||||
} else {
|
||||
DEBUGC(DBCLASS_DNS, "_resolve: A[%i] - type SRV pr=%i, we=%i, "
|
||||
"po=%i name=[%s]", i, pr, we, po, tmpname);
|
||||
if( !priority || pr < priority ||
|
||||
(pr == priority && we < weight) ) {
|
||||
priority = pr;
|
||||
weight = we;
|
||||
*port = po;
|
||||
strncpy(dname, tmpname, dnamelen-1);
|
||||
xptr+=j;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ERROR("_resolve: unknown type in DNS answer [type=%i]\n", ty);
|
||||
} // if ty
|
||||
} // if dn_expand
|
||||
} // for i
|
||||
|
||||
dname[dnamelen-1]='\0';
|
||||
return 0;
|
||||
}
|
||||
@ -542,8 +542,13 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id,
|
||||
num_ports = configuration.rtp_port_high - configuration.rtp_port_low + 1;
|
||||
for (i2 = (prev_used_port - configuration.rtp_port_low + 1);
|
||||
i2 < (num_ports + prev_used_port - configuration.rtp_port_low + 1);
|
||||
i2 += 2) {
|
||||
i2++) {
|
||||
i = (i2%num_ports) + configuration.rtp_port_low;
|
||||
DEBUGC(DBCLASS_RTP,"&&&& I=%i, i2=%i",i,i2);
|
||||
|
||||
/* only allow even port numbers */
|
||||
if ((i % 2) != 0) continue;
|
||||
|
||||
for (j=0; j<RTPPROXY_SIZE; j++) {
|
||||
/* check if port already in use */
|
||||
if ((memcmp(&rtp_proxytable[j].local_ipaddr,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user