浏览代码

topos: new module - topology stripping

- provides topology hiding by stripping the headers with SIP routing
  details
Daniel-Constantin Mierla 9 年之前
父节点
当前提交
68717c2af0

+ 18 - 0
modules/topos/Makefile

@@ -0,0 +1,18 @@
+#
+# topos module makefile
+#
+# 
+# WARNING: do not run this directly, it should be run by the master Makefile
+
+include ../../Makefile.defs
+auto_gen=
+NAME=topos.so
+LIBS=
+
+DEFS+=-DKAMAILIO_MOD_INTERFACE
+
+SERLIBPATH=../../lib
+SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1
+SER_LIBS+=$(SERLIBPATH)/srutils/srutils
+
+include ../../Makefile.modules

+ 123 - 0
modules/topos/README

@@ -0,0 +1,123 @@
+TOPOS Module
+
+Daniel-Constantin Mierla
+
+   <[email protected]>
+
+Edited by
+
+Daniel-Constantin Mierla
+
+   <[email protected]>
+
+   Copyright © 2016 FhG FOKUS
+     __________________________________________________________________
+
+   Table of Contents
+
+   1. Admin Guide
+
+        1. Overview
+        2. Dependencies
+
+              2.1. Kamailio Modules
+              2.2. External Libraries or Applications
+
+        3. Parameters
+
+              3.1. db_url (str)
+              3.2. mask_callid (int)
+              3.3. sanity_checks (int)
+
+   List of Examples
+
+   1.1. Set db_url parameter
+   1.2. Set mask_callid parameter
+   1.3. Set sanity_checks parameter
+
+Chapter 1. Admin Guide
+
+   Table of Contents
+
+   1. Overview
+   2. Dependencies
+
+        2.1. Kamailio Modules
+        2.2. External Libraries or Applications
+
+   3. Parameters
+
+        3.1. db_url (str)
+        3.2. mask_callid (int)
+        3.3. sanity_checks (int)
+
+1. Overview
+
+   This module offers topology hiding by stripping the SIP routing headers
+   that show topology details. The script interpreter gets the SIP
+   messages with full content, so all existing functionality is preserved.
+
+   The module is transparent for the configuration writer. It only needs
+   to be loaded (tune the parameters if needed).
+
+2. Dependencies
+
+   2.1. Kamailio Modules
+   2.2. External Libraries or Applications
+
+2.1. Kamailio Modules
+
+   The following modules must be loaded before this module:
+     * rr module - server must perform record routing to ensure in-dialog
+       requests are encoded/decoded.
+     * database module - to store the data for topology stripping and
+       restoring.
+
+2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running Kamailio with this module loaded:
+     * none.
+
+3. Parameters
+
+   3.1. db_url (str)
+   3.2. mask_callid (int)
+   3.3. sanity_checks (int)
+
+3.1. db_url (str)
+
+   Database URL.
+
+   Default value is "mysql://kamailio:kamailiorw@localhost/kamailio".
+
+   Example 1.1. Set db_url parameter
+...
+modparam("topos", "db_url", "dbdriver://username:password@dbhost/dbname")
+...
+
+3.2. mask_callid (int)
+
+   Whether to replace or not the Call-ID with another unique id generated
+   by Kamailio.
+
+   Default value is 0 (do not mask).
+
+   Example 1.2. Set mask_callid parameter
+...
+modparam("topos", "mask_callid", 1)
+...
+
+3.3. sanity_checks (int)
+
+   If set to 1, topoh module will bind to sanity module in order to
+   perform sanity checks over received SIP request. Default sanity checks
+   are done. It is useful to check if received request is well formated
+   before proceeding to encoding/decoding.
+
+   Default value is 0 (do not bind to sanity module).
+
+   Example 1.3. Set sanity_checks parameter
+...
+modparam("topoh", "sanity_checks", 1)
+...

+ 4 - 0
modules/topos/doc/Makefile

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

+ 37 - 0
modules/topos/doc/topos.xml

@@ -0,0 +1,37 @@
+<?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>TOPOS Module</title>
+	<productname class="trade">kamailio.org</productname>
+	<authorgroup>
+	    <author>
+		<firstname>Daniel-Constantin</firstname>
+		<surname>Mierla</surname>
+		<email>[email protected]</email>
+	    </author>
+	    <editor>
+		<firstname>Daniel-Constantin</firstname>
+		<surname>Mierla</surname>
+		<email>[email protected]</email>
+	    </editor>
+	</authorgroup>
+	<copyright>
+	    <year>2016</year>
+	    <holder>&fhg;</holder>
+	</copyright>
+    </bookinfo>
+    <toc></toc>
+    
+    <xi:include href="topos_admin.xml"/>
+    
+    
+</book>

+ 132 - 0
modules/topos/doc/topos_admin.xml

@@ -0,0 +1,132 @@
+<?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 offers topology hiding by stripping the SIP routing
+		headers that show topology details.
+		The script interpreter gets the SIP messages with full content,
+		so all existing functionality is preserved.
+	</para>
+	<para>
+		The module is transparent for the configuration writer. It only needs to be
+		loaded (tune the parameters if needed).
+	</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>rr module</emphasis> - server must perform record
+				routing to ensure in-dialog requests are encoded/decoded.
+			</para>
+			</listitem>
+			<listitem>
+			<para>
+				<emphasis>database module</emphasis> - to store the data
+				for topology stripping and restoring.
+			</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>Parameters</title>
+	<section id="topos.p.db_url">
+		<title><varname>db_url</varname> (str)</title>
+		<para>
+		Database URL.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>&defaultdb;</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>db_url</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("topos", "db_url", "&exampledb;")
+...
+</programlisting>
+		</example>
+	</section>
+	<section id="topos.p.mask_callid">
+		<title><varname>mask_callid</varname> (int)</title>
+		<para>
+			Whether to replace or not the Call-ID with another
+			unique id generated by &kamailio;.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 0 (do not mask).
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>mask_callid</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("topos", "mask_callid", 1)
+...
+</programlisting>
+		</example>
+	</section>
+	<section id="topos.p.sanity_checks">
+		<title><varname>sanity_checks</varname> (int)</title>
+		<para>
+			If set to 1, topoh module will bind to sanity module in order
+			to perform sanity checks over received SIP request. Default
+			sanity checks are done. It is useful to check if received request
+			is well formated before proceeding to encoding/decoding.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 0 (do not bind to sanity module).
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>sanity_checks</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("topoh", "sanity_checks", 1)
+...
+</programlisting>
+		</example>
+	</section>
+
+	</section>
+</chapter>
+

+ 352 - 0
modules/topos/topos_mod.c

@@ -0,0 +1,352 @@
+/**
+ * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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 Kamailio topos :: Module interface
+ * \ingroup topos
+ * Module: \ref topos
+ */
+
+/*! \defgroup topoh Kamailio :: Topology stripping
+ *
+ * This module removes the SIP routing headers that show topology details.
+ * The script interpreter gets the SIP messages with full content, so all
+ * existing functionality is preserved.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../sr_module.h"
+#include "../../events.h"
+#include "../../dprint.h"
+#include "../../tcp_options.h"
+#include "../../ut.h"
+#include "../../forward.h"
+#include "../../config.h"
+#include "../../parser/msg_parser.h"
+#include "../../parser/parse_uri.h"
+#include "../../parser/parse_to.h"
+#include "../../parser/parse_from.h"
+
+#include "../../lib/srdb1/db.h"
+#include "../../lib/srutils/sruid.h"
+
+#include "../../modules/sanity/api.h"
+
+#include "tps_msg.h"
+
+MODULE_VERSION
+
+
+/* Database connection handle */
+db1_con_t* _tps_db_handle = NULL;
+/* DB functions */
+db_func_t tpsdbf;
+/* sruid to get internal uid */
+sruid_t _tps_sruid;
+
+/** module parameters */
+static str _tps_db_url = str_init(DEFAULT_DB_URL);
+int _tps_param_mask_callid = 0;
+int _tps_sanity_checks = 0;
+
+sanity_api_t scb;
+
+int tps_msg_received(void *data);
+int tps_msg_sent(void *data);
+
+/** module functions */
+/* Module init function prototype */
+static int mod_init(void);
+/* Module child-init function prototype */
+static int child_init(int rank);
+/* Module destroy function prototype */
+static void destroy(void);
+
+static param_export_t params[]={
+	{"db_url",			PARAM_STR, &_tps_db_url},
+	{"mask_callid",		PARAM_INT, &_tps_param_mask_callid},
+	{"sanity_checks",	PARAM_INT, &_tps_sanity_checks},
+	{0,0,0}
+};
+
+
+/** module exports */
+struct module_exports exports= {
+	"topos",
+	DEFAULT_DLFLAGS, /* dlopen flags */
+	0,
+	params,
+	0,          /* exported statistics */
+	0,          /* exported MI functions */
+	0,          /* exported pseudo-variables */
+	0,          /* extra processes */
+	mod_init,   /* module initialization function */
+	0,
+	destroy,    /* destroy function */
+	child_init  /* child initialization function */
+};
+
+/**
+ * init module function
+ */
+static int mod_init(void)
+{
+	/* Find a database module */
+	if (db_bind_mod(&_tps_db_url, &tpsdbf)) {
+		LM_ERR("unable to bind database module\n");
+		return -1;
+	}
+	if (!DB_CAPABILITY(tpsdbf, DB_CAP_ALL)) {
+		LM_CRIT("database modules does not "
+			"provide all functions needed\n");
+		return -1;
+	}
+
+	if(_tps_sanity_checks!=0) {
+		if(sanity_load_api(&scb)<0) {
+			LM_ERR("cannot bind to sanity module\n");
+			goto error;
+		}
+	}
+
+	if(sruid_init(&_tps_sruid, '-', "tpsh", SRUID_INC)<0)
+		return -1;
+
+	sr_event_register_cb(SREV_NET_DATA_IN,  tps_msg_received);
+	sr_event_register_cb(SREV_NET_DATA_OUT, tps_msg_sent);
+
+#ifdef USE_TCP
+	tcp_set_clone_rcvbuf(1);
+#endif
+
+	return 0;
+error:
+	return -1;
+}
+
+/**
+ *
+ */
+static int child_init(int rank)
+{
+	if(sruid_init(&_tps_sruid, '-', "tpsh", SRUID_INC)<0)
+		return -1;
+
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
+		return 0; /* do nothing for the main process */
+
+	_tps_db_handle = tpsdbf.init(&_tps_db_url);
+	if (!_tps_db_handle) {
+		LM_ERR("unable to connect database\n");
+		return -1;
+	}
+	return 0;
+
+}
+
+/**
+ *
+ */
+static void destroy(void)
+{
+	if (_tps_db_handle) {
+		tpsdbf.close(_tps_db_handle);
+		_tps_db_handle = 0;
+	}
+}
+
+/**
+ *
+ */
+int tps_prepare_msg(sip_msg_t *msg)
+{
+	if (parse_msg(msg->buf, msg->len, msg)!=0) {
+		LM_DBG("outbuf buffer parsing failed!");
+		return 1;
+	}
+
+	if(msg->first_line.type==SIP_REQUEST) {
+		if(!IS_SIP(msg)) {
+			LM_DBG("non sip request message\n");
+			return 1;
+		}
+	} else if(msg->first_line.type!=SIP_REPLY) {
+		LM_DBG("non sip message\n");
+		return 1;
+	}
+
+	if (parse_headers(msg, HDR_EOH_F, 0)==-1) {
+		LM_DBG("parsing headers failed [[%.*s]]\n",
+				msg->len, msg->buf);
+		return 2;
+	}
+
+	/* force 2nd via parsing here - it helps checking it later */
+	if (parse_headers(msg, HDR_VIA2_F, 0)==-1
+			|| (msg->via2==0) || (msg->via2->error!=PARSE_OK)) {
+		LM_DBG("no second via in this message \n");
+	}
+
+	if(parse_from_header(msg)<0) {
+		LM_ERR("cannot parse FROM header\n");
+		return 3;
+	}
+
+	if(parse_to_header(msg)<0 || msg->to==NULL) {
+		LM_ERR("cannot parse TO header\n");
+		return 3;
+	}
+
+	if(get_to(msg)==NULL) {
+		LM_ERR("cannot get TO header\n");
+		return 3;
+	}
+
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_msg_received(void *data)
+{
+	sip_msg_t msg;
+	str *obuf;
+	char *nbuf = NULL;
+	int direction;
+	int dialog;
+
+	obuf = (str*)data;
+	memset(&msg, 0, sizeof(sip_msg_t));
+	msg.buf = obuf->s;
+	msg.len = obuf->len;
+
+	if(tps_prepare_msg(&msg)!=0) {
+		goto done;
+	}
+
+	if(tps_skip_msg(&msg)) {
+		goto done;
+	}
+
+	direction = 0;
+	if(msg.first_line.type==SIP_REQUEST) {
+		if(_tps_sanity_checks!=0) {
+			if(scb.check_defaults(&msg)<1) {
+				LM_ERR("sanity checks failed\n");
+				goto done;
+			}
+		}
+		dialog = (get_to(&msg)->tag_value.len>0)?1:0;
+		if(dialog) {
+			direction = tps_route_direction(&msg);
+			if(direction<0) {
+				LM_ERR("not able to detect direction\n");
+				goto done;
+			}
+		}
+		if(dialog) {
+			/* dialog request */
+			tps_request_received(&msg, dialog, direction);
+		}
+	} else {
+		/* reply */
+		if(msg.via2==0) {
+			/* one Via in received reply -- it is for local generated request
+			 * - nothing to unhide unless is CANCEL/ACK */
+			if(!((get_cseq(&msg)->method_id)&(METHOD_CANCEL)))
+				goto done;
+		}
+		tps_response_received(&msg);
+	}
+
+	nbuf = tps_msg_update(&msg, (unsigned int*)&obuf->len);
+
+	if(obuf->len>=BUF_SIZE) {
+		LM_ERR("new buffer overflow (%d)\n", obuf->len);
+		pkg_free(nbuf);
+		return -1;
+	}
+	memcpy(obuf->s, nbuf, obuf->len);
+	obuf->s[obuf->len] = '\0';
+
+done:
+	if(nbuf!=NULL)
+		pkg_free(nbuf);
+	free_sip_msg(&msg);
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_msg_sent(void *data)
+{
+	sip_msg_t msg;
+	str *obuf;
+	int direction;
+	int dialog;
+	int local;
+
+	obuf = (str*)data;
+	memset(&msg, 0, sizeof(sip_msg_t));
+	msg.buf = obuf->s;
+	msg.len = obuf->len;
+
+	if(tps_prepare_msg(&msg)!=0) {
+		goto done;
+	}
+
+	if(tps_skip_msg(&msg)) {
+		goto done;
+	}
+
+	if(msg.first_line.type==SIP_REQUEST) {
+		direction = tps_route_direction(&msg);
+		dialog = (get_to(&msg)->tag_value.len>0)?1:0;
+
+		local = 0;
+		if(msg.via2==0) {
+			local = 1;
+			if(direction==0) {
+				/* downstream local request (e.g., dlg bye) */
+				local = 2;
+			}
+		}
+
+		tps_request_sent(&msg, dialog, direction, local);
+	} else {
+		tps_response_sent(&msg);
+	}
+
+ready:
+	obuf->s = tps_msg_update(&msg, (unsigned int*)&obuf->len);
+
+done:
+	free_sip_msg(&msg);
+	return 0;
+}
+

+ 233 - 0
modules/topos/tps_msg.c

@@ -0,0 +1,233 @@
+/**
+ * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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-router topoh ::
+ * \ingroup topoh
+ * Module: \ref topoh
+ */
+
+#include <string.h>
+
+#include "../../dprint.h"
+#include "../../mem/mem.h"
+#include "../../data_lump.h"
+#include "../../forward.h"
+#include "../../trim.h"
+#include "../../msg_translator.h"
+#include "../../parser/parse_rr.h"
+#include "../../parser/parse_uri.h"
+#include "../../parser/parse_param.h"
+#include "../../parser/parse_from.h"
+#include "../../parser/parse_to.h"
+#include "../../parser/parse_via.h"
+#include "../../parser/contact/parse_contact.h"
+#include "../../parser/parse_refer_to.h"
+#include "tps_msg.h"
+
+extern int _tps_param_mask_callid;
+
+int tps_skip_rw(char *s, int len)
+{
+	while(len>0)
+	{
+		if(s[len-1]==' ' || s[len-1]=='\t' || s[len-1]=='\n' || s[len-1]=='\r'
+				|| s[len-1]==',')
+			len--;
+		else return len;
+	}
+	return 0;
+}
+
+struct via_param *tps_get_via_param(struct via_body *via, str *name)
+{
+	struct via_param *p;
+	for(p=via->param_lst; p; p=p->next)
+	{
+		if(p->name.len==name->len
+				&& strncasecmp(p->name.s, name->s, name->len)==0)
+			return p;
+	}
+	return NULL;
+}
+
+int tps_get_param_value(str *in, str *name, str *value)
+{
+	param_t* params = NULL;
+	param_t* p = NULL;
+	param_hooks_t phooks;
+	if (parse_params(in, CLASS_ANY, &phooks, &params)<0)
+		return -1;
+	for (p = params; p; p=p->next)
+	{
+		if (p->name.len==name->len
+				&& strncasecmp(p->name.s, name->s, name->len)==0)
+		{
+			*value = p->body;
+			free_params(params);
+			return 0;
+		}
+	}
+	
+	if(params) free_params(params);
+	return 1;
+
+}
+
+int tps_get_uri_param_value(str *uri, str *name, str *value)
+{
+	struct sip_uri puri;
+
+	memset(value, 0, sizeof(str));
+	if(parse_uri(uri->s, uri->len, &puri)<0)
+		return -1;
+	return tps_get_param_value(&puri.params, name, value);
+}
+
+int tps_get_uri_type(str *uri, int *mode, str *value)
+{
+	struct sip_uri puri;
+	int ret;
+	str r2 = {"r2", 2};
+
+	memset(value, 0, sizeof(str));
+	*mode = 0;
+	if(parse_uri(uri->s, uri->len, &puri)<0)
+		return -1;
+
+	LM_DBG("PARAMS [%.*s]\n", puri.params.len, puri.params.s);
+
+	if(check_self(&puri.host, puri.port_no, 0)==1)
+	{
+		/* myself -- matched on all protos */
+		ret = tps_get_param_value(&puri.params, &r2, value);
+		if(ret<0)
+			return -1;
+		if(ret==1) /* not found */
+			return 0; /* skip */
+		LM_DBG("VALUE [%.*s]\n",
+				value->len, value->s);
+		if(value->len==2 && strncasecmp(value->s, "on", 2)==0)
+			*mode = 1;
+		memset(value, 0, sizeof(str));
+		return 0; /* skip */
+	}
+	/* not myself & not mask ip */
+	return 1; /* encode */
+}
+
+char* tps_msg_update(sip_msg_t *msg, unsigned int *olen)
+{
+	struct dest_info dst;
+
+	init_dest_info(&dst);
+	dst.proto = PROTO_UDP;
+	return build_req_buf_from_sip_req(msg,
+			olen, &dst, BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE);
+}
+
+int tps_route_direction(sip_msg_t *msg)
+{
+	rr_t *rr;
+	struct sip_uri puri;
+	str ftn = {"ftag", 4};
+	str ftv = {0, 0};
+
+	if(get_from(msg)->tag_value.len<=0)
+	{
+		LM_ERR("failed to get from header tag\n");
+		return -1;
+	}
+	if(msg->route==NULL)
+	{
+		LM_DBG("no route header - downstream\n");
+		return 0;
+	}
+	if (parse_rr(msg->route) < 0) 
+	{
+		LM_ERR("failed to parse route header\n");
+		return -1;
+	}
+
+	rr =(rr_t*)msg->route->parsed;
+
+	if (parse_uri(rr->nameaddr.uri.s, rr->nameaddr.uri.len, &puri) < 0) {
+		LM_ERR("failed to parse the first route URI\n");
+		return -1;
+	}
+	if(tps_get_param_value(&puri.params, &ftn, &ftv)!=0)
+		return 0;
+
+	if(get_from(msg)->tag_value.len!=ftv.len
+			|| strncmp(get_from(msg)->tag_value.s, ftv.s, ftv.len)!=0)
+	{
+		LM_DBG("ftag mismatch\n");
+		return 1;
+	}
+	LM_DBG("ftag match\n");
+	return 0;
+}
+
+int tps_skip_msg(sip_msg_t *msg)
+{
+	if (msg->cseq==NULL || get_cseq(msg)==NULL) {
+		LM_WARN("Invalid/Unparsed CSeq in message. Skipping.");
+		return 1;
+	}
+
+	if((get_cseq(msg)->method_id)&(METHOD_REGISTER|METHOD_PUBLISH))
+		return 1;
+
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_request_received(sip_msg_t *msg, int dialog, int direction)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_response_received(sip_msg_t *msg)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_request_sent(sip_msg_t *msg, int dialog, int direction, int local)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_response_sent(sip_msg_t *msg)
+{
+	return 0;
+}

+ 43 - 0
modules/topos/tps_msg.h

@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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 Kamailio topoh ::
+ * \ingroup topoh
+ * Module: \ref topoh
+ */
+
+#ifndef _TOPOS_MSG_H_
+#define _TOPOS_MSG_H_
+
+#include "../../parser/msg_parser.h"
+
+int tps_update_hdr_replaces(sip_msg_t *msg);
+char* tps_msg_update(sip_msg_t *msg, unsigned int *olen);
+int tps_route_direction(sip_msg_t *msg);
+int tps_skip_msg(sip_msg_t *msg);
+
+int tps_request_received(sip_msg_t *msg, int dialog, int direction);
+int tps_response_received(sip_msg_t *msg);
+int tps_request_sent(sip_msg_t *msg, int dialog, int direction, int local);
+int tps_response_sent(sip_msg_t *msg);
+#endif

+ 82 - 0
modules/topos/tps_storage.c

@@ -0,0 +1,82 @@
+/**
+ * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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 Kamailio topos ::
+ * \ingroup topos
+ * Module: \ref topos
+ */
+
+#include <string.h>
+
+#include "../../dprint.h"
+
+#include "tps_storage.h"
+
+/**
+ *
+ */
+int tps_storage_dialog_find(sip_msg_t *msg, tps_data_t *td)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_storage_dialog_save(sip_msg_t *msg, tps_data_t *td)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_storage_dialog_rm(sip_msg_t *msg, tps_data_t *td)
+{
+	return 0;
+}
+
+
+/**
+ *
+ */
+int tps_storage_branch_find(sip_msg_t *msg, tps_data_t *td)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_storage_branch_save(sip_msg_t *msg, tps_data_t *td)
+{
+	return 0;
+}
+
+/**
+ *
+ */
+int tps_storage_branch_rm(sip_msg_t *msg, tps_data_t *td)
+{
+	return 0;
+}

+ 55 - 0
modules/topos/tps_storage.h

@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2016 Daniel-Constantin Mierla (asipto.com)
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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 Kamailio topos ::
+ * \ingroup topos
+ * Module: \ref topos
+ */
+
+#ifndef _TOPOS_STORAGE_H_
+#define _TOPOS_STORAGE_H_
+
+#include "../../parser/msg_parser.h"
+
+#define TPS_DATA_SIZE	4096
+typedef struct tps_data {
+	char cbuf[TPS_DATA_SIZE];
+	char *cp;
+	str a_uuid;
+	str b_uuid;
+	str a_callid;
+	str a_rr;
+	str b_rr;
+	str a_contact;
+	str b_contact;
+} tps_data_t;
+
+int tps_storage_dialog_find(sip_msg_t *msg, tps_data_t *td);
+int tps_storage_dialog_save(sip_msg_t *msg, tps_data_t *td);
+int tps_storage_dialog_rm(sip_msg_t *msg, tps_data_t *td);
+
+int tps_storage_branch_find(sip_msg_t *msg, tps_data_t *td);
+int tps_storage_branch_save(sip_msg_t *msg, tps_data_t *td);
+int tps_storage_branch_rm(sip_msg_t *msg, tps_data_t *td);
+
+#endif