diff --git a/src/modules/carrierroute/cr_db.c b/src/modules/carrierroute/cr_db.c
index d651db1b49c..010f99d7158 100644
--- a/src/modules/carrierroute/cr_db.c
+++ b/src/modules/carrierroute/cr_db.c
@@ -265,6 +265,7 @@ int load_user_carrier(str * user, str * domain) {
*/
int load_route_data_db(struct route_data_t * rd) {
db1_res_t * res = NULL;
+ db1_res_t * prob_res = NULL;
db_row_t * row = NULL;
int i, ret;
struct carrier_data_t * tmp_carrier_data;
@@ -352,6 +353,7 @@ int load_route_data_db(struct route_data_t * rd) {
}
}
int n = 0;
+ boolean query_done = false;
do {
LM_DBG("loading, cycle %d", n++);
for (i = 0; i < RES_ROW_N(res); ++i) {
@@ -396,6 +398,35 @@ int load_route_data_db(struct route_data_t * rd) {
p_tmp_comment) == -1) {
goto errout;
}
+ if (row->values[COL_PROB].val.double_val == 0 && !query_done) {
+ int ret_tmp;
+ char query_tmp[QUERY_LEN];
+ str query_tmp_str;
+
+ memset(query_tmp, 0, QUERY_LEN);
+ ret_tmp = snprintf(query_tmp, QUERY_LEN, "SELECT * FROM %.*s WHERE %.*s=%d and %.*s=%d and %.*s>%d",
+ carrierroute_table.len, carrierroute_table.s, columns[COL_CARRIER]->len, columns[COL_CARRIER]->s, row->values[COL_CARRIER].val.int_val,
+ columns[COL_DOMAIN]->len, columns[COL_DOMAIN]->s, row->values[COL_DOMAIN].val.int_val, columns[COL_PROB]->len, columns[COL_PROB]->s, 0);
+
+ if (ret_tmp < 0) {
+ LM_ERR("error in snprintf while querying prob column");
+ goto errout;
+ }
+ query_tmp_str.s = query_tmp;
+ query_tmp_str.len = ret_tmp;
+
+ if (carrierroute_dbf.raw_query(carrierroute_dbh, &query_tmp_str, &prob_res) < 0) {
+ LM_ERR("Failed to query carrierroute db table based on prob column.\n");
+ goto errout;
+ }
+ if(RES_ROW_N(prob_res) == 0) {
+ LM_ERR("Carrierroute db table contains route(s) with only 0 probability.\n");
+ query_done = true;
+ }
+ carrierroute_dbf.free_result(carrierroute_dbh, prob_res);
+ prob_res = NULL;
+ }
+
}
if (DB_CAPABILITY(carrierroute_dbf, DB_CAP_FETCH)) {
if(carrierroute_dbf.fetch_result(carrierroute_dbh, &res, cfg_get(carrierroute, carrierroute_cfg, fetch_rows)) < 0) {
@@ -462,5 +493,8 @@ int load_route_data_db(struct route_data_t * rd) {
if (res) {
carrierroute_dbf.free_result(carrierroute_dbh, res);
}
+ if (prob_res) {
+ carrierroute_dbf.free_result(carrierroute_dbh, prob_res);
+ }
return -1;
}
diff --git a/src/modules/carrierroute/cr_db.h b/src/modules/carrierroute/cr_db.h
index 1f53c9307bd..ffea7311928 100644
--- a/src/modules/carrierroute/cr_db.h
+++ b/src/modules/carrierroute/cr_db.h
@@ -88,4 +88,9 @@ int load_route_data_db (struct route_data_t * rd);
int load_user_carrier(str * user, str * domain);
+typedef enum {
+ false = 0,
+ true = 1
+} boolean;
+
#endif
diff --git a/src/modules/carrierroute/cr_func.c b/src/modules/carrierroute/cr_func.c
index 6b6db1387bb..c4ce4d52a00 100644
--- a/src/modules/carrierroute/cr_func.c
+++ b/src/modules/carrierroute/cr_func.c
@@ -471,7 +471,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
avp_value_t cr_new_uri;
if(rf->dice_max == 0) {
- LM_ERR("invalid dice_max value\n");
+ LM_ERR("invalid dice_max value (route has probability 0)\n");
return -1;
}
if ((prob = hash_func(msg, hash_source, rf->dice_max)) < 0) {
diff --git a/src/modules/dialog/README b/src/modules/dialog/README
index f344c99b532..f56c64cad80 100644
--- a/src/modules/dialog/README
+++ b/src/modules/dialog/README
@@ -1979,15 +1979,17 @@ kamcmd dlg.list _from_ _to_ _op_
11.1. event_route[dialog:start]
- Executed when 200OK for INVITE is processed.
+ Executed when 200OK reply for INVITE is processed.
11.2. event_route[dialog:end]
- Executed when BYE is processed or dialog timed out.
+ Executed when the BYE for the call is processed or the dialog timed
+ out.
11.3. event_route[dialog:failed]
- Executed when dialog is not completed (+300 reply to INVITE).
+ Executed when dialog is not completed (300 or greater reply code to
+ INVITE).
Chapter 2. Developer Guide
diff --git a/src/modules/dialog/doc/dialog_admin.xml b/src/modules/dialog/doc/dialog_admin.xml
index e451ce4b9d9..4823de489d1 100644
--- a/src/modules/dialog/doc/dialog_admin.xml
+++ b/src/modules/dialog/doc/dialog_admin.xml
@@ -2344,7 +2344,7 @@ if(has_totag() and is_present_hf("Route") and uri==myself ) {
- dlg.end_dlg
+ dlg.end_dlg
Terminates an ongoing dialog by sending BYE in both directions.
@@ -2544,21 +2544,23 @@ if(has_totag() and is_present_hf("Route") and uri==myself ) {
Event Routes
- event_route[dialog:start]
+ event_route[dialog:start]
- Executed when 200OK for INVITE is processed.
+ Executed when 200OK reply for INVITE is processed.
- event_route[dialog:end]
+ event_route[dialog:end]
- Executed when BYE is processed or dialog timed out.
+ Executed when the BYE for the call is processed
+ or the dialog timed out.
- event_route[dialog:failed]
+ event_route[dialog:failed]
- Executed when dialog is not completed (+300 reply to INVITE).
+ Executed when dialog is not completed (300 or greater reply code
+ to INVITE).
diff --git a/src/modules/seas/cluster.h b/src/modules/seas/cluster.h
index 6c18116d6c2..b3e596736f1 100644
--- a/src/modules/seas/cluster.h
+++ b/src/modules/seas/cluster.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,8 +13,8 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/src/modules/seas/encode_allow.h b/src/modules/seas/encode_allow.h
index e48ace7a7df..b4663e13f5d 100644
--- a/src/modules/seas/encode_allow.h
+++ b/src/modules/seas/encode_allow.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,11 +13,14 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef __ENCODE_ALLOW_H__
+#define __ENCODE_ALLOW_H__
int encode_allow(char *hdrstart,int hdrlen,unsigned int *bodi,char *where);
int print_encoded_allow(FILE *fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix);
+#endif
diff --git a/src/modules/seas/encode_content_disposition.h b/src/modules/seas/encode_content_disposition.h
index 63d81de366d..48045289f6c 100644
--- a/src/modules/seas/encode_content_disposition.h
+++ b/src/modules/seas/encode_content_disposition.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,11 +13,14 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifndef __ENCODE_CONTENT_DISPOSITION_H__
+#define __ENCODE_CONTENT_DISPOSITION_H__
int encode_content_disposition(char *hdrstart,int hdrlen,struct disposition *body,unsigned char *where);
int print_encoded_content_disposition(FILE *fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix);
+#endif
diff --git a/src/modules/seas/encode_content_length.h b/src/modules/seas/encode_content_length.h
index fc58dbcf9ce..deb1cc40467 100644
--- a/src/modules/seas/encode_content_length.h
+++ b/src/modules/seas/encode_content_length.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,11 +13,13 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
+#ifndef __ENCODE_CONTENT_LENGHT_H__
+#define __ENCODE_CONTENT_LENGHT_H__
int encode_contentlength(char *hdr,int hdrlen,long int len,char *where);
int print_encoded_contentlength(FILE* fd,char *hdr,int hdrlen,unsigned char *payload,int paylen,char *prefix);
+#endif
diff --git a/src/modules/seas/encode_content_type.h b/src/modules/seas/encode_content_type.h
index e52d81d3b4f..b3d359c86a6 100644
--- a/src/modules/seas/encode_content_type.h
+++ b/src/modules/seas/encode_content_type.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,15 +13,17 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
+#ifndef __ENCODE_CONTENT_TYPE_H__
+#define __ENCODE_CONTENT_TYPE_H__
int encode_content_type(char *hdrstart,int hdrlen,unsigned int bodi,char *where);
int encode_accept(char *hdrstart,int hdrlen,unsigned int *bodi,char *where);
int encode_mime_type(char *hdrstart,int hdrlen,unsigned int bodi,char *where);
int print_encoded_mime_type(FILE* fd,char *hdr,int hdrlen,unsigned int* payload,int paylen,char *prefix);
int print_encoded_content_type(FILE* fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix);
int print_encoded_accept(FILE* fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix);
+#endif
diff --git a/src/modules/seas/encode_cseq.h b/src/modules/seas/encode_cseq.h
index 54aaed1022a..bcba4b864c9 100644
--- a/src/modules/seas/encode_cseq.h
+++ b/src/modules/seas/encode_cseq.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,13 +13,15 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
+#ifndef __ENCODE_CSEQ_H__
+#define __ENCODE_CSEQ_H__
#include "../../core/str.h"
#include "../../core/parser/msg_parser.h"
int encode_cseq(char *hdrstart,int hdrlen,struct cseq_body *body,unsigned char *where);
int print_encoded_cseq(FILE* fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix);
+#endif
diff --git a/src/modules/seas/encode_digest.h b/src/modules/seas/encode_digest.h
index e91ff12180d..26952c22822 100644
--- a/src/modules/seas/encode_digest.h
+++ b/src/modules/seas/encode_digest.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,12 +13,14 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
+#ifndef __ENCODE_DIGEST_H__
+#define __ENCODE_DIGEST_H__
int encode_digest(char *hdrstart,int hdrlen,dig_cred_t *digest,unsigned char *where);
int print_encoded_digest(FILE* fd,char *hdr,int hdrlen,unsigned char* payload,int paylen,char *prefix);
int dump_digest_test(char *hdr,int hdrlen,unsigned char* payload,int paylen,FILE* fd,char segregationLevel);
+#endif
diff --git a/src/modules/seas/seas.c b/src/modules/seas/seas.c
index 0c162db5df7..c6c99a9b8b9 100644
--- a/src/modules/seas/seas.c
+++ b/src/modules/seas/seas.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,8 +13,8 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -89,20 +88,20 @@ struct seas_functions seas_f;
static cmd_export_t cmds[]=
{
{"as_relay_t", (cmd_function)w_as_relay_t, 1, fixup_as_relay,
- 0, REQUEST_ROUTE},
+ 0, REQUEST_ROUTE},
{"as_relay_sl", (cmd_function)w_as_relay_sl, 1, fixup_as_relay,
- 0, REQUEST_ROUTE},
+ 0, REQUEST_ROUTE},
{0,0,0,0,0,0}
};
static param_export_t params[]=
{
- {"listen_sockets",PARAM_STRING, &seas_listen_socket},
- {"stats_socket", PARAM_STRING, &seas_stats_socket},
- {"jain_ping", PARAM_STRING, &jain_ping_config},
- {"servlet_ping", PARAM_STRING, &servlet_ping_config},
- {"clusters", PARAM_STRING, &cluster_cfg},
- {0,0,0}
+ {"listen_sockets",PARAM_STRING, &seas_listen_socket},
+ {"stats_socket", PARAM_STRING, &seas_stats_socket},
+ {"jain_ping", PARAM_STRING, &jain_ping_config},
+ {"servlet_ping", PARAM_STRING, &servlet_ping_config},
+ {"clusters", PARAM_STRING, &cluster_cfg},
+ {0,0,0}
};
static proc_export_t seas_procs[] = {
@@ -110,65 +109,65 @@ static proc_export_t seas_procs[] = {
{0,0,0,0,0}
};
-struct module_exports exports=
+struct module_exports exports=
{
- "seas",
- DEFAULT_DLFLAGS,
- cmds, /* exported commands */
- params, /* exported parameters */
- 0, /* exported statistics */
- 0, /* exported mi commands */
- 0, /* exported module-items (pseudo variables) */
- seas_procs, /* extra processes */
- seas_init, /* module initialization function */
- 0, /* response function */
- (destroy_function) seas_exit, /* module exit function */
- (child_init_function) seas_child_init /* per-child init function */
+ "seas",
+ DEFAULT_DLFLAGS,
+ cmds, /* exported commands */
+ params, /* exported parameters */
+ 0, /* exported statistics */
+ 0, /* exported mi commands */
+ 0, /* exported module-items (pseudo variables) */
+ seas_procs, /* extra processes */
+ seas_init, /* module initialization function */
+ 0, /* response function */
+ (destroy_function) seas_exit, /* module exit function */
+ (child_init_function) seas_child_init /* per-child init function */
};
static int fixup_as_relay(void** param, int param_no)
{
- int len;
- char *parameter;
- struct as_entry **entry,*tmp;
-
- parameter=(char *)(*param);
-
- if (param_no!=1)
- return 0;
- len=strlen(parameter);
-
- for (entry=&as_list;*entry;entry=&((*entry)->next)) {
- if (len== (*entry)->name.len &&
- !memcmp((*entry)->name.s,parameter,len)) {
- pkg_free(*param);
- *param=*entry;
- return 1;
- }
- }
- if (!(*entry)) {
- if (!(*entry=(struct as_entry *)shm_malloc(sizeof(struct as_entry)))) {
- LM_ERR("no more shm_mem\n");
- goto error;
- }
- memset(*entry,0,sizeof(struct as_entry));
- if(!((*entry)->name.s=shm_malloc(len))){
- LM_ERR("no more share mem\n");
- goto error;
- }
- (*entry)->name.len=len;
- memcpy((*entry)->name.s,parameter,len);
- (*entry)->u.as.name=(*entry)->name;
- (*entry)->u.as.event_fd=(*entry)->u.as.action_fd=-1;
- (*entry)->type=AS_TYPE;
- pkg_free(*param);
- *param=*entry;
- }
- for (tmp=as_list;tmp;tmp=tmp->next)
- LM_DBG("%.*s\n",tmp->name.len,tmp->name.s);
- return 1;
+ int len;
+ char *parameter;
+ struct as_entry **entry,*tmp;
+
+ parameter=(char *)(*param);
+
+ if (param_no!=1)
+ return 0;
+ len=strlen(parameter);
+
+ for (entry=&as_list;*entry;entry=&((*entry)->next)) {
+ if (len== (*entry)->name.len &&
+ !memcmp((*entry)->name.s,parameter,len)) {
+ pkg_free(*param);
+ *param=*entry;
+ return 1;
+ }
+ }
+ if (!(*entry)) {
+ if (!(*entry=(struct as_entry *)shm_malloc(sizeof(struct as_entry)))) {
+ LM_ERR("no more shm_mem\n");
+ goto error;
+ }
+ memset(*entry,0,sizeof(struct as_entry));
+ if(!((*entry)->name.s=shm_malloc(len))){
+ LM_ERR("no more share mem\n");
+ goto error;
+ }
+ (*entry)->name.len=len;
+ memcpy((*entry)->name.s,parameter,len);
+ (*entry)->u.as.name=(*entry)->name;
+ (*entry)->u.as.event_fd=(*entry)->u.as.action_fd=-1;
+ (*entry)->type=AS_TYPE;
+ pkg_free(*param);
+ *param=*entry;
+ }
+ for (tmp=as_list;tmp;tmp=tmp->next)
+ LM_DBG("%.*s\n",tmp->name.len,tmp->name.s);
+ return 1;
error:
- return -1;
+ return -1;
}
/**
@@ -176,57 +175,57 @@ static int fixup_as_relay(void** param, int param_no)
*/
void seas_sighandler(int signo)
{
- struct as_entry *as;
- if(is_dispatcher)
- sig_flag=signo;
- switch(signo){
- case SIGPIPE:
- if(is_dispatcher)
- return;
- LM_INFO("%s exiting\n",whoami);
- if(my_as->u.as.ac_buffer.s){
- pkg_free(my_as->u.as.ac_buffer.s);
- my_as->u.as.ac_buffer.s=0;
- }
- if(my_as->u.as.action_fd!=-1){
- close(my_as->u.as.action_fd);
- my_as->u.as.action_fd=-1;
- }
- exit(0);
- break;
- case SIGCHLD:
- LM_INFO("Child stopped or terminated\n");
- break;
- case SIGUSR1:
- case SIGUSR2:
- LM_DBG("Memory status (pkg):\n");
+ struct as_entry *as;
+ if(is_dispatcher)
+ sig_flag=signo;
+ switch(signo){
+ case SIGPIPE:
+ if(is_dispatcher)
+ return;
+ LM_INFO("%s exiting\n",whoami);
+ if(my_as->u.as.ac_buffer.s){
+ pkg_free(my_as->u.as.ac_buffer.s);
+ my_as->u.as.ac_buffer.s=0;
+ }
+ if(my_as->u.as.action_fd!=-1){
+ close(my_as->u.as.action_fd);
+ my_as->u.as.action_fd=-1;
+ }
+ exit(0);
+ break;
+ case SIGCHLD:
+ LM_INFO("Child stopped or terminated\n");
+ break;
+ case SIGUSR1:
+ case SIGUSR2:
+ LM_DBG("Memory status (pkg):\n");
#ifdef PKG_MALLOC
- pkg_status();
+ pkg_status();
#endif
- break;
- case SIGINT:
- case SIGTERM:
- LM_INFO("INFO: signal %d received\n",signo);
+ break;
+ case SIGINT:
+ case SIGTERM:
+ LM_INFO("INFO: signal %d received\n",signo);
#ifdef PKG_MALLOC
- pkg_status();
+ pkg_status();
#endif
- if(is_dispatcher){
- for (as=as_list;as;as=as->next) {
- if(as->type==AS_TYPE && as->connected)
- kill(as->u.as.action_pid,signo);
- }
- while(wait(0) > 0);
- exit(0);
- }else{
- LM_INFO("%s exiting\n",whoami);
- if(my_as && my_as->u.as.ac_buffer.s)
- pkg_free(my_as->u.as.ac_buffer.s);
- if(my_as && my_as->u.as.action_fd!=-1)
- close(my_as->u.as.action_fd);
- exit(0);
- }
- break;
- }
+ if(is_dispatcher){
+ for (as=as_list;as;as=as->next) {
+ if(as->type==AS_TYPE && as->connected)
+ kill(as->u.as.action_pid,signo);
+ }
+ while(wait(0) > 0);
+ exit(0);
+ }else{
+ LM_INFO("%s exiting\n",whoami);
+ if(my_as && my_as->u.as.ac_buffer.s)
+ pkg_free(my_as->u.as.ac_buffer.s);
+ if(my_as && my_as->u.as.action_fd!=-1)
+ close(my_as->u.as.action_fd);
+ exit(0);
+ }
+ break;
+ }
}
/**
@@ -235,112 +234,112 @@ void seas_sighandler(int signo)
*/
static int w_as_relay_t(struct sip_msg *msg, char *entry, char *foo)
{
- as_msg_p my_as_ev;
- int new_tran,ret=0,len;
- char *buffer,processor_id;
- struct cell *mycel;
- struct as_entry *as;
- char *msg100="Your call is important to us";
- char *msg500="Server Internal Error!";
-
- buffer=(char*)0;
- my_as_ev=(as_msg_p)0;
-
- /**
- * returns <0 on error
- * 1 if (new transaction was created) or if (ACK for locally replied 200 with totag) or if (ACK for code>=300)
- * 0 if it was a retransmission
- */
- new_tran = seas_f.tmb.t_newtran(msg);
- if(new_tran<0) {
- ret = (ser_error==E_BAD_VIA && reply_to_via) ? 0 : new_tran;
- goto done;
- }
- /*retransmission: script processing should be stopped*/
- if (new_tran==0 && !(msg->REQ_METHOD==METHOD_ACK)){
- ret = 0;
- goto done;
- }
- /*new transaction created, let's pass it to an APP SERVER*/
- if (msg->REQ_METHOD==METHOD_INVITE )
- {
- LM_DBG("new INVITE\n");
- if(!seas_f.tmb.t_reply(msg,100,msg100)){
- LM_DBG("t_reply (100)\n");
- goto error;
- }
- }
- as=(struct as_entry *)entry;
- if(!as->connected){
- LM_ERR("app server %.*s not connected\n",as->name.len,as->name.s);
- goto error;
- }
- if(as->type==AS_TYPE){
- if((processor_id=get_processor_id(&msg->rcv,&(as->u.as)))<0){
- LM_ERR("no processor found for packet dst %s:%d\n",ip_addr2a(&msg->rcv.dst_ip),msg->rcv.dst_port);
- goto error;
- }
- }else if(as->type==CLUSTER_TYPE){
- LM_ERR("clustering not fully implemented\n");
- return 0;
- }else{
- LM_ERR("unknown type of as (neither cluster nor as)\n");
- return -1;
- }
- LM_DBG("as found ! (%.*s) processor id = %d\n",as->name.len,as->name.s,processor_id);
- if(new_tran==1 && msg->REQ_METHOD==METHOD_ACK){
- LM_DBG("message handled in transaction callbacks. skipping\n");
- ret = 0;
- goto done;
- /* core should forward statelessly (says t_newtran)
- LM_DBG("forwarding statelessly !!!\n");
- if(!(buffer=create_as_event_sl(msg,processor_id,&len,0))){
- LM_ERR("create_as_event_sl() unable to create event code\n");
- goto error;
- }
- */
- }else if(!(buffer=create_as_event_t(seas_f.tmb.t_gett(),msg,processor_id,&len,0))){
- LM_ERR("unable to create event code\n");
- goto error;
- }
- if(!(my_as_ev=shm_malloc(sizeof(as_msg_t)))){
- LM_ERR("Out of shared mem!\n");
- goto error;
- }
- my_as_ev->msg = buffer;
- my_as_ev->as = as;
- my_as_ev->type = T_REQ_IN;
- my_as_ev->len = len;
- my_as_ev->transaction=seas_f.tmb.t_gett(); /*does not refcount*/
- if(use_stats && new_tran>0)
- as_relay_stat(seas_f.tmb.t_gett());
+ as_msg_p my_as_ev;
+ int new_tran,ret=0,len;
+ char *buffer,processor_id;
+ struct cell *mycel;
+ struct as_entry *as;
+ char *msg100="Your call is important to us";
+ char *msg500="Server Internal Error!";
+
+ buffer=(char*)0;
+ my_as_ev=(as_msg_p)0;
+
+ /**
+ * returns <0 on error
+ * 1 if (new transaction was created) or if (ACK for locally replied 200 with totag) or if (ACK for code>=300)
+ * 0 if it was a retransmission
+ */
+ new_tran = seas_f.tmb.t_newtran(msg);
+ if(new_tran<0) {
+ ret = (ser_error==E_BAD_VIA && reply_to_via) ? 0 : new_tran;
+ goto done;
+ }
+ /*retransmission: script processing should be stopped*/
+ if (new_tran==0 && !(msg->REQ_METHOD==METHOD_ACK)){
+ ret = 0;
+ goto done;
+ }
+ /*new transaction created, let's pass it to an APP SERVER*/
+ if (msg->REQ_METHOD==METHOD_INVITE )
+ {
+ LM_DBG("new INVITE\n");
+ if(!seas_f.tmb.t_reply(msg,100,msg100)){
+ LM_DBG("t_reply (100)\n");
+ goto error;
+ }
+ }
+ as=(struct as_entry *)entry;
+ if(!as->connected){
+ LM_ERR("app server %.*s not connected\n",as->name.len,as->name.s);
+ goto error;
+ }
+ if(as->type==AS_TYPE){
+ if((processor_id=get_processor_id(&msg->rcv,&(as->u.as)))<0){
+ LM_ERR("no processor found for packet dst %s:%d\n",ip_addr2a(&msg->rcv.dst_ip),msg->rcv.dst_port);
+ goto error;
+ }
+ }else if(as->type==CLUSTER_TYPE){
+ LM_ERR("clustering not fully implemented\n");
+ return 0;
+ }else{
+ LM_ERR("unknown type of as (neither cluster nor as)\n");
+ return -1;
+ }
+ LM_DBG("as found ! (%.*s) processor id = %d\n",as->name.len,as->name.s,processor_id);
+ if(new_tran==1 && msg->REQ_METHOD==METHOD_ACK){
+ LM_DBG("message handled in transaction callbacks. skipping\n");
+ ret = 0;
+ goto done;
+ /* core should forward statelessly (says t_newtran)
+ * LM_DBG("forwarding statelessly !!!\n");
+ * if(!(buffer=create_as_event_sl(msg,processor_id,&len,0))){
+ * LM_ERR("create_as_event_sl() unable to create event code\n");
+ * goto error;
+ * }
+ */
+ }else if(!(buffer=create_as_event_t(seas_f.tmb.t_gett(),msg,processor_id,&len,0))){
+ LM_ERR("unable to create event code\n");
+ goto error;
+ }
+ if(!(my_as_ev=shm_malloc(sizeof(as_msg_t)))){
+ LM_ERR("Out of shared mem!\n");
+ goto error;
+ }
+ my_as_ev->msg = buffer;
+ my_as_ev->as = as;
+ my_as_ev->type = T_REQ_IN;
+ my_as_ev->len = len;
+ my_as_ev->transaction=seas_f.tmb.t_gett(); /*does not refcount*/
+ if(use_stats && new_tran>0)
+ as_relay_stat(seas_f.tmb.t_gett());
again:
- ret=write(write_pipe,&my_as_ev,sizeof(as_msg_p));
- if(ret==-1){
- if(errno==EINTR)
- goto again;
- else if(errno==EPIPE){
- LM_ERR("SEAS Event Dispatcher has closed the pipe. Invalidating it !\n");
- goto error;
- /** TODO handle this correctly !!!*/
- }
- }
- /* seas_f.tmb.t_setkr(REQ_FWDED); */
- ret=0;
+ ret=write(write_pipe,&my_as_ev,sizeof(as_msg_p));
+ if(ret==-1){
+ if(errno==EINTR)
+ goto again;
+ else if(errno==EPIPE){
+ LM_ERR("SEAS Event Dispatcher has closed the pipe. Invalidating it !\n");
+ goto error;
+ /** TODO handle this correctly !!!*/
+ }
+ }
+ /* seas_f.tmb.t_setkr(REQ_FWDED); */
+ ret=0;
done:
- return ret;
+ return ret;
error:
- mycel=seas_f.tmb.t_gett();
- if(mycel && mycel!=T_UNDEFINED){
- if(!seas_f.tmb.t_reply(msg,500,msg500)){
- LM_ERR("t_reply (500)\n");
- }
- }
- if(my_as_ev)
- shm_free(my_as_ev);
- if(buffer)
- shm_free(buffer);
- return ret;
+ mycel=seas_f.tmb.t_gett();
+ if(mycel && mycel!=T_UNDEFINED){
+ if(!seas_f.tmb.t_reply(msg,500,msg500)){
+ LM_ERR("t_reply (500)\n");
+ }
+ }
+ if(my_as_ev)
+ shm_free(my_as_ev);
+ if(buffer)
+ shm_free(buffer);
+ return ret;
}
@@ -350,274 +349,274 @@ static int w_as_relay_t(struct sip_msg *msg, char *entry, char *foo)
*/
static int w_as_relay_sl(struct sip_msg *msg, char *as_name, char *foo)
{
- as_msg_p my_as_ev=0;
- int ret=0,len;
- char *buffer=0,processor_id;
- struct as_entry *as;
-
- as=(struct as_entry *)as_name;
-
- if(as->type==AS_TYPE){
- if((processor_id=get_processor_id(&msg->rcv,&(as->u.as)))<0){
- LM_ERR("no processor found for packet with dst port:%d\n",msg->rcv.dst_port);
- goto error;
- }
- }else if (as->type==CLUSTER_TYPE) {
- LM_ERR("clustering not fully implemented\n");
- goto error;
- }else{
- LM_ERR("unknown type of as\n");
- goto error;
- }
-
- LM_DBG("as found ! (%.*s) processor id = %d\n",as->name.len,as->name.s,processor_id);
- if(!(buffer=create_as_event_sl(msg,processor_id,&len,0))){
- LM_ERR("unable to create event code\n");
- goto error;
- }
- if(!(my_as_ev=shm_malloc(sizeof(as_msg_t))))
- goto error;
- my_as_ev->msg = buffer;
- my_as_ev->as = as;
- my_as_ev->type = SL_REQ_IN;
- my_as_ev->len = len;
- my_as_ev->transaction=seas_f.tmb.t_gett(); /*does not refcount*/
- if(use_stats)
- as_relay_stat(seas_f.tmb.t_gett());
+ as_msg_p my_as_ev=0;
+ int ret=0,len;
+ char *buffer=0,processor_id;
+ struct as_entry *as;
+
+ as=(struct as_entry *)as_name;
+
+ if(as->type==AS_TYPE){
+ if((processor_id=get_processor_id(&msg->rcv,&(as->u.as)))<0){
+ LM_ERR("no processor found for packet with dst port:%d\n",msg->rcv.dst_port);
+ goto error;
+ }
+ }else if (as->type==CLUSTER_TYPE) {
+ LM_ERR("clustering not fully implemented\n");
+ goto error;
+ }else{
+ LM_ERR("unknown type of as\n");
+ goto error;
+ }
+
+ LM_DBG("as found ! (%.*s) processor id = %d\n",as->name.len,as->name.s,processor_id);
+ if(!(buffer=create_as_event_sl(msg,processor_id,&len,0))){
+ LM_ERR("unable to create event code\n");
+ goto error;
+ }
+ if(!(my_as_ev=shm_malloc(sizeof(as_msg_t))))
+ goto error;
+ my_as_ev->msg = buffer;
+ my_as_ev->as = as;
+ my_as_ev->type = SL_REQ_IN;
+ my_as_ev->len = len;
+ my_as_ev->transaction=seas_f.tmb.t_gett(); /*does not refcount*/
+ if(use_stats)
+ as_relay_stat(seas_f.tmb.t_gett());
again:
- ret=write(write_pipe,&my_as_ev,sizeof(as_msg_p));
- if(ret==-1){
- if(errno==EINTR)
- goto again;
- else if(errno==EPIPE){
- LM_ERR("SEAS Event Dispatcher has closed the pipe. Invalidating it !\n");
- return -2;
- /** TODO handle this correctly !!!*/
- }
- }
- //this shouln't be here, because it will remove the transaction from memory, but
- //if transaction isn't unref'ed iw will be released anyway at t_unref if kr (killreason)==0
- // a wait timer will be put to run with WT_TIME_OUT (5 seconds, within which the AS should respond)
- // this is a bug !!! I think this is why we lose calls at high load !!
- //t_release(msg, 0, 0);
- /* seas_f.tmb.t_setkr(REQ_FWDED); */
-
- ret=0;
- return ret;
+ ret=write(write_pipe,&my_as_ev,sizeof(as_msg_p));
+ if(ret==-1){
+ if(errno==EINTR)
+ goto again;
+ else if(errno==EPIPE){
+ LM_ERR("SEAS Event Dispatcher has closed the pipe. Invalidating it !\n");
+ return -2;
+ /** TODO handle this correctly !!!*/
+ }
+ }
+ //this shouln't be here, because it will remove the transaction from memory, but
+ //if transaction isn't unref'ed iw will be released anyway at t_unref if kr (killreason)==0
+ // a wait timer will be put to run with WT_TIME_OUT (5 seconds, within which the AS should respond)
+ // this is a bug !!! I think this is why we lose calls at high load !!
+ //t_release(msg, 0, 0);
+ /* seas_f.tmb.t_setkr(REQ_FWDED); */
+
+ ret=0;
+ return ret;
error:
- if(my_as_ev)
- shm_free(my_as_ev);
- if(buffer)
- shm_free(buffer);
- return ret;
+ if(my_as_ev)
+ shm_free(my_as_ev);
+ if(buffer)
+ shm_free(buffer);
+ return ret;
}
/**
* creates an as_event in shared memory and returns its address or NULL if error.
* event_length(4) UNSIGNED INT includes the length 4 bytes itself
- * type(1),
+ * type(1),
* flags(4),
* transport(1).
- * src_ip_len(1),
- * src_ip(4 or 16),
- * dst_ip_len(1),
- * dst_ip(4 or 16),
- * src_port(2),
- * dst_port(2),
- * hash index(4),
- * label(4),
+ * src_ip_len(1),
+ * src_ip(4 or 16),
+ * dst_ip_len(1),
+ * dst_ip(4 or 16),
+ * src_port(2),
+ * dst_port(2),
+ * hash index(4),
+ * label(4),
* [cancelled hash_index,label]
*
*/
char * create_as_event_t(struct cell *t,struct sip_msg *msg,char processor_id,int *evt_len,int flags)
{
- unsigned int i,hash_index,label;
- unsigned short int port;
- unsigned int k,len;
- char *buffer=NULL;
- struct cell *originalT;
-
- originalT=0;
-
- if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
- LM_ERR("Out Of Memory !!\n");
- return 0;
- }
- *evt_len=0;
- if(t){
- hash_index=t->hash_index;
- label=t->label;
- }else{
- /**seas_f.tmb.t_get_trans_ident(msg,&hash_index,&label); this is bad, because it ref-counts !!!*/
- LM_ERR("no transaction provided...\n");
- goto error;
- }
-
- k=4;
- /*type*/
- buffer[k++]=(unsigned char)T_REQ_IN;
- /*processor_id*/
- buffer[k++]=(unsigned char)processor_id;
- /*flags*/
- if(is_e2e_ack(t,msg)){
- flags|=E2E_ACK;
- }else if(msg->REQ_METHOD==METHOD_CANCEL){
- LM_DBG("new CANCEL\n");
- originalT=seas_f.tmb.t_lookup_original(msg);
- if(!originalT || originalT==T_UNDEFINED){
- /** we dont even pass the unknown CANCEL to JAIN*/
- LM_WARN("CANCEL does not match any existing transaction!!\n");
- goto error;
- }else{
- flags|=CANCEL_FOUND;
- //seas_f.tmb.unref_cell(originalT);
- }
- LM_DBG("Cancelling transaction !!\n");
- }
- flags=htonl(flags);
- memcpy(buffer+k,&flags,4);
- k+=4;
- /*protocol should be UDP,TCP,TLS or whatever*/
- buffer[k++]=(unsigned char)msg->rcv.proto;
- /*src ip len + src ip*/
- len=msg->rcv.src_ip.len;
- buffer[k++]=(unsigned char)len;
- memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
- k+=len;
- /*dst ip len + dst ip*/
- len=msg->rcv.dst_ip.len;
- buffer[k++]=(unsigned char)len;
- memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
- k+=len;
- /*src port */
- port=htons(msg->rcv.src_port);
- memcpy(buffer+k,&port,2);
- k+=2;
- /*dst port */
- port=htons(msg->rcv.dst_port);
- memcpy(buffer+k,&port,2);
- k+=2;
- /*hash_index*/
- i=htonl(hash_index);
- memcpy(buffer+k,&i,4);
- k+=4;
- /*label (is the collision slot in the hash-table)*/
- i=htonl(label);
- memcpy(buffer+k,&i,4);
- k+=4;
- if(msg->REQ_METHOD==METHOD_CANCEL && originalT){
- LM_DBG("Cancelled transaction: Hash_Index=%d, Label=%d\n",originalT->hash_index,originalT->label);
- /*hash_index*/
- i=htonl(originalT->hash_index);
- memcpy(buffer+k,&i,4);
- k+=4;
- /*label (is the collision slot in the hash-table)*/
- i=htonl(originalT->label);
- memcpy(buffer+k,&i,4);
- k+=4;
- }
-
- /*length of event (hdr+payload-4), copied at the beginning*/
- if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
- LM_ERR("Unable to encode msg\n");
- goto error;
- }
- i = GET_PAY_SIZE(buffer+k);
- k+=i;
- *evt_len=k;
- k=htonl(k);
- memcpy(buffer,&k,4);
- return buffer;
+ unsigned int i,hash_index,label;
+ unsigned short int port;
+ unsigned int k,len;
+ char *buffer=NULL;
+ struct cell *originalT;
+
+ originalT=0;
+
+ if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
+ LM_ERR("Out Of Memory !!\n");
+ return 0;
+ }
+ *evt_len=0;
+ if(t){
+ hash_index=t->hash_index;
+ label=t->label;
+ }else{
+ /**seas_f.tmb.t_get_trans_ident(msg,&hash_index,&label); this is bad, because it ref-counts !!!*/
+ LM_ERR("no transaction provided...\n");
+ goto error;
+ }
+
+ k=4;
+ /*type*/
+ buffer[k++]=(unsigned char)T_REQ_IN;
+ /*processor_id*/
+ buffer[k++]=(unsigned char)processor_id;
+ /*flags*/
+ if(is_e2e_ack(t,msg)){
+ flags|=E2E_ACK;
+ }else if(msg->REQ_METHOD==METHOD_CANCEL){
+ LM_DBG("new CANCEL\n");
+ originalT=seas_f.tmb.t_lookup_original(msg);
+ if(!originalT || originalT==T_UNDEFINED){
+ /** we dont even pass the unknown CANCEL to JAIN*/
+ LM_WARN("CANCEL does not match any existing transaction!!\n");
+ goto error;
+ }else{
+ flags|=CANCEL_FOUND;
+ //seas_f.tmb.unref_cell(originalT);
+ }
+ LM_DBG("Cancelling transaction !!\n");
+ }
+ flags=htonl(flags);
+ memcpy(buffer+k,&flags,4);
+ k+=4;
+ /*protocol should be UDP,TCP,TLS or whatever*/
+ buffer[k++]=(unsigned char)msg->rcv.proto;
+ /*src ip len + src ip*/
+ len=msg->rcv.src_ip.len;
+ buffer[k++]=(unsigned char)len;
+ memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
+ k+=len;
+ /*dst ip len + dst ip*/
+ len=msg->rcv.dst_ip.len;
+ buffer[k++]=(unsigned char)len;
+ memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
+ k+=len;
+ /*src port */
+ port=htons(msg->rcv.src_port);
+ memcpy(buffer+k,&port,2);
+ k+=2;
+ /*dst port */
+ port=htons(msg->rcv.dst_port);
+ memcpy(buffer+k,&port,2);
+ k+=2;
+ /*hash_index*/
+ i=htonl(hash_index);
+ memcpy(buffer+k,&i,4);
+ k+=4;
+ /*label (is the collision slot in the hash-table)*/
+ i=htonl(label);
+ memcpy(buffer+k,&i,4);
+ k+=4;
+ if(msg->REQ_METHOD==METHOD_CANCEL && originalT){
+ LM_DBG("Cancelled transaction: Hash_Index=%d, Label=%d\n",originalT->hash_index,originalT->label);
+ /*hash_index*/
+ i=htonl(originalT->hash_index);
+ memcpy(buffer+k,&i,4);
+ k+=4;
+ /*label (is the collision slot in the hash-table)*/
+ i=htonl(originalT->label);
+ memcpy(buffer+k,&i,4);
+ k+=4;
+ }
+
+ /*length of event (hdr+payload-4), copied at the beginning*/
+ if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
+ LM_ERR("Unable to encode msg\n");
+ goto error;
+ }
+ i = GET_PAY_SIZE(buffer+k);
+ k+=i;
+ *evt_len=k;
+ k=htonl(k);
+ memcpy(buffer,&k,4);
+ return buffer;
error:
- if(buffer)
- shm_free(buffer);
- return 0;
+ if(buffer)
+ shm_free(buffer);
+ return 0;
}
/**
* creates an as_event in shared memory and returns its address or NULL if error.
* event_length(4) UNSIGNED INT includes the length 4 bytes itself
- * type(1),
- * processor_id(4),
+ * type(1),
+ * processor_id(4),
* flags(4),
* transport(1).
- * src_ip_len(1),
- * src_ip(4 or 16),
- * dst_ip_len(1),
- * dst_ip(4 or 16),
- * src_port(2),
- * dst_port(2),
+ * src_ip_len(1),
+ * src_ip(4 or 16),
+ * dst_ip_len(1),
+ * dst_ip(4 or 16),
+ * src_port(2),
+ * dst_port(2),
*
*/
char * create_as_event_sl(struct sip_msg *msg,char processor_id,int *evt_len,int flags)
{
- unsigned int i;
- unsigned short int port;
- unsigned int k,len;
- char *buffer=NULL;
-
- if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
- LM_ERR("create_as_event_t Out Of Memory !!\n");
- return 0;
- }
- *evt_len=0;
-
- /*leave 4 bytes for event length*/
- k=4;
- /*type*/
- buffer[k++]=(unsigned char)SL_REQ_IN;
- /*processor_id*/
- buffer[k++]=(unsigned char)processor_id;
- /*flags*/
- flags=htonl(flags);
- memcpy(buffer+k,&flags,4);
- k+=4;
- /*protocol should be UDP,TCP,TLS or whatever*/
- buffer[k++]=(unsigned char)msg->rcv.proto;
- /*src ip len + src ip*/
- len=msg->rcv.src_ip.len;
- buffer[k++]=(unsigned char)len;
- memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
- k+=len;
- /*dst ip len + dst ip*/
- len=msg->rcv.dst_ip.len;
- buffer[k++]=(unsigned char)len;
- memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
- k+=len;
- /*src port */
- port=htons(msg->rcv.src_port);
- memcpy(buffer+k,&port,2);
- k+=2;
- /*dst port */
- port=htons(msg->rcv.dst_port);
- memcpy(buffer+k,&port,2);
- k+=2;
- /*length of event (hdr+payload-4), copied at the beginning*/
- if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
- LM_ERR("Unable to encode msg\n");
- goto error;
- }
- i = GET_PAY_SIZE(buffer+k);
- k+=i;
- *evt_len=k;
- k=htonl(k);
- memcpy(buffer,&k,4);
- return buffer;
+ unsigned int i;
+ unsigned short int port;
+ unsigned int k,len;
+ char *buffer=NULL;
+
+ if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
+ LM_ERR("create_as_event_t Out Of Memory !!\n");
+ return 0;
+ }
+ *evt_len=0;
+
+ /*leave 4 bytes for event length*/
+ k=4;
+ /*type*/
+ buffer[k++]=(unsigned char)SL_REQ_IN;
+ /*processor_id*/
+ buffer[k++]=(unsigned char)processor_id;
+ /*flags*/
+ flags=htonl(flags);
+ memcpy(buffer+k,&flags,4);
+ k+=4;
+ /*protocol should be UDP,TCP,TLS or whatever*/
+ buffer[k++]=(unsigned char)msg->rcv.proto;
+ /*src ip len + src ip*/
+ len=msg->rcv.src_ip.len;
+ buffer[k++]=(unsigned char)len;
+ memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
+ k+=len;
+ /*dst ip len + dst ip*/
+ len=msg->rcv.dst_ip.len;
+ buffer[k++]=(unsigned char)len;
+ memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
+ k+=len;
+ /*src port */
+ port=htons(msg->rcv.src_port);
+ memcpy(buffer+k,&port,2);
+ k+=2;
+ /*dst port */
+ port=htons(msg->rcv.dst_port);
+ memcpy(buffer+k,&port,2);
+ k+=2;
+ /*length of event (hdr+payload-4), copied at the beginning*/
+ if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
+ LM_ERR("Unable to encode msg\n");
+ goto error;
+ }
+ i = GET_PAY_SIZE(buffer+k);
+ k+=i;
+ *evt_len=k;
+ k=htonl(k);
+ memcpy(buffer,&k,4);
+ return buffer;
error:
- if(buffer)
- shm_free(buffer);
- return 0;
+ if(buffer)
+ shm_free(buffer);
+ return 0;
}
static inline int is_e2e_ack(struct cell *t,struct sip_msg *msg)
{
- if(msg->REQ_METHOD != METHOD_ACK)
- return 0;
- if (t->uas.status<300)
- return 1;
- return 0;
+ if(msg->REQ_METHOD != METHOD_ACK)
+ return 0;
+ if (t->uas.status<300)
+ return 1;
+ return 0;
}
/** Initializes seas module. It first parses the listen_sockets parameter
@@ -626,75 +625,75 @@ static inline int is_e2e_ack(struct cell *t,struct sip_msg *msg)
*/
static int seas_init(void)
{
- char *p,*port;
- struct hostent *he;
- struct socket_info *si;
- int c_pipe[2],mierr,i;
- /** Populate seas_functions*/
- if (load_tm_api(&seas_f.tmb)!=0) {
- LM_ERR( "can't load TM API\n");
- return -1;
- }
- if(!(seas_f.t_check_orig_trans = find_export("t_check_trans", 0, 0))){
- LM_ERR( "Seas requires transaction module (t_check_trans not found)\n");
- return -1;
- }
- /** Populate seas_functions*/
- c_pipe[0]=c_pipe[1]=-1;
- p=seas_listen_socket;
- port=(char *)0;
- seas_listen_port=5080;
- /*if the seas_listen_socket configuration string is empty, use default values*/
- if(p==NULL || *p==0){
- si=get_first_socket();
- seas_listen_ip=&si->address;
- } else {/*if config string is not empty, then try to find host first, and maybe port..*/
- while(*p){
- if(*p == ':'){
- *p=0;
- port=p+1;
- break;
- }
- p++;
- }
- if(!(he=resolvehost(seas_listen_socket)))
- goto error;
- if(!(seas_listen_ip=pkg_malloc(sizeof(struct ip_addr))))
- goto error;
- hostent2ip_addr(seas_listen_ip, he, 0);
- if(port!=(char *)0 && (seas_listen_port=str2s(port,strlen(port),&mierr))==0){
- LM_ERR("invalid port %s \n",port);
- goto error;
- }
- }
- memset(unc_as_t,0,2*MAX_UNC_AS_NR*sizeof(struct unc_as));//useless because unc_as_t is in bss?
- if (pipe(c_pipe)==-1) {
- LM_ERR("cannot create pipe!\n");
- goto error;
- }
- read_pipe=c_pipe[0];
- write_pipe=c_pipe[1];
- seas_init_tags();
- if(0>start_stats_server(seas_stats_socket))
- goto error;
- if(0>prepare_ha())
- goto error;
- if(0>parse_cluster_cfg())
- goto error;
- register_procs(1);
+ char *p,*port;
+ struct hostent *he;
+ struct socket_info *si;
+ int c_pipe[2],mierr,i;
+ /** Populate seas_functions*/
+ if (load_tm_api(&seas_f.tmb)!=0) {
+ LM_ERR( "can't load TM API\n");
+ return -1;
+ }
+ if(!(seas_f.t_check_orig_trans = find_export("t_check_trans", 0, 0))){
+ LM_ERR( "Seas requires transaction module (t_check_trans not found)\n");
+ return -1;
+ }
+ /** Populate seas_functions*/
+ c_pipe[0]=c_pipe[1]=-1;
+ p=seas_listen_socket;
+ port=(char *)0;
+ seas_listen_port=5080;
+ /*if the seas_listen_socket configuration string is empty, use default values*/
+ if(p==NULL || *p==0){
+ si=get_first_socket();
+ seas_listen_ip=&si->address;
+ } else {/*if config string is not empty, then try to find host first, and maybe port..*/
+ while(*p){
+ if(*p == ':'){
+ *p=0;
+ port=p+1;
+ break;
+ }
+ p++;
+ }
+ if(!(he=resolvehost(seas_listen_socket)))
+ goto error;
+ if(!(seas_listen_ip=pkg_malloc(sizeof(struct ip_addr))))
+ goto error;
+ hostent2ip_addr(seas_listen_ip, he, 0);
+ if(port!=(char *)0 && (seas_listen_port=str2s(port,strlen(port),&mierr))==0){
+ LM_ERR("invalid port %s \n",port);
+ goto error;
+ }
+ }
+ memset(unc_as_t,0,2*MAX_UNC_AS_NR*sizeof(struct unc_as));//useless because unc_as_t is in bss?
+ if (pipe(c_pipe)==-1) {
+ LM_ERR("cannot create pipe!\n");
+ goto error;
+ }
+ read_pipe=c_pipe[0];
+ write_pipe=c_pipe[1];
+ seas_init_tags();
+ if(0>start_stats_server(seas_stats_socket))
+ goto error;
+ if(0>prepare_ha())
+ goto error;
+ if(0>parse_cluster_cfg())
+ goto error;
+ register_procs(1);
/* add child to update local config framework structures */
cfg_register_child(1);
- return 0;
+ return 0;
error:
- for(i=0;i<2;i++)
- if(c_pipe[i]!=-1)
- close(c_pipe[i]);
- if(seas_listen_ip!=0)
- pkg_free(seas_listen_ip);
- if(use_stats)
- stop_stats_server();
- return -1;
+ for(i=0;i<2;i++)
+ if(c_pipe[i]!=-1)
+ close(c_pipe[i]);
+ if(seas_listen_ip!=0)
+ pkg_free(seas_listen_ip);
+ if(use_stats)
+ stop_stats_server();
+ return -1;
}
@@ -702,8 +701,8 @@ static int seas_init(void)
*/
static void seas_init_tags(void)
{
- init_tags(seas_tags, &seas_tag_suffix,"VozTele-Seas/tags",'-');
- LM_DBG("seas_init_tags, seas_tags=%s\n",seas_tags);
+ init_tags(seas_tags, &seas_tag_suffix,"VozTele-Seas/tags",'-');
+ LM_DBG("seas_init_tags, seas_tags=%s\n",seas_tags);
}
/**
@@ -716,30 +715,30 @@ static void seas_init_tags(void)
*/
static int seas_child_init(int rank)
{
- int pid;
-
- /* only the child 1 will execute this */
- if (rank != PROC_MAIN){
- /* only dispatcher needs to read from the pipe, so close reading fd*/
- /*close(read_pipe);*/
- return 0;
- }
- if ((pid=fork_process(PROC_NOCHLDINIT,"SEAS",0))<0) {
- LM_ERR("forking failed\n");
- return -1;
- }
- if (!pid) {
- /*dispatcher child. we leave writing end open so that new childs spawned
- * by event dispatcher can also write to pipe.. */
+ int pid;
+
+ /* only the child 1 will execute this */
+ if (rank != PROC_MAIN){
+ /* only dispatcher needs to read from the pipe, so close reading fd*/
+ /*close(read_pipe);*/
+ return 0;
+ }
+ if ((pid=fork_process(PROC_NOCHLDINIT,"SEAS",0))<0) {
+ LM_ERR("forking failed\n");
+ return -1;
+ }
+ if (!pid) {
+ /*dispatcher child. we leave writing end open so that new childs spawned
+ * by event dispatcher can also write to pipe.. */
/* initialize the config framework */
if (cfg_child_init())
return -1;
- /* close(write_pipe); */
- return dispatcher_main_loop();
- }
- return 0;
+ /* close(write_pipe); */
+ return dispatcher_main_loop();
+ }
+ return 0;
}
/* this should close the sockets open to any of the application servers, and
@@ -748,27 +747,27 @@ static int seas_child_init(int rank)
*/
static int seas_exit(void)
{
- if( seas_listen_ip!=NULL && seas_listen_ip!=&(get_first_socket()->address))
- pkg_free(seas_listen_ip);
- return 0;
+ if( seas_listen_ip!=NULL && seas_listen_ip!=&(get_first_socket()->address))
+ pkg_free(seas_listen_ip);
+ return 0;
}
/**
* search within a given AS, if any of the registered processors is bound
- * to the receive_info structure passed. If there is one, it returns its
+ * to the receive_info structure passed. If there is one, it returns its
* identifier (number between 0 and 128), otherwise it returns -1;
*/
char get_processor_id(struct receive_info *rcv,as_p as)
{
- int i;
- for(i=0;ibound_processor[i]!=0 &&
- (rcv->dst_ip.len == as->binds[i]->address.len) &&
- (rcv->dst_ip.af==as->binds[i]->address.af) &&
- (!memcmp(rcv->dst_ip.u.addr,as->binds[i]->address.u.addr,rcv->dst_ip.len))/* &&
- (rcv->dst_port==as->binds[i].dst_port) &&
- (rcv->proto==as->binds[i].proto)*/)
- return as->bound_processor[i];
- }
- return -1;
+ int i;
+ for(i=0;ibound_processor[i]!=0 &&
+ (rcv->dst_ip.len == as->binds[i]->address.len) &&
+ (rcv->dst_ip.af==as->binds[i]->address.af) &&
+ (!memcmp(rcv->dst_ip.u.addr,as->binds[i]->address.u.addr,rcv->dst_ip.len))/* &&
+ (rcv->dst_port==as->binds[i].dst_port) &&
+ (rcv->proto==as->binds[i].proto)*/)
+ return as->bound_processor[i];
+ }
+ return -1;
}
diff --git a/src/modules/seas/seas.h b/src/modules/seas/seas.h
index 6a7c03a0c18..9f525f48c40 100644
--- a/src/modules/seas/seas.h
+++ b/src/modules/seas/seas.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,8 +13,8 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -67,9 +66,9 @@
#define SPIRAL_FLAG 0x00000001
#define net2hostL(dst,from,index) do{ \
- memcpy(&(dst),(from)+(index),4); \
- dst=ntohl(dst); \
- (index)+=4; \
+ memcpy(&(dst),(from)+(index),4); \
+ dst=ntohl(dst); \
+ (index)+=4; \
}while(0);
@@ -94,32 +93,32 @@ extern int servlet_pings_lost;
extern struct as_entry *as_table;
struct seas_functions{
- struct tm_binds tmb;
- cmd_function t_check_orig_trans;
+ struct tm_binds tmb;
+ cmd_function t_check_orig_trans;
};
/*TODO listen_points should be dynamically allocated ?*/
typedef struct app_server {
- int event_fd;
- int action_fd;
- str name;
- pid_t action_pid;
- struct socket_info *binds[MAX_BINDS];
- char bound_processor[MAX_BINDS];
- int num_binds;
- str ev_buffer;
- str ac_buffer;
- struct ha jain_pings;
- struct ha servlet_pings;
- struct cluster *cluster;
+ int event_fd;
+ int action_fd;
+ str name;
+ pid_t action_pid;
+ struct socket_info *binds[MAX_BINDS];
+ char bound_processor[MAX_BINDS];
+ int num_binds;
+ str ev_buffer;
+ str ac_buffer;
+ struct ha jain_pings;
+ struct ha servlet_pings;
+ struct cluster *cluster;
}as_t, *as_p;
struct cluster{
- str name;
- int num;
- int registered;
- str as_names[MAX_AS_PER_CLUSTER];
- as_p servers[MAX_AS_PER_CLUSTER];
+ str name;
+ int num;
+ int registered;
+ str as_names[MAX_AS_PER_CLUSTER];
+ as_p servers[MAX_AS_PER_CLUSTER];
};
/**
@@ -127,32 +126,32 @@ struct cluster{
* when one matches, they will put the as pointer inside the event that should process
* that event.
* If eventually the as becomes unavailable, the dispatcher will set valid=false, which should be
- * atomic operation. This way, we prevent having to put a mutex on the array, which would make
+ * atomic operation. This way, we prevent having to put a mutex on the array, which would make
* it slower , as only one process could be accessing it at a time.
*/
struct as_entry{
- str name;
- int type;
- int connected;
- union{
- struct app_server as;
- struct cluster cs;
- }u;
- struct as_entry *next;
+ str name;
+ int type;
+ int connected;
+ union{
+ struct app_server as;
+ struct cluster cs;
+ }u;
+ struct as_entry *next;
};
extern struct as_entry *my_as;
-extern struct seas_functions seas_f;
+extern struct seas_functions seas_f;
extern struct as_entry *as_list;
typedef struct as_msg {
- struct cell *transaction;
- char *msg;
- int len;
- int type;
- int id;
- struct as_entry *as;
+ struct cell *transaction;
+ char *msg;
+ int len;
+ int type;
+ int id;
+ struct as_entry *as;
}as_msg_t,*as_msg_p;
char get_processor_id(struct receive_info *rcv,as_p as);
@@ -162,17 +161,17 @@ char* create_as_event_sl(struct sip_msg *msg,char processor_id,int *evt_len,int
static inline void print_ip_buf(struct ip_addr* ip, char *where,int len)
{
- switch(ip->af){
- case AF_INET:
- snprintf(where,len,"%d.%d.%d.%d", ip->u.addr[0], ip->u.addr[1], ip->u.addr[2], ip->u.addr[3]);
- break;
- case AF_INET6:
- snprintf(where,len,"%x:%x:%x:%x:%x:%x:%x:%x",htons(ip->u.addr16[0]),htons(ip->u.addr16[1]),htons(ip->u.addr16[2]),
- htons(ip->u.addr16[3]), htons(ip->u.addr16[4]), htons(ip->u.addr16[5]), htons(ip->u.addr16[6]),
- htons(ip->u.addr16[7]));
- break;
- default:
- break;
- }
+ switch(ip->af){
+ case AF_INET:
+ snprintf(where,len,"%d.%d.%d.%d", ip->u.addr[0], ip->u.addr[1], ip->u.addr[2], ip->u.addr[3]);
+ break;
+ case AF_INET6:
+ snprintf(where,len,"%x:%x:%x:%x:%x:%x:%x:%x",htons(ip->u.addr16[0]),htons(ip->u.addr16[1]),htons(ip->u.addr16[2]),
+ htons(ip->u.addr16[3]), htons(ip->u.addr16[4]), htons(ip->u.addr16[5]), htons(ip->u.addr16[6]),
+ htons(ip->u.addr16[7]));
+ break;
+ default:
+ break;
+ }
}
#endif
diff --git a/src/modules/seas/seas_action.c b/src/modules/seas/seas_action.c
index 3cb5513fbd1..7c963e6fe7a 100644
--- a/src/modules/seas/seas_action.c
+++ b/src/modules/seas/seas_action.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Copyright (C) 2006-2007 VozTelecom Sistemas S.L
*
* This file is part of Kamailio, a free SIP server.
@@ -14,15 +13,10 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * History:
- * -------
- * 2008-04-04 added support for local and remote dispaly name in TM dialogs
- * (by Andrei Pisau )
- *
*/
#include
@@ -496,7 +490,7 @@ int ac_cancel(as_p the_as,unsigned char processor_id,unsigned int flags,char *ac
the_param->uac_id=uac_id;
the_param->processor_id=processor_id;
the_param->destroy_cb_set=0;
-
+
/* registers TMCB_RESPONSE_IN|TMCB_LOCAL_COMPLETED tm callbacks */
ret=seas_f.tmb.t_cancel_uac(&headers,&body,cancelled_hashIdx,cancelled_label,uac_cb,(void*)the_param);
if (ret == 0) {
@@ -901,15 +895,15 @@ int forward_sl_request(struct sip_msg *msg,str *uri,int proto)
if ((uri2dst(NULL,&dst, msg, uri, proto)==0) || (dst.send_sock==0))
#else
if ((uri2dst(&dst, msg, uri, proto)==0) || (dst.send_sock==0))
-#endif
+#endif
{
- LOG(L_ERR, "forward_sl_request: no socket found\n");
+ LM_ERR("no socket found\n");
return -1;
}
LM_DBG("Sending:\n%.*s.\n", (int)msg->len,msg->buf);
if (msg_send(&dst, msg->buf,msg->len)<0){
- LM_ERR("ERROR:seas:forward_sl_request: Error sending message !!\n");
+ LM_ERR("Error sending message !!\n");
return -1;
}
return ret;
diff --git a/src/modules/tm/README b/src/modules/tm/README
index bec0630d959..bd10d0d7790 100644
--- a/src/modules/tm/README
+++ b/src/modules/tm/README
@@ -140,6 +140,7 @@ Daniel-Constantin Mierla
5.5. tm.hash_stats
5.6. tm.reply
5.7. tm.reply_callid
+ 5.8. tm.clean
6. Event Routes
@@ -379,6 +380,7 @@ Chapter 1. Admin Guide
5.5. tm.hash_stats
5.6. tm.reply
5.7. tm.reply_callid
+ 5.8. tm.clean
6. Event Routes
@@ -2806,6 +2808,7 @@ t_uac_send("OPTIONS", "sip:alice@kamailio.org", "", "",
5.5. tm.hash_stats
5.6. tm.reply
5.7. tm.reply_callid
+ 5.8. tm.clean
5.1. tm.list
@@ -2878,6 +2881,13 @@ t_uac_send("OPTIONS", "sip:alice@kamailio.org", "", "",
* body - (optional, may not be present) reply body (if present,
requires the “Content-Type” and “Content-length” headers)
+5.8. tm.clean
+
+ Trigger an hard clean of expired transactions.
+
+ Parameters:
+ * none
+
6. Event Routes
6.1. event_route[tm:branch-failure]
diff --git a/src/modules/tm/doc/rpc.xml b/src/modules/tm/doc/rpc.xml
index bc3fe332c5b..efc445cbee2 100644
--- a/src/modules/tm/doc/rpc.xml
+++ b/src/modules/tm/doc/rpc.xml
@@ -177,5 +177,19 @@
+
+
+ tm.clean
+
+
+ Trigger an hard clean of expired transactions.
+
+ Parameters:
+
+
+ none
+
+
+
diff --git a/src/modules/tm/h_table.c b/src/modules/tm/h_table.c
index 19b5daec0bb..ee79b91fd3f 100644
--- a/src/modules/tm/h_table.c
+++ b/src/modules/tm/h_table.c
@@ -575,3 +575,62 @@ void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd)
return;
}
}
+
+void tm_log_transaction(tm_cell_t *tcell, int llev, char *ltext)
+{
+ LOG(llev, "%s [start] transaction %p\n", ltext, tcell);
+ LOG(llev, "%s - tindex=%u tlabel=%u method='%.*s' from='%.*s'"
+ " to='%.*s' callid='%.*s' cseq='%.*s' uas_request=%s"
+ " tflags=%u outgoings=%u ref_count=%u lifetime=%u\n",
+ ltext, (unsigned)tcell->hash_index, (unsigned)tcell->label,
+ tcell->method.len, tcell->method.s,
+ tcell->from.len, tcell->from.s,
+ tcell->to.len, tcell->to.s,
+ tcell->callid.len, tcell->callid.s,
+ tcell->cseq_n.len, tcell->cseq_n.s,
+ (tcell->uas.request)?"yes":"no",
+ (unsigned)tcell->flags,
+ (unsigned)tcell->nr_of_outgoings,
+#ifdef TM_DEL_UNREF
+ (unsigned)atomic_get(&tcell->ref_count),
+#else
+ tcell->ref_count,
+#endif
+ (unsigned)TICKS_TO_S(tcell->end_of_life)
+ );
+
+ LOG(llev, "%s [end] transaction %p\n", ltext, tcell);
+}
+
+#define TM_LIFETIME_LIMIT 90
+/* clean active but very old transactions */
+void tm_clean_lifetime(void)
+{
+ int r;
+ tm_cell_t *tcell;
+ ticks_t texp;
+
+ texp = get_ticks_raw() - S_TO_TICKS(TM_LIFETIME_LIMIT);
+
+ for (r=0; rentries[r], next_c)) {
+ continue;
+ }
+ lock_hash(r);
+ /* one more time with lock to be avoid any cpu races */
+ if(clist_empty(&_tm_table->entries[r], next_c)) {
+ unlock_hash(r);
+ continue;
+ }
+
+ clist_foreach(&_tm_table->entries[r], tcell, next_c)
+ {
+ if(TICKS_GT(texp, tcell->end_of_life)) {
+ tm_log_transaction(tcell, L_WARN, "[hard cleanup]");
+ free_cell(tcell);
+ }
+ }
+ unlock_hash(r);
+ }
+}
diff --git a/src/modules/tm/h_table.h b/src/modules/tm/h_table.h
index 904709579af..7d61ae36730 100644
--- a/src/modules/tm/h_table.h
+++ b/src/modules/tm/h_table.h
@@ -607,6 +607,8 @@ inline static void remove_from_hash_table_unsafe(struct cell *p_cell)
t_stats_deleted(is_local(p_cell));
}
+void tm_clean_lifetime(void);
+
/**
* backup xdata from/to msg context to local var and use T lists
*/
diff --git a/src/modules/tm/t_stats.c b/src/modules/tm/t_stats.c
index d6ae5f52e4a..6b26aedba00 100644
--- a/src/modules/tm/t_stats.c
+++ b/src/modules/tm/t_stats.c
@@ -252,7 +252,7 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c)
#endif /* TM_HASH_STATS */
}
-/* hash statistics */
+/* list active transactions */
void tm_rpc_list(rpc_t* rpc, void* c)
{
int r;
@@ -294,3 +294,10 @@ void tm_rpc_list(rpc_t* rpc, void* c)
unlock_hash(r);
}
}
+
+
+/* rpc command to clean active but very old transactions */
+void tm_rpc_clean(rpc_t* rpc, void* c)
+{
+ tm_clean_lifetime();
+}
diff --git a/src/modules/tm/t_stats.h b/src/modules/tm/t_stats.h
index 0a0057c6203..bd21befd0fd 100644
--- a/src/modules/tm/t_stats.h
+++ b/src/modules/tm/t_stats.h
@@ -150,5 +150,6 @@ void tm_rpc_hash_stats(rpc_t* rpc, void* c);
typedef int (*tm_get_stats_f)(struct t_proc_stats *all);
int tm_get_stats(struct t_proc_stats *all);
void tm_rpc_list(rpc_t* rpc, void* c);
+void tm_rpc_clean(rpc_t* rpc, void* c);
#endif
diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c
index 7adaa8796d0..9bc1695a0f8 100644
--- a/src/modules/tm/tm.c
+++ b/src/modules/tm/tm.c
@@ -2521,6 +2521,11 @@ static const char* tm_rpc_list_doc[2] = {
0
};
+static const char* tm_rpc_clean_doc[2] = {
+ "Clean expired (lifetime exceeded) transactions.",
+ 0
+};
+
/* rpc exports */
static rpc_export_t tm_rpc[] = {
@@ -2532,6 +2537,7 @@ static rpc_export_t tm_rpc[] = {
{"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 },
{"tm.t_uac_wait", rpc_t_uac_wait, rpc_t_uac_wait_doc, RET_ARRAY},
{"tm.list", tm_rpc_list, tm_rpc_list_doc, RET_ARRAY},
+ {"tm.clean", tm_rpc_clean, tm_rpc_clean_doc, 0},
{0, 0, 0, 0}
};
diff --git a/src/modules/uid_auth_db/aaa_avps.h b/src/modules/uid_auth_db/aaa_avps.h
index 21f9954097d..62f1062bf3d 100644
--- a/src/modules/uid_auth_db/aaa_avps.h
+++ b/src/modules/uid_auth_db/aaa_avps.h
@@ -39,8 +39,8 @@
* Parse list of tokens separated by some char and put each token
* into result array. Caller frees result array!
*/
-static inline int
-parse_token_list(char *p, char *pend, char separator, str **result)
+static inline int parse_token_list(char *p, char *pend, char separator,
+ str **result)
{
int i;
@@ -63,29 +63,27 @@ parse_token_list(char *p, char *pend, char separator, str **result)
* Parse the list of AVP names separated by '|' into an array
* of names, each element of the array is str string
*/
-static int
-aaa_avps_init(str *avp_list, str **parsed_avps, int *avps_n)
+static int aaa_avps_init(str *avp_list, str **parsed_avps, int *avps_n)
{
int errcode, i;
char *cp;
if (!avp_list->s || !avp_list->len) {
- /* AVPs disabled, nothing to do */
+ /* AVPs disabled, nothing to do */
*avps_n = 0;
return 1;
}
cp = pkg_malloc(avp_list->len + 1);
if (cp == NULL) {
- LOG(L_ERR, "aaa_avps::aaa_avps_init(): can't allocate memory\n");
+ LM_ERR("can't allocate memory\n");
errcode = -1;
goto bad;
}
memcpy(cp, avp_list->s, avp_list->len);
*avps_n = parse_token_list(cp, cp + avp_list->len, '|', parsed_avps);
if (*avps_n == -1) {
- LOG(L_ERR, "aaa_avps::aaa_avps_init(): can't parse avps_column_int "
- "parameter\n");
+ LM_ERR("can't parse avps_column_int parameter\n");
errcode = -2;
pkg_free(cp);
goto bad;
diff --git a/src/modules/uid_auth_db/authorize.c b/src/modules/uid_auth_db/authorize.c
index cc3e9807079..0dd155adda9 100644
--- a/src/modules/uid_auth_db/authorize.c
+++ b/src/modules/uid_auth_db/authorize.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* Digest Authentication - Database support
*
* Copyright (C) 2001-2003 FhG Fokus
@@ -22,16 +20,10 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * history:
- * ---------
- * 2003-02-28 scratchpad compatibility abandoned
- * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
- * 2004-06-06 updated to the new DB api, added auth_db_{init,bind,close,ver}
- * (andrei)
*/
@@ -57,31 +49,31 @@
#define IS_NULL(f) ((f).flags & DB_NULL)
static inline int get_ha1(struct username* username, str* did, str* realm,
- authdb_table_info_t *table_info, char* ha1, db_res_t** res, db_rec_t** row)
+ authdb_table_info_t *table_info, char* ha1, db_res_t** res, db_rec_t** row)
{
str result;
db_cmd_t *q = NULL;
-
+
if (calc_ha1) {
q = table_info->query_password;
- DBG("querying plain password\n");
+ LM_DBG("querying plain password\n");
} else {
if (username->domain.len) {
q = table_info->query_pass2;
- DBG("querying ha1b\n");
+ LM_DBG("querying ha1b\n");
} else {
q = table_info->query_pass;
- DBG("querying ha1\n");
+ LM_DBG("querying ha1\n");
}
}
-
+
q->match[0].v.lstr = username->user;
q->match[1].v.lstr = *realm;
if (use_did) q->match[2].v.lstr = *did;
if (db_exec(res, q) < 0 ) {
- ERR("Error while querying database\n");
+ LM_ERR("Error while querying database\n");
return -1;
}
@@ -89,8 +81,10 @@ static inline int get_ha1(struct username* username, str* did, str* realm,
else *row = NULL;
while (*row) {
if (IS_NULL((*row)->fld[0]) || IS_NULL((*row)->fld[1])) {
- LOG(L_ERR, "auth_db:get_ha1: Credentials for '%.*s'@'%.*s' contain NULL value, skipping\n",
- username->user.len, ZSW(username->user.s), realm->len, ZSW(realm->s));
+ LM_ERR("Credentials for '%.*s'@'%.*s' contain NULL value,"
+ " skipping\n",
+ username->user.len, ZSW(username->user.s),
+ realm->len, ZSW(realm->s));
} else {
if ((*row)->fld[1].v.int4 & SRDB_DISABLED) {
/* disabled rows ignored */
@@ -105,10 +99,11 @@ static inline int get_ha1(struct username* username, str* did, str* realm,
}
if (!*row) {
- DBG("auth_db:get_ha1: Credentials for '%.*s'@'%.*s' not found\n",
- username->user.len, ZSW(username->user.s), realm->len, ZSW(realm->s));
+ LM_DBG("Credentials for '%.*s'@'%.*s' not found\n",
+ username->user.len, ZSW(username->user.s),
+ realm->len, ZSW(realm->s));
return 1;
- }
+ }
result.s = (*row)->fld[0].v.cstr;
result.len = strlen(result.s);
@@ -117,7 +112,7 @@ static inline int get_ha1(struct username* username, str* did, str* realm,
/* Only plaintext passwords are stored in database,
* we have to calculate HA1 */
auth_api.calc_HA1(HA_MD5, &username->whole, realm, &result, 0, 0, ha1);
- DBG("auth_db:get_ha1: HA1 string calculated: %s\n", ha1);
+ LM_DBG("HA1 string calculated: %s\n", ha1);
} else {
memcpy(ha1, result.s, result.len);
ha1[result.len] = '\0';
@@ -133,36 +128,36 @@ static inline int get_ha1(struct username* username, str* did, str* realm,
static inline int check_response(dig_cred_t* cred, str* method, char* ha1)
{
HASHHEX resp, hent;
-
+
/*
* First, we have to verify that the response received has
* the same length as responses created by us
*/
if (cred->response.len != 32) {
- DBG("auth_db:check_response: Receive response len != 32\n");
+ LM_DBG("Receive response len != 32\n");
return 1;
}
-
+
/*
* Now, calculate our response from parameters received
* from the user agent
*/
- auth_api.calc_response(ha1, &(cred->nonce),
- &(cred->nc), &(cred->cnonce),
- &(cred->qop.qop_str), cred->qop.qop_parsed == QOP_AUTHINT,
- method, &(cred->uri), hent, resp);
-
- DBG("auth_db:check_response: Our result = \'%s\'\n", resp);
-
+ auth_api.calc_response(ha1, &(cred->nonce),
+ &(cred->nc), &(cred->cnonce),
+ &(cred->qop.qop_str), cred->qop.qop_parsed == QOP_AUTHINT,
+ method, &(cred->uri), hent, resp);
+
+ LM_DBG("Our result = \'%s\'\n", resp);
+
/*
* And simply compare the strings, the user is
* authorized if they match
*/
if (!memcmp(resp, cred->response.s, 32)) {
- DBG("auth_db:check_response: Authorization is OK\n");
+ LM_DBG("Authorization is OK\n");
return 0;
} else {
- DBG("auth_db:check_response: Authorization failed\n");
+ LM_DBG("Authorization failed\n");
return 2;
}
}
@@ -177,7 +172,7 @@ static int generate_avps(db_res_t* result, db_rec_t *row)
int_str iname, ivalue;
str value;
char buf[32];
-
+
for (i = 2; i < credentials_n + 2; i++) {
value = row->fld[i].v.lstr;
@@ -185,18 +180,18 @@ static int generate_avps(db_res_t* result, db_rec_t *row)
continue;
switch (row->fld[i].type) {
- case DB_STR:
- value = row->fld[i].v.lstr;
- break;
-
- case DB_INT:
- value.len = sprintf(buf, "%d", row->fld[i].v.int4);
- value.s = buf;
- break;
-
- default:
- abort();
- break;
+ case DB_STR:
+ value = row->fld[i].v.lstr;
+ break;
+
+ case DB_INT:
+ value.len = sprintf(buf, "%d", row->fld[i].v.int4);
+ value.s = buf;
+ break;
+
+ default:
+ abort();
+ break;
}
if (value.s == NULL)
@@ -205,15 +200,16 @@ static int generate_avps(db_res_t* result, db_rec_t *row)
iname.s = credentials[i - 2];
ivalue.s = value;
- if (add_avp(AVP_NAME_STR | AVP_VAL_STR | AVP_CLASS_USER, iname, ivalue) < 0) {
- LOG(L_ERR, "auth_db:generate_avps: Error while creating AVPs\n");
+ if (add_avp(AVP_NAME_STR | AVP_VAL_STR | AVP_CLASS_USER,
+ iname, ivalue) < 0) {
+ LM_ERR("Error while creating AVPs\n");
return -1;
}
- DBG("auth_db:generate_avps: set string AVP \'%.*s = %.*s\'\n",
- iname.s.len, ZSW(iname.s.s), value.len, ZSW(value.s));
+ LM_DBG("set string AVP \'%.*s = %.*s\'\n",
+ iname.s.len, ZSW(iname.s.s), value.len, ZSW(value.s));
}
-
+
return 0;
}
@@ -226,32 +222,32 @@ static int generate_avps(db_res_t* result, db_rec_t *row)
* WARNING: if -1 is returned res _must_ _not_ be freed (it's empty)
*
*/
-static inline int check_all_ha1(struct sip_msg* msg, struct hdr_field* hdr,
- dig_cred_t* dig, str* method, str* did, str* realm,
- authdb_table_info_t *table_info, db_res_t** res)
+static inline int check_all_ha1(struct sip_msg* msg, struct hdr_field* hdr,
+ dig_cred_t* dig, str* method, str* did, str* realm,
+ authdb_table_info_t *table_info, db_res_t** res)
{
char ha1[256];
db_rec_t *row;
str result;
db_cmd_t *q;
-
+
if (calc_ha1) {
q = table_info->query_password;
- DBG("querying plain password\n");
+ LM_DBG("querying plain password\n");
}
else {
- if (dig->username.domain.len) {
+ if (dig->username.domain.len) {
q = table_info->query_pass2;
- DBG("querying ha1b\n");
+ LM_DBG("querying ha1b\n");
}
else {
q = table_info->query_pass;
- DBG("querying ha1\n");
+ LM_DBG("querying ha1\n");
}
}
-
+
q->match[0].v.lstr = dig->username.user;
- if (dig->username.domain.len)
+ if (dig->username.domain.len)
q->match[1].v.lstr = dig->username.domain;
else
q->match[1].v.lstr = *realm;
@@ -259,15 +255,17 @@ static inline int check_all_ha1(struct sip_msg* msg, struct hdr_field* hdr,
if (use_did) q->match[2].v.lstr = *did;
if (db_exec(res, q) < 0 ) {
- ERR("Error while querying database\n");
+ LM_ERR("Error while querying database\n");
}
if (*res) row = db_first(*res);
else row = NULL;
while (row) {
if (IS_NULL(row->fld[0]) || IS_NULL(row->fld[1])) {
- LOG(L_ERR, "auth_db:check_all_ha1: Credentials for '%.*s'@'%.*s' contain NULL value, skipping\n",
- dig->username.user.len, ZSW(dig->username.user.s), realm->len, ZSW(realm->s));
+ LM_ERR("Credentials for '%.*s'@'%.*s' contain NULL value,"
+ " skipping\n",
+ dig->username.user.len, ZSW(dig->username.user.s),
+ realm->len, ZSW(realm->s));
}
else {
if (row->fld[1].v.int4 & SRDB_DISABLED) {
@@ -278,17 +276,19 @@ static inline int check_all_ha1(struct sip_msg* msg, struct hdr_field* hdr,
result.s = row->fld[0].v.cstr;
result.len = strlen(result.s);
if (calc_ha1) {
- /* Only plaintext passwords are stored in database,
- * we have to calculate HA1 */
- auth_api.calc_HA1(HA_MD5, &(dig->username.whole), realm, &result, 0, 0, ha1);
- DBG("auth_db:check_all_ha1: HA1 string calculated: %s\n", ha1);
+ /* Only plaintext passwords are stored in database,
+ * we have to calculate HA1 */
+ auth_api.calc_HA1(HA_MD5, &(dig->username.whole),
+ realm, &result, 0, 0, ha1);
+ LM_DBG("HA1 string calculated: %s\n", ha1);
} else {
memcpy(ha1, result.s, result.len);
ha1[result.len] = '\0';
}
if (!check_response(dig, method, ha1)) {
- if (auth_api.post_auth(msg, hdr, ha1) == AUTHENTICATED) {
+ if (auth_api.post_auth(msg, hdr, ha1)
+ == AUTHENTICATED) {
generate_avps(*res, row);
return 0;
}
@@ -300,9 +300,10 @@ static inline int check_all_ha1(struct sip_msg* msg, struct hdr_field* hdr,
}
if (!row) {
- DBG("auth_db:check_all_ha1: Credentials for '%.*s'@'%.*s' not found",
- dig->username.user.len, ZSW(dig->username.user.s), realm->len, ZSW(realm->s));
- }
+ LM_DBG("Credentials for '%.*s'@'%.*s' not found",
+ dig->username.user.len, ZSW(dig->username.user.s),
+ realm->len, ZSW(realm->s));
+ }
return 1;
@@ -317,7 +318,8 @@ static inline int check_all_ha1(struct sip_msg* msg, struct hdr_field* hdr,
* -1 -- Authentication failed
* 1 -- Authentication successful
*/
-static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_info_t *table, hdr_types_t hftype)
+static inline int authenticate(struct sip_msg* msg, str* realm,
+ authdb_table_info_t *table, hdr_types_t hftype)
{
char ha1[256];
int res, ret;
@@ -326,51 +328,51 @@ static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_inf
auth_body_t* cred;
db_res_t* result;
str did;
-
+
cred = 0;
result = 0;
ret = -1;
-
+
switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) {
- case NONCE_REUSED:
- LM_DBG("nonce reused");
- ret = AUTH_NONCE_REUSED;
- goto end;
- case STALE_NONCE:
- LM_DBG("stale nonce\n");
- ret = AUTH_STALE_NONCE;
- goto end;
- case NO_CREDENTIALS:
- LM_DBG("no credentials\n");
- ret = AUTH_NO_CREDENTIALS;
- goto end;
- case ERROR:
- case BAD_CREDENTIALS:
- ret = -3;
- goto end;
- case CREATE_CHALLENGE:
- ERR("auth_db:authenticate: CREATE_CHALLENGE is not a valid state\n");
- ret = -2;
- goto end;
- case DO_RESYNCHRONIZATION:
- ERR("auth_db:authenticate: DO_RESYNCHRONIZATION is not a valid state\n");
- ret = -2;
- goto end;
-
- case NOT_AUTHENTICATED:
- ret = -1;
- goto end;
-
- case DO_AUTHENTICATION:
- break;
-
- case AUTHENTICATED:
- ret = 1;
- goto end;
+ case NONCE_REUSED:
+ LM_DBG("nonce reused");
+ ret = AUTH_NONCE_REUSED;
+ goto end;
+ case STALE_NONCE:
+ LM_DBG("stale nonce\n");
+ ret = AUTH_STALE_NONCE;
+ goto end;
+ case NO_CREDENTIALS:
+ LM_DBG("no credentials\n");
+ ret = AUTH_NO_CREDENTIALS;
+ goto end;
+ case ERROR:
+ case BAD_CREDENTIALS:
+ ret = -3;
+ goto end;
+ case CREATE_CHALLENGE:
+ LM_ERR("CREATE_CHALLENGE is not a valid state\n");
+ ret = -2;
+ goto end;
+ case DO_RESYNCHRONIZATION:
+ LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
+ ret = -2;
+ goto end;
+
+ case NOT_AUTHENTICATED:
+ ret = -1;
+ goto end;
+
+ case DO_AUTHENTICATION:
+ break;
+
+ case AUTHENTICATED:
+ ret = 1;
+ goto end;
}
-
+
cred = (auth_body_t*)h->parsed;
-
+
if (use_did) {
if (msg->REQ_METHOD == METHOD_REGISTER) {
ret = get_to_did(&did, msg);
@@ -384,11 +386,12 @@ static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_inf
} else {
did.len = 0;
did.s = 0;
- }
-
+ }
+
if (check_all) {
- res = check_all_ha1(msg, h, &(cred->digest), &msg->first_line.u.request.method, &did, realm, table, &result);
+ res = check_all_ha1(msg, h, &(cred->digest),
+ &msg->first_line.u.request.method, &did, realm, table, &result);
if (res < 0) {
ret = -2;
goto end;
@@ -401,8 +404,9 @@ static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_inf
ret = 1;
goto end;
}
- } else {
- res = get_ha1(&cred->digest.username, &did, realm, table, ha1, &result, &row);
+ } else {
+ res = get_ha1(&cred->digest.username, &did, realm, table, ha1,
+ &result, &row);
if (res < 0) {
ret = -2;
goto end;
@@ -411,39 +415,41 @@ static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_inf
/* Username not found in the database */
ret = -1;
goto end;
- }
- }
-
+ }
+ }
+
/* Recalculate response, it must be same to authorize successfully */
- if (!check_response(&(cred->digest), &msg->first_line.u.request.method, ha1)) {
+ if (!check_response(&(cred->digest), &msg->first_line.u.request.method,
+ ha1)) {
switch(auth_api.post_auth(msg, h, ha1)) {
- case ERROR:
- case BAD_CREDENTIALS:
- ret = -2;
- break;
-
- case NOT_AUTHENTICATED:
- ret = -1;
- break;
-
- case AUTHENTICATED:
- generate_avps(result, row);
- ret = 1;
- break;
-
- default:
- ret = -1;
- break;
+ case ERROR:
+ case BAD_CREDENTIALS:
+ ret = -2;
+ break;
+
+ case NOT_AUTHENTICATED:
+ ret = -1;
+ break;
+
+ case AUTHENTICATED:
+ generate_avps(result, row);
+ ret = 1;
+ break;
+
+ default:
+ ret = -1;
+ break;
}
} else {
ret = -1;
}
- end:
+end:
if (result) db_res_free(result);
if (ret < 0) {
- if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) {
- ERR("Error while creating challenge\n");
+ if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm,
+ NULL, NULL, hftype) < 0) {
+ LM_ERR("Error while creating challenge\n");
ret = -2;
}
}
@@ -459,7 +465,8 @@ int proxy_authenticate(struct sip_msg* msg, char* p1, char* p2)
str realm;
if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
- ERR("Cannot obtain digest realm from parameter '%s'\n", ((fparam_t*)p1)->orig);
+ LM_ERR("Cannot obtain digest realm from parameter '%s'\n",
+ ((fparam_t*)p1)->orig);
return -1;
}
@@ -475,9 +482,11 @@ int www_authenticate(struct sip_msg* msg, char* p1, char* p2)
str realm;
if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
- ERR("Cannot obtain digest realm from parameter '%s'\n", ((fparam_t*)p1)->orig);
+ LM_ERR("Cannot obtain digest realm from parameter '%s'\n",
+ ((fparam_t*)p1)->orig);
return -1;
}
- return authenticate(msg, &realm, (authdb_table_info_t*)p2, HDR_AUTHORIZATION_T);
+ return authenticate(msg, &realm, (authdb_table_info_t*)p2,
+ HDR_AUTHORIZATION_T);
}
diff --git a/src/modules/uid_auth_db/authorize.h b/src/modules/uid_auth_db/authorize.h
index d0f2a07d2f7..dbda474d5ca 100644
--- a/src/modules/uid_auth_db/authorize.h
+++ b/src/modules/uid_auth_db/authorize.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* Digest Authentication - Database support
*
* Copyright (C) 2001-2003 FhG Fokus
@@ -22,8 +20,8 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
diff --git a/src/modules/uid_auth_db/uid_auth_db_mod.c b/src/modules/uid_auth_db/uid_auth_db_mod.c
index 56ee952cea9..d67e40806a0 100644
--- a/src/modules/uid_auth_db/uid_auth_db_mod.c
+++ b/src/modules/uid_auth_db/uid_auth_db_mod.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* Digest Authentication Module
*
* Copyright (C) 2001-2003 FhG Fokus
@@ -26,14 +24,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * History:
- * --------
- * 2003-02-26: checks and group moved to separate modules (janakj)
- * 2003-03-11: New module interface (janakj)
- * 2003-03-16: flags export parameter added (janakj)
- * 2003-03-19 all mallocs/frees replaced w/ pkg_malloc/pkg_free (andrei)
- * 2003-04-05: default_uri #define used (jiri)
- * 2004-06-06 cleanup: static & auth_db_{init,bind,close.ver} used (andrei)
*/
#include
@@ -113,11 +103,11 @@ int credentials_n; /* Number of credentials in the list */
* Exported functions
*/
static cmd_export_t cmds[] = {
- {"www_authenticate", www_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
- {"www_authorize", www_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
- {"proxy_authenticate", proxy_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
- {"proxy_authorize", proxy_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
- {0, 0, 0, 0, 0}
+ {"www_authenticate", www_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
+ {"www_authorize", www_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
+ {"proxy_authenticate", proxy_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
+ {"proxy_authorize", proxy_authenticate, 2, authdb_fixup, REQUEST_ROUTE},
+ {0, 0, 0, 0, 0}
};
@@ -125,19 +115,19 @@ static cmd_export_t cmds[] = {
* Exported parameters
*/
static param_export_t params[] = {
- {"db_url", PARAM_STRING, &db_url },
- {"username_column", PARAM_STR, &username_column },
- {"did_column", PARAM_STR, &did_column },
- {"realm_column", PARAM_STR, &realm_column },
- {"password_column", PARAM_STR, &pass_column },
- {"password_column_2", PARAM_STR, &pass_column_2 },
- {"plain_password_column", PARAM_STR, &plain_password_column },
- {"flags_column", PARAM_STR, &flags_column },
- {"calculate_ha1", PARAM_INT, &calc_ha1 },
- {"load_credentials", PARAM_STR, &credentials_list},
- {"use_did", PARAM_INT, &use_did },
- {"check_all_ha1", PARAM_INT, &check_all },
- {0, 0, 0}
+ {"db_url", PARAM_STRING, &db_url },
+ {"username_column", PARAM_STR, &username_column },
+ {"did_column", PARAM_STR, &did_column },
+ {"realm_column", PARAM_STR, &realm_column },
+ {"password_column", PARAM_STR, &pass_column },
+ {"password_column_2", PARAM_STR, &pass_column_2 },
+ {"plain_password_column", PARAM_STR, &plain_password_column },
+ {"flags_column", PARAM_STR, &flags_column },
+ {"calculate_ha1", PARAM_INT, &calc_ha1 },
+ {"load_credentials", PARAM_STR, &credentials_list},
+ {"use_did", PARAM_INT, &use_did },
+ {"check_all_ha1", PARAM_INT, &check_all },
+ {0, 0, 0}
};
@@ -145,15 +135,15 @@ static param_export_t params[] = {
* Module interface
*/
struct module_exports exports = {
- "uid_auth_db",
- cmds, /* Exported functions */
- 0, /* RPC methods */
- params, /* Exported parameters */
- mod_init, /* module initialization function */
- 0, /* response function */
- destroy, /* destroy function */
- 0, /* oncancel function */
- child_init /* child initialization function */
+ "uid_auth_db",
+ cmds, /* Exported functions */
+ 0, /* RPC methods */
+ params, /* Exported parameters */
+ mod_init, /* module initialization function */
+ 0, /* response function */
+ destroy, /* destroy function */
+ 0, /* oncancel function */
+ child_init /* child initialization function */
};
static authdb_table_info_t *registered_tables = NULL;
@@ -161,14 +151,14 @@ static authdb_table_info_t *registered_tables = NULL;
static int generate_queries(authdb_table_info_t *info)
{
db_fld_t match_with_did[] = {
- { .name = username_column.s, .type = DB_STR },
- { .name = realm_column.s, .type = DB_STR },
- { .name = did_column.s, .type = DB_STR },
+ { .name = username_column.s, .type = DB_STR },
+ { .name = realm_column.s, .type = DB_STR },
+ { .name = did_column.s, .type = DB_STR },
{ .name = NULL }
};
db_fld_t match_without_did[] = {
- { .name = username_column.s, .type = DB_STR },
- { .name = realm_column.s, .type = DB_STR },
+ { .name = username_column.s, .type = DB_STR },
+ { .name = realm_column.s, .type = DB_STR },
{ .name = NULL }
};
db_fld_t *result_cols = NULL;
@@ -184,7 +174,7 @@ static int generate_queries(authdb_table_info_t *info)
result_cols[0].name = pass_column.s;
result_cols[0].type = DB_CSTR;
-
+
result_cols[1].name = flags_column.s;
result_cols[1].type = DB_INT;
for (i = 0; i < credentials_n; i++) {
@@ -194,23 +184,23 @@ static int generate_queries(authdb_table_info_t *info)
result_cols[2 + i].name = NULL;
if (use_did) {
- info->query_pass = db_cmd(DB_GET, auth_db_handle, info->table.s,
+ info->query_pass = db_cmd(DB_GET, auth_db_handle, info->table.s,
result_cols, match_with_did, NULL);
result_cols[0].name = pass_column_2.s;
- info->query_pass2 = db_cmd(DB_GET, auth_db_handle, info->table.s,
+ info->query_pass2 = db_cmd(DB_GET, auth_db_handle, info->table.s,
result_cols, match_with_did, NULL);
result_cols[0].name = plain_password_column.s;
- info->query_password = db_cmd(DB_GET, auth_db_handle, info->table.s,
+ info->query_password = db_cmd(DB_GET, auth_db_handle, info->table.s,
result_cols, match_with_did, NULL);
}
else {
- info->query_pass = db_cmd(DB_GET, auth_db_handle, info->table.s,
+ info->query_pass = db_cmd(DB_GET, auth_db_handle, info->table.s,
result_cols, match_without_did, NULL);
result_cols[0].name = pass_column_2.s;
- info->query_pass2 = db_cmd(DB_GET, auth_db_handle, info->table.s,
+ info->query_pass2 = db_cmd(DB_GET, auth_db_handle, info->table.s,
result_cols, match_without_did, NULL);
result_cols[0].name = plain_password_column.s;
- info->query_password = db_cmd(DB_GET, auth_db_handle, info->table.s,
+ info->query_password = db_cmd(DB_GET, auth_db_handle, info->table.s,
result_cols, match_without_did, NULL);
}
@@ -235,12 +225,12 @@ static int child_init(int rank)
i = registered_tables;
while (i) {
if (generate_queries(i) < 0) {
- ERR("can't prepare queries\n");
+ LM_ERR("can't prepare queries\n");
return -1;
}
i = i->next;
}
-
+
return 0;
err:
@@ -250,56 +240,56 @@ static int child_init(int rank)
db_ctx_free(auth_db_handle);
}
- ERR("Error while initializing database layer\n");
+ LM_ERR("Error while initializing database layer\n");
return -1;
}
static int mod_init(void)
{
- bind_auth_s_t bind_auth;
-
- DBG("auth_db module - initializing\n");
-
- bind_auth = (bind_auth_s_t)find_export("bind_auth_s", 0, 0);
- if (!bind_auth) {
- LOG(L_ERR, "auth_db:mod_init: Unable to find bind_auth function\n");
- return -1;
- }
- if (bind_auth(&auth_api) < 0) {
- LOG(L_ERR, "auth_db:child_init: Unable to bind auth module\n");
- return -3;
- }
-
- if (aaa_avps_init(&credentials_list, &credentials, &credentials_n)) {
- return -1;
- }
-
- return 0;
+ bind_auth_s_t bind_auth;
+
+ LM_DBG("auth_db module - initializing\n");
+
+ bind_auth = (bind_auth_s_t)find_export("bind_auth_s", 0, 0);
+ if (!bind_auth) {
+ LM_ERR("Unable to find bind_auth function\n");
+ return -1;
+ }
+ if (bind_auth(&auth_api) < 0) {
+ LM_ERR("Unable to bind auth module\n");
+ return -3;
+ }
+
+ if (aaa_avps_init(&credentials_list, &credentials, &credentials_n)) {
+ return -1;
+ }
+
+ return 0;
}
static void destroy(void)
{
- if (auth_db_handle) {
+ if (auth_db_handle) {
db_ctx_free(auth_db_handle);
auth_db_handle = NULL;
- }
+ }
}
static int str_case_equals(const str *a, const str *b)
{
/* ugly hack: taken from libcds */
int i;
-
+
if (!a) {
if (!b) return 0;
else return (b->len == 0) ? 0 : 1;
}
if (!b) return (a->len == 0) ? 0 : 1;
if (a->len != b->len) return 1;
-
- for (i = 0; i < a->len; i++)
+
+ for (i = 0; i < a->len; i++)
if (a->s[i] != b->s[i]) return 1;
return 0;
}
@@ -307,9 +297,9 @@ static int str_case_equals(const str *a, const str *b)
static authdb_table_info_t *find_table_info(str *table)
{
authdb_table_info_t *i = registered_tables;
-
+
/* sequential search is OK because it is called only in child init */
- while (i) {
+ while (i) {
if (str_case_equals(&i->table, table) == 0) return i;
i = i->next;
}
@@ -323,9 +313,10 @@ static authdb_table_info_t *register_table(str *table)
info = find_table_info(table);
if (info) return info; /* queries for this table already exist */
- info = (authdb_table_info_t*)pkg_malloc(sizeof(authdb_table_info_t) + table->len + 1);
+ info = (authdb_table_info_t*)pkg_malloc(sizeof(authdb_table_info_t)
+ + table->len + 1);
if (!info) {
- ERR("can't allocate pkg mem\n");
+ LM_ERR("can't allocate pkg mem\n");
return NULL;
}
@@ -359,11 +350,12 @@ static int authdb_fixup(void** param, int param_no)
return -1;
}
} else {
- ERR("Non-string value of table with credentials is not allowed.\n");
+ LM_ERR("Non-string value of table with credentials"
+ " is not allowed.\n");
/* TODO: allow this too */
return -1;
}
}
- return 0;
+ return 0;
}
diff --git a/src/modules/uid_auth_db/uid_auth_db_mod.h b/src/modules/uid_auth_db/uid_auth_db_mod.h
index 25ae11e7c91..00dc138d07c 100644
--- a/src/modules/uid_auth_db/uid_auth_db_mod.h
+++ b/src/modules/uid_auth_db/uid_auth_db_mod.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* Digest Authentication - Database support
*
* Copyright (C) 2001-2003 FhG Fokus
@@ -22,8 +20,8 @@
* 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
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,8 +43,8 @@ extern str did_column; /* 'did' column name */
extern str realm_column; /* 'realm' column name */
extern str pass_column; /* 'password' column name */
extern str pass_column_2; /* Column containing HA1 string constructed
- * of user@domain username
- */
+ * of user@domain username
+ */
extern str flags_column; /* Flags column in credentials table */
extern int calc_ha1; /* if set to 1, ha1 is calculated by the server */
diff --git a/src/modules/uid_uri_db/uid_uri_db_mod.c b/src/modules/uid_uri_db/uid_uri_db_mod.c
index b7bff72e728..e3887fb75d3 100644
--- a/src/modules/uid_uri_db/uid_uri_db_mod.c
+++ b/src/modules/uid_uri_db/uid_uri_db_mod.c
@@ -395,7 +395,7 @@ static int lookup_user_2(struct sip_msg* msg, char* attr, char* select)
while(rec) {
if (rec->fld[0].flags & DB_NULL ||
rec->fld[1].flags & DB_NULL) {
- LOG(L_ERR, "lookup_user: Bogus line in %s table\n", uri_table.s);
+ LM_ERR("bogus line in %s table\n", uri_table.s);
goto skip;
}
diff --git a/src/modules/usrloc/ul_rpc.c b/src/modules/usrloc/ul_rpc.c
index bace4885e1c..c27921d0fc7 100644
--- a/src/modules/usrloc/ul_rpc.c
+++ b/src/modules/usrloc/ul_rpc.c
@@ -31,11 +31,11 @@
/*! CSEQ nr used */
#define RPC_UL_CSEQ 1
/*! call-id used for ul_add and ul_rm_contact */
-static str rpc_ul_cid = str_init("dfjrewr12386fd6-343@kamailio.mi");
+static str rpc_ul_cid = str_init("dfjrewr12386fd6-343@kamailio.rpc");
/*! path used for ul_add and ul_rm_contact */
static str rpc_ul_path = str_init("dummypath");
/*! user agent used for ul_add */
-static str rpc_ul_ua = str_init("SIP Router MI Server");
+static str rpc_ul_ua = str_init(NAME " SIP Router - RPC Server");
extern sruid_t _ul_sruid;
@@ -65,10 +65,10 @@ int rpc_dump_contact(rpc_t* rpc, void* ctx, void *ih, ucontact_t* c)
return -1;
}
if (c->expires == 0) { if(rpc->struct_add(vh, "s", "Expires", "permanent")<0)
- {
+ {
rpc->fault(ctx, 500, "Internal error adding expire");
return -1;
- }
+ }
} else if (c->expires == UL_EXPIRED_TIME) {
if(rpc->struct_add(vh, "s", "Expires", "deleted")<0)
{
@@ -122,19 +122,19 @@ int rpc_dump_contact(rpc_t* rpc, void* ctx, void *ih, ucontact_t* c)
return -1;
}
if(rpc->struct_add(vh, "S", "User-Agent",
- (c->user_agent.len)?&c->user_agent: &empty_str)<0)
+ (c->user_agent.len)?&c->user_agent: &empty_str)<0)
{
rpc->fault(ctx, 500, "Internal error adding user-agent");
return -1;
}
if(rpc->struct_add(vh, "S", "Received",
- (c->received.len)?&c->received: &empty_str)<0)
+ (c->received.len)?&c->received: &empty_str)<0)
{
rpc->fault(ctx, 500, "Internal error adding received");
return -1;
}
if(rpc->struct_add(vh, "S", "Path",
- (c->path.len)?&c->path: &empty_str)<0)
+ (c->path.len)?&c->path: &empty_str)<0)
{
rpc->fault(ctx, 500, "Internal error adding path");
return -1;
@@ -170,7 +170,7 @@ int rpc_dump_contact(rpc_t* rpc, void* ctx, void *ih, ucontact_t* c)
return -1;
}
if(rpc->struct_add(vh, "S", "Instance",
- (c->instance.len)?&c->instance: &empty_str)<0)
+ (c->instance.len)?&c->instance: &empty_str)<0)
{
rpc->fault(ctx, 500, "Internal error adding instance");
return -1;
@@ -180,17 +180,17 @@ int rpc_dump_contact(rpc_t* rpc, void* ctx, void *ih, ucontact_t* c)
rpc->fault(ctx, 500, "Internal error adding reg_id");
return -1;
}
- if(rpc->struct_add(vh, "d", "Server-Id", c->server_id)<0)
+ if(rpc->struct_add(vh, "d", "Server-Id", c->server_id)<0)
{
rpc->fault(ctx, 500, "Internal error adding server_id");
return -1;
}
- if(rpc->struct_add(vh, "d", "Tcpconn-Id", c->tcpconn_id)<0)
+ if(rpc->struct_add(vh, "d", "Tcpconn-Id", c->tcpconn_id)<0)
{
rpc->fault(ctx, 500, "Internal error adding tcpconn_id");
return -1;
}
- if(rpc->struct_add(vh, "d", "Keepalive", c->keepalive)<0)
+ if(rpc->struct_add(vh, "d", "Keepalive", c->keepalive)<0)
{
rpc->fault(ctx, 500, "Internal error adding keepalive");
return -1;
@@ -227,7 +227,7 @@ static void ul_rpc_dump(rpc_t* rpc, void* ctx)
if(brief.len==5 && (strncmp(brief.s, "brief", 5)==0))
summary = 1;
-
+
for( dl=root ; dl ; dl=dl->next ) {
dom = dl->d;
if (rpc->add(ctx, "{", &th) < 0)
@@ -252,23 +252,23 @@ static void ul_rpc_dump(rpc_t* rpc, void* ctx)
if(summary==1)
{
if(rpc->struct_add(ah, "S",
- "AoR", &r->aor)<0)
+ "AoR", &r->aor)<0)
{
rpc->fault(ctx, 500, "Internal error creating aor struct");
return;
}
} else {
if(rpc->struct_add(ah, "{",
- "Info", &bh)<0)
+ "Info", &bh)<0)
{
unlock_ulslot( dom, i);
rpc->fault(ctx, 500, "Internal error creating aor struct");
return;
}
if(rpc->struct_add(bh, "Sd[",
- "AoR", &r->aor,
- "HashID", r->aorhash,
- "Contacts", &ih)<0)
+ "AoR", &r->aor,
+ "HashID", r->aorhash,
+ "Contacts", &ih)<0)
{
unlock_ulslot( dom, i);
rpc->fault(ctx, 500, "Internal error creating aor struct");
@@ -294,8 +294,8 @@ static void ul_rpc_dump(rpc_t* rpc, void* ctx)
return;
}
if(rpc->struct_add(sh, "dd",
- "Records", n,
- "Max-Slots", max)<0)
+ "Records", n,
+ "Max-Slots", max)<0)
{
rpc->fault(ctx, 500, "Internal error adding stats");
return;
@@ -319,7 +319,7 @@ static inline udomain_t* rpc_find_domain(str* table)
for( dom=root ; dom ; dom=dom->next ) {
if ((dom->name.len == table->len) &&
- !memcmp(dom->name.s, table->s, table->len))
+ !memcmp(dom->name.s, table->s, table->len))
return dom->d;
}
return 0;
@@ -410,8 +410,8 @@ static void ul_rpc_lookup(rpc_t* rpc, void* ctx)
return;
}
if(rpc->struct_add(th, "S[",
- "AoR", &aor,
- "Contacts", &ih)<0)
+ "AoR", &aor,
+ "Contacts", &ih)<0)
{
unlock_udomain(dom, &aor);
rpc->fault(ctx, 500, "Internal error creating aor struct");
@@ -578,7 +578,7 @@ static void ul_rpc_add(rpc_t* rpc, void* ctx)
memset( &ci, 0, sizeof(ucontact_info_t));
ret = rpc->scan(ctx, "SSSdfSddd", &table, &aor, &contact, &ci.expires,
- &dtemp, &path, &ci.flags, &ci.cflags, &ci.methods);
+ &dtemp, &path, &ci.flags, &ci.cflags, &ci.methods);
if(path.len==1 && (strncmp(path.s, "0", 1)==0)) {
LM_DBG("path == 0 -> unset\n");
}
@@ -586,8 +586,8 @@ static void ul_rpc_add(rpc_t* rpc, void* ctx)
ci.path = &path;
}
LM_DBG("ret: %d table:%.*s aor:%.*s contact:%.*s expires:%d dtemp:%f path:%.*s flags:%d bflags:%d methods:%d\n",
- ret, table.len, table.s, aor.len, aor.s, contact.len, contact.s,
- (int) ci.expires, dtemp, (ci.path)?ci.path->len:0, (ci.path && ci.path->s)?ci.path->s:"", ci.flags, ci.cflags, (int) ci.methods);
+ ret, table.len, table.s, aor.len, aor.s, contact.len, contact.s,
+ (int) ci.expires, dtemp, (ci.path)?ci.path->len:0, (ci.path && ci.path->s)?ci.path->s:"", ci.flags, ci.cflags, (int) ci.methods);
if ( ret != 9) {
rpc->fault(ctx, 500, "Not enough parameters or wrong format");
return;
@@ -676,52 +676,52 @@ static const char* ul_rpc_add_doc[2] = {
static void ul_rpc_db_users(rpc_t* rpc, void* ctx)
{
- str table = {0, 0};
- char query[QUERY_LEN];
- str query_str;
- db1_res_t* res;
- int count;
-
- if (db_mode == NO_DB) {
- rpc->fault(ctx, 500, "Command is not supported in db_mode=0");
- return;
- }
+ str table = {0, 0};
+ char query[QUERY_LEN];
+ str query_str;
+ db1_res_t* res;
+ int count;
- if (rpc->scan(ctx, "S", &table) != 1) {
- rpc->fault(ctx, 500, "Not enough parameters (table to lookup)");
- return;
- }
+ if (db_mode == NO_DB) {
+ rpc->fault(ctx, 500, "Command is not supported in db_mode=0");
+ return;
+ }
- if (user_col.len + domain_col.len + table.len + 32 > QUERY_LEN) {
- rpc->fault(ctx, 500, "Too long database query");
- return;
- }
+ if (rpc->scan(ctx, "S", &table) != 1) {
+ rpc->fault(ctx, 500, "Not enough parameters (table to lookup)");
+ return;
+ }
- if (!DB_CAPABILITY(ul_dbf, DB_CAP_RAW_QUERY)) {
- rpc->fault(ctx, 500, "Database does not support raw queries");
- return;
- }
- if (ul_dbf.use_table(ul_dbh, &table) < 0) {
- rpc->fault(ctx, 500, "Failed to use table");
- return;
- }
-
- memset(query, 0, QUERY_LEN);
- query_str.len = snprintf(query, QUERY_LEN,
- "SELECT COUNT(DISTINCT %.*s, %.*s) FROM %.*s WHERE (UNIX_TIMESTAMP(expires) = 0) OR (expires > NOW())",
- user_col.len, user_col.s,
- domain_col.len, domain_col.s,
- table.len, table.s);
- query_str.s = query;
- if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) {
- rpc->fault(ctx, 500, "Failed to query AoR count");
- return;
- }
+ if (user_col.len + domain_col.len + table.len + 32 > QUERY_LEN) {
+ rpc->fault(ctx, 500, "Too long database query");
+ return;
+ }
+
+ if (!DB_CAPABILITY(ul_dbf, DB_CAP_RAW_QUERY)) {
+ rpc->fault(ctx, 500, "Database does not support raw queries");
+ return;
+ }
+ if (ul_dbf.use_table(ul_dbh, &table) < 0) {
+ rpc->fault(ctx, 500, "Failed to use table");
+ return;
+ }
+
+ memset(query, 0, QUERY_LEN);
+ query_str.len = snprintf(query, QUERY_LEN,
+ "SELECT COUNT(DISTINCT %.*s, %.*s) FROM %.*s WHERE (UNIX_TIMESTAMP(expires) = 0) OR (expires > NOW())",
+ user_col.len, user_col.s,
+ domain_col.len, domain_col.s,
+ table.len, table.s);
+ query_str.s = query;
+ if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) {
+ rpc->fault(ctx, 500, "Failed to query AoR count");
+ return;
+ }
- count = (int)VAL_INT(ROW_VALUES(RES_ROWS(res)));
- ul_dbf.free_result(ul_dbh, res);
+ count = (int)VAL_INT(ROW_VALUES(RES_ROWS(res)));
+ ul_dbf.free_result(ul_dbh, res);
- rpc->add(ctx, "d", count);
+ rpc->add(ctx, "d", count);
}
static const char* ul_rpc_db_users_doc[2] = {
@@ -731,49 +731,49 @@ static const char* ul_rpc_db_users_doc[2] = {
static void ul_rpc_db_contacts(rpc_t* rpc, void* ctx)
{
- str table = {0, 0};
- char query[QUERY_LEN];
- str query_str;
- db1_res_t* res;
- int count;
-
- if (db_mode == NO_DB) {
- rpc->fault(ctx, 500, "Command is not supported in db_mode=0");
- return;
- }
+ str table = {0, 0};
+ char query[QUERY_LEN];
+ str query_str;
+ db1_res_t* res;
+ int count;
- if (rpc->scan(ctx, "S", &table) != 1) {
- rpc->fault(ctx, 500, "Not enough parameters (table to lookup)");
- return;
- }
+ if (db_mode == NO_DB) {
+ rpc->fault(ctx, 500, "Command is not supported in db_mode=0");
+ return;
+ }
- if (table.len + 22 > QUERY_LEN) {
- rpc->fault(ctx, 500, "Too long database query");
- return;
- }
+ if (rpc->scan(ctx, "S", &table) != 1) {
+ rpc->fault(ctx, 500, "Not enough parameters (table to lookup)");
+ return;
+ }
- if (!DB_CAPABILITY(ul_dbf, DB_CAP_RAW_QUERY)) {
- rpc->fault(ctx, 500, "Database does not support raw queries");
- return;
- }
- if (ul_dbf.use_table(ul_dbh, &table) < 0) {
- rpc->fault(ctx, 500, "Failed to use table");
- return;
- }
-
- memset(query, 0, QUERY_LEN);
- query_str.len = snprintf(query, QUERY_LEN, "SELECT COUNT(*) FROM %.*s WHERE (UNIX_TIMESTAMP(expires) = 0) OR (expires > NOW())",
- table.len, table.s);
- query_str.s = query;
- if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) {
- rpc->fault(ctx, 500, "Failed to query contact count");
- return;
- }
+ if (table.len + 22 > QUERY_LEN) {
+ rpc->fault(ctx, 500, "Too long database query");
+ return;
+ }
+
+ if (!DB_CAPABILITY(ul_dbf, DB_CAP_RAW_QUERY)) {
+ rpc->fault(ctx, 500, "Database does not support raw queries");
+ return;
+ }
+ if (ul_dbf.use_table(ul_dbh, &table) < 0) {
+ rpc->fault(ctx, 500, "Failed to use table");
+ return;
+ }
- count = (int)VAL_INT(ROW_VALUES(RES_ROWS(res)));
- ul_dbf.free_result(ul_dbh, res);
+ memset(query, 0, QUERY_LEN);
+ query_str.len = snprintf(query, QUERY_LEN, "SELECT COUNT(*) FROM %.*s WHERE (UNIX_TIMESTAMP(expires) = 0) OR (expires > NOW())",
+ table.len, table.s);
+ query_str.s = query;
+ if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) {
+ rpc->fault(ctx, 500, "Failed to query contact count");
+ return;
+ }
- rpc->add(ctx, "d", count);
+ count = (int)VAL_INT(ROW_VALUES(RES_ROWS(res)));
+ ul_dbf.free_result(ul_dbh, res);
+
+ rpc->add(ctx, "d", count);
}
static const char* ul_rpc_db_contacts_doc[2] = {
@@ -783,49 +783,49 @@ static const char* ul_rpc_db_contacts_doc[2] = {
static void ul_rpc_db_expired_contacts(rpc_t* rpc, void* ctx)
{
- str table = {0, 0};
- char query[QUERY_LEN];
- str query_str;
- db1_res_t* res;
- int count;
-
- if (db_mode == NO_DB) {
- rpc->fault(ctx, 500, "Command is not supported in db_mode=0");
- return;
- }
+ str table = {0, 0};
+ char query[QUERY_LEN];
+ str query_str;
+ db1_res_t* res;
+ int count;
- if (rpc->scan(ctx, "S", &table) != 1) {
- rpc->fault(ctx, 500, "Not enough parameters (table to lookup)");
- return;
- }
+ if (db_mode == NO_DB) {
+ rpc->fault(ctx, 500, "Command is not supported in db_mode=0");
+ return;
+ }
- if (table.len + 22 > QUERY_LEN) {
- rpc->fault(ctx, 500, "Too long database query");
- return;
- }
+ if (rpc->scan(ctx, "S", &table) != 1) {
+ rpc->fault(ctx, 500, "Not enough parameters (table to lookup)");
+ return;
+ }
- if (!DB_CAPABILITY(ul_dbf, DB_CAP_RAW_QUERY)) {
- rpc->fault(ctx, 500, "Database does not support raw queries");
- return;
- }
- if (ul_dbf.use_table(ul_dbh, &table) < 0) {
- rpc->fault(ctx, 500, "Failed to use table");
- return;
- }
-
- memset(query, 0, QUERY_LEN);
- query_str.len = snprintf(query, QUERY_LEN, "SELECT COUNT(*) FROM %.*s WHERE (UNIX_TIMESTAMP(expires) > 0) AND (expires <= NOW())",
- table.len, table.s);
- query_str.s = query;
- if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) {
- rpc->fault(ctx, 500, "Failed to query contact count");
- return;
- }
+ if (table.len + 22 > QUERY_LEN) {
+ rpc->fault(ctx, 500, "Too long database query");
+ return;
+ }
+
+ if (!DB_CAPABILITY(ul_dbf, DB_CAP_RAW_QUERY)) {
+ rpc->fault(ctx, 500, "Database does not support raw queries");
+ return;
+ }
+ if (ul_dbf.use_table(ul_dbh, &table) < 0) {
+ rpc->fault(ctx, 500, "Failed to use table");
+ return;
+ }
+
+ memset(query, 0, QUERY_LEN);
+ query_str.len = snprintf(query, QUERY_LEN, "SELECT COUNT(*) FROM %.*s WHERE (UNIX_TIMESTAMP(expires) > 0) AND (expires <= NOW())",
+ table.len, table.s);
+ query_str.s = query;
+ if (ul_dbf.raw_query(ul_dbh, &query_str, &res) < 0) {
+ rpc->fault(ctx, 500, "Failed to query contact count");
+ return;
+ }
- count = (int)VAL_INT(ROW_VALUES(RES_ROWS(res)));
- ul_dbf.free_result(ul_dbh, res);
+ count = (int)VAL_INT(ROW_VALUES(RES_ROWS(res)));
+ ul_dbf.free_result(ul_dbh, res);
- rpc->add(ctx, "d", count);
+ rpc->add(ctx, "d", count);
}
static const char* ul_rpc_db_expired_contacts_doc[2] = {