diff --git a/ChangeLog b/ChangeLog index 016d235..cf7cf97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ 0.5.5 ===== 9-Apr-2004: - SDP body: do rewrite 'o=' (originator) address, too + - siproxd can be linked to a customer firewall control + module (library) that will be called for each RTP + stream that is started/stopped. 8-Apr-2004: - small FAQ updates 5-Apr-2004: - config file: don't complain on line s with only whitespaces - fix: Via branch calculation diff --git a/configure.in b/configure.in index 3dbdd54..3969e85 100644 --- a/configure.in +++ b/configure.in @@ -58,6 +58,7 @@ dnl AC_PROG_AWK AC_PROG_CC AC_PROG_CPP +AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_LN_S @@ -296,10 +297,10 @@ dnl add dnl --with-custom-fwmodule AC_MSG_CHECKING(building with a custom FW module) AC_ARG_WITH(custom-fwmodule, - [ --with-custom-fwmodule=MODULE.o use custom firewall control module], - LDFLAGS="$LDFLAGS $withval "; + [ --with-custom-fwmodule=LIBRARY.a use custom firewall control module], + FWLIBS="$withval"; AC_DEFINE(CUSTOM_FWMODULE, 1,[use custom firewall control module]) - AC_MSG_RESULT($withval), AC_MSG_RESULT(no)) + AC_MSG_RESULT($FWLIBS), AC_MSG_RESULT(no)) dnl @@ -362,8 +363,10 @@ done AC_DEFINE_UNQUOTED(SIPROXDCONFPATH,"$SIPROXDCONFPATH", [will search for config file here]) +LIBS="$LIBS $FWLIBS" AC_SUBST(CPPFLAGS) +AC_SUBST(LDFLAGS) AC_SUBST(LIBS) dnl diff --git a/src/Makefile.am b/src/Makefile.am index 594f6e9..c0fd71d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright (C) 2002 Thomas Ries +# Copyright (C) 2002-2004 Thomas Ries # # This file is part of Siproxd. # @@ -21,13 +21,25 @@ AM_CFLAGS = -Wall -DBUILDSTR=\"`cat .buildno`\" -D_GNU_SOURCE +# +# Siproxd itself +# 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 accessctl.c \ - security.c auth.c + security.c auth.c fwapi.c -noinst_HEADERS = log.h rewrite_rules.h siproxd.h digcalc.h rtpproxy.h +# +# an example for a custom firewall control module +# that can be linked into siproxd (--with-custom-fwmodule) +# +noinst_LIBRARIES = libcustom_fw_module.a +libcustom_fw_module_a_SOURCES = custom_fw_module.c + + +noinst_HEADERS = log.h rewrite_rules.h siproxd.h digcalc.h rtpproxy.h \ + fwapi.h EXTRA_DIST = .buildno diff --git a/src/custom_fw_module.c b/src/custom_fw_module.c new file mode 100644 index 0000000..15799bb --- /dev/null +++ b/src/custom_fw_module.c @@ -0,0 +1,108 @@ +/* + Copyright (C) 2004 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 +*/ + +/* + * This is just an example of how to build your custom + * interface between siproxd and your firewall. + * + * Take this as a starting point for your own code. + * + * To build siproxd with you own firewall control module: + * 1) compile your interface module (e.g. this example code) + * and make an static library out of it. + * 2) configure siproxd with: + * ./configure --with-custom-fwmodule=/.a + * (for example: --with-custom-fwmodule=`pwd`/src/libcustom_fw_module.a) + * + * + * The START_RTP action will be called BEFORE the RTP stream + * actually is started. The STOP_RTP action will be called after + * the RTP stream has been stopped. + * START_RTP will only be called once for an starting RTP stream, + * in case of repetitions (SIP INVITE sequence) it will not + * be called multiple times. + * + * The code here is called synchroneously, means the time you spend + * in here doing things, siproxd will not do anything else, so + * try to do thins as fast as possible and don't wait for something + * to happen. + * + */ + +#include /* sprintf */ +#include /* strcat */ + + +#include +#include "fwapi.h" +#include "log.h" + +/* + * some prototypes of util.c - so I don't have to suck in the + * whole bunch of include files. You probably will not use this + * in your code anyway - or then should make it in a proper way. + */ +char *utils_inet_ntoa(struct in_addr in); + +/* + * Should return with 0 on success. + * If return status is != 0, siproxd will complain with an + * an ERROR() but continue. + */ +int custom_fw_control(fw_ctl_t fwdata) { + static char tmp[256]; + + tmp[0]='\0'; + switch (fwdata.action) { + case ACT_START_RTP: + strcat(tmp, "ACT_START_RTP: "); + break; + case ACT_STOP_RTP: + strcat(tmp, "ACT_STOP_RTP: "); + break; + default: + strcat(tmp, "ACT_unknown: "); + break; + } + + switch (fwdata.direction) { + case DIR_IN: + strcat(tmp, "DIR_IN "); + break; + case DIR_OUT: + strcat(tmp, "DIR_OUT "); + break; + default: + strcat(tmp, "DIR_unknown "); + break; + } + + sprintf(&tmp[strlen(tmp)],"[lcl %s:%i] ", + utils_inet_ntoa(fwdata.local_ipaddr), + fwdata.local_port); + + sprintf(&tmp[strlen(tmp)],"[rem %s:%i] ", + utils_inet_ntoa(fwdata.remote_ipaddr), + fwdata.remote_port); + + INFO("CUSTOM: %s", tmp); + + return 0; +} diff --git a/src/fwapi.c b/src/fwapi.c new file mode 100644 index 0000000..c440ece --- /dev/null +++ b/src/fwapi.c @@ -0,0 +1,67 @@ +/* + Copyright (C) 2004 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 +#include +#include "siproxd.h" +#include "fwapi.h" +#include "log.h" + +int fwapi_start_rtp(int rtp_direction, + struct in_addr local_ipaddr, int local_port, + struct in_addr remote_ipaddr, int remote_port) { +#ifdef CUSTOM_FWMODULE + int sts; + fw_ctl_t fwdata; + fwdata.action = ACT_START_RTP; + fwdata.direction = (rtp_direction == DIR_INCOMING)? DIR_IN: DIR_OUT; + memcpy(&fwdata.local_ipaddr, &local_ipaddr, sizeof(fwdata.local_ipaddr)); + fwdata.local_port = local_port; + memcpy(&fwdata.remote_ipaddr, &remote_ipaddr, sizeof(fwdata.remote_ipaddr)); + fwdata.remote_port = remote_port; + + sts=custom_fw_control(fwdata); + if (sts != STS_SUCCESS) { + ERROR("Custom firewall module returned error [START, sts=%s]",sts); + } +#endif + return STS_SUCCESS; +} + +int fwapi_stop_rtp(int rtp_direction, + struct in_addr local_ipaddr, int local_port, + struct in_addr remote_ipaddr, int remote_port) { +#ifdef CUSTOM_FWMODULE + int sts; + fw_ctl_t fwdata; + fwdata.action = ACT_STOP_RTP; + fwdata.direction = (rtp_direction == DIR_INCOMING)? DIR_IN: DIR_OUT; + memcpy(&fwdata.local_ipaddr, &local_ipaddr, sizeof(fwdata.local_ipaddr)); + fwdata.local_port = local_port; + memcpy(&fwdata.remote_ipaddr, &remote_ipaddr, sizeof(fwdata.remote_ipaddr)); + fwdata.remote_port = remote_port; + + sts=custom_fw_control(fwdata); + if (sts != STS_SUCCESS) { + ERROR("Custom firewall module returned error [STOP, sts=%s]",sts); + } +#endif + return STS_SUCCESS; +} diff --git a/src/fwapi.h b/src/fwapi.h new file mode 100644 index 0000000..3535261 --- /dev/null +++ b/src/fwapi.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2004 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 +*/ + + +/* + * constants + */ +#define ACT_START_RTP 1 /* action: start RTP stream */ +#define ACT_STOP_RTP 2 /* action: stop RTP stream */ + +#define DIR_IN 1 /* direction: incoming */ +#define DIR_OUT 2 /* direction: outgoing */ + + +/* + * structure passed to custom firewall control module + */ +typedef struct { + int action; + int direction; + + struct in_addr local_ipaddr; + int local_port; + + struct in_addr remote_ipaddr; + int remote_port; + +} fw_ctl_t; + + +/* + * Functions that must be present in custom firewall control module. + * Siproxd will link against it. + */ +int custom_fw_control(fw_ctl_t fwdata); + diff --git a/src/rtpproxy_relay.c b/src/rtpproxy_relay.c index bb1d27c..0608b86 100644 --- a/src/rtpproxy_relay.c +++ b/src/rtpproxy_relay.c @@ -554,6 +554,13 @@ int rtp_relay_start_fwd (osip_call_id_t *callid, char *client_id, *local_port=port; + /* call to firewall API */ + fwapi_start_rtp(rtp_proxytable[freeidx].direction, + rtp_proxytable[freeidx].local_ipaddr, + rtp_proxytable[freeidx].local_port, + rtp_proxytable[freeidx].remote_ipaddr, + rtp_proxytable[freeidx].remote_port); + /* prepare FD set for next select operation */ rtp_recreate_fdset(); @@ -644,9 +651,16 @@ int rtp_relay_stop_fwd (osip_call_id_t *callid, strerror(errno), nolock, callid->number, callid->host); } + /* call to firewall API */ + fwapi_stop_rtp(rtp_proxytable[i].direction, + rtp_proxytable[i].local_ipaddr, + rtp_proxytable[i].local_port, + rtp_proxytable[i].remote_ipaddr, + rtp_proxytable[i].remote_port); + /* clean up */ memset(&rtp_proxytable[i], 0, sizeof(rtp_proxytable[0])); got_match=1; - } + } } diff --git a/src/siproxd.h b/src/siproxd.h index f3a6098..a51ed43 100644 --- a/src/siproxd.h +++ b/src/siproxd.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002 Thomas Ries + Copyright (C) 2002-2004 Thomas Ries This file is part of Siproxd. @@ -94,6 +94,13 @@ int authenticate_proxy(osip_message_t *request); /*X*/ int auth_include_authrq(osip_message_t *response); /*X*/ void CvtHex(char *hash, char *hashstring); +/* fwapi.h */ +int fwapi_start_rtp(int rtp_direction, + struct in_addr local_ipaddr, int local_port, + struct in_addr remote_ipaddr, int remote_port); +int fwapi_stop_rtp(int rtp_direction, + struct in_addr local_ipaddr, int local_port, + struct in_addr remote_ipaddr, int remote_port); /*