Browse Source

Merge remote branch 'origin/sr_3.0'

* origin/sr_3.0:
  tm: fix setting the pre-T callbacks
  drouting: register MI commands
  drouting(k): Makefile updated to link libs
  registrar(k): preserve old bflags upon lookup
  pv: fixed author name
  tm: set request and reply for TMCB_RESPONSE_SENT
  tm: run release function for tmcb parameters
  tm: t_on_xyz("0") fixup updates
  core: usage of drop in onsend_route for Kamailio compatibility
  core: exit() is now equivalent to exit 1
  core: drop reply ser compatibility
  core: drop reply in K compatible style
  sanity: fix include file due to previous re-location
  sanity: moved module from modules_s to modules
Andrei Pelinescu-Onciul 15 years ago
parent
commit
13ecdcd7dd

+ 4 - 2
cfg.y

@@ -3239,7 +3239,8 @@ ret_cmd:
 						(void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
 	}
 	| EXIT LPAREN RPAREN		{
-		$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F);
+		$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
+						(void*)EXIT_R_F);
 		set_cfg_pos($$);
 	}
 	| EXIT rval_expr	{
@@ -3247,7 +3248,8 @@ ret_cmd:
 		set_cfg_pos($$);
 	}
 	| EXIT				{
-		$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST, (void*)EXIT_R_F);
+		$$=mk_action(DROP_T, 2, NUMBER_ST, (void*)1, NUMBER_ST,
+						(void*)EXIT_R_F);
 		set_cfg_pos($$);
 	}
 	| RETURN			{

+ 0 - 0
modules_s/sanity/Makefile → modules/sanity/Makefile


+ 0 - 0
modules_s/sanity/README → modules/sanity/README


+ 0 - 0
modules_s/sanity/doc/Makefile → modules/sanity/doc/Makefile


+ 0 - 0
modules_s/sanity/doc/functions.xml → modules/sanity/doc/functions.xml


+ 0 - 0
modules_s/sanity/doc/params.xml → modules/sanity/doc/params.xml


+ 0 - 0
modules_s/sanity/doc/sanity.xml → modules/sanity/doc/sanity.xml


+ 0 - 0
modules_s/sanity/mod_sanity.c → modules/sanity/mod_sanity.c


+ 1 - 1
modules_s/sanity/mod_sanity.h → modules/sanity/mod_sanity.h

@@ -32,7 +32,7 @@
 #define MOD_SANITY_CHK_H
 
 #include "../../str.h"
-#include "../sl/sl.h"
+#include "../../modules_s/sl/sl.h"
 #include "../../parser/msg_parser.h"
 
 #define SANITY_RURI_SIP_VERSION        (1<<0)

+ 0 - 0
modules_s/sanity/sanity.c → modules/sanity/sanity.c


+ 0 - 0
modules_s/sanity/sanity.h → modules/sanity/sanity.h


+ 4 - 1
modules/tm/h_table.c

@@ -325,8 +325,11 @@ struct cell*  build_cell( struct sip_msg* p_msg )
 
 	/* enter callback, which may potentially want to parse some stuff,
 	 * before the request is shmem-ized */
-	if (p_msg && has_reqin_tmcbs())
+	if (p_msg) {
+		set_early_tmcb_list(p_msg, new_cell);
+		if(has_reqin_tmcbs())
 			run_reqin_callbacks( new_cell, p_msg, p_msg->REQ_METHOD);
+	}
 
 	if (p_msg) {
 #ifndef POSTPONE_MSG_CLONING

+ 40 - 11
modules/tm/t_hooks.c

@@ -57,7 +57,36 @@
 struct tmcb_head_list* req_in_tmcb_hl = 0;
 struct tmcb_head_list* local_req_in_tmcb_hl = 0;
 
+struct tm_early_cb {
+	unsigned int msgid;
+	struct tmcb_head_list cb_list;
+} tmcb_early_hl = { 0, {0, 0} };
 
+struct tmcb_head_list* get_early_tmcb_list(struct sip_msg *msg)
+{
+	struct tm_callback *cbp, *cbp_tmp;
+	if (msg->id!=tmcb_early_hl.msgid) {
+		for( cbp=(struct tm_callback*)tmcb_early_hl.cb_list.first; cbp ; ) {
+			cbp_tmp = cbp;
+			cbp = cbp->next;
+			if (cbp_tmp->param && cbp_tmp->release)
+					cbp_tmp->release( cbp_tmp->param );
+			shm_free( cbp_tmp );
+		}
+		memset(&tmcb_early_hl.cb_list, 0, sizeof(struct tmcb_head_list));
+		tmcb_early_hl.msgid = msg->id;
+	}
+	return &tmcb_early_hl.cb_list;
+}
+
+void set_early_tmcb_list(struct sip_msg *msg, struct cell *t)
+{
+	if (msg->id==tmcb_early_hl.msgid) {
+		t->tmcb_hl = tmcb_early_hl.cb_list;
+		memset(&tmcb_early_hl.cb_list, 0, sizeof(struct tmcb_head_list));
+		tmcb_early_hl.msgid = 0;
+	}
+}
 
 int init_tmcb_lists()
 {
@@ -95,7 +124,8 @@ void destroy_tmcb_lists()
 		for( cbp=(struct tm_callback*)req_in_tmcb_hl->first; cbp ; ) {
 			cbp_tmp = cbp;
 			cbp = cbp->next;
-			if (cbp_tmp->param) shm_free( cbp_tmp->param );
+			if (cbp_tmp->param && cbp_tmp->release)
+					cbp_tmp->release( cbp_tmp->param );
 			shm_free( cbp_tmp );
 		}
 		shm_free(req_in_tmcb_hl);
@@ -105,7 +135,8 @@ void destroy_tmcb_lists()
 		for( cbp=(struct tm_callback*)local_req_in_tmcb_hl->first; cbp ; ) {
 			cbp_tmp = cbp;
 			cbp = cbp->next;
-			if (cbp_tmp->param) shm_free( cbp_tmp->param );
+			if (cbp_tmp->param && cbp_tmp->release)
+					cbp_tmp->release( cbp_tmp->param );
 			shm_free( cbp_tmp );
 		}
 		shm_free(local_req_in_tmcb_hl);
@@ -207,17 +238,15 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
 				return E_BUG;
 			}
 			/* look for the transaction */
-			if ( t_check(p_msg,0)!=1 ){
-				LOG(L_CRIT,"BUG:tm:register_tmcb: no transaction found\n");
-				return E_BUG;
-			}
-			if ( (t=get_t())==0 ) {
-				LOG(L_CRIT,"BUG:tm:register_tmcb: transaction found "
-					"is NULL\n");
-				return E_BUG;
+			t=get_t();
+			if ( t!=0 && t!=T_UNDEFINED) {
+				cb_list = &(t->tmcb_hl);
+			} else {
+				cb_list = get_early_tmcb_list(p_msg);
 			}
+		} else {
+			cb_list = &(t->tmcb_hl);
 		}
-		cb_list = &(t->tmcb_hl);
 	}
 
 	return insert_tmcb( cb_list, types, f, param, rel_func );

+ 2 - 0
modules/tm/t_hooks.h

@@ -418,6 +418,8 @@ struct tmcb_head_list {
 extern struct tmcb_head_list*  req_in_tmcb_hl;
 extern struct tmcb_head_list*  local_req_in_tmcb_hl;
 
+void set_early_tmcb_list(struct sip_msg *msg,
+		struct cell *t);
 
 #define has_tran_tmcbs(_T_, _types_) \
 	( ((_T_)->tmcb_hl.reg_types)&(_types_) )

+ 2 - 1
modules/tm/t_reply.c

@@ -602,7 +602,8 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 									trans->uas.request, FAKED_REPLY, code);
 #ifdef TMCB_ONSEND
 			if (unlikely(has_tran_tmcbs(trans, TMCB_RESPONSE_SENT))){
-				INIT_TMCB_ONSEND_PARAMS(onsend_params, 0, 0, rb, &rb->dst, 
+				INIT_TMCB_ONSEND_PARAMS(onsend_params, trans->uas.request,
+								FAKED_REPLY, rb, &rb->dst, 
 								buf, len, TMCB_LOCAL_F, rb->branch, code);
 				run_onsend_callbacks2(TMCB_RESPONSE_SENT, trans,
 										&onsend_params);

+ 15 - 0
modules/tm/tm.c

@@ -589,6 +589,11 @@ static int fixup_t_reply(void** param, int param_no)
 static int fixup_on_failure(void** param, int param_no)
 {
 	if (param_no==1){
+		if(strlen((char*)*param)<=1
+				&& (*(char*)(*param)==0 || *(char*)(*param)=='0')) {
+			*param = (void*)0;
+			return 0;
+		}
 		return fixup_routes("t_on_failure", &failure_rt, param);
 	}
 	return 0;
@@ -599,6 +604,11 @@ static int fixup_on_failure(void** param, int param_no)
 static int fixup_on_reply(void** param, int param_no)
 {
 	if (param_no==1){
+		if(strlen((char*)*param)<=1
+				&& (*(char*)(*param)==0 || *(char*)(*param)=='0')) {
+			*param = (void*)0;
+			return 0;
+		}
 		return fixup_routes("t_on_reply", &onreply_rt, param);
 	}
 	return 0;
@@ -609,6 +619,11 @@ static int fixup_on_reply(void** param, int param_no)
 static int fixup_on_branch(void** param, int param_no)
 {
 	if (param_no==1){
+		if(strlen((char*)*param)<=1
+				&& (*(char*)(*param)==0 || *(char*)(*param)=='0')) {
+			*param = (void*)0;
+			return 0;
+		}
 		return fixup_routes("t_on_branch", &branch_rt, param);
 	}
 	return 0;

+ 5 - 0
modules_k/drouting/Makefile

@@ -8,4 +8,9 @@ NAME=drouting.so
 LIBS= 
 DEFS+=-DOPENSER_MOD_INTERFACE
 
+SERLIBPATH=../../lib
+SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1
+SER_LIBS+=$(SERLIBPATH)/kcore/kcore
+SER_LIBS+=$(SERLIBPATH)/kmi/kmi
+
 include ../../Makefile.modules

+ 1 - 1
modules_k/pv/README

@@ -1,6 +1,6 @@
 Pseudo-Variables Module
 
-Daniel-Constantin Modroiu
+Daniel-Constantin Mierla
 
    asipto.com
    <[email protected]>

+ 1 - 1
modules_k/pv/doc/pv.xml

@@ -15,7 +15,7 @@
 	<authorgroup>
 	    <author>
 		<firstname>Daniel-Constantin</firstname>
-		<surname>Modroiu</surname>
+		<surname>Mierla</surname>
 		<affiliation><orgname>asipto.com</orgname></affiliation>
 		<email>[email protected]</email>
 		<address>

+ 5 - 1
modules_k/registrar/lookup.c

@@ -65,6 +65,8 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
 	int res;
 	int ret;
 	str path_dst;
+	flag_t old_bflags;
+
 
 	if (_m->new_uri.s) uri = _m->new_uri;
 	else uri = _m->first_line.u.request.uri;
@@ -131,7 +133,9 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
 
 		set_ruri_q(ptr->q);
 
-		setbflagsval( 0, ptr->cflags);
+		old_bflags = 0;
+		getbflagsval(0, &old_bflags);
+		setbflagsval(0, old_bflags|ptr->cflags);
 
 		if (ptr->sock)
 			set_force_socket(_m, ptr->sock);

+ 0 - 16
modules_k/sanity/Makefile

@@ -1,16 +0,0 @@
-# $Id$
-#
-# sanity check module makefile
-#
-#
-# WARNING: do not run this directly, it should be run by the master Makefile
-
-include ../../Makefile.defs
-
-auto_gen=
-NAME=sanity.so
-LIBS=
-
-DEFS+=-DOPENSER_MOD_INTERFACE
-
-include ../../Makefile.modules

+ 0 - 196
modules_k/sanity/README

@@ -1,196 +0,0 @@
-Sanity Module
-
-Nils Ohlmeier
-
-   iptelorg GmbH
-   <[email protected]>
-
-Edited by
-
-Nils Ohlmeier
-
-   <[email protected]>
-
-   Copyright © 2006 iptelorg GmbH
-     __________________________________________________________
-
-   Table of Contents
-
-   1. Admin Guide
-
-        1.1. Overview
-        1.2. Dependencies
-
-              1.2.1. Kamailio Modules
-              1.2.2. External Libraries or Applications
-
-        1.3. Exported Parameters
-
-              1.3.1. default_checks (integer)
-              1.3.2. uri_checks (integer)
-              1.3.3. proxy_require (string)
-
-        1.4. Exported Functions
-
-              1.4.1. sanity_check([checks, [uri_checks]])
-
-   List of Examples
-
-   1.1. Set default_checks parameter
-   1.2. Set proxy_require parameter
-   1.3. sanity_check usage
-   1.4. sanity_check usage with parameter
-   1.5. sanity_check usage with two parameters
-
-Chapter 1. Admin Guide
-
-1.1. Overview
-
-   This module aims to implement several sanity checks on incoming
-   requests which are suggested or even required by a RFC.
-
-   This checks are not required by Kamailio itself for its
-   functionality. But on the other side it makes not much sence if
-   a broken request traverses through a SIP network if it is
-   rejected sooner or later by a SIP device any way. As every
-   sanity cost extra performance because of additional parsing and
-   evaluation it is now with this module up to the Kamailio
-   adminstrator which checks should be done on which request.
-
-   The following checks are available:
-     * ruri sip version - (1) - checks if the SIP version in the
-       request URI is supported, currently only 2.0.
-     * ruri scheme - (2) - checks if the URI scheme of the request
-       URI is supported (sip[s]|tel[s]) by Kamailio.
-     * required headers - (4) -checks if the minimum set of
-       required headers to, from, cseq, callid and via is present
-       in the request.
-     * via sip version - (8) - not working because parser fails
-       already when another version then 2.0 is present.
-     * via protocol - (16) - not working because parser fails
-       already if an unsupported transport is present.
-     * cseq method - (32) - checks if the method from the cseq
-       header is equal to the request method.
-     * cseq value - (64) - checks if the number in the cseq header
-       is a valid unsigend integer.
-     * content length - (128) - checks if the size of the body
-       matches with the value from the content length header.
-     * expires value - (256) - checks if the value of the expires
-       header is a valid unsigned integer.
-     * proxy require - (512) - checks if all items of the proxy
-       require header are present in the list of the extensions
-       from the module parameter proxy_require.
-     * parse uri's - (1024) - checks if the specified URIs are
-       present and parseable by the Kamailio parsers
-     * digest credentials (2048) Check all instances of digest
-       credentials in a message. The test checks whether there are
-       all required digest parameters and have meaningful values.
-
-1.2. Dependencies
-
-1.2.1. Kamailio Modules
-
-   The following modules must be loaded before this module:
-     * sl - send reply.
-
-1.2.2. External Libraries or Applications
-
-   The following libraries or applications must be installed
-   before running Kamailio with this module loaded:
-     * None.
-
-1.3. Exported Parameters
-
-1.3.1. default_checks (integer)
-
-   This parameter determines which of the checks from the sanity
-   module are executed if no parameter was given to the
-   sanity_check function call. By default all implemented checks
-   are included in the execution of the sanity_check function. The
-   integer value is the sum of the check numbers which should be
-   executed by default.
-
-   Default value is 999. This resolves to the following list of
-   checks: ruri_sip_version (1), ruri_scheme (2), required_headers
-   (4), cseq_method (32), cseq_value (64), content_length (128),
-   expires_value (256), proxy_require (512).
-
-   Example 1.1. Set default_checks parameter
-...
-modparam("sanity", "default_checks", 1)
-...
-
-1.3.2. uri_checks (integer)
-
-   This parameter determines which URIs are going to be checked if
-   the 'parse uri' will be executed.
-
-   Default value is 7. This resolves to the following list of
-   parsed URIs: Request RUI (1), From URI (2) and To URI (4).
-
-1.3.3. proxy_require (string)
-
-   This parameter set the list of supported extensions for this
-   Kamailio. The value is expected as comma seperated list of the
-   extensions. This list is seperated into single tokens. Each
-   token from a proxy require header will be compare to the tokens
-   from this list.
-
-   Example 1.2. Set proxy_require parameter
-...
-modparam("sanity", "proxy_require", "foo, bar")
-...
-
-1.4. Exported Functions
-
-1.4.1.  sanity_check([checks, [uri_checks]])
-
-   This function makes a row of sanity checks on the given
-   request. The function returns true if one of the checks failed.
-   If one of the checks fails the module sends a precise error
-   reply via sl_send_reply. Thus their is no need to reply with a
-   generic error message.
-
-   Example 1.3. sanity_check usage
-
-...
-if (sanity_check()) {
-        xlog("malformed message from $si:$sp\n");
-        exit;
-}
-...
-
-
-   Optionally the function takes an integer argument which
-   overwrites the global module parameter default_checks. This
-   allows to make certain test from script regions. The integer
-   value is again the sum of the checks (like for the module
-   parameter) which should be executed at this function call.
-
-   Example 1.4. sanity_check usage with parameter
-
-...
-if (method=="REGISTER" && sanity_check("256")) {
-        /* the register contains an invalid expires value and is replied
- with a 400 */
-        xlog("malformed message from $si:$sp\n");
-        exit;
-}
-...
-
-
-   Optionally the function takes a second integer argument which
-   overwrites the global module parameter uri_checks and thus
-   determines which URIs will be checked if the parse uri test
-   will be executed.
-
-   Example 1.5. sanity_check usage with two parameters
-
-...
-if (method=="INVITE" && sanity_check("1024", "6")) {
-        /* the INVITE contains an invalid From or To header and is repli
-ed with a 400 */
-        xlog("malformed message from $si:$sp\n");
-        exit;
-}
-...

+ 0 - 4
modules_k/sanity/doc/Makefile

@@ -1,4 +0,0 @@
-docs = sanity.xml
-
-docbook_dir = ../../../docbook
-include $(docbook_dir)/Makefile.module

+ 0 - 41
modules_k/sanity/doc/sanity.xml

@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding='ISO-8859-1'?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
-
-<!-- Include general documentation entities -->
-<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
-%docentities;
-
-]>
-
-<book xmlns:xi="http://www.w3.org/2001/XInclude">
-    <bookinfo>
-	<title>Sanity Module</title>
-	<productname class="trade">&kamailioname;</productname>
-	<authorgroup>
-	    <author>
-		<firstname>Nils</firstname>
-		<surname>Ohlmeier</surname>
-		<affiliation><orgname>iptelorg GmbH</orgname></affiliation>
-		<email>[email protected]</email>
-		<address>
-		</address>
-	    </author>
-	    <editor>
-		<firstname>Nils</firstname>
-		<surname>Ohlmeier</surname>
-		<email>[email protected]</email>
-	    </editor>
-	</authorgroup>
-	<copyright>
-	    <year>2006</year>
-	    <holder>iptelorg GmbH</holder>
-	</copyright>
-    </bookinfo>
-    <toc></toc>
-    
-    <xi:include href="sanity_admin.xml"/>
-    
-    
-</book>
-

+ 0 - 271
modules_k/sanity/doc/sanity_admin.xml

@@ -1,271 +0,0 @@
-<?xml version="1.0" encoding='ISO-8859-1'?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
-
-<!-- Include general documentation entities -->
-<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
-%docentities;
-
-]>
-<!-- Module User's Guide -->
-
-<chapter>
-	
-	<title>&adminguide;</title>
-	
-	<section>
-	<title>Overview</title>
-	<para>
-		This module aims to implement several sanity checks on incoming
-		requests which are suggested or even required by a RFC.
-	</para>
-	<para>
-		This checks are not required by &kamailio; itself for its functionality.
-		But on the other side it makes not much sence if a broken
-		request traverses through a SIP network if it is rejected sooner
-		or later by a SIP device any way. As every sanity cost extra
-		performance because of additional parsing and evaluation it
-		is now with this module up to the &kamailio; adminstrator which checks
-		should be done on which request.
-	</para>
-	<para>
-		The following checks are available:
-		<itemizedlist>
-		<listitem>
-			<para>
-			ruri sip version - (1) - checks if the SIP version in the request
-			URI is supported, currently only 2.0.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			ruri scheme - (2) - checks if the URI scheme of the request URI is
-			supported (sip[s]|tel[s]) by &kamailio;.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			required headers - (4) -checks if the minimum set of required headers
-			to, from, cseq, callid and via is present in the request.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			via sip version - (8) - not working because parser fails already 
-			when another version then 2.0 is present.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			via protocol - (16) - not working because parser fails already if an
-			unsupported transport is present.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			cseq method - (32) - checks if the method from the cseq header is equal
-			to the request method.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			cseq value - (64) - checks if the number in the cseq header is a valid
-			unsigend integer.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			content length - (128) - checks if the size of the body matches with the
-			value from the content length header.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			expires value - (256) - checks if the value of the expires header is a
-			valid unsigned integer.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			proxy require - (512) - checks if all items of the proxy require header
-			are present in the list of the extensions from the module 
-			parameter proxy_require.
-			</para>
-		</listitem>
-		<listitem>
-			<para>
-			parse uri's - (1024) - checks if the specified URIs are present and
-			parseable by the &kamailio; parsers
-			</para>
-		</listitem>
-		<listitem>
-		    <para>
-			digest credentials (2048) Check all instances of digest credentials in a
-			message. The test checks whether there are all required
-			digest parameters and have meaningful values.
-			</para>
-		</listitem>
-		</itemizedlist>
-	</para>
-
-	</section>
-	<section>
-	<title>Dependencies</title>
-	<section>
-		<title>&kamailio; Modules</title>
-		<para>
-		The following modules must be loaded before this module:
-			<itemizedlist>
-			<listitem>
-			<para>
-				<emphasis>sl</emphasis> - send reply.
-			</para>
-			</listitem>
-			</itemizedlist>
-		</para>
-	</section>
-	<section>
-		<title>External Libraries or Applications</title>
-		<para>
-		The following libraries or applications must be installed before running
-		&kamailio; with this module loaded:
-			<itemizedlist>
-			<listitem>
-			<para>
-				<emphasis>None</emphasis>.
-			</para>
-			</listitem>
-			</itemizedlist>
-		</para>
-	</section>
-
-	</section>
-	<section>
-	<title>Exported Parameters</title>
-   <section>
-	<title><varname>default_checks</varname> (integer)</title>
-	<para>
-		This parameter determines which of the checks from the sanity
-		module are executed if no parameter was given to the sanity_check
-		function call. By default all implemented checks are included
-		in the execution of the sanity_check function. The integer value
-		is the sum of the check numbers which should be executed by default.
-	</para>
-	<para>
-	    Default value is 999. This resolves to the following list of
-		checks: ruri_sip_version (1), ruri_scheme (2), required_headers (4),
-		cseq_method (32), cseq_value (64), content_length (128), 
-		expires_value (256), proxy_require (512).
-	</para>
-	<example>
-	    <title>Set <varname>default_checks</varname> parameter</title>
-	    <programlisting>
-...
-modparam("sanity", "default_checks", 1)
-...
-	    </programlisting>
-	</example>
-    </section>
-
-	<section>
-	<title><varname>uri_checks</varname> (integer)</title>
-	<para>
-		This parameter determines which URIs are going to be checked
-		if the 'parse uri' will be executed.
-	</para>
-	<para>
-		Default value is 7. This resolves to the following list of
-		parsed URIs: Request RUI (1), From URI (2) and To URI (4).
-	</para>
-	</section>
-
-	<section>
-	<title><varname>proxy_require</varname> (string)</title>
-	<para>
-		This parameter set the list of supported extensions for this &kamailio;.
-		The value is expected as comma seperated list of the extensions.
-		This list is seperated into single tokens. Each token from
-		a proxy require header will be compare to the tokens from this
-		list.
-	</para>
-	<example>
-	    <title>Set <varname>proxy_require</varname> parameter</title>
-	    <programlisting>
-...
-modparam("sanity", "proxy_require", "foo, bar")
-...
-	    </programlisting>
-	</example>
-	</section>
-	</section>
-	<section>
-	<title>Exported Functions</title>
-    <section id="sanity_check">
-	    <title>
-		<function>sanity_check([checks, [uri_checks]])</function>
-	    </title>
-	<para>
-		This function makes a row of sanity checks on the given request.
-		The function returns true if one of the checks failed. If one
-		of the checks fails the module sends a precise error reply via 
-		sl_send_reply. Thus their is no need to reply with a generic 
-		error message.
-	</para>
-	<example>
-	    <title><function>sanity_check</function> usage</title>
-	    <programlisting>
-<![CDATA[
-...
-if (sanity_check()) {
-	xlog("malformed message from $si:$sp\n");
-	exit;
-}
-...
-]]>
-	    </programlisting>
-	</example>
-	<para>
-		Optionally the function takes an integer argument which overwrites
-		the global module parameter default_checks. This allows to make
-		certain test from script regions. The integer value is again the sum
-		of the checks (like for the module parameter) which should be executed
-		at this function call.
-	</para>
-	<example>
-	    <title><function>sanity_check</function> usage with parameter</title>
-	    <programlisting>
-<![CDATA[
-...
-if (method=="REGISTER" && sanity_check("256")) {
-	/* the register contains an invalid expires value and is replied with a 400 */
-	xlog("malformed message from $si:$sp\n");
-	exit;
-}
-...
-]]>
-	    </programlisting>
-	</example>
-	<para>
-		Optionally the function takes a second integer argument which
-		overwrites the global module parameter uri_checks and thus determines
-		which URIs will be checked if the parse uri test will be executed.
-	</para>
-	<example>
-		<title><function>sanity_check</function> usage with two parameters</title>
-		<programlisting>
-<![CDATA[
-...
-if (method=="INVITE" && sanity_check("1024", "6")) {
-	/* the INVITE contains an invalid From or To header and is replied with a 400 */
-	xlog("malformed message from $si:$sp\n");
-	exit;
-}
-...
-]]>
-		</programlisting>
-	</example>
-    </section>
-    </section>
-
-</chapter>
-

+ 0 - 221
modules_k/sanity/mod_sanity.c

@@ -1,221 +0,0 @@
-/*
- * $Id$
- *
- * Sanity Checks Module
- * 
- * Copyright (C) 2006 iptelorg GbmH
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * Kamailio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * Kamailio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "mod_sanity.h"
-#include "sanity.h"
-#include "../../sr_module.h"
-#include "../../ut.h"
-#include "../../error.h"
-
-MODULE_VERSION
-
-#define PROXY_REQUIRE_DEF 	""
-
-str pr_str 	= {PROXY_REQUIRE_DEF, sizeof(PROXY_REQUIRE_DEF)-1 };
-
-int default_checks = SANITY_DEFAULT_CHECKS;
-int uri_checks = SANITY_DEFAULT_URI_CHECKS;
-strl* proxyrequire_list = NULL;
-
-struct sl_binds sl;
-
-static int mod_init(void);
-static int sanity_fixup(void** param, int param_no);
-static int sanity_check(struct sip_msg* _msg, char* _foo, char* _bar);
-
-/*
- * Exported functions
- */
-static cmd_export_t cmds[] = {
-	{"sanity_check", (cmd_function)sanity_check, 0, 0, 0, REQUEST_ROUTE},
-	{"sanity_check", (cmd_function)sanity_check, 1, sanity_fixup, 0,
-		REQUEST_ROUTE},
-	{"sanity_check", (cmd_function)sanity_check, 2, sanity_fixup, 0,
-		REQUEST_ROUTE},
-	{0, 0, 0, 0, 0, 0}
-};
-
-/*
- * Exported parameters
- */
-static param_export_t params[] = {
-	{"default_checks", 	INT_PARAM, 	&default_checks},
-	{"uri_checks",		INT_PARAM,  &uri_checks	},
-	{"proxy_require", 	STR_PARAM, 	&pr_str 	},
-	{0, 0, 0}
-};
-
-/*
- * Module description
- */
-struct module_exports exports = {
-	"sanity",        /* Module name */
-	DEFAULT_DLFLAGS, /* dlopen flags */
-	cmds,            /* Exported functions */
-	params,          /* Exported parameters */
-	0,          /* exported statistics */
-	0,          /* exported MI functions */
-	0,          /* exported pseudo-variables */
-	0,          /* extra processes */
-	mod_init,        /* Initialization function */
-	0,               /* Response function */
-	0,               /* Destroy function */
-	0                /* Child init function */
-};
-
-/*
- * initialize module
- */
-static int mod_init(void) {
-	strl* ptr;
-
-	/*
-	 * We will need sl_send_reply from stateless
-	 * module for sending replies
-	 */
-	if (load_sl_api(&sl)!=0) {
-		LM_ERR("can't load SL API\n");
-		return -1;
-	}
-
-	LM_DBG("parsing proxy requires string:\n");
-	ptr = parse_str_list(&pr_str);
-
-	proxyrequire_list = ptr;
-
-	while (ptr != NULL) {
-		LM_DBG("string: '%.*s', next: %p\n", ptr->string.len,
-				ptr->string.s, ptr->next);
-		ptr = ptr->next;
-	}
-
-	return 0;
-}
-
-static int sanity_fixup(void** param, int param_no) {
-	int checks;
-	str in;
-
-	if (param_no == 1) {
-		in.s = (char*)*param;
-		in.len = strlen(in.s);
-		if (str2int(&in, (unsigned int*)&checks) < 0) {
-			LM_ERR("failed to convert input integer\n");
-			return E_UNSPEC;
-		}
-		if ((checks < 1) || (checks >= (SANITY_MAX_CHECKS))) {
-			LM_ERR("input parameter (%i) outside of valid range <1-%i)\n",
-					checks, SANITY_MAX_CHECKS);
-			return E_UNSPEC;
-		}
-		*param = (void*)(long)checks;
-	}
-	if (param_no == 2) {
-		in.s = (char*)*param;
-		in.len = strlen(in.s);
-		if (str2int(&in, (unsigned int*)&checks) < 0) {
-			LM_ERR("failed to convert second integer argument\n");
-			return E_UNSPEC;
-		}
-		if ((checks < 1) || (checks > (SANITY_DEFAULT_URI_CHECKS))) {
-			LM_ERR("second input parameter (%i) outside of valid range 1-%i\n",
-					checks, SANITY_DEFAULT_URI_CHECKS);
-			return E_UNSPEC;
-		}
-		*param = (void*)(long)checks;
-	}
-	return 0;
-}
-
-static int sanity_check(struct sip_msg* _msg, char* _number, char* _arg) {
-	int ret, check, arg;
-
-	if (_number == NULL) {
-		check = default_checks;
-	}
-	else {
-		check = (int)(long)_number;
-	}
-	if (_arg == NULL) {
-		arg = uri_checks;
-	}
-	else {
-		arg = (int)(long)_arg;
-	}
-
-	if (SANITY_RURI_SIP_VERSION & check &&
-		(ret = check_ruri_sip_version(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_RURI_SCHEME & check &&
-		(ret = check_ruri_scheme(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_REQUIRED_HEADERS & check &&
-		(ret = check_required_headers(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_VIA_SIP_VERSION & check &&
-		(ret = check_via_sip_version(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_VIA_PROTOCOL & check &&
-		(ret = check_via_protocol(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_CSEQ_METHOD & check &&
-		(ret = check_cseq_method(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_CSEQ_VALUE & check &&
-		(ret = check_cseq_value(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_CL & check &&
-		(ret = check_cl(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_EXPIRES_VALUE & check &&
-		(ret = check_expires_value(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_PROXY_REQUIRE & check &&
-		(ret = check_proxy_require(_msg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-	if (SANITY_PARSE_URIS & check &&
-		(ret = check_parse_uris(_msg, arg)) != SANITY_CHECK_PASSED) {
-		return ret;
-	}
-
-	if (SANITY_CHECK_DIGEST & check &&
-	        (ret = check_digest(_msg, arg)) != SANITY_CHECK_PASSED) {
-	        return ret;
-	}
-
-	LM_DBG("all sanity checks passed\n");
-	/* nobody complained so everything is fine */
-	return 1;
-}

+ 0 - 85
modules_k/sanity/mod_sanity.h

@@ -1,85 +0,0 @@
-/*
- * $Id$
- *
- * Sanity Checks Module
- * 
- * Copyright (C) 2006 iptelorg GbmH
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * Kamailio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * Kamailio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef MOD_SANITY_CHK_H
-#define MOD_SANITY_CHK_H
-
-#include "../../str.h"
-#include "../sl/sl_api.h"
-#include "../../parser/msg_parser.h"
-
-#define SANITY_RURI_SIP_VERSION        (1<<0)
-#define SANITY_RURI_SCHEME             (1<<1)
-#define SANITY_REQUIRED_HEADERS        (1<<2)
-#define SANITY_VIA_SIP_VERSION         (1<<3)
-#define SANITY_VIA_PROTOCOL            (1<<4)
-#define SANITY_CSEQ_METHOD             (1<<5)
-#define SANITY_CSEQ_VALUE              (1<<6)
-#define SANITY_CL                      (1<<7)
-#define SANITY_EXPIRES_VALUE           (1<<8)
-#define SANITY_PROXY_REQUIRE           (1<<9)
-#define SANITY_PARSE_URIS              (1<<10)
-#define SANITY_CHECK_DIGEST            (1<<11)
-#define SANITY_MAX_CHECKS              (1<<12)  /* Make sure this is the highest value */
-
-/* VIA_SIP_VERSION and VIA_PROTOCOL do not work yet
- * and PARSE_URIS is very expensive */
-#define SANITY_DEFAULT_CHECKS 	SANITY_RURI_SIP_VERSION | \
-								SANITY_RURI_SCHEME | \
-								SANITY_REQUIRED_HEADERS | \
-								SANITY_CSEQ_METHOD | \
-								SANITY_CSEQ_VALUE | \
-								SANITY_CL | \
-								SANITY_EXPIRES_VALUE | \
-								SANITY_PROXY_REQUIRE | \
-                                                                SANITY_CHECK_DIGEST
-
-
-#define SANITY_URI_CHECK_RURI    (1<<0)
-#define SANITY_URI_CHECK_FROM    (1<<1)
-#define SANITY_URI_CHECK_TO      (1<<2)
-#define SANITY_URI_CHECK_CONTACT (1<<3)
-
-#define SANITY_DEFAULT_URI_CHECKS	SANITY_URI_CHECK_RURI | \
-									SANITY_URI_CHECK_FROM | \
-									SANITY_URI_CHECK_TO
-
-#define SANITY_CHECK_PASSED 1
-#define SANITY_CHECK_FAILED 0
-#define SANITY_CHECK_ERROR -1
-
-struct _strlist {
-	str string;            /* the string */
-	struct _strlist* next; /* the next strlist element */
-};
-
-typedef struct _strlist strl;
-
-extern int default_checks;
-extern strl* proxyrequire_list;
-
-extern struct sl_binds sl;
-
-#endif /* MOD_SANITY_CHK_H */

+ 0 - 749
modules_k/sanity/sanity.c

@@ -1,749 +0,0 @@
-/*
- * $Id$
- *
- * Sanity Checks Module
- * 
- * Copyright (C) 2006 iptelorg GbmH
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * Kamailio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * Kamailio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "mod_sanity.h"
-#include "sanity.h"
-#include "../../ut.h"
-#include "../../trim.h"
-#include "../../data_lump_rpl.h"
-#include "../../mem/mem.h"
-#include "../../parser/parse_uri.h"
-#include "../../parser/parse_to.h"
-#include "../../parser/parse_expires.h"
-#include "../../parser/parse_content.h"
-#include "../../parser/digest/digest.h"
-#include "../../parser/contact/parse_contact.h"
-
-#define UNSUPPORTED_HEADER "Unsupported: "
-#define UNSUPPORTED_HEADER_LEN (sizeof(UNSUPPORTED_HEADER)-1)
-
-int sanity_reply(struct sip_msg* _msg, int _code, char *_reason)
-{
-	str s;
-	s.s = _reason;
-	s.len = strlen(s.s);
-	return sl.send_reply(_msg, _code, &s);
-}
-
-
-/* check if the given string is a valid unsigned int value */
-int str2valid_uint(str* _number, unsigned int* _result) {
-	int i;
-	int result= 0;
-	int equal = 1;
-	char mui[10] = "4294967296";
-
-	*_result = 0;
-	if (_number->len > 10) {
-		return -1;
-	}
-	if (_number->len < 10) {
-		equal = 0;
-	}
-	for (i=0; i < _number->len; i++) {
-		if (_number->s[i] < '0' || _number->s[i] > '9') {
-			return -1;
-		}
-		if (equal == 1) {
-			if (_number->s[i] < mui[i]) {
-				equal = 0;
-			}
-			else if (_number->s[i] > mui[i]) {
-				return -1;
-			}
-		}
-		result *= 10;
-		result += _number->s[i] - '0';
-	}
-	*_result = result;
-	return 0;
-}
-
-/* parses the given comma seperated string into a string list */
-strl* parse_str_list(str* _string) {
-	str input;
-	strl *parsed_list, *pl;
-	char *comma;
-
-	/* make a copy because we trim it */
-	input.s = _string->s;
-	input.len = _string->len;
-
-	trim(&input);
-
-	if (input.len == 0) {
-		return NULL;
-	}
-	parsed_list = pkg_malloc(sizeof(strl));
-	if (parsed_list == NULL) {
-		LM_ERR("OUT OF MEMORY for initial list element\n");
-		return NULL;
-	}
-	memset(parsed_list, 0, sizeof(strl));
-	parsed_list->string.s = input.s;
-	parsed_list->string.len = input.len;
-
-	comma = q_memchr(input.s, ',', input.len);
-	pl = parsed_list;
-	while (comma != NULL) {
-		pl->next = pkg_malloc(sizeof(strl));
-		if (pl->next == NULL) {
-			LM_ERR("parse_str_list: OUT OF MEMORY for further list element\n");
-			return parsed_list;
-		}
-		memset(pl->next, 0, sizeof(strl));
-		pl->next->string.s = comma + 1;
-		pl->next->string.len = pl->string.len - (pl->next->string.s - pl->string.s);
-		pl->string.len = comma - pl->string.s;
-		trim_trailing(&(pl->string));
-		pl = pl->next;
-		trim_leading(&(pl->string));
-		comma = q_memchr(pl->string.s, ',', pl->string.len);
-	}
-
-	return parsed_list;
-}
-
-/* free the elements of the linked str list */
-void free_str_list(strl *_list) {
-	strl *cur, *next;
-
-	if (_list != NULL) {
-		cur = _list;
-		while (cur != NULL) {
-			next = cur->next;
-			pkg_free(cur);
-			cur = next;
-		}
-	}
-}
-
-int parse_proxyrequire(struct hdr_field* _h) {
-	strl *pr_l;
-
-	if (_h->parsed) {
-		return 0; /* Already parsed */
-	}
-
-	if ((pr_l = parse_str_list(&(_h->body))) == NULL) {
-		LM_ERR("Error while parsing\n");
-		return -1;
-	}
-
-	_h->parsed = pr_l;
-	return 0;
-}
-
-/* check the SIP version in the request URI */
-int check_ruri_sip_version(struct sip_msg* _msg) {
-	char *sep;
-	str version;
-
-	if (_msg->first_line.u.request.version.len != 0) {
-		sep = q_memchr(_msg->first_line.u.request.version.s, '/',
-						_msg->first_line.u.request.version.len);
-		if (sep == NULL) {
-			LM_WARN("check_ruri_sip_version(): failed to find / in ruri version\n");
-			return SANITY_CHECK_FAILED;
-		}
-		version.s = sep + 1;
-		version.len = _msg->first_line.u.request.version.len - (version.s - _msg->first_line.u.request.version.s);
-
-		if (version.len != SIP_VERSION_TWO_POINT_ZERO_LENGTH ||
-			(memcmp(version.s, SIP_VERSION_TWO_POINT_ZERO, 
-				SIP_VERSION_TWO_POINT_ZERO_LENGTH) != 0)) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 505, "Version Not Supported (R-URI)") == -1) {
-					LM_WARN("check_ruri_sip_version(): failed to send 505 via send_reply\n");
-				}
-			}
-			return SANITY_CHECK_FAILED;
-		}
-	}
-	return SANITY_CHECK_PASSED;
-}
-
-/* check if the r-uri scheme */
-int check_ruri_scheme(struct sip_msg* _msg) {
-
-	if (_msg->parsed_uri_ok == 0 &&
-			parse_sip_msg_uri(_msg) != 1) {
-		/* unsupported schemes end up here already */
-		LM_WARN("failed to parse request uri\n");
-	}
-	if (_msg->parsed_uri.type == ERROR_URI_T) {
-		if (_msg->REQ_METHOD != METHOD_ACK) {
-			if (sanity_reply(_msg, 416, "Unsupported URI Scheme in Request URI") == -1) {
-				LM_WARN("failed to send 416 via send_reply\n");
-			}
-		}
-		LM_DBG("check_ruri_scheme failed\n");
-		return SANITY_CHECK_FAILED;
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* check for the presence of the minimal required headers */
-int check_required_headers(struct sip_msg* _msg) {
-
-	if (!check_transaction_quadruple(_msg)) {
-		if (_msg->REQ_METHOD != METHOD_ACK) {
-			if (sanity_reply(_msg, 400, "Missing Required Header in Request") == -1) {
-				LM_WARN("failed to send 400 via send_reply\n");
-			}
-		}
-		LM_DBG("check_required_headers failed\n");
-		return SANITY_CHECK_FAILED;
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* check if the SIP version in the Via header is 2.0 */
-int check_via_sip_version(struct sip_msg* _msg) {
-
-	LM_DBG("this is a useless check for now; check the source code comments for details\n");
-	return SANITY_CHECK_PASSED;
-
-	/* FIMXE the Via parser fails already on non-2.0 versions
-	 * thus this check makes no sence yet
-	DBG("check_via_sip_version entered\n");
-
-	// FIXME via parser fails on non 2.0 number
-	if (parse_headers(_msg, HDR_VIA1_F, 0) != 0) {
-		LOG(L_WARN, "sanity_check(): check_via_sip_version(): failed to parse the first Via header\n");
-		return SANITY_CHECK_FAILED;
-	}
-
-	if (_msg->via1->version.len != 3 ||
-			memcmp(_msg->via1->version.s, SIP_VERSION_TWO_POINT_ZERO, 
-					SIP_VERSION_TWO_POINT_ZERO_LENGTH ) != 0) {
-		if (_msg->REQ_METHOD != METHOD_ACK) {
-			if (sl.reply(_msg, 505, "Version Not Supported (Via)") == -1) {
-				LOG(L_WARN, "sanity_check(): check_via_sip_version(): failed to send 505 via send_reply\n");
-			}
-		}
-		DBG("check_via_sip_version failed\n");
-		return SANITY_CHECK_FAILED;
-	}
-#ifdef EXTRA_DEBUG
-	DBG("check_via_sip_version passed\n");
-#endif
-
-	return SANITY_CHECK_PASSED;
-	*/
-}
-
-/* compare the protocol string in the Via header with the transport */
-int check_via_protocol(struct sip_msg* _msg) {
-
-	LM_DBG("this is a useless check for now; check the source code comment for details\n");
-	return SANITY_CHECK_PASSED;
-
-	/* FIXME as the Via parser fails already on unknown transports
-	 * this function makes no sence yet
-	DBG("check_via_protocol entered\n");
-
-	// FIXME via parser fails on unknown transport
-	if (parse_headers(_msg, HDR_VIA1_F, 0) != 0) {
-		LOG(L_WARN, "sanity_check(): check_via_protocol(): failed to parse the first Via header\n");
-		return SANITY_CHECK_FAILED;
-	}
-	if (_msg->via1->transport.len != 3 &&
-			_msg->via1->transport.len != 4) {
-		if (_msg->REQ_METHOD != METHOD_ACK) {
-			if (sl.reply(_msg, 400, "Unsupported Transport in Topmost Via") == -1) {
-				LOG(L_WARN, "sanity_check(): check_via_protocol(): failed to send 400 via send_reply\n");
-			}
-		}
-		DBG("check_via_protocol failed\n");
-		return SANITY_CHECK_FAILED;
-	}
-	switch (_msg->rcv.proto) {
-		case PROTO_UDP:
-			if (memcmp(_msg->via1->transport.s, "UDP", 3) != 0) {
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sl.reply(_msg, 400, "Transport Missmatch in Topmost Via") == -1) {
-						LOG(L_WARN, "sanity_check(): check_via_protocol(): failed to send 505 via send_reply\n");
-					}
-				}
-				DBG("check_via_protocol failed\n");
-				return SANITY_CHECK_FAILED;
-			}
-			break;
-		case PROTO_TCP:
-			if (memcmp(_msg->via1->transport.s, "TCP", 3) != 0) {
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sl.reply(_msg, 400, "Transport Missmatch in Topmost Via") == -1) {
-						LOG(L_WARN, "sanity_check(): check_via_protocol(): failed to send 505 via send_reply\n");
-					}
-				}
-				DBG("check_via_protocol failed\n");
-				return SANITY_CHECK_FAILED;
-			}
-			break;
-		case PROTO_TLS:
-			if (memcmp(_msg->via1->transport.s, "TLS", 3) != 0) {
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sl.reply(_msg, 400, "Transport Missmatch in Topmost Via") == -1) {
-						LOG(L_WARN, "sanity_check(): check_via_protocol(): failed to send 505 via send_reply\n");
-					}
-				}
-				DBG("check_via_protocol failed\n");
-				return SANITY_CHECK_FAILED;
-			}
-			break;
-		case PROTO_SCTP:
-			if (memcmp(_msg->via1->transport.s, "SCTP", 4) != 0) {
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sl.reply(_msg, 400, "Transport Missmatch in Topmost Via") == -1) {
-						LOG(L_WARN, "sanity_check(): check_via_protocol(): failed to send 505 via send_reply\n");
-					}
-				}
-				DBG("check_via_protocol failed\n");
-				return SANITY_CHECK_FAILED;
-			}
-			break;
-		default:
-			LOG(L_WARN, "sanity_check(): check_via_protocol(): unknown protocol in received structure\n");
-			return SANITY_CHECK_FAILED;
-	}
-#ifdef EXTRA_DEBUG
-	DBG("check_via_protocol passed\n");
-#endif
-
-	return SANITY_CHECK_PASSED;
-	*/
-}
-
-/* compare the method in the CSeq header with the request line value */
-int check_cseq_method(struct sip_msg* _msg) {
-
-	if (parse_headers(_msg, HDR_CSEQ_F, 0) != 0) {
-		LM_WARN("failed to parse the CSeq header\n");
-		return SANITY_CHECK_FAILED;
-	}
-	if (_msg->cseq != NULL && _msg->cseq->parsed != NULL) {
-		if (((struct cseq_body*)_msg->cseq->parsed)->method.len == 0) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Missing method in CSeq header") == -1) {
-					LM_WARN("failed to send 400 via send_reply\n");
-				}
-			}
-			LM_DBG("check_cseq_method failed (missing method)\n");
-			return SANITY_CHECK_FAILED;
-		}
-
-		if (((struct cseq_body*)_msg->cseq->parsed)->method.len != 
-					_msg->first_line.u.request.method.len ||
-			memcmp(((struct cseq_body*)_msg->cseq->parsed)->method.s, 
-				_msg->first_line.u.request.method.s,
-				((struct cseq_body*)_msg->cseq->parsed)->method.len) != 0) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "CSeq method does not match request method") == -1) {
-					LM_WARN("failed to send 400 via send_reply 2\n");
-				}
-			}
-			LM_DBG("check_cseq_method failed (non-equal method)\n");
-			return SANITY_CHECK_FAILED;
-		}
-	}
-	else {
-		LM_WARN("missing CSeq header\n");
-		return SANITY_CHECK_FAILED;
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* check the number within the CSeq header */
-int check_cseq_value(struct sip_msg* _msg) {
-	unsigned int cseq;
-
-	if (parse_headers(_msg, HDR_CSEQ_F, 0) != 0) {
-		LM_WARN("failed to parse the CSeq header\n");
-		return SANITY_CHECK_FAILED;
-	}
-	if (_msg->cseq != NULL && _msg->cseq->parsed != NULL) {
-		if (((struct cseq_body*)_msg->cseq->parsed)->number.len == 0) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Missing number in CSeq header") == -1) {
-					LM_WARN("failed to send 400 via send_reply\n");
-				}
-			}
-			return SANITY_CHECK_FAILED;
-		}
-		if (str2valid_uint(&((struct cseq_body*)_msg->cseq->parsed)->number, &cseq) != 0) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "CSeq number is illegal") == -1) {
-					LM_WARN("failed to send 400 via send_reply 2\n");
-				}
-			}
-			LM_DBG("check_cseq_value failed\n");
-			return SANITY_CHECK_FAILED;
-		}
-	}
-	else {
-		LM_WARN("missing CSeq header\n");
-		return SANITY_CHECK_FAILED;
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* compare the Content-Length value with the accutal body length */
-int check_cl(struct sip_msg* _msg) {
-	char *body;
-
-	if (parse_headers(_msg, HDR_CONTENTLENGTH_F, 0) != 0) {
-		LM_WARN("failed to parse content-length header\n");
-		return SANITY_CHECK_FAILED;
-	}
-	if (_msg->content_length != NULL) {
-		//dump_hdr_field(_msg->content_length);
-		if ((body = get_body(_msg)) == NULL) {
-			return SANITY_CHECK_FAILED;
-		}
-		if ((_msg->len - (body - _msg->buf)) != get_content_length(_msg)) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Content-Length mis-match") == -1) {
-					LM_WARN("failed to send 400 via send_reply\n");
-				}
-			}
-			LM_DBG("check_cl failed\n");
-			return SANITY_CHECK_FAILED;
-		}
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* check the number within the Expires header */
-int check_expires_value(struct sip_msg* _msg) {
-	unsigned int expires;
-
-	if (parse_headers(_msg, HDR_EXPIRES_F, 0) != 0) {
-		LM_WARN("failed to parse expires header\n");
-		return SANITY_CHECK_FAILED;
-	}
-	if (_msg->expires != NULL) {
-		//dump_hdr_field(_msg->expires);
-		if (_msg->expires->parsed == NULL &&
-				parse_expires(_msg->expires) < 0) {
-			LM_WARN("parse_expires failed\n");
-			return SANITY_CHECK_FAILED;
-		}
-		if (((struct exp_body*)_msg->expires->parsed)->text.len == 0) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Missing number in Expires header") == -1) {
-					LM_WARN("failed to send 400 via send_reply\n");
-				}
-			}
-			LM_DBG("check_expires_value failed\n");
-			return SANITY_CHECK_FAILED;
-		}
-		if (str2valid_uint(&((struct exp_body*)_msg->expires->parsed)->text, &expires) != 0) {
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Expires value is illegal") == -1) {
-					LM_WARN("failed to send 400 via send_reply 2\n");
-				}
-			}
-			LM_DBG("check_expires_value failed\n");
-			return SANITY_CHECK_FAILED;
-		}
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* check the content of the Proxy-Require header */
-int check_proxy_require(struct sip_msg* _msg) {
-	strl *r_pr, *l_pr;
-	char *u;
-	int u_len;
-
-	if (parse_headers(_msg, HDR_PROXYREQUIRE_F, 0) != 0) {
-		LM_WARN("failed to parse proxy require header\n");
-		return SANITY_CHECK_FAILED;
-	}
-	if (_msg->proxy_require != NULL) {
-		dump_hdr_field(_msg->proxy_require);
-		if (_msg->proxy_require->parsed == NULL &&
-				parse_proxyrequire(_msg->proxy_require) < 0) {
-			LM_WARN("parse_proxy_require failed\n");
-			return SANITY_CHECK_FAILED;
-		}
-		r_pr = _msg->proxy_require->parsed;
-		while (r_pr != NULL) {
-			l_pr = proxyrequire_list;
-			while (l_pr != NULL) {
-				if (l_pr->string.len == r_pr->string.len &&
-						/* FIXME tokens are case in-sensitive */
-						memcmp(l_pr->string.s, r_pr->string.s, l_pr->string.len) == 0) {
-					break;
-				}
-				l_pr = l_pr->next;
-			}
-			if (l_pr == NULL) {
-				LM_DBG("request contains unsupported extension: %.*s\n", r_pr->string.len, r_pr->string.s);
-				u_len = UNSUPPORTED_HEADER_LEN + 2 + r_pr->string.len;
-				u = pkg_malloc(u_len);
-				if (u == NULL) {
-					LM_ERR("failed to allocate memory for Unsupported header\n");
-				}
-				else {
-					memcpy(u, UNSUPPORTED_HEADER, UNSUPPORTED_HEADER_LEN);
-					memcpy(u + UNSUPPORTED_HEADER_LEN, r_pr->string.s, r_pr->string.len);
-					memcpy(u + UNSUPPORTED_HEADER_LEN + r_pr->string.len, CRLF, CRLF_LEN);
-					add_lump_rpl(_msg, u, u_len, LUMP_RPL_HDR);
-				}
-
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sanity_reply(_msg, 420, "Bad Extension") == -1) {
-						LM_WARN("failed to send 420 via send_reply\n");
-					}
-				}
-				if (u) pkg_free(u);
-				return SANITY_CHECK_FAILED;
-			}
-			else {
-				r_pr = r_pr->next;
-			}
-		}
-		if (_msg->proxy_require->parsed) {
-			/* TODO we have to free it here, because it is not automatically
-			 * freed when the message freed. Lets hope nobody needs to access
-			 * this header again later on */
-			free_str_list(_msg->proxy_require->parsed);
-		}
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-/* check if the typical URI's are parseable */
-int check_parse_uris(struct sip_msg* _msg, int checks) {
-
-	struct to_body *ft_body = NULL;
-	struct sip_uri uri;
-
-	/* check R-URI */
-	if (SANITY_URI_CHECK_RURI & checks) {
-		if (_msg->parsed_uri_ok == 0 &&
-				parse_sip_msg_uri(_msg) != 1) {
-			LM_WARN("failed to parse request uri\n");
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Bad Request URI") == -1) {
-					LM_WARN("failed to send 400 via send_reply (bad ruri)\n");
-				}
-			}
-			return SANITY_CHECK_FAILED;
-		}
-		/* FIXME: would it make sense to check here for "mandatory"
-		 * or "requested" parts of the URI? */
-	}
-	/* check From URI */
-	if (SANITY_URI_CHECK_FROM & checks) {
-		if ((!_msg->from && parse_headers(_msg, HDR_FROM_F, 0) != 0) || !_msg->from) {
-			LM_WARN("missing from header\n");
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Missing From Header") == -1) {
-					LM_WARN("failed to send 400 via send_reply (missing From)\n");
-				}
-			}
-			return SANITY_CHECK_FAILED;
-		}
-		if (!_msg->from->parsed) {
-			ft_body = pkg_malloc(sizeof(struct to_body));
-			if (!ft_body) {
-				LM_ERR("out of pkg_memory (From)\n");
-				return SANITY_CHECK_ERROR;
-			}
-			memset(ft_body, 0, sizeof(struct to_body));
-			parse_to(_msg->from->body.s, _msg->from->body.s + \
-					_msg->from->body.len + 1, ft_body);
-			if (ft_body->error == PARSE_ERROR) {
-				LM_WARN("failed to parse From header\n");
-				pkg_free(ft_body);
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sanity_reply(_msg, 400, "Bad From header") == -1) {
-						LM_WARN("failed to send 400 via send_reply (bad from header)\n");
-					}
-				}
-				return SANITY_CHECK_FAILED;
-			}
-			_msg->from->parsed = ft_body;
-			ft_body = NULL;
-		}
-		if (((struct to_body*)_msg->from->parsed)->uri.s) {
-			if (parse_uri(((struct to_body*)_msg->from->parsed)->uri.s, 
-					((struct to_body*)_msg->from->parsed)->uri.len, &uri) != 0) {
-			    LM_WARN("failed to parse From uri\n");
-			    if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Bad From URI") == -1) {
-				    LM_WARN("failed to send 400 via send_reply (bad from uri)\n");
-				}
-			    }
-			    return SANITY_CHECK_FAILED;
-			}
-			/* FIXME: we should store this parsed struct somewhere so that
-			 * it could be re-used */
-			/* FIXME 2: would it make sense to check here for "mandatory"
-			 * or "requested" parts of the URI? */
-		}
-	}
-	/* check To URI */
-	if (SANITY_URI_CHECK_TO & checks) {
-		if ((!_msg->to && parse_headers(_msg, HDR_TO_F, 0) != 0) || !_msg->to) {
-			LM_WARN("missing to header\n");
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Missing To Header") == -1) {
-					LM_WARN("failed to send 400 via send_reply (missing To)\n");
-				}
-			}
-			return SANITY_CHECK_FAILED;
-		}
-		/* parse_to is automatically called for HDR_TO_F */
-		if (!_msg->to->parsed) {
-			LM_WARN("failed to parse To header\n");
-			if (_msg->REQ_METHOD != METHOD_ACK) {
-				if (sanity_reply(_msg, 400, "Bad To URI") == -1) {
-					LM_WARN("failed to send 400 via send_reply (bad to uri)\n");
-				}
-			}
-			return SANITY_CHECK_FAILED;
-		}
-		if (((struct to_body*)_msg->to->parsed)->uri.s) {
-			if (parse_uri(((struct to_body*)_msg->to->parsed)->uri.s, 
-					((struct to_body*)_msg->to->parsed)->uri.len, &uri) != 0) {
-				LM_WARN("failed to parse To uri\n");
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sanity_reply(_msg, 400, "Bad To URI") == -1) {
-						LM_WARN("failed to send 400 via send_reply (bad to uri)\n");
-					}
-				}
-				return SANITY_CHECK_FAILED;
-			}
-			/* FIXME: we should store this parsed struct somewhere so that
-			 * it could be re-used */
-			/* FIXME 2: would it make sense to check here for "mandatory"
-			 * or "requested" parts of the URI? */
-		}
-	}
-	/* check Contact URI */
-	if (SANITY_URI_CHECK_CONTACT & checks) {
-		if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0) || !_msg->contact) {
-			LM_WARN("missing contact header\n");
-		}
-		if (_msg->contact) {
-			if (parse_contact(_msg->contact) < 0) {
-				LM_WARN("check_parse_uris(): failed to parse Contact header\n");
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sanity_reply(_msg, 400, "Bad Contact Header") == -1) {
-						LM_WARN("failed to send 400 via send_reply (bad Contact)\n");
-					}
-				}
-				return SANITY_CHECK_FAILED;
-			}
-			if (parse_uri(((struct contact_body*)_msg->contact->parsed)->contacts->uri.s,
-					((struct contact_body*)_msg->contact->parsed)->contacts->uri.len, &uri) != 0) {
-				LM_WARN("failed to parse Contact uri\n");
-				if (_msg->REQ_METHOD != METHOD_ACK) {
-					if (sanity_reply(_msg, 400, "Bad Contact URI") == -1) {
-						LM_WARN("failed to send 400 via send_reply (bad Contact uri)\n");
-					}
-				}
-				return SANITY_CHECK_FAILED;
-			}
-		}
-	}
-
-	return SANITY_CHECK_PASSED;
-}
-
-
-/* Make sure that username attribute in all digest credentials
- * instances has a meaningful value
- */
-int check_digest(struct sip_msg* msg, int checks)
-{
-    struct hdr_field* ptr;
-    dig_cred_t* cred;
-    int ret;
-    int hf_type;
-
-    if (parse_headers(msg, HDR_EOH_F, 0) != 0) {
-		LM_ERR("failed to parse proxy require header\n");
-		return SANITY_CHECK_FAILED;
-    }
-
-    if (!msg->authorization && !msg->proxy_auth) {
-		return SANITY_CHECK_PASSED;
-    }
-
-    if (msg->authorization) {
-	hf_type = HDR_AUTHORIZATION_T;
-	ptr = msg->authorization;
-    } else {
-	hf_type = HDR_PROXYAUTH_T;
-	ptr = msg->proxy_auth;
-    }
-    while(ptr) {
-	if ((ret = parse_credentials(ptr)) != 0) {
-	    LM_DBG("Cannot parse credentials: %d\n", ret);
-	    return SANITY_CHECK_FAILED;
-	}
-
-	cred = &((auth_body_t*)ptr->parsed)->digest;
-
-	if (check_dig_cred(cred) != E_DIG_OK) {
-	    return SANITY_CHECK_FAILED;
-	}
-
-	if (cred->username.whole.len == 0) {
-	    return SANITY_CHECK_FAILED;
-	}
-	
-	if (cred->nonce.len == 0) {
-	    return SANITY_CHECK_FAILED;
-	}
-
-	if (cred->response.len == 0) {
-	    return SANITY_CHECK_FAILED;
-	}
-
-	do {
-	    ptr = ptr->next;
-	} while(ptr && ptr->type != hf_type);
-
-	if (!ptr && hf_type == HDR_AUTHORIZATION_T) {
-	    hf_type = HDR_PROXYAUTH_T;
-	    ptr = msg->proxy_auth;
-	}
-    }
-
-    return SANITY_CHECK_PASSED;
-}

+ 0 - 79
modules_k/sanity/sanity.h

@@ -1,79 +0,0 @@
-/*
- * $Id$
- *
- * Sanity Checks Module
- * 
- * Copyright (C) 2006 iptelorg GbmH
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * Kamailio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * Kamailio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef SANITY_CHK_H
-#define SANITY_CHK_H
-
-#include "mod_sanity.h"
-
-#define SIP_VERSION_TWO_POINT_ZERO "2.0"
-#define SIP_VERSION_TWO_POINT_ZERO_LENGTH 3
-
-/* check if the given string is a valid unsigned int value
- * and converts it into _result. returns -1 on error and 0 on success*/
-int str2valid_uint(str* _number, unsigned int* _result);
-
-/* parses the given comma seperated string into a string list */
-strl* parse_str_list(str* _string);
-
-/* compare the protocol string in the Via header with the transport */
-int check_via_protocol(struct sip_msg* _msg);
-
-/* check if the SIP version in the Via header is 2.0 */
-int check_via_sip_version(struct sip_msg* _msg);
-
-/* compare the Content-Length value with the accutal body length */
-int check_cl(struct sip_msg* _msg);
-
-/* compare the method in the CSeq header with the request line value */
-int check_cseq_method(struct sip_msg* _msg);
-
-/* check the number within the CSeq header */
-int check_cseq_value(struct sip_msg* _msg);
-
-/* check the number within the Expires header */
-int check_expires_value(struct sip_msg* _msg);
-
-/* check for the presence of the minimal required headers */
-int check_required_headers(struct sip_msg* _msg);
-
-/* check the content of the Proxy-Require header */
-int check_proxy_require(struct sip_msg* _msg);
-
-/* check the SIP version in the request URI */
-int check_ruri_sip_version(struct sip_msg* _msg);
-
-/* check if the r-uri scheme */
-int check_ruri_scheme(struct sip_msg* _msg);
-
-/* check if the typical URIs are parseable */
-int check_parse_uris(struct sip_msg* _msg, int checks);
-
-/* Make sure that username attribute in all digest credentials
- * instances has a meaningful value
- */
-int check_digest(struct sip_msg* _msg, int checks);
-
-#endif /* SANITY_CHK_H */

+ 5 - 0
onsend.h

@@ -40,6 +40,7 @@
 #include "action.h"
 #include "route.h"
 #include "script_cb.h"
+#include "sr_compat.h"
 
 struct onsend_info{
 	union sockaddr_union* to;
@@ -89,6 +90,10 @@ static inline int run_onsend(struct sip_msg* orig_msg, struct dest_info* dst,
 			orig_msg->fwd_send_flags=fwd_snd_flags_bak;
 			orig_msg->rpl_send_flags=rpl_snd_flags_bak;
 			exec_post_script_cb(orig_msg, ONSEND_CB_TYPE);
+			if((sr_cfg_compat==SR_COMPAT_KAMAILIO)
+					&& (ret==0) && !(ra_ctx.run_flags&DROP_R_F)){
+				ret = 1;
+			}
 		} else {
 			ret=0; /* drop the message */
 		}

+ 11 - 4
receive.c

@@ -98,6 +98,7 @@ unsigned int inc_msg_no(void)
 int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
 {
 	struct sip_msg* msg;
+	struct run_act_ctx ctx;
 	int ret;
 #ifdef STATS
 	int skipped = 1;
@@ -235,13 +236,17 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 		/* exec the onreply routing script */
 		if (onreply_rt.rlist[DEFAULT_RT]){
 			set_route_type(ONREPLY_ROUTE);
-			ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, 0);
-			if (ret<0){
+			ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
+#ifndef NO_ONREPLY_ROUTE_ERROR
+			if (unlikely(ret<0)){
 				LOG(L_WARN, "WARNING: receive_msg: "
 						"error while trying onreply script\n");
 				goto error_rpl;
-			}else if (ret==0) goto skip_send_reply; /* drop the message, 
-													   no error */
+			}else
+#endif /* NO_ONREPLY_ROUTE_ERROR */
+			if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
+				goto skip_send_reply; /* drop the message, no error */
+			}
 		}
 		/* send the msg */
 		forward_reply(msg);
@@ -271,11 +276,13 @@ end:
 	if (skipped) STATS_RX_DROPS;
 #endif
 	return 0;
+#ifndef NO_ONREPLY_ROUTE_ERROR
 error_rpl:
 	/* execute post reply-script callbacks */
 	exec_post_script_cb(msg, ONREPLY_CB_TYPE);
 	reset_avps();
 	goto error02;
+#endif /* NO_ONREPLY_ROUTE_ERROR */
 error_req:
 	DBG("receive_msg: error:...\n");
 	/* execute post request-script callbacks */