You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/modules/sst/sst.c

220 lines
5.6 KiB

/*
* $Id$
*
* SIP Session Timer (sst) module - support for tracking dialogs and
* SIP Session Timers.
*
* Copyright (C) 2006 SOMA Networks, INC.
* Written by: Ron Winacott (karwin)
*
* This file is part of SIP-router, a free SIP server.
*
* SIP-router is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* SIP-router is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* History:
* --------
* 2006-05-11 initial version (karwin)
* 2006-10-10 RFC compilent changes. Added the other flags (karwin)
*/
/*! \file sst/sst.c
* \brief SST :: Core
* \ingroup sst
* Modules: \ref sst
*/
/*! \defgroup sst SIP Session Timers module
* Implementation of SIP Session Timers - a way to make sure a SIP dialog is alive
* and force hangup if a UA involved in a dialog stops responding.
*
* - \ref SST_support
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../../modules/sl/sl.h"
#include "sst_handlers.h" /* also includes sr_module.h needed by
handlers */
#ifdef STATISTICS
#include "../../lib/kcore/kstats_wrapper.h"
#endif
MODULE_VERSION
static int mod_init(void);
/** SL API structure */
sl_api_t slb;
/*
* statistic variables
*/
int sst_enable_stats = 1;
stat_var *expired_sst = 0;
/*!
* The name of the AVP the dialog module will use to hold the timeout
* value so we can set the AVP in the dialog callbacks so the dialog
* code will set the dialog lifetime when it returns from the INVITE
* and IN_ROUTE callbacks.
*/
pv_spec_t timeout_avp;
static char* timeout_spec = 0; /*!< Place holder for the passed in name */
/*!
* The default or script parameter for the requested MIN-SE: value for
* this proxy. (in seconds) If the passed in value is 0, then this
* proxy will except any value from the UAC as its min-SE value. If
* the value is NOT set then the default will be asserted.
*/
unsigned int sst_minSE = 90;
/*!
* Should the PROXY (us) reject (with a 422 reply) and SE < sst_minSE
* requests is it can. Default is YES.
*/
unsigned int sst_reject = 1;
/*! The sst message flag value */
static int sst_flag = -1;
/*
* Binding to the dialog module
*/
struct dlg_binds dialog_st;
struct dlg_binds *dlg_binds = &dialog_st;
/*
* Script commands we export.
*/
static cmd_export_t cmds[]={
{"sstCheckMin", (cmd_function)sst_check_min, 1, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
{0,0,0,0,0,0}
};
/*
* Script parameters
*/
static param_export_t mod_params[]={
{ "enable_stats", INT_PARAM, &sst_enable_stats },
{ "min_se", INT_PARAM, &sst_minSE },
{ "timeout_avp", STR_PARAM, &timeout_spec },
{ "reject_to_small", INT_PARAM, &sst_reject },
{ "sst_flag", INT_PARAM, &sst_flag },
{ 0,0,0 }
};
#ifdef STATISTICS
/*
* Export the statistics we have
*/
static stat_export_t mod_stats[] = {
{"expired_sst", 0, &expired_sst},
{0,0,0}
};
#endif /* STATISTICS */
struct module_exports exports= {
"sst", /* module's name */
DEFAULT_DLFLAGS, /* dlopen flags */
cmds, /* exported functions */
mod_params, /* param exports */
0, /* exported statistics (they are registered from mod_init) */
0, /* exported MI functions */
0, /* exported pseudo-variables */
0, /* extra processes */
mod_init, /* module initialization function */
0, /* reply processing function */
0, /* Destroy function */
0 /* per-child init function */
};
/**
* The initialization function, called when the module is loaded by
* the script. This function is called only once.
*
* Bind to the dialog module and setup the callbacks. Also initialize
* the shared memory to store our interninal information in.
*
* @return 0 to continue to load the Kamailio, -1 to stop the loading
* and abort Kamailio.
*/
static int mod_init(void)
{
str s;
/* if statistics are disabled, prevent their registration to core. */
if (sst_enable_stats==0) {
exports.stats = 0;
}
#ifdef STATISTICS
/* register statistics */
if (sst_enable_stats!=0)
{
if (register_module_stats( exports.name, mod_stats)!=0 ) {
LM_ERR("failed to register core statistics\n");
return -1;
}
}
#endif
if (sst_flag == -1) {
LM_ERR("no sst flag set!!\n");
return -1;
}
else if (sst_flag > MAX_FLAG) {
LM_ERR("invalid sst flag %d!!\n", sst_flag);
return -1;
}
if (timeout_spec != NULL) {
LM_DBG("Dialog AVP is %s", timeout_spec);
s.s = timeout_spec; s.len = strlen(s.s);
if (pv_parse_spec(&s, &timeout_avp)==0
&& (timeout_avp.type != PVT_AVP)){
LM_ERR("malformed or non AVP timeout AVP definition in '%s'\n",
timeout_spec);
return -1;
}
}
/* bind the SL API */
if (sl_load_api(&slb)!=0) {
LM_ERR("cannot bind to SL API\n");
return -1;
}
/* Init the handlers */
sst_handler_init((timeout_spec?&timeout_avp:0), sst_minSE,
sst_flag, sst_reject);
/* Register the main (static) dialog call back. */
if (load_dlg_api(&dialog_st) != 0) {
LM_ERR("failed to load dialog hooks");
return(-1);
}
/* Load dialog hooks */
dialog_st.register_dlgcb(NULL, DLGCB_CREATED, sst_dialog_created_CB, NULL, NULL);
return 0;
}