mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-09 09:17:34 +00:00
wrap potentially non-threadsafe snmp operations in mutex; support snmpwalk in subagent
This commit is contained in:
parent
02d1af647b
commit
636c1ecb4e
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
|
switch_mutex_t *mutex;
|
||||||
int shutdown;
|
int shutdown;
|
||||||
} globals;
|
} globals;
|
||||||
|
|
||||||
@ -55,27 +56,13 @@ static int snmp_callback_log(int major, int minor, void *serverarg, void *client
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static switch_state_handler_table_t state_handlers = {
|
|
||||||
/*.on_init */ NULL,
|
|
||||||
/*.on_routing */ NULL,
|
|
||||||
/*.on_execute */ NULL,
|
|
||||||
/*.on_hangup */ NULL,
|
|
||||||
/*.on_exchange_media */ NULL,
|
|
||||||
/*.on_soft_execute */ NULL,
|
|
||||||
/*.on_consume_media */ NULL,
|
|
||||||
/*.on_hibernate */ NULL,
|
|
||||||
/*.on_reset */ NULL,
|
|
||||||
/*.on_park */ NULL,
|
|
||||||
/*.on_reporting */ NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static switch_status_t load_config(switch_memory_pool_t *pool)
|
static switch_status_t load_config(switch_memory_pool_t *pool)
|
||||||
{
|
{
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
memset(&globals, 0, sizeof(globals));
|
memset(&globals, 0, sizeof(globals));
|
||||||
globals.pool = pool;
|
globals.pool = pool;
|
||||||
|
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -87,7 +74,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
|
|||||||
|
|
||||||
load_config(pool);
|
load_config(pool);
|
||||||
|
|
||||||
switch_core_add_state_handler(&state_handlers);
|
|
||||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||||
|
|
||||||
/* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */
|
/* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */
|
||||||
@ -114,9 +100,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
|
|||||||
|
|
||||||
SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
|
SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
|
||||||
{
|
{
|
||||||
while (!globals.shutdown) {
|
if (!globals.shutdown) {
|
||||||
/* Block on select() */
|
/* Block on select() */
|
||||||
|
switch_mutex_lock(globals.mutex);
|
||||||
agent_check_and_process(1);
|
agent_check_and_process(1);
|
||||||
|
switch_mutex_unlock(globals.mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
@ -126,9 +114,12 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
|
|||||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown)
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown)
|
||||||
{
|
{
|
||||||
globals.shutdown = 1;
|
globals.shutdown = 1;
|
||||||
switch_core_remove_state_handler(&state_handlers);
|
|
||||||
|
|
||||||
|
switch_mutex_lock(globals.mutex);
|
||||||
snmp_shutdown("mod_snmp");
|
snmp_shutdown("mod_snmp");
|
||||||
|
switch_mutex_unlock(globals.mutex);
|
||||||
|
|
||||||
|
switch_mutex_destroy(globals.mutex);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ void init_subagent(void)
|
|||||||
{
|
{
|
||||||
DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n"));
|
DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n"));
|
||||||
|
|
||||||
netsnmp_register_handler(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY));
|
netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2);
|
||||||
netsnmp_register_handler(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY));
|
netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -76,33 +76,29 @@ int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *
|
|||||||
oid subid;
|
oid subid;
|
||||||
|
|
||||||
switch(reqinfo->mode) {
|
switch(reqinfo->mode) {
|
||||||
case MODE_GET:
|
case MODE_GET:
|
||||||
for (request = requests; request; request = request->next) {
|
for (request = requests; request; request = request->next) {
|
||||||
subid = request->requestvb->name[OID_LENGTH(systemStats_oid)];
|
subid = request->requestvb->name[reginfo->rootoid_len - 2];
|
||||||
|
|
||||||
switch (subid) {
|
switch (subid) {
|
||||||
case versionString_oid:
|
case versionString_oid:
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version));
|
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version));
|
||||||
break;
|
break;
|
||||||
case uuid_oid:
|
case uuid_oid:
|
||||||
strncpy(uuid, switch_core_get_uuid(), sizeof(uuid));
|
strncpy(uuid, switch_core_get_uuid(), sizeof(uuid));
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid));
|
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
|
snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
|
||||||
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
|
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MODE_GETNEXT:
|
default:
|
||||||
snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n");
|
/* we should never get here, so this is a really bad error */
|
||||||
break;
|
snmp_log(LOG_ERR, "Unknown mode (%d) in handle_identity\n", reqinfo->mode );
|
||||||
|
return SNMP_ERR_GENERR;
|
||||||
default:
|
|
||||||
/* we should never get here, so this is a really bad error */
|
|
||||||
snmp_log(LOG_ERR, "Unknown mode (%d) in handle_versionString\n", reqinfo->mode );
|
|
||||||
return SNMP_ERR_GENERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SNMP_ERR_NOERROR;
|
return SNMP_ERR_NOERROR;
|
||||||
@ -117,59 +113,55 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
|
|||||||
uint32_t int_val;
|
uint32_t int_val;
|
||||||
|
|
||||||
switch(reqinfo->mode) {
|
switch(reqinfo->mode) {
|
||||||
case MODE_GET:
|
case MODE_GET:
|
||||||
for (request = requests; request; request = request->next) {
|
for (request = requests; request; request = request->next) {
|
||||||
subid = request->requestvb->name[OID_LENGTH(systemStats_oid)];
|
subid = request->requestvb->name[reginfo->rootoid_len - 2];
|
||||||
|
|
||||||
switch (subid) {
|
switch (subid) {
|
||||||
case uptime_oid:
|
case uptime_oid:
|
||||||
uptime = switch_core_uptime() / 10000;
|
uptime = switch_core_uptime() / 10000;
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime));
|
snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime));
|
||||||
break;
|
break;
|
||||||
case sessionsSinceStartup_oid:
|
case sessionsSinceStartup_oid:
|
||||||
int_val = switch_core_session_id() - 1;
|
int_val = switch_core_session_id() - 1;
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val));
|
snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val));
|
||||||
break;
|
break;
|
||||||
case currentSessions_oid:
|
case currentSessions_oid:
|
||||||
int_val = switch_core_session_count();
|
int_val = switch_core_session_count();
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
||||||
break;
|
break;
|
||||||
case maxSessions_oid:
|
case maxSessions_oid:
|
||||||
switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);;
|
switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);;
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
||||||
break;
|
break;
|
||||||
case currentCalls_oid:
|
case currentCalls_oid:
|
||||||
/*
|
/*
|
||||||
* This is zero for now, since there is no convenient way to get total call
|
* This is zero for now, since there is no convenient way to get total call
|
||||||
* count (not to be confused with session count), without touching the
|
* count (not to be confused with session count), without touching the
|
||||||
* database.
|
* database.
|
||||||
*/
|
*/
|
||||||
int_val = 0;
|
int_val = 0;
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
||||||
break;
|
break;
|
||||||
case sessionsPerSecond_oid:
|
case sessionsPerSecond_oid:
|
||||||
switch_core_session_ctl(SCSC_LAST_SPS, &int_val);
|
switch_core_session_ctl(SCSC_LAST_SPS, &int_val);
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
||||||
break;
|
break;
|
||||||
case maxSessionsPerSecond_oid:
|
case maxSessionsPerSecond_oid:
|
||||||
switch_core_session_ctl(SCSC_SPS, &int_val);
|
switch_core_session_ctl(SCSC_SPS, &int_val);
|
||||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
|
snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
|
||||||
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
|
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case MODE_GETNEXT:
|
default:
|
||||||
snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n");
|
/* we should never get here, so this is a really bad error */
|
||||||
break;
|
snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode);
|
||||||
|
return SNMP_ERR_GENERR;
|
||||||
default:
|
|
||||||
/* we should never get here, so this is a really bad error */
|
|
||||||
snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode);
|
|
||||||
return SNMP_ERR_GENERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SNMP_ERR_NOERROR;
|
return SNMP_ERR_NOERROR;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user