diff --git a/ChangeLog b/ChangeLog index bf083e2..b0c9dae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/doc/siproxd.conf.example b/doc/siproxd.conf.example index 61d8cb7..1a36a5f 100644 --- a/doc/siproxd.conf.example +++ b/doc/siproxd.conf.example @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index bdf2acd..12fb566 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/rtpproxy.c b/src/rtpproxy.c index 5872468..5fc7b75 100644 --- a/src/rtpproxy.c +++ b/src/rtpproxy.c @@ -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); diff --git a/src/rtpproxy.h b/src/rtpproxy.h index edf7301..02c81f9 100644 --- a/src/rtpproxy.h +++ b/src/rtpproxy.h @@ -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 */ diff --git a/src/rtpproxy_masq.c b/src/rtpproxy_masq.c deleted file mode 100644 index 3f7e06f..0000000 --- a/src/rtpproxy_masq.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - Copyright (C) 2003 Thomas Ries - - 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 -#include -#include -#include - -#include -#include -#include - -#include - -#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; inumber, 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; inumber) { - 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; inumber, 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 diff --git a/src/rtpproxy_mchains.c b/src/rtpproxy_mchains.c deleted file mode 100644 index a30cf08..0000000 --- a/src/rtpproxy_mchains.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2003 Thomas Ries - - 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 -#include -#include -#include - -#include -#include -#include - -#if defined(HAVE_LINUX_IP_MASQ_H) -/* masq specific stuff */ -#include /* For __uXX types */ -#include -#include -#include -#include -#include /* For IP_FW_MASQ_CTL */ -#include /* For specific masq defs */ -#include -#endif - -#include - -#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; -} diff --git a/src/rtpproxy_mnetfltr.c b/src/rtpproxy_mnetfltr.c deleted file mode 100644 index a219e49..0000000 --- a/src/rtpproxy_mnetfltr.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - Copyright (C) 2003 Thomas Ries - - 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 -#include -#include -#include - -#include -#include -#include - -#if defined(HAVE_LINUX_NETFILTER_H) -/* iptables/netfilter specific stuff */ -//&&&& -#endif - -#include - -#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 diff --git a/src/rtpproxy_relay.c b/src/rtpproxy_relay.c index cb33ccc..7d5aae1 100644 --- a/src/rtpproxy_relay.c +++ b/src/rtpproxy_relay.c @@ -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;(i0);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 (last_t+10) ) { last_t = t; for (i=0;inumber) { 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; inumber, 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 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 */