1 /*
2  * Copyright (C) 2014 Federico Cabiddu, federico.cabiddu@gmail.com
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21 
22 /*!
23  * \file
24  * \brief Functions and definitions related to per user transaction indexing and searching
25  * \ingroup tsilo
26  * Module: \ref tsilo
27  */
28 
29 #ifndef _TS_HASH_H_
30 #define _TS_HASH_H_
31 
32 #include "../../core/locking.h"
33 #include "../../modules/tm/tm_load.h"
34 
35 #define MAX_TS_LOCKS  2048
36 #define MIN_TS_LOCKS  2
37 
38 extern stat_var *stored_ruris;
39 extern stat_var *stored_transactions;
40 extern stat_var *total_ruris;
41 extern stat_var *total_transactions;
42 extern stat_var *added_branches;
43 
44 typedef struct ts_transaction
45 {
46 	unsigned int		tindex;		/*!< transaction index */
47 	unsigned int		tlabel;		/*!< transaction label */
48 
49 	struct ts_urecord	*urecord;	/*!< > urecord entry the transaction belongs to */
50 
51 	struct ts_transaction	*next;		/*!< next entry in the list */
52 	struct ts_transaction	*prev;		/*!< previous entry in the list */
53 } ts_transaction_t;
54 
55 /*! entries in the transaction list */
56 typedef struct ts_urecord
57 {
58 	str		     ruri;		/*!< request uri of the transaction */
59 	unsigned int	     rurihash;		/*!< hash request uri of the transaction */
60 
61 	struct ts_entry     *entry;		/*!< Collision slot in the hash table */
62 	ts_transaction_t    *transactions;	/*!< One or more transactions */
63 
64 	struct ts_urecord   *next;		/*!< next entry in the list */
65 	struct ts_urecord   *prev;		/*!< previous entry in the list */
66 } ts_urecord_t;
67 
68 
69 /*! entries in the main transaction table */
70 typedef struct ts_entry
71 {
72 	int n;                  	    /*!< Number of elements in the collision slot */
73 	struct ts_urecord    *first;	/*!< urecord list */
74 	struct ts_urecord    *last;	    /*!< optimisation, end of the urecord list */
75 	unsigned int       next_id;	    /*!< next id */
76 	unsigned int       lock_idx;	/*!< lock index */
77 } ts_entry_t;
78 
79 
80 /*! main transaction table */
81 typedef struct ts_table
82 {
83 	unsigned int       size;	    /*!< size of the tsilo table */
84 	struct ts_entry    *entries;	/*!< urecord hash table */
85 	unsigned int       locks_no;	/*!< number of locks */
86 	gen_lock_set_t     *locks;	    /*!< lock table */
87 } ts_table_t;
88 
89 /*! global transactions table */
90 extern ts_table_t *t_table;
91 
92 /*!
93  * \brief Set a transaction lock
94  * \param _table transaction table
95  * \param _entry locked entry
96  */
97 #define ts_lock(_table, _entry) \
98 		lock_set_get( (_table)->locks, (_entry)->lock_idx);
99 
100 /*!
101  * \brief Release a transaction lock
102  * \param _table transaction table
103  * \param _entry locked entry
104  */
105 #define ts_unlock(_table, _entry) \
106 		lock_set_release( (_table)->locks, (_entry)->lock_idx);
107 
108 void lock_entry(ts_entry_t *entry);
109 void unlock_entry(ts_entry_t *entry);
110 
111 void lock_entry_by_ruri(str* ruri);
112 void unlock_entry_by_ruri(str* ruri);
113 
114 /*!
115  * \brief Initialize the per user transactions table
116  * \param size size of the table
117  * \return 0 on success, -1 on failure
118  */
119 int init_ts_table(unsigned int size);
120 
121 /*!
122  * \brief Destroy the per user transaction table
123  */
124 void destroy_ts_table(void);
125 
126 /*
127  * Obtain a urecord pointer if the urecord exists in the table
128  */
129 int get_ts_urecord(str* ruri, struct ts_urecord** _r);
130 
131 /*!
132  * \brief Create and initialize new record structure
133  * \param ruri request uri
134  * \param _r pointer to the new record
135  * \return 0 on success, negative on failure
136  */
137 int new_ts_urecord(str* ruri, ts_urecord_t** _r);
138 
139 /*!
140  * \brief Insert a new record into transactions table
141  * \param ruri request uri
142  * \param _r pointer to the new record
143  * \return 0 on success, -1 on failure
144  */
145 int insert_ts_urecord(str* ruri, ts_urecord_t** _r);
146 
147 /*!
148  * \brief remove a urecord from table and free the memory
149  * \param _r urecord
150  * \return 0 on success, -1 on failure
151  */
152 void remove_ts_urecord(ts_urecord_t* _r);
153 
154 /*!
155  * \brief Insert a new transaction structure into urecord
156  * \param t transaction
157  * \param msg SIP message
158  * \param _r urecord
159  * \return 0 on success, -1 otherwise
160  */
161 int insert_ts_transaction(struct cell* t, sip_msg_t* msg, struct ts_urecord* _r);
162 
163 /*!
164  * \brief Create a new transaction structure
165  * \param tindex transaction index in tm table
166  * \param tlabel transaction label in tm table
167  * \return created transaction structure on success, NULL otherwise
168  */
169 ts_transaction_t* new_ts_transaction(int tindex, int tlabel);
170 
171 /*!
172  * \brief Clone a transaction structure
173  * \param ts transaction to be cloned
174  * \return cloned transaction structure on success, NULL otherwise
175  */
176 ts_transaction_t* clone_ts_transaction(ts_transaction_t* ts);
177 
178 /*!
179  * \brief remove a transaction from the urecord transactions list
180  * \param ts_t unlinked transaction
181  */
182 void remove_ts_transaction(ts_transaction_t* ts_t);
183 
184 void free_ts_transaction(void *ts_t);
185 #endif
186