- feature: auto-save registration table during operation

This commit is contained in:
Thomas Ries 2005-04-16 09:30:55 +00:00
parent 2fd9cde299
commit 2757a6bad6
6 changed files with 88 additions and 63 deletions

View File

@ -1,5 +1,6 @@
0.5.11
======
15-Apr-2005: - feature: auto-save registration table during operation
10-Apr-2005: - started DocBook documentation
3-Apr-2005: - fix: changing public IP address
27-Mar-2005: - feature: siproxd "in front of" a NAT router should work

View File

@ -90,6 +90,11 @@ user = nobody
# the specified directory path does exist!
registration_file = /var/lib/siproxd/siproxd_registrations
######################################################################
# Automatically save current registrations every 'n' seconds
#
autosave_registrations = 300
######################################################################
# PID file:
# Where to create the PID file.
@ -108,7 +113,7 @@ rtp_proxy_enable = 1
######################################################################
# Port range to allocate listen ports from for incoming RTP traffic
# This should be a range that is not blocked by the firewall
#
#
rtp_port_low = 7070
rtp_port_high = 7079
@ -126,7 +131,7 @@ rtp_timeout = 300
# If a REGISTER request does not contain an Expires header
# or expires= parameter in the Contact header, this number of
# seconds will be used - and reported back to the UA in the answer.
#
#
default_expires = 600
######################################################################

View File

@ -171,10 +171,11 @@ static int parse_config (FILE *configfile) {
{ "outbound_domain_name",TYP_STRINGA,&configuration.outbound_proxy_domain_name },
{ "outbound_domain_host",TYP_STRINGA,&configuration.outbound_proxy_domain_host },
{ "outbound_domain_port",TYP_STRINGA,&configuration.outbound_proxy_domain_port },
{ "registration_file", TYP_STRING ,&configuration.registrationfile },
{ "registration_file", TYP_STRING, &configuration.registrationfile },
{ "log_calls", TYP_INT4, &configuration.log_calls },
{ "pid_file", TYP_STRING ,&configuration.pid_file },
{ "default_expires", TYP_INT4 ,&configuration.default_expires },
{ "pid_file", TYP_STRING, &configuration.pid_file },
{ "default_expires", TYP_INT4, &configuration.default_expires },
{ "autosave_registrations",TYP_INT4, &configuration.autosave_registrations },
{0, 0, 0}
};

View File

@ -40,9 +40,15 @@ static char const ident[]="$Id$";
/* configuration storage */
extern struct siproxd_config configuration;
struct urlmap_s urlmap[URLMAP_SIZE]; /* URL mapping table */
/* URL mapping table */
struct urlmap_s urlmap[URLMAP_SIZE];
/* time of last save */
static time_t last_save=0;
extern int errno;
/*
* initialize the URL mapping table
*/
@ -73,7 +79,7 @@ void register_init(void) {
osip_uri_init(&urlmap[i].masq_url);
osip_uri_init(&urlmap[i].reg_url);
#define R(X) {\
#define R(X) {\
fgets(buff, sizeof(buff), stream);\
buff[sizeof(buff)-1]='\0';\
if (strchr(buff, 10)) *strchr(buff, 10)='\0';\
@ -104,6 +110,8 @@ void register_init(void) {
fclose(stream);
}
}
/* initialize save-timer */
time(&last_save);
return;
}
@ -111,7 +119,7 @@ void register_init(void) {
/*
* shut down the URL mapping table
*/
void register_shut(void) {
void register_save(void) {
int i;
FILE *stream;
@ -290,7 +298,7 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
j=-1;
for (i=0; i<URLMAP_SIZE; i++) {
if (urlmap[i].active == 0) {
if (j < 0) j=i; /* remember first hole */
if (j < 0) j=i; /* remember first hole */
continue;
}
@ -300,11 +308,11 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
if (compare_url(url1_to, url2_to)==STS_SUCCESS) {
DEBUGC(DBCLASS_REG, "found entry for %s@%s <-> %s@%s at "
"slot=%i, exp=%li",
(url1_contact->username) ? url1_contact->username : "*NULL*",
(url1_contact->username) ? url1_contact->username : "*NULL*",
(url1_contact->host) ? url1_contact->host : "*NULL*",
(url2_to->username) ? url2_to->username : "*NULL*",
(url2_to->username) ? url2_to->username : "*NULL*",
(url2_to->host) ? url2_to->host : "*NULL*",
i, urlmap[i].expires-time_now);
i, urlmap[i].expires-time_now);
break;
}
}
@ -324,15 +332,15 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
/* Contact: field */
osip_uri_clone( ((osip_contact_t*)
(ticket->sipmsg->contacts->node->element))->url,
&urlmap[i].true_url);
&urlmap[i].true_url);
/* To: field */
osip_uri_clone( ticket->sipmsg->to->url,
&urlmap[i].reg_url);
&urlmap[i].reg_url);
DEBUGC(DBCLASS_REG,"create new entry for %s@%s <-> %s@%s at slot=%i",
(url1_contact->username) ? url1_contact->username : "*NULL*",
(url1_contact->host) ? url1_contact->host : "*NULL*",
(urlmap[i].reg_url->username) ? urlmap[i].reg_url->username : "*NULL*",
(urlmap[i].reg_url->username) ? urlmap[i].reg_url->username : "*NULL*",
(urlmap[i].reg_url->host) ? urlmap[i].reg_url->host : "*NULL*",
i);
@ -340,7 +348,7 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
* try to figure out if we ought to do some masquerading
*/
osip_uri_clone( ticket->sipmsg->to->url,
&urlmap[i].masq_url);
&urlmap[i].masq_url);
n=configuration.mask_host.used;
if (n != configuration.masked_host.used) {
@ -439,7 +447,7 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
if (compare_url(url1_to, url2_to)==STS_SUCCESS) {
DEBUGC(DBCLASS_REG, "removing registration for %s@%s at slot=%i",
(url2_to->username) ? url2_to->username : "*NULL*",
(url2_to->username) ? url2_to->username : "*NULL*",
(url2_to->host) ? url2_to->host : "*NULL*", i);
urlmap[i].expires=0;
break;
@ -455,24 +463,33 @@ int register_client(sip_ticket_t *ticket, int force_lcl_masq) {
/*
* cyclically called to do the aging of the URL mapping table entries
* and throw out expired entries.
* Also we do the cyclic saving here - if required.
*/
void register_agemap(void) {
int i;
time_t t;
/* expire old entries */
time(&t);
DEBUGC(DBCLASS_BABBLE,"sip_agemap, t=%i",(int)t);
for (i=0; i<URLMAP_SIZE; i++) {
if ((urlmap[i].active == 1) && (urlmap[i].expires < t)) {
DEBUGC(DBCLASS_REG,"cleaned entry:%i %s@%s", i,
urlmap[i].masq_url->username, urlmap[i].masq_url->host);
DEBUGC(DBCLASS_REG,"cleaned entry:%i %s@%s", i,
urlmap[i].masq_url->username, urlmap[i].masq_url->host);
urlmap[i].active=0;
osip_uri_free(urlmap[i].true_url);
osip_uri_free(urlmap[i].masq_url);
osip_uri_free(urlmap[i].reg_url);
// osip_via_free(urlmap[i].via);
}
}
/* auto-save of registration table */
if ((configuration.autosave_registrations > 0) &&
((last_save + configuration.autosave_registrations) < t)) {
DEBUGC(DBCLASS_REG,"auto-saving registration table");
register_save();
last_save = t;
}
return;
}
@ -484,8 +501,8 @@ void register_agemap(void) {
* flag = STS_NEED_AUTH -> proxy authentication needed (407)
*
* RETURNS
* STS_SUCCESS on success
* STS_FAILURE on error
* STS_SUCCESS on success
* STS_FAILURE on error
*/
int register_response(sip_ticket_t *ticket, int flag) {
osip_message_t *response;
@ -501,16 +518,16 @@ int register_response(sip_ticket_t *ticket, int flag) {
/* ok -> 200, fail -> 503 */
switch (flag) {
case STS_SUCCESS:
code = 200; /* OK */
code = 200; /* OK */
break;
case STS_FAILURE:
code = 503; /* failed */
code = 503; /* failed */
break;
case STS_NEED_AUTH:
code = 407; /* proxy authentication needed */
code = 407; /* proxy authentication needed */
break;
default:
code = 503; /* failed */
code = 503; /* failed */
break;
}

View File

@ -29,7 +29,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef HAVE_GETOPT_H
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
@ -51,7 +51,7 @@ static const char str_helpmsg[] =
PACKAGE "-" VERSION "-" BUILDSTR " (c) 2002-2005 Thomas Ries\n"
"\nUsage: siproxd [options]\n\n"
"options:\n"
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
" -h, --help help\n"
" -d, --debug <pattern> set debug-pattern\n"
" -c, --config <cfgfile> use the specified config file\n"
@ -87,11 +87,11 @@ int main (int argc, char *argv[])
char buff [BUFFER_SIZE];
sip_ticket_t ticket;
extern char *optarg; /* Defined in libc getopt and unistd.h */
extern char *optarg; /* Defined in libc getopt and unistd.h */
int ch1;
char configfile[64]="siproxd"; /* basename of configfile */
int config_search=1; /* search the config file */
char configfile[64]="siproxd"; /* basename of configfile */
int config_search=1; /* search the config file */
int cmdline_debuglevel=0;
char *pidfilename=NULL;
struct sigaction act;
@ -120,7 +120,7 @@ int main (int argc, char *argv[])
*/
make_default_config();
log_set_pattern(configuration.debuglevel);
log_set_pattern(configuration.debuglevel);
/*
* open a the pwfile instance, so we still have access after
@ -136,7 +136,7 @@ int main (int argc, char *argv[])
* parse command line
*/
{
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
int option_index = 0;
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
@ -148,37 +148,37 @@ int main (int argc, char *argv[])
while ((ch1 = getopt_long(argc, argv, "hc:d:p:",
long_options, &option_index)) != -1) {
#else /* ! HAVE_GETOPT_LONG */
#else /* ! HAVE_GETOPT_LONG */
while ((ch1 = getopt(argc, argv, "hc:d:p:")) != -1) {
#endif
switch (ch1) {
case 'h': /* help */
case 'h': /* help */
DEBUGC(DBCLASS_CONFIG,"option: help");
fprintf(stderr,str_helpmsg);
exit(0);
break;
break;
case 'c': /* load config file */
case 'c': /* load config file */
DEBUGC(DBCLASS_CONFIG,"option: config file=%s",optarg);
i=sizeof(configfile)-1;
strncpy(configfile,optarg,i-1);
configfile[i]='\0';
config_search=0;
break;
configfile[i]='\0';
config_search=0;
break;
case 'd': /* set debug level */
case 'd': /* set debug level */
DEBUGC(DBCLASS_CONFIG,"option: set debug level: %s",optarg);
cmdline_debuglevel=atoi(optarg);
cmdline_debuglevel=atoi(optarg);
log_set_pattern(cmdline_debuglevel);
break;
break;
case 'p':
pidfilename = optarg;
break;
pidfilename = optarg;
break;
default:
DEBUGC(DBCLASS_CONFIG,"no command line options");
break;
break;
}
}
}
@ -315,7 +315,7 @@ int main (int argc, char *argv[])
ticket.sipmsg->message=NULL;
if (sts != 0) {
ERROR("osip_message_init() failed... this is not good");
continue; /* skip, there are no resources to free */
continue; /* skip, there are no resources to free */
}
/*
@ -400,7 +400,7 @@ int main (int argc, char *argv[])
/* NOT IMPLEMENTED */
DEBUGC(DBCLASS_SIP,"received SIP type %s:%s",
(MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES",
(MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES",
(MSG_IS_REQUEST(ticket.sipmsg) ?
((ticket.sipmsg->sip_method)?
ticket.sipmsg->sip_method : "NULL") :
@ -445,10 +445,10 @@ int main (int argc, char *argv[])
sip_gen_response(&ticket, 408 /*request timeout*/);
}
}
} else {
} else {
WARN("non-authorized registration attempt from %s",
utils_inet_ntoa(ticket.from.sin_addr));
}
utils_inet_ntoa(ticket.from.sin_addr));
}
/*
* check if outbound interface is UP.
@ -471,10 +471,10 @@ int main (int argc, char *argv[])
} else if (MSG_IS_REQUEST(ticket.sipmsg)) {
if (access & ACCESSCTL_SIP) {
sts = proxy_request(&ticket);
} else {
} else {
INFO("non-authorized request received from %s",
utils_inet_ntoa(ticket.from.sin_addr));
}
utils_inet_ntoa(ticket.from.sin_addr));
}
/*
* MSG is a response, remove current via and
@ -483,18 +483,18 @@ int main (int argc, char *argv[])
} else if (MSG_IS_RESPONSE(ticket.sipmsg)) {
if (access & ACCESSCTL_SIP) {
sts = proxy_response(&ticket);
} else {
} else {
INFO("non-authorized response received from %s",
utils_inet_ntoa(ticket.from.sin_addr));
}
utils_inet_ntoa(ticket.from.sin_addr));
}
/*
* unsupported message
*/
} else {
ERROR("received unsupported SIP type %s %s",
(MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES",
ticket.sipmsg->sip_method);
(MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES",
ticket.sipmsg->sip_method);
}
@ -507,8 +507,8 @@ int main (int argc, char *argv[])
} /* while TRUE */
exit_prg:
/* dump current known SIP registrations */
register_shut();
/* save current known SIP registrations */
register_save();
INFO("properly terminating siproxd");
/* remove PID file */

View File

@ -87,6 +87,7 @@ struct siproxd_config {
int log_calls;
char *pid_file;
int default_expires;
int autosave_registrations;
};
/*
@ -125,7 +126,7 @@ int sockbind(struct in_addr ipaddr, int localport, int errflg);
/* register.c */
void register_init(void);
void register_shut(void);
void register_save(void);
int register_client(sip_ticket_t *ticket, int force_lcl_masq); /*X*/
void register_agemap(void);
int register_response(sip_ticket_t *ticket, int flag); /*X*/