- allocate only even RTP port numbers
- started with own name lookup routines that honor SRV and NAPTR records
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user