this is 0.1.3
- Bugfixes in the SIP proxy part - Performance imporvement in RTP proxy part - some documentation updates - include ./scripts subdirectory in the distribution, was an error in the autoconf/automake setup
This commit is contained in:
parent
038f5ef904
commit
c3e10ec745
18
ChangeLog
18
ChangeLog
@ -1,3 +1,21 @@
|
||||
0.1.3
|
||||
=====
|
||||
- 11-Sep-2002: - Fixed a error in the autoconf/automake part of the project.
|
||||
(scripts subdirectory was missing in the tar.gz archive.
|
||||
This resulted in an error during ./configure - complaining
|
||||
about non existent install-sh script)
|
||||
- startup is more silent - set initial debug level to 0
|
||||
- 10-Sep-2002: - Some (yea, I know...) -minor- docu updates
|
||||
- 8-Sep-2002: - Masquerade Contact Headers of inbound clients
|
||||
(Contact header will be used by the remote SIP
|
||||
user agent to directly contact the local user agent -
|
||||
and bypassing the proxy. This of course will *not* work
|
||||
if the local user agent is located in a private IP range.)
|
||||
- Performance optimizations in RTP proxy
|
||||
- Bugfix: now masqueraded clients work with any
|
||||
SIP port (other than 5060). Before, incomming
|
||||
requests/responses where always sent to port 5060.
|
||||
|
||||
0.1.2
|
||||
=====
|
||||
- 7-Sep-2002: - Releases version 0.1.2
|
||||
|
||||
@ -21,4 +21,4 @@
|
||||
|
||||
SUBDIRS = src doc
|
||||
|
||||
EXTRA_DIST = TODO RELNOTES
|
||||
EXTRA_DIST = scripts TODO RELNOTES
|
||||
|
||||
@ -87,7 +87,7 @@ VERSION = @VERSION@
|
||||
|
||||
SUBDIRS = src doc
|
||||
|
||||
EXTRA_DIST = TODO RELNOTES
|
||||
EXTRA_DIST = scripts TODO RELNOTES
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
|
||||
155
README
155
README
@ -4,8 +4,8 @@ Be warned, this (and all the other) documentantation is far from
|
||||
complete. This is still considered an alpha release.
|
||||
|
||||
|
||||
Overview:
|
||||
=========
|
||||
OVERVIEW
|
||||
========
|
||||
Siprox is an proxy/masquerading daemon for the SIP protocol.
|
||||
It handles registrations of SIP clients on a private IP network
|
||||
and performs rewriting of the SIP message bodies to make SIP
|
||||
@ -20,17 +20,18 @@ IP addresses and port numbers.
|
||||
|
||||
|
||||
|
||||
Requirements:
|
||||
=============
|
||||
REQUIREMENTS
|
||||
============
|
||||
- libosip-0.8.8 (http://www.fsf.org/software/osip/)
|
||||
- pthreads (should be part of any Linux distribution)
|
||||
|
||||
Up to now, this packages only has been tested under an i386 Redhat Linux 6.0.
|
||||
Up to now, siporxd only has been tested under an i386 Redhat Linux 6.0.
|
||||
However, it should build and run under newer versions (feedback is welcome).
|
||||
|
||||
|
||||
|
||||
How to get started:
|
||||
===================
|
||||
HOW TO GET STARTED
|
||||
==================
|
||||
|
||||
- ./configure
|
||||
|
||||
@ -38,82 +39,124 @@ How to get started:
|
||||
|
||||
- make install
|
||||
|
||||
- copy sipproxd.conf.example to /etc/siproxd.conf
|
||||
- copy doc/sipproxd.conf.example to /etc/siproxd.conf
|
||||
|
||||
- edit /etc/siproxd.conf according to your situation
|
||||
At least 'host_inbound' and 'host_outbound' have to be adapted!
|
||||
host_inbound is your IP address of your private network,
|
||||
host_outbound is your publich IP address or hostname (if you
|
||||
have dynamic IP addresses, then you might want to use a hostname
|
||||
here and use a dynamic DNS service like dyndns.org)
|
||||
At least 'host_inbound' and 'host_outbound' *must* be adapted!
|
||||
'host_inbound' is the firewalls IP address of your private network,
|
||||
'host_outbound' is the publich IP address or hostname of the
|
||||
firewall. (If you have dynamic IP addresses, then you might want
|
||||
to use a hostname here and use a dynamic DNS service like [1])
|
||||
|
||||
- start siproxd (siproxd does *not* require root privilegdes)
|
||||
$ siproxd
|
||||
|
||||
|
||||
|
||||
What siproxd does:
|
||||
WHAT SIPROXD DOES
|
||||
=================
|
||||
Siproxd's main purpose (up to now) is to rewrite SIP messages
|
||||
to be able to operate via an masquerading firewall.
|
||||
Since release 0.1.2 siproxd can proxy incomming RTP streams.
|
||||
Siproxd's purpose is to act as an SIP proxy for softphones located
|
||||
in private IP ranges. Therefore it will rewrite SIP messages to allow a
|
||||
softphone to communicate to a counterpart that is located in the Internet.
|
||||
There usually will be a masquerading firewall in between to 'hide' the
|
||||
private IP range (either via NAT - network address translation or
|
||||
masuerading). Check the scenario drawn below.
|
||||
|
||||
|
||||
|
||||
What siproxd does NOT do:
|
||||
=========================
|
||||
|
||||
SINCE RELEASE 0.1.2:
|
||||
Siproxd should be able to proxy incomming RTP data streams (UDP only).
|
||||
This is still very experimental code ;-)
|
||||
The config parameters 'rtp_port_low' and rtp_port_high' define
|
||||
With release 0.1.2 siproxd is also able to proxy incomming RTP data
|
||||
streams. The config parameters 'rtp_port_low' and rtp_port_high' define
|
||||
the port range that siproxd will use for incomming RTP data streams.
|
||||
'rtp_timeout' defines after what time an unused (no data received)
|
||||
rtp stream is considered dead and removed.
|
||||
|
||||
** As I had not yet the possibility to test this feature,
|
||||
** I'd be glad about feedback.
|
||||
|
||||
PRIOR TO RELEASE 0.1.2:
|
||||
Siproxd does *not* (yet) create masquerading tunnels or port-forwarding
|
||||
for the data stream through the firewall.
|
||||
|
||||
These forwarding rules have to be set-up manually (currently)
|
||||
|
||||
Example, using ipchains (mfw):
|
||||
# ipchains -A input --proto udp --dport 7078 -m 100 -j ACCEPT
|
||||
# ipmasqadm mfw -A -m 100 -r <remoteaddress> 7078
|
||||
|
||||
Example, using ipchains (portfw):
|
||||
# portfw -a -P udp -L <localaddress> 7078 -R <remoteaddress> 7078
|
||||
** RTP data stream proxying is still experimental code.
|
||||
** As I had not yet the possibility to test this feature extensively,
|
||||
** I'm happy about any feedback.
|
||||
|
||||
|
||||
|
||||
Limitations:
|
||||
============
|
||||
- currently, only UDP is supported
|
||||
- very likely it does not follow the SIP spec in all details ;-)
|
||||
Scenario
|
||||
--------
|
||||
|
||||
private IP address range : Internet
|
||||
10.0.0.x : (publich IP address range)
|
||||
:
|
||||
: foo.bar.org
|
||||
+-------------+ +--------------+
|
||||
! !.10 .1 ! masquerading ! publicIP
|
||||
! IntHost !---------------! Firewall !------------>>
|
||||
! ! ! !
|
||||
+-------------+ +--------------+
|
||||
:
|
||||
|
||||
|
||||
|
||||
Important Notice:
|
||||
=================
|
||||
The gethostbyname() function leaks memory in RedHat 6.0 with glibc 2.1.1.
|
||||
The quick fix is to delete nisplus service from hosts entry in
|
||||
/etc/nsswitch.conf. In my tests, memory use remained stable after I
|
||||
made the mentioned change.
|
||||
- The Firewall does IP masquerading and is running siproxd
|
||||
|
||||
- IntHost is running an SIP softphone (like linphone, kphone)
|
||||
|
||||
- The SIP address used by the softphone is sip:johndoe@foo.bar.org
|
||||
|
||||
- The softphone is configured to register itself at siproxd
|
||||
running on the firewall host (10.0.0.1) as sip:johndoe@foo.bar.org
|
||||
|
||||
- foo.bar.org is the domain name corresponding to the public IP address
|
||||
of the firewall (eg use some dynamic DNS service [1])
|
||||
|
||||
Firewall rules for incomming traffic (ipchains example):
|
||||
$ ipchains -A input --proto udp --dport 5060 --log -j ACCEPT
|
||||
$ ipchains -A input --proto udp --dport 7070:7080 -j ACCEPT
|
||||
|
||||
The first line will allow incomming SIP traffic. The second line will
|
||||
allow incomming RTP traffic on the ports 7070 - 7080 (the default port
|
||||
range used by siproxd for incomming RTP traffic).
|
||||
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
[1] dynamic DNS service http://www.dyndns.org
|
||||
|
||||
|
||||
|
||||
LIMITATIONS
|
||||
===========
|
||||
- currently, the SIP part only supports UDP
|
||||
- RTP proxy support is still experimantal (so as the rest of siproxd ;-)
|
||||
- very likely it does not follow the SIP spec (RFC3261) in all details
|
||||
- check the TODO file for more things that we-cannot-do-but-would-like-to
|
||||
|
||||
|
||||
IMPORTANT NOTICE
|
||||
================
|
||||
The gethostbyname() function leaks memory in glibc 2.1.1 (-> RedHat 6.0).
|
||||
The quick fix is to delete the nisplus service from hosts entry in
|
||||
/etc/nsswitch.conf.
|
||||
In my tests, memory use remained stable after I made the mentioned change.
|
||||
|
||||
(source: http://www.squid-cache.org/Doc/FAQ/FAQ-14.html)
|
||||
|
||||
|
||||
Contacts:
|
||||
=========
|
||||
CONTACTS
|
||||
========
|
||||
Please feel free to contact the author to:
|
||||
- provide feedback
|
||||
- report bugs,
|
||||
- provide feedback, report bugs,
|
||||
- request for additional features
|
||||
- report interoperability with softphones
|
||||
- ...
|
||||
|
||||
and visit the website at http://siproxd.sourceforge.net/
|
||||
|
||||
There also is a siproxd mailinglist available on sourceforge.
|
||||
|
||||
Thomas Ries (tries@gmx.net)
|
||||
GnuPG Public Key:
|
||||
pub 1024D/87BCDC94 2000-03-19 Thomas Ries (tries@gmx.net)
|
||||
Key fingerprint = 13D1 19F5 77D0 4CEC 8D3F A24E 09FC C18A 87BC DC94
|
||||
|
||||
|
||||
|
||||
CREDITS
|
||||
=======
|
||||
|
||||
Thanks to sourceforge.net for providing the distribution platform and
|
||||
infrastructure.
|
||||
|
||||
|
||||
21
TODO
21
TODO
@ -1,20 +1,19 @@
|
||||
TODOs, in anarchistic order:
|
||||
============================
|
||||
|
||||
TODOs, in random order:
|
||||
=======================
|
||||
|
||||
- re-think the registration mechanism (mapping and decision criteria
|
||||
for in- and outgoing stuff...
|
||||
|
||||
- 2.2.x kernels:
|
||||
make use of the portfw.so (ipmasqadm package) to create forwarding
|
||||
tunnels for incomming data streams
|
||||
How to determine when finished? Is it possible to keep it stateless?
|
||||
|
||||
- Is there a possibility to open up an masquerading tunnel by
|
||||
a userspace program on the firewall?
|
||||
|
||||
- logging via syslog if running in daemon mode
|
||||
|
||||
- get_ip_by_host: reduce DNS timeouts
|
||||
|
||||
- Documentation
|
||||
|
||||
- automagically create a proper config file during install
|
||||
|
||||
- client authentication
|
||||
|
||||
- portability to other platforms / operating systems
|
||||
first goal: other Unixes
|
||||
|
||||
|
||||
39
config.h.in
39
config.h.in
@ -21,18 +21,57 @@
|
||||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define if you have the bind function. */
|
||||
#undef HAVE_BIND
|
||||
|
||||
/* Define if you have the fgets function. */
|
||||
#undef HAVE_FGETS
|
||||
|
||||
/* Define if you have the gethostbyname function. */
|
||||
#undef HAVE_GETHOSTBYNAME
|
||||
|
||||
/* Define if you have the getopt_long_only function. */
|
||||
#undef HAVE_GETOPT_LONG_ONLY
|
||||
|
||||
/* Define if you have the read function. */
|
||||
#undef HAVE_READ
|
||||
|
||||
/* Define if you have the select function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define if you have the send function. */
|
||||
#undef HAVE_SEND
|
||||
|
||||
/* Define if you have the sendto function. */
|
||||
#undef HAVE_SENDTO
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
#undef HAVE_SOCKET
|
||||
|
||||
/* Define if you have the sprintf function. */
|
||||
#undef HAVE_SPRINTF
|
||||
|
||||
/* Define if you have the sscanf function. */
|
||||
#undef HAVE_SSCANF
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the strncpy function. */
|
||||
#undef HAVE_STRNCPY
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
#undef HAVE_STRSTR
|
||||
|
||||
/* Define if you have the vfprintf function. */
|
||||
#undef HAVE_VFPRINTF
|
||||
|
||||
/* Define if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
/* Define if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
|
||||
21
configure.in
21
configure.in
@ -1,3 +1,13 @@
|
||||
dnl
|
||||
dnl History
|
||||
dnl -------
|
||||
dnl before time a lot happend before start of history
|
||||
dnl 8-Sep-2002 tries included more tests for used functions
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(src/siproxd.c)
|
||||
|
||||
@ -5,7 +15,7 @@ dnl ******************************************************************
|
||||
dnl
|
||||
SPD_MAJOR_VERSION=0
|
||||
SPD_MINOR_VERSION=1
|
||||
SPD_MICRO_VERSION=2
|
||||
SPD_MICRO_VERSION=3
|
||||
SPD_VERSION=$SPD_MAJOR_VERSION.$SPD_MINOR_VERSION.$SPD_MICRO_VERSION
|
||||
|
||||
dnl *********************************************************************
|
||||
@ -26,7 +36,7 @@ AC_CHECK_LIB(pthread, pthread_create)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(sys/time.h unistd.h)
|
||||
AC_CHECK_HEADERS(sys/time.h unistd.h errno.h)
|
||||
AC_CHECK_HEADERS(stdarg.h varargs.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
@ -38,7 +48,12 @@ AC_STRUCT_TM
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(select socket strerror strstr)
|
||||
AC_CHECK_FUNCS(strerror)
|
||||
AC_CHECK_FUNCS(gethostbyname)
|
||||
AC_CHECK_FUNCS(socket bind select read send sendto)
|
||||
AC_CHECK_FUNCS(getopt_long_only)
|
||||
AC_CHECK_FUNCS(strncpy strchr strstr sprintf vfprintf fgets sscanf)
|
||||
|
||||
|
||||
AC_OUTPUT(Makefile \
|
||||
src/Makefile \
|
||||
|
||||
@ -4,20 +4,6 @@
|
||||
# !! This is a sample file, adapt it to your needs before using it
|
||||
#
|
||||
|
||||
######################################################################
|
||||
# DBCLASS_BABBLE 0x00000001 // babble (like entering/leaving fnc)
|
||||
# DBCLASS_NET 0x00000002 // network
|
||||
# DBCLASS_SIP 0x00000004 // SIP manipulations
|
||||
# DBCLASS_REG 0x00000008 // Client registration
|
||||
# DBCLASS_NOSPEC 0x00000010 // non specified class
|
||||
# DBCLASS_PROXY 0x00000020 // proxy
|
||||
# DBCLASS_DNS 0x00000040 // DNS stuff
|
||||
# DBCLASS_NETTRAF 0x00000080 // network traffic
|
||||
# DBCLASS_CONFIG 0x00000100 // configuration
|
||||
# DBCLASS_RTP 0x00000200 // RTP proxy
|
||||
#
|
||||
debug_level = 0x000002fe
|
||||
|
||||
######################################################################
|
||||
# The IP addresses of the INBOUND and OUTBOUND interface can
|
||||
# be specified as hostnames or in dotted decimal form:
|
||||
@ -59,8 +45,22 @@ rtp_port_high = 7080
|
||||
|
||||
######################################################################
|
||||
# Timeout for RTP streams
|
||||
# after this number of seconds, at RTP stream is considered dead
|
||||
# after this number of seconds, an RTP stream is considered dead
|
||||
# and proxying it will be stopped.
|
||||
#
|
||||
rtp_timeout = 60
|
||||
|
||||
######################################################################
|
||||
# DBCLASS_BABBLE 0x00000001 // babble (like entering/leaving fnc)
|
||||
# DBCLASS_NET 0x00000002 // network
|
||||
# DBCLASS_SIP 0x00000004 // SIP manipulations
|
||||
# DBCLASS_REG 0x00000008 // Client registration
|
||||
# DBCLASS_NOSPEC 0x00000010 // non specified class
|
||||
# DBCLASS_PROXY 0x00000020 // proxy
|
||||
# DBCLASS_DNS 0x00000040 // DNS stuff
|
||||
# DBCLASS_NETTRAF 0x00000080 // network traffic
|
||||
# DBCLASS_CONFIG 0x00000100 // configuration
|
||||
# DBCLASS_RTP 0x00000200 // RTP proxy
|
||||
#
|
||||
debug_level = 0x00000218
|
||||
|
||||
|
||||
121
src/proxy.c
121
src/proxy.c
@ -41,10 +41,6 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
|
||||
/* configuration storage */
|
||||
extern struct siproxd_config configuration;
|
||||
|
||||
/*
|
||||
* knows hot to rewrite the SIP URLs in a request/response
|
||||
*/
|
||||
|
||||
extern int errno;
|
||||
extern struct urlmap_s urlmap[]; /* URL mapping table */
|
||||
extern struct lcl_if_s local_addresses;
|
||||
@ -60,7 +56,7 @@ int proxy_request (sip_t *request) {
|
||||
int sts;
|
||||
int type;
|
||||
struct in_addr addr;
|
||||
// contact_t *contact; /* contact header issue */
|
||||
contact_t *contact;
|
||||
url_t *url;
|
||||
int port;
|
||||
char *buffer;
|
||||
@ -77,25 +73,6 @@ int proxy_request (sip_t *request) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0 /* Contact Header Issue */
|
||||
/* figure out if this is an request comming from the outside
|
||||
* world to one of our registered clients ('to' == 'masq' URL)
|
||||
* or if this is a request sent by on e of our registered clients
|
||||
* ('from' == 'true' URL)
|
||||
*/
|
||||
msg_getcontact(request,0,&contact);
|
||||
|
||||
/* seen with linphone-0.9.1pre1 w/ user-agent: oSIP/Linphone-0.8.0
|
||||
no contact header in reequest */
|
||||
if (contact==NULL) {
|
||||
ERROR("Contact header is missing!");
|
||||
/* THIS IS SEVERE - I HAVE NO WAY TO FIGURE OUT WHO THE
|
||||
REAL CLIENT IS BEHIND THIS PACKET...
|
||||
what can I do here? */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
type = 0;
|
||||
for (i=0; i<URLMAP_SIZE; i++) {
|
||||
if (urlmap[i].active == 0) continue;
|
||||
@ -109,16 +86,6 @@ int proxy_request (sip_t *request) {
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0 /* Contact Header Issue */
|
||||
/* outgoing request ('contact' == 'true') */
|
||||
if (compare_url(contact->url, urlmap[i].true_url)==0) {
|
||||
type=REQTYP_OUTGOING;
|
||||
DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",
|
||||
request->from->url->username,
|
||||
request->from->url->host);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* outgoing request ('from' == 'masq') */
|
||||
if (compare_url(request->from->url, urlmap[i].masq_url)==0) {
|
||||
type=REQTYP_OUTGOING;
|
||||
@ -146,11 +113,23 @@ int proxy_request (sip_t *request) {
|
||||
url=msg_geturi(request);
|
||||
free(url->host);url->host=NULL;
|
||||
{
|
||||
char *copy;
|
||||
copy = (char *)malloc(strlen(urlmap[i].true_url->host)+1);
|
||||
memcpy(copy, urlmap[i].true_url->host, strlen(urlmap[i].true_url->host));
|
||||
copy[strlen(urlmap[i].true_url->host)]='\0';
|
||||
url_sethost(url, copy);
|
||||
char *host;
|
||||
char *port;
|
||||
/* set the true host */
|
||||
if(urlmap[i].true_url->host) {
|
||||
host = (char *)malloc(strlen(urlmap[i].true_url->host)+1);
|
||||
memcpy(host, urlmap[i].true_url->host, strlen(urlmap[i].true_url->host));
|
||||
host[strlen(urlmap[i].true_url->host)]='\0';
|
||||
url_sethost(url, host);
|
||||
}
|
||||
|
||||
/* set the true port */
|
||||
if(urlmap[i].true_url->port) {
|
||||
port = (char *)malloc(strlen(urlmap[i].true_url->port)+1);
|
||||
memcpy(port, urlmap[i].true_url->port, strlen(urlmap[i].true_url->port));
|
||||
port[strlen(urlmap[i].true_url->port)]='\0';
|
||||
url_setport(url, port);
|
||||
}
|
||||
}
|
||||
|
||||
/* add my Via header line (inbound interface)*/
|
||||
@ -159,7 +138,7 @@ int proxy_request (sip_t *request) {
|
||||
/* if this is CANCEL/BYE request, stop RTP proxying */
|
||||
if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
|
||||
/* stop the RTP proxying stream */
|
||||
sts = rtp_stop_fwd(msg_getcall_id(request));
|
||||
rtp_stop_fwd(msg_getcall_id(request));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -173,13 +152,36 @@ int proxy_request (sip_t *request) {
|
||||
sts = proxy_rewrite_invitation_body(request);
|
||||
}
|
||||
|
||||
/* rewrite Contact header to represent the masqued address */
|
||||
msg_getcontact(request,0,&contact);
|
||||
if (contact != NULL) {
|
||||
for (i=0;i<URLMAP_SIZE;i++){
|
||||
if (urlmap[i].active == 0) continue;
|
||||
if (compare_url(contact->url, urlmap[i].true_url)==0) break;
|
||||
}
|
||||
/* found a mapping entry */
|
||||
if (i<URLMAP_SIZE) {
|
||||
DEBUGC(DBCLASS_PROXY, "rewrote Contact header %s@%s -> %s@%s",
|
||||
contact->url->username, contact->url->host,
|
||||
urlmap[i].masq_url->username, urlmap[i].masq_url->host);
|
||||
/* remove old entry */
|
||||
list_remove(request->contacts,0);
|
||||
contact_free(contact);
|
||||
free(contact);
|
||||
/* clone the masquerading url */
|
||||
contact_init(&contact);
|
||||
url_clone(urlmap[i].masq_url, &contact->url);
|
||||
list_add(request->contacts,contact,-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* add my Via header line (outbound interface)*/
|
||||
sts = proxy_add_myvia(request, 0);
|
||||
|
||||
/* if this is CANCEL/BYE request, stop RTP proxying */
|
||||
if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
|
||||
/* stop the RTP proxying stream */
|
||||
sts = rtp_stop_fwd(msg_getcall_id(request));
|
||||
rtp_stop_fwd(msg_getcall_id(request));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -252,6 +254,7 @@ int proxy_response (sip_t *response) {
|
||||
int type;
|
||||
struct in_addr addr;
|
||||
via_t *via;
|
||||
contact_t *contact;
|
||||
int port;
|
||||
char *buffer;
|
||||
|
||||
@ -318,16 +321,6 @@ int proxy_response (sip_t *response) {
|
||||
* from an external host to the internal masqueraded host
|
||||
*/
|
||||
case RESTYP_INCOMMING:
|
||||
#if 0 /* do we really have to?? in the incomming response
|
||||
we have the correct address. But we must rewrite an
|
||||
outgoing response to an incomming INVITE request ! */
|
||||
/* If an 200 answer to an INVITE request, rewrite body */
|
||||
if ((MSG_IS_RESPONSEFOR(response,"INVITE") &&
|
||||
(MSG_TEST_CODE(response, 200)) ) {
|
||||
sts = proxy_rewrite_invitation_body(response);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -340,6 +333,30 @@ int proxy_response (sip_t *response) {
|
||||
(MSG_TEST_CODE(response, 200))) {
|
||||
sts = proxy_rewrite_invitation_body(response);
|
||||
}
|
||||
|
||||
/* rewrite Contact header to represent the masqued address */
|
||||
msg_getcontact(response,0,&contact);
|
||||
if (contact != NULL) {
|
||||
for (i=0;i<URLMAP_SIZE;i++){
|
||||
if (urlmap[i].active == 0) continue;
|
||||
if (compare_url(contact->url, urlmap[i].true_url)==0) break;
|
||||
}
|
||||
/* found a mapping entry */
|
||||
if (i<URLMAP_SIZE) {
|
||||
DEBUGC(DBCLASS_PROXY, "rewrote Contact header %s@%s -> %s@%s",
|
||||
contact->url->username, contact->url->host,
|
||||
urlmap[i].masq_url->username, urlmap[i].masq_url->host);
|
||||
/* remove old entry */
|
||||
list_remove(response->contacts,0);
|
||||
contact_free(contact);
|
||||
free(contact);
|
||||
/* clone the masquerading url */
|
||||
contact_init(&contact);
|
||||
url_clone(urlmap[i].masq_url, &contact->url);
|
||||
list_add(response->contacts,contact,-1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -529,7 +546,7 @@ int proxy_rewrite_invitation_body(sip_t *mymsg){
|
||||
sts = get_ip_by_host(configuration.outboundhost, &outb_addr);
|
||||
inb_clnt_port = atoi(sdp_m_port_get(sdp,0));
|
||||
/* start an RTP proxying stream */
|
||||
sts = rtp_start_fwd(msg_getcall_id(mymsg),
|
||||
rtp_start_fwd(msg_getcall_id(mymsg),
|
||||
outb_addr, &outb_rtp_port,
|
||||
lcl_clnt_addr, inb_clnt_port);
|
||||
|
||||
|
||||
@ -53,11 +53,11 @@ int main (int argc, char *argv[])
|
||||
extern char *optarg;
|
||||
int ch1;
|
||||
|
||||
char configfile[64]="siproxd";
|
||||
int config_search=1;
|
||||
char configfile[64]="siproxd"; /* basename of configfile */
|
||||
int config_search=1; /* search the config file */
|
||||
|
||||
/* prepare default configuration */
|
||||
configuration.debuglevel=-1;
|
||||
configuration.debuglevel=0;
|
||||
configuration.daemonize=0;
|
||||
configuration.sip_listen_port=SIP_PORT;
|
||||
configuration.inboundhost=NULL;
|
||||
@ -121,7 +121,12 @@ int main (int argc, char *argv[])
|
||||
register_init();
|
||||
|
||||
/* listen for incomming messages */
|
||||
sipsock_listen();
|
||||
sts=sipsock_listen();
|
||||
if (sts != 0) {
|
||||
/* failure to allocate SIP socket... */
|
||||
ERROR("unable to bind to SIP listening socket - aborting");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize the RTP proxy thread */
|
||||
rtpproxy_init();
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -43,8 +44,6 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
|
||||
/* configuration storage */
|
||||
extern struct siproxd_config configuration;
|
||||
|
||||
extern int errno;
|
||||
|
||||
static int listen_socket=0;
|
||||
|
||||
/*
|
||||
@ -57,6 +56,7 @@ int sipsock_listen (void) {
|
||||
|
||||
memset(&ipaddr, 0, sizeof(struct in_addr));
|
||||
listen_socket=sockbind(ipaddr, configuration.sip_listen_port);
|
||||
if (listen_socket==0) return 1; /* failure*/
|
||||
|
||||
DEBUGC(DBCLASS_NET,"bound listen socket %i",listen_socket);
|
||||
return 0;
|
||||
@ -121,9 +121,12 @@ int sipsock_send_udp(int *sock, struct in_addr addr, int port,
|
||||
sts = sendto (*sock, buffer, size, 0, &dst_addr, sizeof(dst_addr));
|
||||
|
||||
if (sts == -1) {
|
||||
if (errno != ECONNREFUSED) {
|
||||
ERROR("sendto() call failed:%s",strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
DEBUGC(DBCLASS_BABBLE,"sendto() call failed:%s",strerror(errno));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
12
src/utils.c
12
src/utils.c
@ -187,7 +187,7 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
if (dns_cache[i].hostname[0]=='\0') continue; /* empty */
|
||||
if (strcmp(hostname, dns_cache[i].hostname) == 0) { /* match */
|
||||
memcpy(addr, &dns_cache[i].addr, sizeof(struct in_addr));
|
||||
DEBUGC(DBCLASS_DNS, "from cache: %s -> %s",
|
||||
DEBUGC(DBCLASS_DNS, "DNS lookup - from cache: %s -> %s",
|
||||
hostname, inet_ntoa(*addr));
|
||||
return 0;
|
||||
}
|
||||
@ -202,7 +202,8 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
}
|
||||
|
||||
memcpy(addr, hostentry->h_addr, sizeof(struct in_addr));
|
||||
DEBUGC(DBCLASS_DNS, "resolved: %s -> %s", hostname, inet_ntoa(*addr));
|
||||
DEBUGC(DBCLASS_DNS, "DNS lookup - resolved: %s -> %s",
|
||||
hostname, inet_ntoa(*addr));
|
||||
|
||||
/*
|
||||
* remember the result in the cache
|
||||
@ -221,7 +222,7 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
if (i >= DNS_CACHE_SIZE) i=j;
|
||||
|
||||
/* store in cache */
|
||||
DEBUGC(DBCLASS_DNS, "store into DNS cache, entry %i)", i);
|
||||
DEBUGC(DBCLASS_DNS, "DNS lookup - store into cache, entry %i)", i);
|
||||
memset(&dns_cache[i], 0, sizeof(dns_cache[0]));
|
||||
strncpy(dns_cache[i].hostname, hostname, HOSTNAME_SIZE);
|
||||
time(&dns_cache[i].timestamp);
|
||||
@ -232,11 +233,14 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
|
||||
|
||||
/*
|
||||
* compares two URLs
|
||||
* returns 0 if equal, >0 if non equal, <0 if error
|
||||
* returns 0 if equal, <0 if non equal, >0 if error
|
||||
* (by now, only hostname and username are compared)
|
||||
*/
|
||||
int compare_url(url_t *url1, url_t *url2) {
|
||||
int sts;
|
||||
|
||||
if ((url1 == NULL) || (url2 == NULL)) return 1;
|
||||
|
||||
/* comparison of hosts should be based on IP addresses, no? */
|
||||
DEBUGC(DBCLASS_BABBLE, "comparng urls: %s@%s -> %s@%s",
|
||||
url1->username, url1->host, url2->username, url2->host);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user