Module: sip-router Branch: master Commit: e9b9c8f7ccdfe4824b58e252ef157dcfbf4c9738 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e9b9c8f7...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Fri Nov 26 12:39:07 2010 +0100
sanity: export inter-module API
- sanity functions can be used from inside other modules (e.g., topoh can use it now before getting to config file execution)
---
modules/sanity/api.h | 68 ++++++++++++++++++++++++ modules/sanity/mod_sanity.c | 123 ++++++++++++++++++++++++++++-------------- 2 files changed, 150 insertions(+), 41 deletions(-)
diff --git a/modules/sanity/api.h b/modules/sanity/api.h new file mode 100644 index 0000000..0386bd8 --- /dev/null +++ b/modules/sanity/api.h @@ -0,0 +1,68 @@ +/* + * $Id$ + * + * Sanity Checks Module + * + * Copyright (C) 2006 iptelorg GbmH + * + * This file is part of ser, a free SIP server. + * + * ser 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 + * + * For a license to use the ser software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * ser 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_API_H_ +#define _SANITY_API_H_ + +#include "../../parser/msg_parser.h" + +typedef int (*sanity_check_f)(struct sip_msg* msg, int msg_checks, + int uri_checks); +typedef int (*sanity_check_defaults_f)(struct sip_msg* msg); + +typedef struct sanity_api { + sanity_check_f check; + sanity_check_defaults_f check_defaults; +} sanity_api_t; + +typedef int (*bind_sanity_f)(sanity_api_t* api); + +/** + * @brief Load the Sanity API + */ +static inline int sanity_load_api(sanity_api_t *api) +{ + bind_sanity_f bindsanity; + + bindsanity = (bind_sanity_f)find_export("bind_sanity", 0, 0); + if(bindsanity == 0) { + LM_ERR("cannot find bind_sanity\n"); + return -1; + } + if(bindsanity(api)<0) + { + LM_ERR("cannot bind sanity api\n"); + return -1; + } + return 0; +} + + +#endif /* _SANITY_API_H_ */ diff --git a/modules/sanity/mod_sanity.c b/modules/sanity/mod_sanity.c index ffe888f..fee6890 100644 --- a/modules/sanity/mod_sanity.c +++ b/modules/sanity/mod_sanity.c @@ -30,6 +30,7 @@
#include "mod_sanity.h" #include "sanity.h" +#include "api.h" #include "../../sr_module.h" #include "../../ut.h" #include "../../error.h" @@ -40,8 +41,8 @@ MODULE_VERSION
str pr_str = STR_STATIC_INIT(PROXY_REQUIRE_DEF);
-int default_checks = SANITY_DEFAULT_CHECKS; -int uri_checks = SANITY_DEFAULT_URI_CHECKS; +int default_msg_checks = SANITY_DEFAULT_CHECKS; +int default_uri_checks = SANITY_DEFAULT_URI_CHECKS; int _sanity_drop = 1;
strl* proxyrequire_list = NULL; @@ -50,18 +51,20 @@ sl_api_t slb;
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); +static int w_sanity_check(struct sip_msg* _msg, char* _foo, char* _bar); +static int bind_sanity(sanity_api_t* api);
/* * Exported functions */ static cmd_export_t cmds[] = { - {"sanity_check", (cmd_function)sanity_check, 0, 0, + {"sanity_check", (cmd_function)w_sanity_check, 0, 0, REQUEST_ROUTE}, - {"sanity_check", (cmd_function)sanity_check, 1, sanity_fixup, + {"sanity_check", (cmd_function)w_sanity_check, 1, sanity_fixup, REQUEST_ROUTE}, - {"sanity_check", (cmd_function)sanity_check, 2, sanity_fixup, + {"sanity_check", (cmd_function)w_sanity_check, 2, sanity_fixup, REQUEST_ROUTE}, + {"bind_sanity", (cmd_function)bind_sanity, 0, 0, 0}, {0, 0, 0, 0} };
@@ -69,8 +72,8 @@ static cmd_export_t cmds[] = { * Exported parameters */ static param_export_t params[] = { - {"default_checks", PARAM_INT, &default_checks }, - {"uri_checks", PARAM_INT, &uri_checks }, + {"default_checks", PARAM_INT, &default_msg_checks }, + {"uri_checks", PARAM_INT, &default_uri_checks }, {"proxy_require", PARAM_STR, &pr_str }, {"autodrop", PARAM_INT, &_sanity_drop }, {0, 0, 0} @@ -151,79 +154,117 @@ static int sanity_fixup(void** param, int param_no) { 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; - } +/** + * perform SIP message sanity check + * @param _msg - SIP message structure + * @param msg_checks - bitmask of sanity tests to perform over message + * @param uri_checks - bitmask of sanity tests to perform over uri + * @return -1 on error, 0 on tests failure, 1 on success + */ +int sanity_check(struct sip_msg* _msg, int msg_checks, int uri_checks) +{ + int ret;
- ret = 1; - if (SANITY_RURI_SIP_VERSION & check && + ret = SANITY_CHECK_PASSED; + if (SANITY_RURI_SIP_VERSION & msg_checks && (ret = check_ruri_sip_version(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_RURI_SCHEME & check && + if (SANITY_RURI_SCHEME & msg_checks && (ret = check_ruri_scheme(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_REQUIRED_HEADERS & check && + if (SANITY_REQUIRED_HEADERS & msg_checks && (ret = check_required_headers(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_VIA_SIP_VERSION & check && + if (SANITY_VIA_SIP_VERSION & msg_checks && (ret = check_via_sip_version(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_VIA_PROTOCOL & check && + if (SANITY_VIA_PROTOCOL & msg_checks && (ret = check_via_protocol(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_CSEQ_METHOD & check && + if (SANITY_CSEQ_METHOD & msg_checks && (ret = check_cseq_method(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_CSEQ_VALUE & check && + if (SANITY_CSEQ_VALUE & msg_checks && (ret = check_cseq_value(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_CL & check && + if (SANITY_CL & msg_checks && (ret = check_cl(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_EXPIRES_VALUE & check && + if (SANITY_EXPIRES_VALUE & msg_checks && (ret = check_expires_value(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_PROXY_REQUIRE & check && + if (SANITY_PROXY_REQUIRE & msg_checks && (ret = check_proxy_require(_msg)) != SANITY_CHECK_PASSED) { goto done; } - if (SANITY_PARSE_URIS & check && - (ret = check_parse_uris(_msg, arg)) != SANITY_CHECK_PASSED) { + if (SANITY_PARSE_URIS & msg_checks && + (ret = check_parse_uris(_msg, uri_checks)) != SANITY_CHECK_PASSED) { goto done; }
- if (SANITY_CHECK_DIGEST & check && - (ret = check_digest(_msg, arg)) != SANITY_CHECK_PASSED) { + if (SANITY_CHECK_DIGEST & msg_checks && + (ret = check_digest(_msg, uri_checks)) != SANITY_CHECK_PASSED) { goto done; }
done: + return ret; +} + +/** + * do default checks + */ +int sanity_check_defaults(struct sip_msg* msg) +{ + return sanity_check(msg, default_msg_checks, default_uri_checks); +} + +/** + * wrapper for sanity_check() to be used from config file + */ +static int w_sanity_check(struct sip_msg* _msg, char* _number, char* _arg) { + int ret, check, arg; + + if (_number == NULL) { + check = default_msg_checks; + } + else { + check = (int)(long)_number; + } + if (_arg == NULL) { + arg = default_uri_checks; + } + else { + arg = (int)(long)_arg; + } + ret = sanity_check(_msg, check, arg); + + DBG("sanity checks result: %d\n", ret); if(_sanity_drop!=0) return ret; return (ret==SANITY_CHECK_FAILED)?-1:ret; +}
- DBG("all sanity checks passed\n"); - /* nobody complained so everything is fine */ - return 1; +/** + * load sanity module API + */ +static int bind_sanity(sanity_api_t* api) +{ + if (!api) { + ERR("Invalid parameter value\n"); + return -1; + } + api->check = sanity_check; + api->check_defaults = sanity_check_defaults; + + return 0; }