1 /*
2  * SNMPStats Module
3  * Copyright (C) 2006 SOMA Networks, INC.
4  * Written by: Jeffrey Magder (jmagder@somanetworks.com)
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  *
23  */
24 
25 /*!
26  * \file
27  * \brief SNMP statistic module, interprocess buffer
28  *
29  * The SNMPStats module exposes user information through kamailioSIPRegUserTable,
30  * kamailioSIPContactTable, and kamailioSIPRegUserLookupTable.  These tables are
31  * populated through callback mechanisms from the usrloc module.  Unfortunately
32  * the NetSNMP table population code is very slow when dealing with large
33  * amounts of data.  Because we don't want to experience a performance hit when
34  * registering users, we make use of the interprocess buffer.  Specifically,
35  * instead of adding/removing users/contacts from the SNMP tables directly, the
36  * callbacks add an add/delete command to the interprocessBuffer.
37  *
38  * When an snmp request is received by the SNMPStats sub-process, it will
39  * consume this interprocess buffer, adding and deleting users.  When it is
40  * finished, it can service the SNMP request.
41  *
42  * This doesn't remove the NetSNMP inefficiency of course, but it does move it
43  * to a non-critical path.  Such an approach allows SNMP support with almost no
44  * overhead to the rest of the server.
45  * \ingroup snmpstats
46  * - Module: \ref snmpstats
47  */
48 
49 
50 #ifndef _SNMPSTATS_USER_UTILITIES_
51 #define _SNMPSTATS_USER_UTILITIES_
52 
53 #include "../../core/str.h"
54 #include "../../core/locking.h"
55 
56 #include "snmpstats_globals.h"
57 #include "hashTable.h"
58 
59 #include "../usrloc/ucontact.h"
60 
61 /* Represents an element of the interprocess buffer. */
62 typedef struct interprocessBuffer
63 {
64 	char *stringName;
65 	char *stringContact;
66 	int callbackType;
67 	struct interprocessBuffer *next;
68 
69 	ucontact_t *contactInfo;
70 } interprocessBuffer_t;
71 
72 /* Both of these will be used to reference in the interprocess buffer */
73 extern interprocessBuffer_t *frontRegUserTableBuffer;
74 extern interprocessBuffer_t *endRegUserTableBuffer;
75 
76 /* A request to consume the interprocess buffer could occur at the same time
77  * there is a request to add to the interprocess buffer. (Or vice-versa).  This
78  * lock is used to prevent these race conditions. */
79 extern gen_lock_t *interprocessCBLock;
80 extern hashSlot_t *hashTable;
81 
82 /*
83  * Initialize shared memory used to buffer communication between the usrloc
84  * module and the SNMPStats module.  (Specifically, the user and contact tables)
85  */
86 int initInterprocessBuffers(void);
87 
88 /* USRLOC Callback Handler:
89  *
90  * This function should be registered to receive callbacks from the usrloc
91  * module.  It can be called for any of the callbacks listed in ul_Callback.h.
92  * The callback type will be passed in 'type', and the contact the callback
93  * applies to will be supplied in 'contactInfo.  This information will be copied
94  * into the interprocess buffer.  The interprocess buffer will beconsumed at a
95  * later time, when consumeInterprocessBuffer() is called.
96  *
97  * This callback is thread safe with respect to the consumeInterprocessBuffer()
98  * function.  Specifically, the interprocess buffer should not be corrupted by
99  * any race conditions between this function and the consumeInterprocessBuffer()
100  * function.
101  */
102 void handleContactCallbacks(ucontact_t *contactInfo, int type, void *param);
103 
104 
105 /* Interprocess Buffer consumption Function.  This function will iterate over
106  * every element of the interprocess buffer, and add or remove the specified
107  * contacts and users.  Whether the contacts are added or removed is dependent
108  * on if the original element was added as a result of a UL_CONTACT_INSERT or
109  * UL_CONTACT_EXPIRE callback.
110  *
111  * The function will free any memory occupied by the interprocess buffer.
112  *
113  * Note: This function is believed to be thread safe.  Specifically, it protects
114  *       corruption of the interprocess buffer through the interprocessCBLock.
115  *       This ensures no corruption of the buffer by race conditions.  The lock
116  *       has been designed to be occupied for as short a period as possible, so
117  *       as to prevent long waits.  Specifically, once we start consumption of
118  *       the list, other processes are free to continue even before we are done.
119  *       This is made possible by simply changing the head of the interprocess
120  *       buffer, and then releasing the lock.
121  */
122 void consumeInterprocessBuffer(void);
123 
124 void freeInterprocessBuffer(void);
125 
126 #endif