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