Release 0.1.2

includes experimantal RTP data stream proxy
This commit is contained in:
Thomas Ries
2002-09-07 20:17:19 +00:00
parent bbfdfe25fe
commit 82fa326895
17 changed files with 351 additions and 2306 deletions
+9 -1
View File
@@ -1,9 +1,17 @@
0.1.2
=====
- 7-Sep-2002: Releases version 0.1.2
Experimental RTP proxying feature (using pthreads)
- 26-Aug-2002: Optimized DNS caching
0.1.1
=====
- 25-Aug-2002: Released version 0.1.1
can daemonize (detach and run in background)
do some DNS caching
- 24-Aug-2002: Imlemented support for a config file,
obsoletes siproxd_conf.h
0.1.0
=====
- 19-Aug-2002: Released version 0.1.0
- 19-Aug-2002: Released version 0.1.0
+38 -17
View File
@@ -1,8 +1,7 @@
Be warned, this (and all the other) documentantation is far from
complete. This is just a *very* preliminary pre-alpha release. Don't
expect anything!
complete. This is still considered an alpha release.
Overview:
@@ -26,7 +25,7 @@ Requirements:
- libosip-0.8.8 (http://www.fsf.org/software/osip/)
Up to now, this packages only has been tested under an i386 Redhat Linux 6.0.
However, it should build and run under newer versions.
However, it should build and run under newer versions (feedback is welcome).
@@ -49,25 +48,41 @@ How to get started:
here and use a dynamic DNS service like dyndns.org)
What siproxd does:
=================
Siproxd's main purpose (up to now) is to rewrite SIP messages.
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.
What siproxd does NOT do:
=========================
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.
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.
'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.
Example, using ipchains (mfw):
# ipchains -A input --proto udp --dport 7078 -m 100 -j ACCEPT
# ipmasqadm mfw -A -m 100 -r <remoteaddress> 7078
PRIOR TO RELEASE 0.1.2:
Siproxd does *not* (yet) create masquerading tunnels or port-forwarding
for the data stream through the firewall.
Example, using ipchains (portfw):
# portfw -a -P udp -L <localaddress> 7078 -R <remoteaddress> 7078
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
@@ -80,17 +95,23 @@ Limitations:
Important Notice:
=================
gethostbyname() leaks memory in RedHat 6.0 with glibc 2.1.1.
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 above change.
(->http://www.squid-cache.org/Doc/FAQ/FAQ-14.html)
/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:
=========
Please feel free to contact the author to:
- provide feedback
- report bugs,
- request for additional features
- report interoperability with softphones
- ...
and visit the website at http://siproxd.sourceforge.net/
Thomas Ries (tries@gmx.net)
GnuPG Public Key:
+3
View File
@@ -13,3 +13,6 @@ TODOs, in anarchistic order:
- logging via syslog if running in daemon mode
- get_ip_by_host: reduce DNS timeouts
- forwarding(proxying) of incomming RTP media streams
? own thread/process (is pending)
+3
View File
@@ -48,6 +48,9 @@
/* Define if you have the osip library (-losip). */
#undef HAVE_LIBOSIP
/* Define if you have the pthread library (-lpthread). */
#undef HAVE_LIBPTHREAD
/* Name of package */
#undef PACKAGE
Vendored
-2192
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -5,7 +5,7 @@ dnl ******************************************************************
dnl
SPD_MAJOR_VERSION=0
SPD_MINOR_VERSION=1
SPD_MICRO_VERSION=1
SPD_MICRO_VERSION=2
SPD_VERSION=$SPD_MAJOR_VERSION.$SPD_MINOR_VERSION.$SPD_MICRO_VERSION
dnl *********************************************************************
@@ -22,6 +22,7 @@ AC_PROG_LN_S
dnl Checks for libraries.
AC_CHECK_LIB(osip, parser_init)
AC_CHECK_LIB(pthread, pthread_create)
dnl Checks for header files.
AC_HEADER_STDC
+27 -5
View File
@@ -14,7 +14,9 @@
# DBCLASS_DNS 0x00000040 // DNS stuff
# DBCLASS_NETTRAF 0x00000080 // network traffic
# DBCLASS_CONFIG 0x00000100 // configuration
debug_level = 0x0ffffffe
# DBCLASS_RTP 0x00000200 // RTP proxy
#
debug_level = 0x000002fe
######################################################################
# The IP addresses of the INBOUND and OUTBOUND interface can
@@ -25,8 +27,8 @@ debug_level = 0x0ffffffe
# or as dotted decimal IP:
#
# host_inbound=10.0.0.1
host_inbound = 192.168.1.8
#
host_inbound = 192.168.1.1
host_outbound = ries.homeip.net
@@ -34,11 +36,31 @@ host_outbound = ries.homeip.net
# Port to listen for incomming SIP messages.
# 5060 is usually the correct choise - don't change is unless you
# know what you're doing
sip_port = 5060
#
sip_listen_port = 5060
######################################################################
# Shall we daemonize?
#
daemonize = 0
######################################################################
# global switch to enable (1) or disable (0) the RTP proxy feature
#
rtp_proxy_enable = 1
######################################################################
# Port range where to allocate listen ports for incomming RTP traffic
# this should be a range that is not blocked by the firewall
#
rtp_port_low = 7070
rtp_port_high = 7080
######################################################################
# Timeout for RTP streams
# after this number of seconds, at RTP stream is considered dead
# and proxying it will be stopped.
#
rtp_timeout = 60
+2 -2
View File
@@ -19,11 +19,11 @@
#
CFLAGS =@CFLAGS@ -Wall -DBUILDSTR=\"`cat .buildno`\"
CFLAGS =@CFLAGS@ -Wall -DBUILDSTR=\"`cat .buildno`\" -D_GNU_SOURCE
bin_PROGRAMS = siproxd
siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c \
log.c readconf.c
log.c readconf.c rtpproxy.c
noinst_HEADERS = log.h siproxd.h
+4 -4
View File
@@ -85,10 +85,10 @@ MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
VERSION = @VERSION@
CFLAGS = @CFLAGS@ -Wall -DBUILDSTR=\"`cat .buildno`\"
CFLAGS = @CFLAGS@ -Wall -DBUILDSTR=\"`cat .buildno`\" -D_GNU_SOURCE
bin_PROGRAMS = siproxd
siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c log.c readconf.c
siproxd_SOURCES = siproxd.c proxy.c register.c sock.c utils.c log.c readconf.c rtpproxy.c
noinst_HEADERS = log.h siproxd.h
@@ -105,7 +105,7 @@ CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
siproxd_OBJECTS = siproxd.o proxy.o register.o sock.o utils.o log.o \
readconf.o
readconf.o rtpproxy.o
siproxd_LDADD = $(LDADD)
siproxd_DEPENDENCIES =
siproxd_LDFLAGS =
@@ -122,7 +122,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
GZIP_ENV = --best
DEP_FILES = .deps/log.P .deps/proxy.P .deps/readconf.P .deps/register.P \
.deps/siproxd.P .deps/sock.P .deps/utils.P
.deps/rtpproxy.P .deps/siproxd.P .deps/sock.P .deps/utils.P
SOURCES = $(siproxd_SOURCES)
OBJECTS = $(siproxd_OBJECTS)
+1
View File
@@ -29,6 +29,7 @@
#define DBCLASS_DNS 0x00000040 // DNS stuff
#define DBCLASS_NETTRAF 0x00000080 // network traffic
#define DBCLASS_CONFIG 0x00000100 // configuration
#define DBCLASS_RTP 0x00000200 // RTP proxy
#define DEBUG(F...) log_debug(1,__FILE__, __LINE__,F)
+168 -48
View File
@@ -29,6 +29,7 @@
#include <netdb.h>
#include <osip/smsg.h>
#include <osip/sdp.h>
#include "siproxd.h"
#include "log.h"
@@ -45,9 +46,15 @@ extern struct siproxd_config configuration;
*/
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 int sip_socket; /* sending SIP datagrams */
/*
* PROXY_REQUEST
*
*/
int proxy_request (sip_t *request) {
int i;
int sts;
@@ -125,6 +132,13 @@ int proxy_request (sip_t *request) {
/* add my Via header line (inbound interface)*/
sts = proxy_add_myvia(request, 1);
/* 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));
}
break;
/*
@@ -138,6 +152,13 @@ int proxy_request (sip_t *request) {
/* 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));
}
break;
default:
@@ -192,12 +213,16 @@ int proxy_request (sip_t *request) {
port=configuration.sip_listen_port;
}
sipsock_send_udp(addr, port, buffer, strlen(buffer));
sipsock_send_udp(&sip_socket, addr, port, buffer, strlen(buffer), 1);
free (buffer);
return 0;
}
/*
* PROXY_RESPONSE
*
*/
int proxy_response (sip_t *response) {
int i;
int sts;
@@ -271,7 +296,7 @@ int proxy_response (sip_t *response) {
*/
case RESTYP_INCOMMING:
#if 0 /* do we really have to?? in the incomming response
we have the correct address. But we mus rewrite an
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") &&
@@ -319,18 +344,15 @@ int proxy_response (sip_t *response) {
port=configuration.sip_listen_port;
}
sipsock_send_udp(addr, port, buffer, strlen(buffer));
sipsock_send_udp(&sip_socket, addr, port, buffer, strlen(buffer), 1);
free (buffer);
return 0;
}
/*
* PROXY_GEN_RESPONSE
*
* send an proxy generated response back to the client.
* Only errors are reported from the proxy itself.
* code = SIP result code to deliver
@@ -373,7 +395,8 @@ DEBUGC(DBCLASS_PROXY,"response=%p",response);
}
/* send to destination */
sipsock_send_udp(addr, atoi(via->port), buffer, strlen(buffer));
sipsock_send_udp(&sip_socket, addr, atoi(via->port),
buffer, strlen(buffer), 1);
/* free the resources */
msg_free(response);
@@ -384,10 +407,11 @@ DEBUGC(DBCLASS_PROXY,"response=%p",response);
/*
* routine to rewrite the header and message bodies
* PROXY_ADD_MYVIA
*
*
* interface == 0 -> outbound interface, else inbound interface
*/
/* interface == 0 -> outbound interface, else inbound interface */
int proxy_add_myvia (sip_t *request, int interface) {
struct in_addr addr;
char tmp[URL_STRING_SIZE];
@@ -414,7 +438,10 @@ int proxy_add_myvia (sip_t *request, int interface) {
}
/*
* PROXY_DEL_MYVIA
*
*/
int proxy_del_myvia (sip_t *response) {
via_t *via;
int sts;
@@ -434,14 +461,19 @@ int proxy_del_myvia (sip_t *response) {
}
/*
* PROXY_REWRITE_INVITATION_BODY
*
*/
int proxy_rewrite_invitation_body(sip_t *mymsg){
body_t *body;
struct in_addr addr;
sdp_t *sdp;
struct in_addr outb_addr, lcl_clnt_addr;
int sts;
char *oldbody;
char newbody[BODY_MESSAGE_MAX_SIZE];
char clen[8]; /* probably never more than 7 digits for content length !*/
char clen[8]; /* content length: probably never more than 7 digits !*/
int outb_rtp_port, inb_clnt_port;
sts = msg_getbody(mymsg, 0, &body);
if (sts != 0) {
@@ -451,7 +483,14 @@ int proxy_rewrite_invitation_body(sip_t *mymsg){
sts = body_2char(body, &oldbody);
{
sts = sdp_init(&sdp);
sts = sdp_parse (sdp, oldbody);
if (sts != 0) {
ERROR("rewrite_invitation_body: unable to sdp_parse body");
return 1;
}
{ /* just dump the buffer */
char *tmp2;
content_length_2char(mymsg->contentlength, &tmp2);
DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----",
@@ -460,60 +499,141 @@ int proxy_rewrite_invitation_body(sip_t *mymsg){
}
/* TODO */
/* - change the 'c=' line to present the outbound address (the other
side will send its audio data there
- 'm=' line: here we should change the port number to a free local
(outbound) port and set up an port forwarding to the hidden
inbound client ...*/
/*
* RTP proxy: get ready and start forwarding
*/
sts = get_ip_by_host(sdp_c_addr_get(sdp,-1,0), &lcl_clnt_addr);
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),
outb_addr, &outb_rtp_port,
lcl_clnt_addr, inb_clnt_port);
/*
* yup, I know - here are some HARDCODED strings that we
* search for in the connect information and media description
* in the SDP part of the INVITE packet
*
* TODO: redo the rewriting section below,
* using the nice sdp_ routines of libosip!
*
* Up to now, also only ONE incomming media port per session
* is supported! I guess, there may be more allowed.
*/
{
char *data=NULL;
char *data2=NULL;
char *data_c=NULL; /* connection information 'c=' line*/
char *data_m=NULL; /* media description 'm=' line*/
char *data2_c=NULL; /* end of IP address on 'c=' line */
char *data2_m=NULL; /* end of port number on 'm=' line */
char *ptr=NULL;
memset(newbody, 0, sizeof(newbody));
data = strstr (oldbody, "\nc=");
if (data == NULL) data = strstr (oldbody, "\rc=");
if (data == NULL) {
/*
* find where to patch connection information (IP address)
*/
data_c = strstr (oldbody, "\nc=");
if (data_c == NULL) data_c = strstr (oldbody, "\rc=");
if (data_c == NULL) {
ERROR("did not find a c= line in the body");
return 1;
}
data += 3;
data_c += 3;
/* can only rewrite IPV4 addresses by now */
if (strncmp(data,"IN IP4 ",7)!=0) {
if (strncmp(data_c,"IN IP4 ",7)!=0) {
ERROR("c= does not contain an IN IP4 address");
return 1;
}
data += 7;
data2 = strstr (data, "\n");
if (data2 == NULL) data2 = strstr (oldbody, "\r");
if (data2 == NULL) {
data_c += 7; /* PTR to start of IP address */
/* find the end of the IP address -> end of line */
data2_c = strstr (data_c, "\n");
if (data2_c == NULL) data2_c = strstr (oldbody, "\r");
if (data2_c == NULL) {
ERROR("did not find a CR/LF after c= line");
return 1;
}
/* copy up to the to-be-masqueraded address */
memcpy(newbody, oldbody, data-oldbody);
/*
* find where to patch media description (port number)
*/
data_m = strstr (oldbody, "\nm=");
if (data_m == NULL) data_m = strstr (oldbody, "\rm=");
if (data_m == NULL) {
ERROR("did not find a m= line in the body");
return 1;
}
data_m += 3;
/* check for audio media */
if (strncmp(data_m,"audio ",6)!=0) {
ERROR("m= does not contain audio");
return 1;
}
data_m += 6; /* PTR to start of port number */
/* find the end of the IP address -> end of line */
data2_m = strstr (data_m, " RTP/");
if (data2_m == NULL) {
ERROR("did not find RTP/ on m= line");
return 1;
}
/*
* what is first? c= or m= ?
* (Im sure this can be made nicer)
*/
if (data_c < data_m) {
DEBUGC(DBCLASS_PROXY,"c= before m=");
/*
* c= line first, replace IP address, then port
*/
/* copy up to the to-be-masqueraded address */
memcpy(newbody, oldbody, data_c-oldbody);
/* insert proxy outbound address */
ptr=newbody+(data_c-oldbody);
sprintf(ptr, "%s", inet_ntoa(outb_addr));
ptr += strlen(ptr);
/* copy up to the m= line */
memcpy (ptr, data2_c, data_m-data2_c);
ptr += strlen(ptr);
/* substitute port number */
sprintf(ptr, "%i", outb_rtp_port);
ptr += strlen(ptr);
/* copy the rest */
memcpy (ptr, data2_m, strlen(data2_m));
} else {
DEBUGC(DBCLASS_PROXY,"m= before c=");
/*
* m= line first, replace port, then IP address
*/
/* copy up to the to-be-masqueraded port */
memcpy(newbody, oldbody, data_m-oldbody);
ptr=newbody+(data_m-oldbody);
/* substitute port number */
sprintf(ptr, "%i", outb_rtp_port);
ptr += strlen(ptr);
/* copy up to the c= line */
memcpy (ptr, data2_m, data_c-data2_m);
ptr += strlen(ptr);
/* insert proxy outbound address */
sprintf(ptr, "%s", inet_ntoa(outb_addr));
ptr += strlen(ptr);
/* copy the rest */
memcpy (ptr, data2_c, strlen(data2_c));
}
/* insert proxy outbound address */
sts = get_ip_by_host(configuration.outboundhost, &addr);
ptr=newbody+(data-oldbody);
sprintf(ptr, "%s", inet_ntoa(addr));
ptr += strlen(ptr);
/* copy rest */
memcpy (ptr, data2, strlen(data2));
}
/* remove old body */
sts = list_remove(mymsg->bodies, 0);
body_free(body);
free(body);
/* free sdp structure */
sdp_free(sdp);
free(sdp);
/* include new body */
msg_setbody(mymsg, newbody);
@@ -526,7 +646,7 @@ int proxy_rewrite_invitation_body(sip_t *mymsg){
sts = msg_setcontent_length(mymsg, clen);
{
{ /* just dump the buffer */
char *tmp, *tmp2;
sts = msg_getbody(mymsg, 0, &body);
sts = body_2char(body, &tmp);
+10 -5
View File
@@ -19,6 +19,7 @@
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -111,11 +112,15 @@ static int parse_config (FILE *configfile) {
enum type {TYP_INT4, TYP_STRING, TYP_FLOAT} type;
void *dest;
} configoptions[] = {
{ "debug_level", TYP_INT4, &configuration.debuglevel },
{ "sip_port", TYP_INT4, &configuration.sip_listen_port },
{ "daemonize", TYP_INT4, &configuration.daemonize },
{ "host_inbound", TYP_STRING, &configuration.inboundhost },
{ "host_outbound", TYP_STRING, &configuration.outboundhost },
{ "debug_level", TYP_INT4, &configuration.debuglevel },
{ "sip_listen_port", TYP_INT4, &configuration.sip_listen_port },
{ "daemonize", TYP_INT4, &configuration.daemonize },
{ "host_inbound", TYP_STRING, &configuration.inboundhost },
{ "host_outbound", TYP_STRING, &configuration.outboundhost },
{ "rtp_port_low", TYP_INT4, &configuration.rtp_port_low },
{ "rtp_port_high", TYP_INT4, &configuration.rtp_port_high },
{ "rtp_timeout", TYP_INT4, &configuration.rtp_timeout },
{ "rtp_proxy_enable", TYP_INT4, &configuration.rtp_proxy_enable },
{0, 0, 0}
};
+3 -2
View File
@@ -39,7 +39,8 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
extern struct siproxd_config configuration;
extern int errno;
struct urlmap_s urlmap[URLMAP_SIZE]; // URL mapping table
struct urlmap_s urlmap[URLMAP_SIZE]; /* URL mapping table */
extern int sip_socket; /* sending SIP datagrams */
/*
* initialize the URL mapping table
@@ -237,7 +238,7 @@ int register_response(sip_t *request, int flag) {
port=configuration.sip_listen_port;
}
sipsock_send_udp(addr, port, buffer, strlen(buffer));
sipsock_send_udp(&sip_socket, addr, port, buffer, strlen(buffer), 1);
/* free the resources */
msg_free(response);
+6
View File
@@ -40,6 +40,9 @@ static char const ident[]="$Id: " __FILE__ ": " PACKAGE "-" VERSION "-"\
/* configuration storage */
struct siproxd_config configuration;
/* socket used for sending SIP datagrams */
int sip_socket=0;
int main (int argc, char *argv[])
{
int sts;
@@ -120,6 +123,9 @@ int main (int argc, char *argv[])
/* listen for incomming messages */
sipsock_listen();
/* initialize the RTP proxy thread */
rtpproxy_init();
/* daemonize if requested to */
if (configuration.daemonize) {
DEBUGC(DBCLASS_CONFIG,"daemonizing");
+18 -2
View File
@@ -24,7 +24,9 @@
int sipsock_listen (void);
int sipsock_wait(void);
int sipsock_read(void *buf, size_t bufsize);
int sipsock_send_udp(struct in_addr addr, int port, char *buffer, int size);
int sipsock_send_udp(int *sock, struct in_addr addr, int port,
char *buffer, int size, int allowdump);
int sockbind(struct in_addr ipaddr, int localport);
/* register.c */
void register_init(void);
@@ -50,6 +52,13 @@ int compare_url(url_t *url1, url_t *url2);
/* config.c */
int read_config(char *name, int search);
/* rtpproxy.c */
int rtpproxy_init( void );
int rtp_start_fwd (call_id_t *callid,
struct in_addr outbound_ipaddr, int *outboundport,
struct in_addr lcl_client_ipaddr, int lcl_clientport);
int rtp_stop_fwd (call_id_t *callid);
/*
* table to hold the client registrations
@@ -72,6 +81,10 @@ struct siproxd_config {
char *outboundhost;
int sip_listen_port;
int daemonize;
int rtp_port_low;
int rtp_port_high;
int rtp_timeout;
int rtp_proxy_enable;
};
@@ -80,8 +93,11 @@ struct siproxd_config {
*/
#define SIP_PORT 5060
#define URLMAP_SIZE 128 // size of URL mapping table
#define URLMAP_SIZE 8 // number of URL mapping table entries
#define RTPPROXY_SIZE 8 // number of rtp proxy entries
#define BUFFER_SIZE 1024 // input buffer for read from socket
#define RTP_BUFFER_SIZE 512 // max size of an RTP frame
#define URL_STRING_SIZE 128 // max size of an URL/URI string
#define STATUSCODE_SIZE 5 // size of string representation of status
#define DNS_CACHE_SIZE 32 // number of entries in internal DNS cache
+48 -26
View File
@@ -53,24 +53,10 @@ static int listen_socket=0;
* returns 0 on success
*/
int sipsock_listen (void) {
struct sockaddr_in my_addr;
int sts;
struct in_addr ipaddr;
my_addr.sin_family = AF_INET;
memset(&my_addr.sin_addr.s_addr, 0, sizeof(struct in_addr));
my_addr.sin_port= htons(configuration.sip_listen_port);
listen_socket=socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (listen_socket == 0) {
ERROR("socket() call failed:%s",strerror(errno));
return 1;
}
sts=bind(listen_socket, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (sts != 0) {
ERROR("bind failed:%s",strerror(errno));
return 2;
}
memset(&ipaddr, 0, sizeof(struct in_addr));
listen_socket=sockbind(ipaddr, configuration.sip_listen_port);
DEBUGC(DBCLASS_NET,"bound listen socket %i",listen_socket);
return 0;
@@ -106,29 +92,33 @@ int sipsock_read(void *buf, size_t bufsize) {
/*
* sends an UDP datagram to the specified destination
*/
int sipsock_send_udp(struct in_addr addr, int port, char *buffer, int size) {
int sipsock_send_udp(int *sock, struct in_addr addr, int port,
char *buffer, int size, int allowdump) {
struct sockaddr_in dst_addr;
static int s=0;
int sts;
/* first time: allocate a socket for sending */
if (s == 0) {
s=socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == 0) {
if (*sock == 0) {
*sock=socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (*sock == 0) {
ERROR("socket() call failed:%s",strerror(errno));
return 1;
}
DEBUGC(DBCLASS_NET,"allocated send socket %i",s);
DEBUGC(DBCLASS_NET,"allocated send socket %i",*sock);
}
dst_addr.sin_family = AF_INET;
memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr));
dst_addr.sin_port= htons(port);
DEBUGC(DBCLASS_NET,"send UDP packet to %s",inet_ntoa(addr));
DUMP_BUFFER(DBCLASS_NETTRAF, buffer, size);
sts = sendto (s, buffer, size, 0, &dst_addr, sizeof(dst_addr));
if (allowdump) {
DEBUGC(DBCLASS_NET,"send UDP packet to %s:%i",
inet_ntoa(addr),port);
DUMP_BUFFER(DBCLASS_NETTRAF, buffer, size);
}
sts = sendto (*sock, buffer, size, 0, &dst_addr, sizeof(dst_addr));
if (sts == -1) {
ERROR("sendto() call failed:%s",strerror(errno));
@@ -138,3 +128,35 @@ int sipsock_send_udp(struct in_addr addr, int port, char *buffer, int size) {
return 0;
}
/*
* generic routine to allocate and bind a socket to a specified
* local address and port (UDP)
*
* returns socket number on success, zero on failure
*/
int sockbind(struct in_addr ipaddr, int localport) {
struct sockaddr_in my_addr;
int sts;
int sock;
my_addr.sin_family = AF_INET;
memcpy(&my_addr.sin_addr.s_addr, &ipaddr, sizeof(struct in_addr));
my_addr.sin_port= htons(localport);
sock=socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == 0) {
ERROR("socket() call failed:%s",strerror(errno));
return 0;
}
sts=bind(sock, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (sts != 0) {
ERROR("bind failed:%s",strerror(errno));
close(sock);
return 0;
}
return sock;
}
+9 -1
View File
@@ -113,6 +113,7 @@ int is_via_local (via_t *via) {
struct in_addr addr_via, addr_myself;
char *my_hostnames[]=
{ configuration.inboundhost, configuration.outboundhost, NULL };
int port;
int i;
char *ptr;
@@ -131,7 +132,11 @@ int is_via_local (via_t *via) {
/* check the extracted VIA against my own host addresses */
sts = get_ip_by_host(ptr, &addr_myself);
if (memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) {
if (via->port) port=atoi(via->port);
else port=SIP_PORT;
if ( (memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) &&
(port == configuration.sip_listen_port) ) {
sts=1;
break;
}
@@ -156,6 +161,8 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
} dns_cache[DNS_CACHE_SIZE];
static int cache_initialized=0;
if (hostname == NULL) return 1;
/* first time: initialize DNS cache */
if (cache_initialized == 0) {
DEBUGC(DBCLASS_DNS, "initializing DNS cache (%i entries)", DNS_CACHE_SIZE);
@@ -166,6 +173,7 @@ int get_ip_by_host(char *hostname, struct in_addr *addr) {
time(&t);
/* clean expired entries */
for (i=0; i<DNS_CACHE_SIZE; i++) {
if (dns_cache[i].hostname[0]=='\0') continue;
if ( (dns_cache[i].timestamp+DNS_MAX_AGE) < t ) {
DEBUGC(DBCLASS_DNS, "cleaning DNS cache, entry %i)", i);
memset (&dns_cache[i], 0, sizeof(dns_cache[0]));