00001 /* 00002 * $Id: sub_agent.c 4764 2008-08-28 14:41:06Z henningw $ 00003 * 00004 * SNMPStats Module 00005 * Copyright (C) 2006 SOMA Networks, INC. 00006 * Written by: Jeffrey Magder (jmagder@somanetworks.com) 00007 * 00008 * This file is part of Kamailio, a free SIP server. 00009 * 00010 * Kamailio is free software; you can redistribute it and/or modify it 00011 * under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version 00014 * 00015 * Kamailio is distributed in the hope that it will be useful, but 00016 * WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 * USA 00024 * 00025 * History: 00026 * -------- 00027 * 2006-11-23 initial version (jmagder) 00028 */ 00029 00030 /*! 00031 * \file 00032 * \brief SNMP statistic module, master agent connection 00033 * 00034 * This file defines all functions required to establish a relationship with a 00035 * master agent. 00036 * \ingroup snmpstats 00037 * - Module: \ref snmpstats 00038 */ 00039 00040 00041 #include <sys/types.h> 00042 #include <stdlib.h> 00043 #include <unistd.h> 00044 #include <signal.h> 00045 00046 #include "sub_agent.h" 00047 00048 /* Bring in the NetSNMP headers */ 00049 #include <net-snmp/net-snmp-config.h> 00050 #include <net-snmp/net-snmp-includes.h> 00051 #include <net-snmp/agent/net-snmp-agent-includes.h> 00052 00053 /* Bring in the initialization functions for all scalars */ 00054 #include "openserSIPCommonObjects.h" 00055 #include "openserSIPServerObjects.h" 00056 #include "openserObjects.h" 00057 00058 /* Bring in the initialization functions for all tables */ 00059 #include "openserSIPPortTable.h" 00060 #include "openserSIPMethodSupportedTable.h" 00061 #include "openserSIPStatusCodesTable.h" 00062 #include "openserSIPRegUserTable.h" 00063 #include "openserSIPContactTable.h" 00064 #include "openserSIPRegUserLookupTable.h" 00065 #include "openserMIBNotifications.h" 00066 00067 #include "../../dprint.h" 00068 00069 static int keep_running; 00070 00071 /*! The function handles Handles shutting down of the sub_agent process. */ 00072 static void sigterm_handler(int signal) 00073 { 00074 /* Just exit. The master agent will clean everything up for us */ 00075 exit(0); 00076 } 00077 00078 /*! This function: 00079 * 00080 * 1) Registers itself with the Master Agent 00081 * 2) Initializes all of the SNMPStats modules scalars and tables, while 00082 * simultaneously registering their respective SNMP OID's and handlers 00083 * with the master agent. 00084 * 3) Repeatedly checks for new SNMP messages to process 00085 * 00086 * \note This function never returns, so it should always be called from a 00087 * sub-process. 00088 */ 00089 static int initialize_agentx(void) 00090 { 00091 /* We register with a master agent */ 00092 register_with_master_agent(AGENT_PROCESS_NAME); 00093 00094 /* Initialize all scalars, and let the master agent know we want to 00095 * handle all OID's pertaining to these scalars. */ 00096 init_openserSIPCommonObjects(); 00097 init_openserSIPServerObjects(); 00098 init_openserObjects(); 00099 00100 /* Initialiaze all the tables, and let the master agent know we want to 00101 * handle all the OID's pertaining to these tables */ 00102 init_openserSIPPortTable(); 00103 init_openserSIPMethodSupportedTable(); 00104 init_openserSIPStatusCodesTable(); 00105 init_openserSIPRegUserTable(); 00106 init_openserSIPContactTable(); 00107 init_openserSIPRegUserLookupTable(); 00108 00109 /* In case we recevie a request to stop (kill -TERM or kill -INT) */ 00110 keep_running = 1; 00111 00112 while(keep_running) { 00113 agent_check_and_process(1); /* 0 == don't block */ 00114 } 00115 00116 snmp_shutdown(AGENT_PROCESS_NAME); 00117 SOCK_CLEANUP; 00118 exit (0); 00119 00120 return 0; 00121 } 00122 00123 /*! Creates a child that will become the AgentX sub-agent. The child will 00124 * insulate itself from the rest of OpenSER by overriding most of signal 00125 * handlers. */ 00126 void agentx_child(int rank) 00127 { 00128 struct sigaction new_sigterm_handler; 00129 struct sigaction default_handlers; 00130 struct sigaction sigpipe_handler; 00131 00132 /* Setup a SIGTERM handler */ 00133 sigfillset(&new_sigterm_handler.sa_mask); 00134 new_sigterm_handler.sa_flags = 0; 00135 new_sigterm_handler.sa_handler = sigterm_handler; 00136 sigaction(SIGTERM, &new_sigterm_handler, NULL); 00137 00138 /* We don't want OpenSER's normal handlers doing anything when 00139 * we die. As far as OpenSER knows this process never existed. 00140 * So override all signal handlers to the OS default. */ 00141 sigemptyset(&default_handlers.sa_mask); 00142 default_handlers.sa_flags = 0; 00143 default_handlers.sa_handler = SIG_DFL; 00144 00145 sigaction(SIGCHLD, &default_handlers, NULL); 00146 sigaction(SIGINT, &default_handlers, NULL); 00147 sigaction(SIGHUP, &default_handlers, NULL); 00148 sigaction(SIGUSR1, &default_handlers, NULL); 00149 sigaction(SIGUSR2, &default_handlers, NULL); 00150 00151 /* It is possible that the master agent will unregister us if we 00152 * take too long to respond to an SNMP request. This would 00153 * happen if a large number of users/contacts have been 00154 * registered between snmp requests to the user/contact tables. 00155 * In this situation we may try to write to a closed socket when 00156 * we are done processing, resulting in a SIGPIPE. This doesn't 00157 * need to be fatal however, because we can re-establish our 00158 * connection. Therefore we set ourselves up to ignore the 00159 * SIGPIPE. */ 00160 sigpipe_handler.sa_flags = SA_RESTART; 00161 sigpipe_handler.sa_handler = SIG_IGN; 00162 00163 sigaction(SIGPIPE, &sigpipe_handler, NULL); 00164 00165 initialize_agentx(); 00166 } 00167 00168 00169 00170 /*! This function opens up a connection with the master agent specified in 00171 * the snmpstats modules configuration file */ 00172 void register_with_master_agent(char *name_to_register_under) 00173 { 00174 /* Set ourselves up as an AgentX Client. */ 00175 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); 00176 00177 /* Initialize TCP if necessary. (Its here for WIN32) compatibility. */ 00178 SOCK_STARTUP; 00179 00180 /* Read in our configuration file to determine master agent ping times 00181 * what port communication is to take place over, etc. */ 00182 init_agent("snmpstats"); 00183 00184 /* Use a name we can register our agent under. */ 00185 init_snmp(name_to_register_under); 00186 }
1.5.6