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:
Thomas Ries 2002-09-11 17:12:30 +00:00
parent 038f5ef904
commit c3e10ec745
13 changed files with 296 additions and 153 deletions

View File

@ -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 0.1.2
===== =====
- 7-Sep-2002: - Releases version 0.1.2 - 7-Sep-2002: - Releases version 0.1.2

View File

@ -21,4 +21,4 @@
SUBDIRS = src doc SUBDIRS = src doc
EXTRA_DIST = TODO RELNOTES EXTRA_DIST = scripts TODO RELNOTES

View File

@ -87,7 +87,7 @@ VERSION = @VERSION@
SUBDIRS = src doc SUBDIRS = src doc
EXTRA_DIST = TODO RELNOTES EXTRA_DIST = scripts TODO RELNOTES
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = config.h CONFIG_HEADER = config.h

155
README
View File

@ -4,8 +4,8 @@ Be warned, this (and all the other) documentantation is far from
complete. This is still considered an alpha release. complete. This is still considered an alpha release.
Overview: OVERVIEW
========= ========
Siprox is an proxy/masquerading daemon for the SIP protocol. Siprox is an proxy/masquerading daemon for the SIP protocol.
It handles registrations of SIP clients on a private IP network It handles registrations of SIP clients on a private IP network
and performs rewriting of the SIP message bodies to make SIP 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/) - 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). However, it should build and run under newer versions (feedback is welcome).
How to get started: HOW TO GET STARTED
=================== ==================
- ./configure - ./configure
@ -38,82 +39,124 @@ How to get started:
- make install - 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 - edit /etc/siproxd.conf according to your situation
At least 'host_inbound' and 'host_outbound' have to be adapted! At least 'host_inbound' and 'host_outbound' *must* be adapted!
host_inbound is your IP address of your private network, 'host_inbound' is the firewalls IP address of your private network,
host_outbound is your publich IP address or hostname (if you 'host_outbound' is the publich IP address or hostname of the
have dynamic IP addresses, then you might want to use a hostname firewall. (If you have dynamic IP addresses, then you might want
here and use a dynamic DNS service like dyndns.org) 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 Siproxd's purpose is to act as an SIP proxy for softphones located
to be able to operate via an masquerading firewall. in private IP ranges. Therefore it will rewrite SIP messages to allow a
Since release 0.1.2 siproxd can proxy incomming RTP streams. 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.
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
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
the port range that siproxd will use for incomming RTP data streams. the port range that siproxd will use for incomming RTP data streams.
'rtp_timeout' defines after what time an unused (no data received) 'rtp_timeout' defines after what time an unused (no data received)
rtp stream is considered dead and removed. rtp stream is considered dead and removed.
** As I had not yet the possibility to test this feature, ** RTP data stream proxying is still experimental code.
** I'd be glad about feedback. ** As I had not yet the possibility to test this feature extensively,
** I'm happy about any 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
Limitations: Scenario
============ --------
- currently, only UDP is supported
- very likely it does not follow the SIP spec in all details ;-) 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 Firewall does IP masquerading and is running siproxd
=================
The gethostbyname() function leaks memory in RedHat 6.0 with glibc 2.1.1. - IntHost is running an SIP softphone (like linphone, kphone)
The quick fix is to delete nisplus service from hosts entry in
/etc/nsswitch.conf. In my tests, memory use remained stable after I - The SIP address used by the softphone is sip:johndoe@foo.bar.org
made the mentioned change.
- 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) (source: http://www.squid-cache.org/Doc/FAQ/FAQ-14.html)
Contacts: CONTACTS
========= ========
Please feel free to contact the author to: Please feel free to contact the author to:
- provide feedback - provide feedback, report bugs,
- report bugs,
- request for additional features - request for additional features
- report interoperability with softphones - report interoperability with softphones
- ... - ...
and visit the website at http://siproxd.sourceforge.net/ and visit the website at http://siproxd.sourceforge.net/
There also is a siproxd mailinglist available on sourceforge.
Thomas Ries (tries@gmx.net) Thomas Ries (tries@gmx.net)
GnuPG Public Key: GnuPG Public Key:
pub 1024D/87BCDC94 2000-03-19 Thomas Ries (tries@gmx.net) pub 1024D/87BCDC94 2000-03-19 Thomas Ries (tries@gmx.net)
Key fingerprint = 13D1 19F5 77D0 4CEC 8D3F A24E 09FC C18A 87BC DC94 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
View File

@ -1,20 +1,19 @@
TODOs, in anarchistic order: TODOs, in random order:
============================ =======================
- re-think the registration mechanism (mapping and decision criteria - re-think the registration mechanism (mapping and decision criteria
for in- and outgoing stuff... 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 - logging via syslog if running in daemon mode
- get_ip_by_host: reduce DNS timeouts - 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

View File

@ -21,18 +21,57 @@
/* Define if your <sys/time.h> declares struct tm. */ /* Define if your <sys/time.h> declares struct tm. */
#undef TM_IN_SYS_TIME #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. */ /* Define if you have the select function. */
#undef HAVE_SELECT #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. */ /* Define if you have the socket function. */
#undef HAVE_SOCKET #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. */ /* Define if you have the strerror function. */
#undef HAVE_STRERROR #undef HAVE_STRERROR
/* Define if you have the strncpy function. */
#undef HAVE_STRNCPY
/* Define if you have the strstr function. */ /* Define if you have the strstr function. */
#undef HAVE_STRSTR #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. */ /* Define if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H #undef HAVE_STDARG_H

View File

@ -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. dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/siproxd.c) AC_INIT(src/siproxd.c)
@ -5,7 +15,7 @@ dnl ******************************************************************
dnl dnl
SPD_MAJOR_VERSION=0 SPD_MAJOR_VERSION=0
SPD_MINOR_VERSION=1 SPD_MINOR_VERSION=1
SPD_MICRO_VERSION=2 SPD_MICRO_VERSION=3
SPD_VERSION=$SPD_MAJOR_VERSION.$SPD_MINOR_VERSION.$SPD_MICRO_VERSION SPD_VERSION=$SPD_MAJOR_VERSION.$SPD_MINOR_VERSION.$SPD_MICRO_VERSION
dnl ********************************************************************* dnl *********************************************************************
@ -26,7 +36,7 @@ AC_CHECK_LIB(pthread, pthread_create)
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC 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) AC_CHECK_HEADERS(stdarg.h varargs.h)
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
@ -38,7 +48,12 @@ AC_STRUCT_TM
dnl Checks for library functions. dnl Checks for library functions.
AC_FUNC_MEMCMP AC_FUNC_MEMCMP
AC_FUNC_VPRINTF 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 \ AC_OUTPUT(Makefile \
src/Makefile \ src/Makefile \

View File

@ -4,20 +4,6 @@
# !! This is a sample file, adapt it to your needs before using it # !! 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 # The IP addresses of the INBOUND and OUTBOUND interface can
# be specified as hostnames or in dotted decimal form: # be specified as hostnames or in dotted decimal form:
@ -59,8 +45,22 @@ rtp_port_high = 7080
###################################################################### ######################################################################
# Timeout for RTP streams # 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. # and proxying it will be stopped.
# #
rtp_timeout = 60 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

View File

@ -41,10 +41,6 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
/* configuration storage */ /* configuration storage */
extern struct siproxd_config configuration; extern struct siproxd_config configuration;
/*
* knows hot to rewrite the SIP URLs in a request/response
*/
extern int errno; extern int errno;
extern struct urlmap_s urlmap[]; /* URL mapping table */ extern struct urlmap_s urlmap[]; /* URL mapping table */
extern struct lcl_if_s local_addresses; extern struct lcl_if_s local_addresses;
@ -60,7 +56,7 @@ int proxy_request (sip_t *request) {
int sts; int sts;
int type; int type;
struct in_addr addr; struct in_addr addr;
// contact_t *contact; /* contact header issue */ contact_t *contact;
url_t *url; url_t *url;
int port; int port;
char *buffer; char *buffer;
@ -77,25 +73,6 @@ int proxy_request (sip_t *request) {
return 1; 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; type = 0;
for (i=0; i<URLMAP_SIZE; i++) { for (i=0; i<URLMAP_SIZE; i++) {
if (urlmap[i].active == 0) continue; if (urlmap[i].active == 0) continue;
@ -109,16 +86,6 @@ int proxy_request (sip_t *request) {
break; 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') */ /* outgoing request ('from' == 'masq') */
if (compare_url(request->from->url, urlmap[i].masq_url)==0) { if (compare_url(request->from->url, urlmap[i].masq_url)==0) {
type=REQTYP_OUTGOING; type=REQTYP_OUTGOING;
@ -146,11 +113,23 @@ int proxy_request (sip_t *request) {
url=msg_geturi(request); url=msg_geturi(request);
free(url->host);url->host=NULL; free(url->host);url->host=NULL;
{ {
char *copy; char *host;
copy = (char *)malloc(strlen(urlmap[i].true_url->host)+1); char *port;
memcpy(copy, urlmap[i].true_url->host, strlen(urlmap[i].true_url->host)); /* set the true host */
copy[strlen(urlmap[i].true_url->host)]='\0'; if(urlmap[i].true_url->host) {
url_sethost(url, copy); 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)*/ /* 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 this is CANCEL/BYE request, stop RTP proxying */
if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) { if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
/* stop the RTP proxying stream */ /* stop the RTP proxying stream */
sts = rtp_stop_fwd(msg_getcall_id(request)); rtp_stop_fwd(msg_getcall_id(request));
} }
break; break;
@ -173,13 +152,36 @@ int proxy_request (sip_t *request) {
sts = proxy_rewrite_invitation_body(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)*/ /* add my Via header line (outbound interface)*/
sts = proxy_add_myvia(request, 0); sts = proxy_add_myvia(request, 0);
/* if this is CANCEL/BYE request, stop RTP proxying */ /* if this is CANCEL/BYE request, stop RTP proxying */
if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) { if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {
/* stop the RTP proxying stream */ /* stop the RTP proxying stream */
sts = rtp_stop_fwd(msg_getcall_id(request)); rtp_stop_fwd(msg_getcall_id(request));
} }
break; break;
@ -252,6 +254,7 @@ int proxy_response (sip_t *response) {
int type; int type;
struct in_addr addr; struct in_addr addr;
via_t *via; via_t *via;
contact_t *contact;
int port; int port;
char *buffer; char *buffer;
@ -318,16 +321,6 @@ int proxy_response (sip_t *response) {
* from an external host to the internal masqueraded host * from an external host to the internal masqueraded host
*/ */
case RESTYP_INCOMMING: 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; break;
/* /*
@ -340,6 +333,30 @@ int proxy_response (sip_t *response) {
(MSG_TEST_CODE(response, 200))) { (MSG_TEST_CODE(response, 200))) {
sts = proxy_rewrite_invitation_body(response); 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; break;
default: default:
@ -529,7 +546,7 @@ int proxy_rewrite_invitation_body(sip_t *mymsg){
sts = get_ip_by_host(configuration.outboundhost, &outb_addr); sts = get_ip_by_host(configuration.outboundhost, &outb_addr);
inb_clnt_port = atoi(sdp_m_port_get(sdp,0)); inb_clnt_port = atoi(sdp_m_port_get(sdp,0));
/* start an RTP proxying stream */ /* 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, outb_addr, &outb_rtp_port,
lcl_clnt_addr, inb_clnt_port); lcl_clnt_addr, inb_clnt_port);

View File

@ -53,11 +53,11 @@ int main (int argc, char *argv[])
extern char *optarg; extern char *optarg;
int ch1; int ch1;
char configfile[64]="siproxd"; char configfile[64]="siproxd"; /* basename of configfile */
int config_search=1; int config_search=1; /* search the config file */
/* prepare default configuration */ /* prepare default configuration */
configuration.debuglevel=-1; configuration.debuglevel=0;
configuration.daemonize=0; configuration.daemonize=0;
configuration.sip_listen_port=SIP_PORT; configuration.sip_listen_port=SIP_PORT;
configuration.inboundhost=NULL; configuration.inboundhost=NULL;
@ -121,7 +121,12 @@ int main (int argc, char *argv[])
register_init(); register_init();
/* listen for incomming messages */ /* 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 */ /* initialize the RTP proxy thread */
rtpproxy_init(); rtpproxy_init();

View File

@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -43,8 +44,6 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
/* configuration storage */ /* configuration storage */
extern struct siproxd_config configuration; extern struct siproxd_config configuration;
extern int errno;
static int listen_socket=0; static int listen_socket=0;
/* /*
@ -57,6 +56,7 @@ int sipsock_listen (void) {
memset(&ipaddr, 0, sizeof(struct in_addr)); memset(&ipaddr, 0, sizeof(struct in_addr));
listen_socket=sockbind(ipaddr, configuration.sip_listen_port); listen_socket=sockbind(ipaddr, configuration.sip_listen_port);
if (listen_socket==0) return 1; /* failure*/
DEBUGC(DBCLASS_NET,"bound listen socket %i",listen_socket); DEBUGC(DBCLASS_NET,"bound listen socket %i",listen_socket);
return 0; 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)); sts = sendto (*sock, buffer, size, 0, &dst_addr, sizeof(dst_addr));
if (sts == -1) { if (sts == -1) {
if (errno != ECONNREFUSED) {
ERROR("sendto() call failed:%s",strerror(errno)); ERROR("sendto() call failed:%s",strerror(errno));
return 1; return 1;
} }
DEBUGC(DBCLASS_BABBLE,"sendto() call failed:%s",strerror(errno));
}
return 0; return 0;
} }

View File

@ -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 (dns_cache[i].hostname[0]=='\0') continue; /* empty */
if (strcmp(hostname, dns_cache[i].hostname) == 0) { /* match */ if (strcmp(hostname, dns_cache[i].hostname) == 0) { /* match */
memcpy(addr, &dns_cache[i].addr, sizeof(struct in_addr)); 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)); hostname, inet_ntoa(*addr));
return 0; 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)); 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 * 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; if (i >= DNS_CACHE_SIZE) i=j;
/* store in cache */ /* 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])); memset(&dns_cache[i], 0, sizeof(dns_cache[0]));
strncpy(dns_cache[i].hostname, hostname, HOSTNAME_SIZE); strncpy(dns_cache[i].hostname, hostname, HOSTNAME_SIZE);
time(&dns_cache[i].timestamp); time(&dns_cache[i].timestamp);
@ -232,11 +233,14 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
/* /*
* compares two URLs * 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) * (by now, only hostname and username are compared)
*/ */
int compare_url(url_t *url1, url_t *url2) { int compare_url(url_t *url1, url_t *url2) {
int sts; int sts;
if ((url1 == NULL) || (url2 == NULL)) return 1;
/* comparison of hosts should be based on IP addresses, no? */ /* comparison of hosts should be based on IP addresses, no? */
DEBUGC(DBCLASS_BABBLE, "comparng urls: %s@%s -> %s@%s", DEBUGC(DBCLASS_BABBLE, "comparng urls: %s@%s -> %s@%s",
url1->username, url1->host, url2->username, url2->host); url1->username, url1->host, url2->username, url2->host);