From 195f7ea8a16aa4df36c722267b6456a4b82fb2bd Mon Sep 17 00:00:00 2001 From: Henning Westerholt Date: Mon, 10 Jan 2022 13:44:51 +0000 Subject: [PATCH] siputils: remove ring 180/183 conversion functions (GH #2989) - remove ring 180/183 conversion functions (GH #2989) - they are not working correctly anymore, and can easily be replaced by textops/htable or reply routes --- src/modules/siputils/doc/siputils_admin.xml | 58 --- src/modules/siputils/ring.c | 388 -------------------- src/modules/siputils/ring.h | 87 ----- src/modules/siputils/siputils.c | 33 -- 4 files changed, 566 deletions(-) delete mode 100644 src/modules/siputils/ring.c delete mode 100644 src/modules/siputils/ring.h diff --git a/src/modules/siputils/doc/siputils_admin.xml b/src/modules/siputils/doc/siputils_admin.xml index db66d40ac67..73178847ad0 100644 --- a/src/modules/siputils/doc/siputils_admin.xml +++ b/src/modules/siputils/doc/siputils_admin.xml @@ -20,12 +20,6 @@ handling and URI handling. - It offers some functions related to handle ringing. In a parallel forking - scenario you get several 183s with SDP. You don't want that your customers - hear more than one ringtone or answer machine in parallel on the phone. - So its necessary to drop the 183 in this cases and send a 180 instead. - - This module also provides a function to answer OPTIONS requests which are directed to the server itself. This means an OPTIONS request which has the address of the server in the request URI, and no @@ -72,26 +66,6 @@
Parameters -
- <varname>ring_timeout</varname> (int) - - Timeout value in seconds, define how long the call-id is stored in the internal list kept for replacing 183 messages with 180. - A reasonable value is 30. - - - - Default value is 0. This means functionality is disabled. - - - - Set <varname>ring_timeout</varname> parameter - -... -modparam("siputils", "ring_timeout", 30) -... - - -
<varname>options_accept</varname> (string) @@ -274,38 +248,6 @@ modparam("auth", "rpid_avp", "$avp(myrpid)")
Functions -
- - <function moreinfo="none">ring_insert_callid()</function> - - - Inserting the call-id in the internal list, which is checked when - further replies arrive. Any 183 reply that is received during the - timeout value will be converted to a 180 message with removed SDP body. - Please note that you need to set a positive ring_timeout value in order - to use this function. - - - Note: the change of sip reply can be done only in cases when it is not - parsed too much before config execution, otherwise it fails. For - example, setting global parameter "log_prefix" can cause this function - to fail changing the replies. - - - The function returns TRUE on success, and FALSE during processing failures. - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>ring_insert_callid()</function> usage - -... -ring_insert_callid(); -... - - -
<function moreinfo="none">options_reply()</function> diff --git a/src/modules/siputils/ring.c b/src/modules/siputils/ring.c deleted file mode 100644 index 82d8bd07b3e..00000000000 --- a/src/modules/siputils/ring.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2008-2009 1&1 Internet AG - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -/** - * \file - * \brief SIP-utils :: Only allow one 183 message per call-id - * \ingroup siputils - * - Module; \ref siputils - * - * \section ring_utils UTILS :: Ringing functionality - * - * In a parallel forking scenario you may get several 183s with SDP. You don't want - * that your customers hear more than one ringtone or answer machine in parallel - * on the phone. So its necessary to drop the 183 in these cases and send a 180 instead. - */ - - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#include "../../core/parser/msg_parser.h" -#include "../../core/dprint.h" -#include "../../core/error.h" -#include "../../core/ut.h" -#include "../../core/mem/mem.h" -#include "../../core/mem/shm_mem.h" -#include "../../core/timer.h" -#include "../../core/locking.h" -#include "../../core/crypto/md5.h" - -#include "config.h" -#include "ring.h" - - -/*! list of calls for ringing functionality */ -struct ring_record_t { - struct ring_record_t *next; - unsigned int time; /*!< timeout value */ - char callid[MAXCALLIDLEN+1]; /*!< callid of this call */ -}; - -/*! hashtable for ringing records */ -struct hashtable_entry_t { - struct ring_record_t *head; - struct ring_record_t *tail; -}; - -typedef struct hashtable_entry_t hashtable_t[HASHTABLESIZE]; - -/*! global hashtable */ -static hashtable_t *hashtable = NULL; - -static void insert(str callid); - -static int contains(str callid); - - -/*! - * \brief Inserts callid of message into hashtable - * - * Inserts callid of message into hashtable. Any 183 messages with - * this callid that occur in the next ring_timeout seconds, will be - * converted to 180. - * \param msg SIP message - * \param unused1 unused - * \param unused2 unused - * \return 1 on success, -1 otherwise - */ -int ring_insert_callid(struct sip_msg *msg, char *unused1, char *unused2) -{ - /* could fail, eg if already parsed don't care about result */ - if(parse_headers(msg, HDR_CALLID_F, 0)<0) { - LM_ERR("failed to parse headers\n"); - return -1; - } - - if (msg->callid) { - lock_get(ring_lock); - if (!contains(msg->callid->body)) insert(msg->callid->body); - lock_release(ring_lock); - } else { - LM_ERR("no callid\n"); - return -1; - } - - return 1; -} - - -/*! - * \brief Initialize the ring hashtable in shared memory - */ -void ring_init_hashtable(void) -{ - int i; - - hashtable = shm_malloc(sizeof(hashtable_t)); - assert(hashtable); - for (i=0; i<HASHTABLESIZE; i++) { - (*hashtable)[i].head = NULL; - (*hashtable)[i].tail = NULL; - } -} - - -/*! - * \brief Destroy the ring hashtable - */ -void ring_destroy_hashtable(void) -{ - int i; - - if (hashtable) { - for (i=0; i<HASHTABLESIZE; i++) { - while ((*hashtable)[i].head) { - struct ring_record_t* rr = (*hashtable)[i].head; - (*hashtable)[i].head = rr->next; - shm_free(rr); - } - (*hashtable)[i].tail = NULL; - } - - shm_free(hashtable); - } -} - - -/*! - * \brief Hash helper function - * \param buf hashed buffer - * \param len length of buffer - * \return hash value, can be 0 - */ -static unsigned int hash(char *buf, int len) -{ - int i; - unsigned int retval = 0; - MD5_CTX md5context; - char digest[16]; - - MD5Init(&md5context); - MD5Update(&md5context, buf, len); - MD5Final(digest, &md5context); - - for (i=0; i<16; i++) { - retval ^= ((unsigned int)((unsigned char)buf[i])) << i; - } - - return retval; -} - - -/*! - * \brief Expire entries on the hashtable - * \param index array index that should expired - */ -static void remove_timeout(unsigned int index) -{ - int ring_timeout = cfg_get(siputils, siputils_cfg, ring_timeout); - if(ring_timeout == 0){ - LM_ERR("Could not get timeout from cfg. This will expire all entries"); - } - while ((*hashtable)[index].head && ((*hashtable)[index].head)->time + ring_timeout < get_ticks()) { - struct ring_record_t* rr = (*hashtable)[index].head; - (*hashtable)[index].head = rr->next; - if ((*hashtable)[index].head == NULL) (*hashtable)[index].tail = NULL; - LM_DBG("deleting ticks=%d %s\n", get_ticks(), rr->callid); - shm_free(rr); - } -} - - -/*! - * \brief Insert a new entry on the hashtable - * \param callid Call-ID string - */ -static void insert(str callid) -{ - unsigned int index = hash(callid.s, callid.len) & HASHTABLEMASK; - struct ring_record_t* rr; - - remove_timeout(index); - rr = shm_malloc(sizeof(struct ring_record_t)); - assert(rr); - - rr->next = NULL; - rr->time = get_ticks(); - strncpy(rr->callid, callid.s, MIN(callid.len, MAXCALLIDLEN)); - rr->callid[MIN(callid.len, MAXCALLIDLEN)] = 0; - - if ((*hashtable)[index].tail) { - (*hashtable)[index].tail->next = rr; - (*hashtable)[index].tail = rr; - } - else { - (*hashtable)[index].head = rr; - (*hashtable)[index].tail = rr; - } - - LM_DBG("inserting at %d %.*s ticks=%d\n", index, callid.len, callid.s, rr->time); -} - - -/*! - * \brief Helper functions that checks if the hash table contains the callid - * \param callid Call-ID that is searched - * \return 1 when callid could be found, 0 when not found - */ -static int contains(str callid) -{ - unsigned int index = hash(callid.s, callid.len) & HASHTABLEMASK; - struct ring_record_t* rr; - - remove_timeout(index); - - rr = (*hashtable)[index].head; - while (rr) { - if (strncmp(rr->callid, callid.s, callid.len) == 0) return 1; - rr = rr->next; - } - return 0; -} - - -/*! - * \brief Convert a 183 to a 180 message. - * \param msg SIP message - */ -static int conv183(struct sip_msg *msg) -{ - /* content-length and content-type headers are removed */ - char *del1_start = strstr(msg->buf, "Content-Length:"); - char *del2_start = strstr(msg->buf, "Content-Type:"); - char *del1_end; - char *del2_end; - char *eoh; - char *chunk1_start; - int chunk1_len; - char *chunk1_dst; - char *chunk2_start; - int chunk2_len; - char *chunk2_dst; - char *chunk3_start; - int chunk3_len; - char *chunk3_dst; - - if (del1_start>del2_start) { - char *tmp = del1_start; - del1_start = del2_start; - del2_start = tmp; - } - - del1_end = NULL; - if (del1_start) { - del1_end = strstr(del1_start, "\r\n"); - if (del1_end) del1_end+=2; - } - del2_end = NULL; - if (del2_start) { - del2_end = strstr(del2_start, "\r\n"); - if (del2_end) del2_end+=2; - } - - /* 180 message does not need session description */ - eoh = strstr(msg->buf, "\r\n\r\n"); - if (eoh) eoh+=2; - - if ((!del1_start) || (!del2_start) || (!del1_end) || (!del2_end) || (!eoh)) { - LM_ERR("got invalid 183 message\n"); - return -1; - } - - /* - * if message is parsed further than first deletion, offsets of parsed strings would - * not be correct any more. In that case do not convert! If this error is reported, - * check if other pre script callbacks are installed before the one of this module. - */ - if (msg->unparsed>del1_start) { - LM_ERR("183 message got parsed too far!\n"); - return -1; - } - - /* setting new status */ - msg->first_line.u.reply.statuscode=180; - msg->first_line.u.reply.status.s[2]='0'; - // don't change length of reason string - strncpy(msg->first_line.u.reply.reason.s, "Ringing ", msg->first_line.u.reply.reason.len); - - /* calculate addresses of chunks to be moved */ - chunk1_start = del1_end; - chunk1_len = (int)(long)(del2_start-del1_end); - chunk1_dst = del1_start; - - chunk2_start = del2_end; - chunk2_len = (int)(long)(eoh-del2_end); - chunk2_dst = chunk1_dst+chunk1_len; - - chunk3_start = "Content-Length: 0\r\n\r\n"; - chunk3_len = strlen(chunk3_start); - chunk3_dst = chunk2_dst+chunk2_len; - - // move chunks - memmove(chunk1_dst, chunk1_start, chunk1_len); - memmove(chunk2_dst, chunk2_start, chunk2_len); - memmove(chunk3_dst, chunk3_start, chunk3_len); - - /* terminate string with zero */ - *(chunk3_dst+chunk3_len)='\0'; - - /* update message length */ - msg->len = strlen(msg->buf); - - return 0; -} - - -/*! - * \brief Callback function that does the work inside the server. - * \param msg SIP message - * \param flags unused - * \param bar unused - * \return 1 on success, -1 on failure - */ -int ring_filter(struct sip_msg *msg, unsigned int flags, void *bar) -{ - int contains_callid; - - if (msg->first_line.type == SIP_REPLY && msg->first_line.u.reply.statuscode == 183) { - /* could fail, eg if already parsed, don't care about result */ - if(parse_headers(msg, HDR_CALLID_F, 0)<0) { - LM_ERR("headers parsing failed\n"); - return -1; - } - - if (msg->callid) { - lock_get(ring_lock); - contains_callid=contains(msg->callid->body); - lock_release(ring_lock); - - if (contains_callid) { - LM_DBG("converting 183 to 180 for %.*s\n", msg->callid->body.len, msg->callid->body.s); - if (conv183(msg)!=0) return -1; - } - } else { - LM_ERR("no callid\n"); - return -1; - } - } - - return 1; -} - - -/*! - * \brief Fixup function for the ring_insert_callid function - * \param param unused - * \param param_no unused - * \return 0 - */ -int ring_fixup(void ** param, int param_no) { - int ring_timeout = cfg_get(siputils, siputils_cfg, ring_timeout); - if (ring_timeout == 0) { - LM_ERR("ring_insert_callid functionality deactivated, you need to set a positive ring_timeout\n"); - return -1; - } - return 0; -} diff --git a/src/modules/siputils/ring.h b/src/modules/siputils/ring.h deleted file mode 100644 index 18fa62851cc..00000000000 --- a/src/modules/siputils/ring.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2008-2009 1&1 Internet AG - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * \file - * \brief SIP-utils :: Module with several utiltity functions related to SIP messages handling - * \ingroup siputils - * - Module; \ref siputils - */ - -#ifndef RING_H -#define RING_H - - -#define HASHTABLEBITS 13 -#define HASHTABLESIZE (((unsigned int)1) << HASHTABLEBITS) -#define HASHTABLEMASK (HASHTABLESIZE - 1) -#define MAXCALLIDLEN 255 - - -extern gen_lock_t *ring_lock; - - -/*! - * \brief Inserts callid of message into hashtable - * - * Inserts callid of message into hashtable. Any 183 messages with - * this callid that occur in the next ring_timeout seconds, will be - * converted to 180. - * \param msg SIP message - * \param unused1 unused - * \param unused2 unused - * \return 1 on success, -1 otherwise - */ -int ring_insert_callid(struct sip_msg *msg, char *unused1, char *unused2); - - -/*! - * \brief Initialize the ring hashtable in shared memory - */ -void ring_init_hashtable(void); - - -/*! - * \brief Destroy the ring hashtable - */ -void ring_destroy_hashtable(void); - - -/*! - * \brief Callback function that does the work inside the server. - * \param msg SIP message - * \param flags unused - * \param bar unused - * \return 1 on success, -1 on failure - */ -int ring_filter(struct sip_msg *msg, unsigned int flags, void *bar); - - -/*! - * \brief Fixup function for the ring_insert_callid function - * \param param unused - * \param param_no unused - * \return 0 - */ -int ring_fixup(void ** param, int param_no); - - -#endif diff --git a/src/modules/siputils/siputils.c b/src/modules/siputils/siputils.c index 747bf408faf..704f3e9a299 100644 --- a/src/modules/siputils/siputils.c +++ b/src/modules/siputils/siputils.c @@ -34,12 +34,6 @@ * This module implement various functions and checks related to * SIP message handling and URI handling. * - * It offers some functions related to handle ringing. In a - * parallel forking scenario you get several 183s with SDP. You - * don't want that your customers hear more than one ringtone or - * answer machine in parallel on the phone. So its necessary to - * drop the 183 in this cases and send a 180 instead. - * * This module provides a function to answer OPTIONS requests * which are directed to the server itself. This means an OPTIONS * request which has the address of the server in the request @@ -68,7 +62,6 @@ #include "../../core/parser/parse_uri.h" #include "../../core/parser/parse_date.h" -#include "ring.h" #include "options.h" #include "checks.h" @@ -96,8 +89,6 @@ str rpid_suffix = {DEF_RPID_SUFFIX, sizeof(DEF_RPID_SUFFIX) - 1}; /*! Definition of AVP containing rpid value */ char* rpid_avp_param = DEF_RPID_AVP; -gen_lock_t *ring_lock = NULL; -unsigned int ring_timeout = 0; /* for options functionality */ str opt_accept = str_init(ACPT_DEF); str opt_accept_enc = str_init(ACPT_ENC_DEF); @@ -128,8 +119,6 @@ static int fixup_option(void** param, int param_no); char *contact_flds_separator = DEFAULT_SEPARATOR; static cmd_export_t cmds[]={ - {"ring_insert_callid", (cmd_function)ring_insert_callid, 0, ring_fixup, - 0, REQUEST_ROUTE|FAILURE_ROUTE}, {"options_reply", (cmd_function)opt_reply, 0, 0, 0, REQUEST_ROUTE}, {"is_user", (cmd_function)is_user, 1, fixup_spve_null, @@ -220,7 +209,6 @@ static cmd_export_t cmds[]={ }; static param_export_t params[] = { - {"ring_timeout", INT_PARAM, &default_siputils_cfg.ring_timeout}, {"options_accept", PARAM_STR, &opt_accept}, {"options_accept_encoding", PARAM_STR, &opt_accept_enc}, {"options_accept_language", PARAM_STR, &opt_accept_lang}, @@ -256,21 +244,6 @@ struct module_exports exports= { static int mod_init(void) { - if(default_siputils_cfg.ring_timeout > 0) { - ring_init_hashtable(); - - ring_lock = lock_alloc(); - assert(ring_lock); - if (lock_init(ring_lock) == 0) { - LM_CRIT("cannot initialize lock.\n"); - return -1; - } - if (register_script_cb(ring_filter, PRE_SCRIPT_CB|ONREPLY_CB, 0) != 0) { - LM_ERR("could not insert callback"); - return -1; - } - } - /* bind the SL API */ if (sl_load_api(&opt_slb)!=0) { LM_ERR("cannot bind to SL API\n"); @@ -293,13 +266,7 @@ static int mod_init(void) static void mod_destroy(void) { - if (ring_lock) { - lock_destroy(ring_lock); - lock_dealloc((void *)ring_lock); - ring_lock = NULL; - } - ring_destroy_hashtable(); }