- removed IPCHAINS & IPTABLES (netfilter) proxy support

- RTPPROXY correction: match RTP ports crosswise -
  use one single port (and socket) on each side (inbound/
  outbound) to send and receive RTP traffic for every
  active stream (patch by Christof Meerwald).
This commit is contained in:
Thomas Ries 2004-01-28 00:19:30 +00:00
parent 17d7438b5c
commit fe9beb76d5
9 changed files with 69 additions and 677 deletions

View File

@ -4,8 +4,13 @@
- better branch parameter calculation (via header),
now honors RFC3261 for stateless proxies (section 16.11)
- SIP request: remove a Route-header pointing to myself.
This was an issue with Linphone 0.12.1. Thanks to
Robert Högberg for a patch.
This was an issue with Linphone 0.12.1.
(patch by Robert Högberg).
- removed IPCHAINS & IPTABLES (netfilter) proxy support
- RTPPROXY correction: match RTP ports crosswise -
use one single port (and socket) on each side (inbound/
outbound) to send and receive RTP traffic for every
active stream (patch by Christof Meerwald).
22-Jan-2004: - ./configure option: --enable-static to build
a completely statically linked executable
- REGISTER honors the expires parameter

View File

@ -84,11 +84,7 @@ registration_file = /var/lib/siproxd/siproxd_registrations
# 0 - RTP proxy disabled
# 1 - RTP proxy (UDP relay of siproxd)
#
# 2 - RTP masquerading IPCHAINS
# 3 - RTP masquerading Netfilter/IPTABLES
# (Siproxd will open masquerading tunnels
# in the firewall. Requires ipchains.
# NOTE: siproxd must be started by root!)
# Note: IPCHAINS and IPTABLES(netfilter) support is no longer present!
#
rtp_proxy_enable = 1

View File

@ -24,9 +24,8 @@ CFLAGS =@CFLAGS@ -Wall -DBUILDSTR=\"`cat .buildno`\" -D_GNU_SOURCE
sbin_PROGRAMS = siproxd
siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c \
sip_utils.c log.c readconf.c rtpproxy.c \
rtpproxy_relay.c rtpproxy_masq.c accessctl.c \
security.c auth.c \
rtpproxy_mchains.c rtpproxy_mnetfltr.c
rtpproxy_relay.c accessctl.c \
security.c auth.c
noinst_HEADERS = log.h rewrite_rules.h siproxd.h digcalc.h rtpproxy.h

View File

@ -49,10 +49,6 @@ int rtpproxy_init( void ) {
sts = STS_SUCCESS;
} else if (configuration.rtp_proxy_enable == 1) { // Relay
sts = rtp_relay_init ();
} else if (configuration.rtp_proxy_enable == 2) { // MASQ tunnels (ipchains)
sts = rtp_masq_init ();
} else if (configuration.rtp_proxy_enable == 3) { // MASQ tunnels (netfilter)
sts = rtp_masq_init ();
} else {
ERROR("CONFIG: rtp_proxy_enable has invalid value",
configuration.rtp_proxy_enable);
@ -80,14 +76,6 @@ int rtp_start_fwd (osip_call_id_t *callid, int direction,
sts = rtp_relay_start_fwd (callid, direction, media_stream_no,
outbound_ipaddr, outboundport,
lcl_client_ipaddr, lcl_clientport);
} else if (configuration.rtp_proxy_enable == 2) { // MASQ tunnels (ipchains)
sts = rtp_masq_start_fwd (callid, direction, media_stream_no,
outbound_ipaddr, outboundport,
lcl_client_ipaddr, lcl_clientport);
} else if (configuration.rtp_proxy_enable == 3) { // MASQ tunnels (netfilter)
sts = rtp_masq_start_fwd (callid, direction, media_stream_no,
outbound_ipaddr, outboundport,
lcl_client_ipaddr, lcl_clientport);
} else {
ERROR("CONFIG: rtp_proxy_enable has invalid value",
configuration.rtp_proxy_enable);
@ -111,10 +99,6 @@ int rtp_stop_fwd (osip_call_id_t *callid, int direction) {
sts = STS_SUCCESS;
} else if (configuration.rtp_proxy_enable == 1) { // Relay
sts = rtp_relay_stop_fwd(callid, direction, 0);
} else if (configuration.rtp_proxy_enable == 2) { // MASQ tunnels (ipchains)
sts = rtp_masq_stop_fwd(callid, direction);
} else if (configuration.rtp_proxy_enable == 3) { // MASQ tunnels (netfilter)
sts = rtp_masq_stop_fwd(callid, direction);
} else {
ERROR("CONFIG: rtp_proxy_enable has invalid value",
configuration.rtp_proxy_enable);

View File

@ -22,7 +22,8 @@
#define CALLIDHOST_SIZE 32
typedef struct {
int sock;
int rtp_rx_sock; /* rx socket (0 -> free slot)*/
int rtp_tx_sock; /* tx socket */
char callid_number[CALLIDNUM_SIZE]; /* call ID */
char callid_host[CALLIDHOST_SIZE]; /* --"-- */
int direction; /* Direction of RTP stream */

View File

@ -1,356 +0,0 @@
/*
Copyright (C) 2003 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 "config.h"
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <osipparser2/osip_parser.h>
#include "siproxd.h"
#include "rtpproxy.h"
#include "log.h"
static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
BUILDSTR " $";
/* configuration storage */
extern struct siproxd_config configuration;
/* table to remember all active rtp proxy streams */
extern rtp_proxytable_t rtp_proxytable[];
#if defined(HAVE_LINUX_IP_MASQ_H) || defined(HAVE_LINUX_NETFILTER_H)
/*
* table to remember all active rtp proxy streams
*/
rtp_proxytable_t rtp_proxytable[RTPPROXY_SIZE];
/************************************************************
THIS HERE WILL ONLY WORK IF SIPROXD IS STARTED SUID ROOT !!
However it is working when started root and then changed
UID to eg. nobody - we'll just raise the privileged when
we need to fiddle with the masquerading
*************************************************************/
/*
* initialize rtp_masq
*
* RETURNS
* STS_SUCCESS on success
*/
int rtp_masq_init( void ) {
/* clean proxy table */
memset (rtp_proxytable, 0, sizeof(rtp_proxytable));
if (configuration.rtp_proxy_enable == 2) { // MASQ tunnels (ipchains)
#if !defined(HAVE_LINUX_IP_MASQ_H)
ERROR("IPCHAINS support not built in");
return STS_FAILURE;
#endif
} else if (configuration.rtp_proxy_enable == 3) { // MASQ tunnels (netfilter)
#if !defined(HAVE_LINUX_NETFILTER_H)
ERROR("NETFILTER/IPTABLES support not built in");
return STS_FAILURE;
#endif
}
return STS_SUCCESS;
}
int rtp_masq_start_fwd(osip_call_id_t *callid, int direction,
int media_stream_no,
struct in_addr outbound_ipaddr, int *outbound_lcl_port,
struct in_addr lcl_client_ipaddr, int lcl_clientport) {
int sts=STS_FAILURE;
int i, j;
int freeidx;
time_t t;
osip_call_id_t cid;
if (callid == NULL) {
ERROR("rtp_masq_start_fwd: callid is NULL!");
return STS_FAILURE;
}
/*
* life insurance: check size of received call_id strings
* I don't know what the maximum allowed size within SIP is,
* so if this test fails maybe it's just necessary to increase
* the constants CALLIDNUM_SIZE and/or CALLIDHOST_SIZE.
*/
if (callid->number && strlen(callid->number) > CALLIDNUM_SIZE) {
ERROR("rtp_masq_start_fwd: received callid number "
"has too many characters (%i, max=%i)",
strlen(callid->number),CALLIDNUM_SIZE);
return STS_FAILURE;
}
if (callid->host && strlen(callid->host) > CALLIDHOST_SIZE) {
ERROR("rtp_masq_start_fwd: received callid host "
"has too many characters (%i, max=%i)",
strlen(callid->host),CALLIDHOST_SIZE);
return STS_FAILURE;
}
/*
* Age proxy table:
* Just throw out expired (timed out) records. The proxy table
* here for the MASQ module is only used to eliminate "doubles"
* during INVITE/ACK. Later on, managing (aging & cleaning) the
* masquerading tunnels is done by the kernel (IPMASQ).
*/
/*&&&&
RACE CONDITIONS! A slot may be timed out, even if the actual
masquerading tunnel is still active. A following new
INVITE then tries to use the believed free port -> Buh
- Can we poll (/proc/something) to figure out if the tunnel
is still active before deleting? This would require knowledge
of the text layout in /proc/xxx.
- are there some other possibilities (netfilter/libiptc)?
- introduce some kind of connection STATE to the proxy table.
Timeout based discarding only is active for non-established.
An INVITE would set the STATE to CONNECTING, the following
ACK to CONNECTED. A CONNECTED entry can only be deleted by
a BYE or CANCEL.
- NETFILTER: during startup (RTP initialization) siproxd should
clean left over entries that are within the RTP proxy port range
*/
time(&t);
for (i=0; i<RTPPROXY_SIZE; i++) {
if ((rtp_proxytable[i].sock != 0) &&
((rtp_proxytable[i].timestamp+configuration.rtp_timeout)<t)) {
/* this one has expired, delete it */
cid.number = rtp_proxytable[i].callid_number;
cid.host = rtp_proxytable[i].callid_host;
rtp_masq_stop_fwd(&cid, rtp_proxytable[i].direction);
DEBUGC(DBCLASS_RTP,"deleting expired proxy slot #%i %s@%s", i,
rtp_proxytable[i].callid_number,
rtp_proxytable[i].callid_host);
memset(&rtp_proxytable[i], 0, sizeof(rtp_proxytable[0]));
}
}
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: starting RTP proxy "
"stream for: %s@%s (%s) #=%i",
callid->number, callid->host,
((direction == DIR_INCOMING) ? "incoming" : "outgoing"),
media_stream_no);
/*
* figure out, if this is an request to start an RTP proxy stream
* that is already existing (identified by SIP Call-ID, direction and
* media_stream_no). This can be due to UDP repetitions of the
* INVITE request...
*/
freeidx=-1;
for (i=0; i<RTPPROXY_SIZE; i++) {
cid.number = rtp_proxytable[i].callid_number;
cid.host = rtp_proxytable[i].callid_host;
if (rtp_proxytable[i].sock != 0) {
if((compare_callid(callid, &cid) == STS_SUCCESS) &&
(rtp_proxytable[i].direction == direction) &&
(rtp_proxytable[i].media_stream_no == media_stream_no)) {
/* return the already known port number */
*outbound_lcl_port=rtp_proxytable[i].outboundport;
DEBUGC(DBCLASS_RTP,"RTP stream already active (port=%i, "
"id=%s, #=%i)", rtp_proxytable[i].outboundport,
rtp_proxytable[i].callid_number,
rtp_proxytable[i].media_stream_no);
return STS_SUCCESS;
} /* compare */
} else {
/* remember the first free slot */
if (freeidx < 0) freeidx=i;
} /* if .sock */
} /* for i */
/* rtp_proxytable port pool full? */
if (freeidx == -1) {
ERROR("rtp_masq_start_fwd: rtp_proxytable is full!");
return STS_FAILURE;
}
/*
* do loop over the range of available ports (7070-...) until able to
* allocate a UDP tunnel with an even port number. If none can be found
* available - Buh! return port=0
*/
for (i=configuration.rtp_port_low; i<=configuration.rtp_port_high; i+=2) {
/* check if this port is already allocated in another stream.
* IPCHAINS will print errors in SYSLOG when I try to use
* the same port twice (IF it is still 'open' - no DST address
* known yet) */
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: checking port %i",i);
for (j=0; j<RTPPROXY_SIZE; j++) {
if (rtp_proxytable[j].sock ==0) continue;
if (rtp_proxytable[j].outboundport == i) {
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: port %i occupied",i);
break;
}
}
if (j < RTPPROXY_SIZE) continue; /* try next port */
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: using port %i",i);
*outbound_lcl_port=i;
/* add masquerading entry */
if (configuration.rtp_proxy_enable == 2) { // ipchains
sts = rtp_mchains_create(lcl_client_ipaddr, lcl_clientport,
outbound_ipaddr, *outbound_lcl_port);
} else if (configuration.rtp_proxy_enable == 3) { // netfilter/iptables
sts = rtp_mnetfltr_create(lcl_client_ipaddr, lcl_clientport,
outbound_ipaddr, *outbound_lcl_port);
}
/* if success break, else try further on */
if (sts == STS_SUCCESS) break;
*outbound_lcl_port=0;
} /* for i */
if (*outbound_lcl_port) {
/* write entry into rtp_proxytable slot (freeidx) */
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: using proxy slot %i",freeidx);
rtp_proxytable[freeidx].sock=1;
if (callid->number) {
strcpy(rtp_proxytable[freeidx].callid_number, callid->number);
} else {
rtp_proxytable[freeidx].callid_number[0]='\0';
}
if (callid->host) {
strcpy(rtp_proxytable[freeidx].callid_host, callid->host);
} else {
rtp_proxytable[freeidx].callid_host[0]='\0';
}
rtp_proxytable[freeidx].direction = direction;
rtp_proxytable[freeidx].media_stream_no = media_stream_no;
memcpy(&rtp_proxytable[freeidx].outbound_ipaddr,
&outbound_ipaddr, sizeof(struct in_addr));
rtp_proxytable[freeidx].outboundport=*outbound_lcl_port;
memcpy(&rtp_proxytable[freeidx].inbound_client_ipaddr,
&lcl_client_ipaddr, sizeof(struct in_addr));
rtp_proxytable[freeidx].inbound_client_port=lcl_clientport;
time(&rtp_proxytable[freeidx].timestamp);
}
DEBUGC(DBCLASS_RTP,"rtp_masq_start_fwd: masq address & port:%s:%i",
utils_inet_ntoa(outbound_ipaddr),*outbound_lcl_port);
return (*outbound_lcl_port)?STS_SUCCESS:STS_FAILURE;
}
int rtp_masq_stop_fwd (osip_call_id_t *callid, int direction) {
int sts=STS_FAILURE;
int i;
int got_match=0;
osip_call_id_t cid;
/* let the UDP tunnel time-out */
if (callid == NULL) {
ERROR("rtp_masq_stop_fwd: callid is NULL!");
return STS_FAILURE;
}
DEBUGC(DBCLASS_RTP,"rtp_masq_stop_fwd: stopping RTP proxy "
"stream for: %s@%s (%s)",
callid->number, callid->host,
((direction == DIR_INCOMING) ? "incoming" : "outgoing"));
for (i=0; i<RTPPROXY_SIZE; i++) {
cid.number = rtp_proxytable[i].callid_number;
cid.host = rtp_proxytable[i].callid_host;
if (rtp_proxytable[i].sock &&
(compare_callid(callid, &cid) == STS_SUCCESS) &&
(rtp_proxytable[i].direction == direction)) {
/* remove masquerading entry */
if (configuration.rtp_proxy_enable == 2) { // ipchains
DEBUGC(DBCLASS_RTP,"rtp_masq_stop_fwd: stop RTP proxy slot %i "
"(IPCHAINS)",i);
sts = rtp_mchains_delete(
rtp_proxytable[i].inbound_client_ipaddr,
rtp_proxytable[i].inbound_client_port,
rtp_proxytable[i].outbound_ipaddr,
rtp_proxytable[i].outboundport);
} else if (configuration.rtp_proxy_enable == 3) { // netfilter/iptables
DEBUGC(DBCLASS_RTP,"rtp_masq_stop_fwd: stop RTP proxy slot %i "
"(NETFILTER)",i);
sts = rtp_mnetfltr_delete(
rtp_proxytable[i].inbound_client_ipaddr,
rtp_proxytable[i].inbound_client_port,
rtp_proxytable[i].outbound_ipaddr,
rtp_proxytable[i].outboundport);
}
DEBUGC(DBCLASS_RTP,"rtp_masq_stop_fwd: cleaning proxy slot %i",i);
memset(&rtp_proxytable[i], 0, sizeof(rtp_proxytable[0]));
got_match=1;
}
}
/* did not find an active stream... */
if (!got_match) {
DEBUGC(DBCLASS_RTP,
"rtp_masq_stop_fwd: can't find active stream for %s@%s (%s)",
callid->number, callid->host,
((direction == DIR_INCOMING) ? "incoming" : "outgoing"));
return STS_FAILURE;
}
return STS_SUCCESS;
}
#else
/*
* don't have ipchains or iptables - dummy routines and complain
*/
int rtp_masq_init( void ) {
ERROR("Masquerading support is not enabled (compile time config option)");
return STS_FAILURE;
}
int rtp_masq_start_fwd(osip_call_id_t *callid, int direction,
int media_stream_no,
struct in_addr outbound_ipaddr, int *outbound_lcl_port,
struct in_addr lcl_client_ipaddr, int lcl_clientport) {
outbound_lcl_port=0;
return STS_FAILURE;
}
int rtp_masq_stop_fwd (osip_call_id_t *callid, int direction) {
return STS_FAILURE;
}
#endif

View File

@ -1,126 +0,0 @@
/*
Copyright (C) 2003 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 "config.h"
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#if defined(HAVE_LINUX_IP_MASQ_H)
/* masq specific stuff */
#include <asm/types.h> /* For __uXX types */
#include <net/if.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <linux/ip_fw.h> /* For IP_FW_MASQ_CTL */
#include <linux/ip_masq.h> /* For specific masq defs */
#include <asm/param.h>
#endif
#include <osipparser2/osip_parser.h>
#include "siproxd.h"
#include "rtpproxy.h"
#include "log.h"
static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
BUILDSTR " $";
#if defined(HAVE_LINUX_IP_MASQ_H)
/* socket for controlling the MASQ tunnels */
static int masq_ctl_sock=0;
int rtp_mchains_create(struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
int uid,euid;
int sts=STS_SUCCESS;
struct ip_masq_ctl masq;
/* elevate privileges */
uid=getuid();
euid=geteuid();
if (uid != euid) seteuid(0);
if (geteuid()!=0) {
ERROR("create_listening_masq: must be running under UID root!");
return STS_FAILURE;
}
if (masq_ctl_sock==0) {
masq_ctl_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (masq_ctl_sock<0) {
ERROR("create_listening_masq: allocating control socket() failed: %s",
strerror(errno));
sts = STS_FAILURE;
goto exit;
}
}
memset (&masq, 0, sizeof (masq));
masq.m_target = IP_MASQ_TARGET_USER;
masq.m_cmd = IP_MASQ_CMD_INSERT;
masq.u.user.protocol= IPPROTO_UDP;
memcpy(&masq.u.user.saddr, &lcl_addr, sizeof(lcl_addr));
masq.u.user.sport = htons(lcl_port);
memcpy(&masq.u.user.maddr, &msq_addr, sizeof(msq_addr));
masq.u.user.mport = htons(msq_port);
if (setsockopt(masq_ctl_sock, IPPROTO_IP,
IP_FW_MASQ_CTL, (char *)&masq, sizeof(masq))) {
DEBUGC(DBCLASS_RTP, "create_listening_masq: setsockopt() failed: %s",
strerror(errno));
sts = STS_FAILURE;
goto exit;
}
exit:
/* drop privileges */
if (uid != euid) seteuid(euid);
return sts;
}
#else
/*
* don't have ipchains - dummy routines and complain
*/
int rtp_mchains_create(struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
ERROR("IPCHAINS support is not enabled (compile time config option)");
return STS_FAILURE;
}
#endif
int rtp_mchains_delete (struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
/* nothing to do here, just let the tunnel time out */
return STS_SUCCESS;
}

View File

@ -1,145 +0,0 @@
/*
Copyright (C) 2003 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 "config.h"
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#if defined(HAVE_LINUX_NETFILTER_H)
/* iptables/netfilter specific stuff */
//&&&&
#endif
#include <osipparser2/osip_parser.h>
#include "siproxd.h"
#include "rtpproxy.h"
#include "log.h"
static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
BUILDSTR " $";
#if defined(HAVE_LINUX_NETFILTER_H)
static char *ipchains_exe="/sbin/iptables";
static char *add_rule =
"%s -t nat -A PREROUTING -p udp --destination-port %i -j DNAT "
"--to-destination %s:%i";
static char *del_rule =
"%s -t nat -D PREROUTING -p udp --destination-port %i -j DNAT "
"--to-destination %s:%i";
/*
* lcl_addr IP of local UA
* lcl_port port of local UA
* msq_addr masqueraded address (public IP of proxy)
* msq_port masqueraded port (where siproxd wants to receive RTP traffic)
*/
int rtp_mnetfltr_create (struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
int uid,euid;
int sts;
char tmp[256];
INFO("rtp_mchains_create");
/* Still an Hack I don't like - use a system() call to alter the FW */
sprintf(tmp, add_rule, ipchains_exe, msq_port, utils_inet_ntoa(lcl_addr),
lcl_port);
DEBUGC(DBCLASS_RTP,"rtp_mnetfltr_create: add FW rule:[%s]",tmp);
/* elevate privileges */
uid=getuid();
euid=geteuid();
if (uid != euid) seteuid(0);
if (geteuid()!=0) {
ERROR("create_listening_masq: must be running under UID root!");
return STS_FAILURE;
}
sts = system(tmp);
if (sts <0) {
ERROR("rtp_mnetfltr_create: system() failed with sts=%i", sts);
}
/* drop privileges */
if (uid != euid) seteuid(euid);
return STS_SUCCESS;
}
int rtp_mnetfltr_delete (struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
int uid,euid;
int sts;
char tmp[256];
INFO("rtp_mchains_delete");
/* Still an Hack I don't like - use a system() call to alter the FW */
sprintf(tmp, del_rule, ipchains_exe, msq_port, utils_inet_ntoa(lcl_addr),
lcl_port);
DEBUGC(DBCLASS_RTP,"rtp_mnetfltr_delete: del FW rule:[%s]",tmp);
/* elevate privileges */
uid=getuid();
euid=geteuid();
if (uid != euid) seteuid(0);
if (geteuid()!=0) {
ERROR("create_listening_masq: must be running under UID root!");
return STS_FAILURE;
}
sts = system(tmp);
if (sts <0) {
ERROR("rtp_mnetfltr_create: system() failed with sts=%i", sts);
}
/* drop privileges */
if (uid != euid) seteuid(euid);
return STS_SUCCESS;
}
#else
/*
* don't have iptables - dummy routines and complain
*/
int rtp_mnetfltr_create (struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
ERROR("NETFILTER support is not enabled (compile time config option)");
return STS_FAILURE;
}
int rtp_mnetfltr_delete (struct in_addr lcl_addr, int lcl_port,
struct in_addr msq_addr, int msq_port) {
ERROR("NETFILTER support is not enabled (compile time config option)");
return STS_FAILURE;
}
#endif

View File

@ -113,7 +113,7 @@ static void *rtpproxy_main(void *arg) {
int i, sts;
int num_fd;
osip_call_id_t callid;
static int rtp_socket=0;
//&&&& static int rtp_socket=0;
static char rtp_buff[RTP_BUFFER_SIZE];
int count;
@ -149,22 +149,54 @@ static void *rtpproxy_main(void *arg) {
/* check for data available and send to destination */
for (i=0;(i<RTPPROXY_SIZE) && (num_fd>0);i++) {
if ( (rtp_proxytable[i].sock != 0) &&
FD_ISSET(rtp_proxytable[i].sock, &fdset) ) {
if ( (rtp_proxytable[i].rtp_rx_sock != 0) &&
FD_ISSET(rtp_proxytable[i].rtp_rx_sock, &fdset) ) {
/* yup, have some data to send */
/* read from sock rtp_proxytable[i].sock*/
count=read(rtp_proxytable[i].sock, rtp_buff, RTP_BUFFER_SIZE);
count=read(rtp_proxytable[i].rtp_rx_sock, rtp_buff, RTP_BUFFER_SIZE);
if (count<0) {
WARN("read() returned error [%s]",strerror(errno));
}
/* write to dest via socket rtp__socket */
sts = sipsock_send_udp(&rtp_socket,
rtp_proxytable[i].inbound_client_ipaddr,
rtp_proxytable[i].inbound_client_port,
rtp_buff, count, 0); /* don't dump it */
//&&&& /* write to dest via socket rtp__socket */
//&&&& sts = sipsock_send_udp(&rtp_socket,
//&&&& rtp_proxytable[i].inbound_client_ipaddr,
//&&&& rtp_proxytable[i].inbound_client_port,
//&&&& rtp_buff, count, 0); /* don't dump it */
if (rtp_proxytable[i].rtp_tx_sock == 0)
{
int j;
osip_call_id_t callid;
int direction = rtp_proxytable[i].direction;
int media_stream_no = rtp_proxytable[i].media_stream_no;
callid.number = rtp_proxytable[i].callid_number;
callid.host = rtp_proxytable[i].callid_host;
for (j=0;(j<RTPPROXY_SIZE);j++) {
osip_call_id_t cid;
cid.number = rtp_proxytable[j].callid_number;
cid.host = rtp_proxytable[j].callid_host;
if ( (rtp_proxytable[j].rtp_rx_sock != 0) &&
(direction != rtp_proxytable[j].direction) &&
(media_stream_no == rtp_proxytable[j].media_stream_no) &&
(compare_callid(&callid, &cid) == STS_SUCCESS) ) {
rtp_proxytable[i].rtp_tx_sock = rtp_proxytable[j].rtp_rx_sock;
break;
}
}
}
if (rtp_proxytable[i].rtp_tx_sock != 0) {
/* write to dest via socket rtp_tx_sock */
sts = sipsock_send_udp(&rtp_proxytable[i].rtp_tx_sock,
rtp_proxytable[i].inbound_client_ipaddr,
rtp_proxytable[i].inbound_client_port,
rtp_buff, count, 0); /* don't dump it */
}
/* update timestamp of last usage */
rtp_proxytable[i].timestamp=t;
@ -179,13 +211,15 @@ static void *rtpproxy_main(void *arg) {
if (t > (last_t+10) ) {
last_t = t;
for (i=0;i<RTPPROXY_SIZE; i++) {
if ( (rtp_proxytable[i].sock != 0) &&
if ( (rtp_proxytable[i].rtp_rx_sock != 0) &&
((rtp_proxytable[i].timestamp+configuration.rtp_timeout)<t)) {
/* this one has expired, clean it up */
callid.number=rtp_proxytable[i].callid_number;
callid.host=rtp_proxytable[i].callid_host;
DEBUGC(DBCLASS_RTP,"RTP stream sock=%i %s@%s (idx=%i) "
"has expired", rtp_proxytable[i].sock,
DEBUGC(DBCLASS_RTP,"RTP stream rx_sock=%i tx_sock=%i "
"%s@%s (idx=%i) has expired",
rtp_proxytable[i].rtp_rx_sock,
rtp_proxytable[i].rtp_tx_sock,
callid.number, callid.host, i);
/* don't lock the mutex, as we own the lock already here */
rtp_relay_stop_fwd(&callid, rtp_proxytable[i].direction, 1);
@ -276,7 +310,7 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int direction,
for (i=0; i<RTPPROXY_SIZE; i++) {
cid.number = rtp_proxytable[i].callid_number;
cid.host = rtp_proxytable[i].callid_host;
if (rtp_proxytable[i].sock &&
if (rtp_proxytable[i].rtp_rx_sock &&
(compare_callid(callid, &cid) == STS_SUCCESS) &&
(rtp_proxytable[i].direction == direction) &&
(rtp_proxytable[i].media_stream_no == media_stream_no) ) {
@ -307,7 +341,7 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int direction,
*/
freeidx=-1;
for (j=0; j<RTPPROXY_SIZE; j++) {
if (rtp_proxytable[j].sock==0) {
if (rtp_proxytable[j].rtp_rx_sock==0) {
freeidx=j;
break;
}
@ -356,7 +390,7 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, int direction,
}
/* write entry into rtp_proxytable slot (freeidx) */
rtp_proxytable[freeidx].sock=sock;
rtp_proxytable[freeidx].rtp_rx_sock=sock;
if (callid->number) {
strcpy(rtp_proxytable[freeidx].callid_number, callid->number);
@ -456,19 +490,19 @@ int rtp_relay_stop_fwd (osip_call_id_t *callid, int direction,
for (i=0; i<RTPPROXY_SIZE; i++) {
cid.number = rtp_proxytable[i].callid_number;
cid.host = rtp_proxytable[i].callid_host;
if (rtp_proxytable[i].sock &&
if (rtp_proxytable[i].rtp_rx_sock &&
(compare_callid(callid, &cid) == STS_SUCCESS) &&
(rtp_proxytable[i].direction == direction)) {
sts = close(rtp_proxytable[i].sock);
sts = close(rtp_proxytable[i].rtp_rx_sock);
DEBUGC(DBCLASS_RTP,"closed socket %i for RTP stream "
"%s:%s == %s:%s (idx=%i) sts=%i",
rtp_proxytable[i].sock,
rtp_proxytable[i].rtp_rx_sock,
rtp_proxytable[i].callid_number,
rtp_proxytable[i].callid_host,
callid->number, callid->host, i, sts);
if (sts < 0) {
ERROR("Error in close(%i): %s nolock=%i %s:%s\n",
rtp_proxytable[i].sock,
rtp_proxytable[i].rtp_rx_sock,
strerror(errno), nolock,
callid->number, callid->host);
}
@ -521,10 +555,10 @@ static int rtp_recreate_fdset(void) {
FD_ZERO(&master_fdset);
master_fd_max=-1;
for (i=0;i<RTPPROXY_SIZE;i++) {
if (rtp_proxytable[i].sock != 0) {
FD_SET(rtp_proxytable[i].sock, &master_fdset);
if (rtp_proxytable[i].sock > master_fd_max) {
master_fd_max=rtp_proxytable[i].sock;
if (rtp_proxytable[i].rtp_rx_sock != 0) {
FD_SET(rtp_proxytable[i].rtp_rx_sock, &master_fdset);
if (rtp_proxytable[i].rtp_rx_sock > master_fd_max) {
master_fd_max=rtp_proxytable[i].rtp_rx_sock;
}
}
} /* for i */