You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
12 KiB
339 lines
12 KiB
708370 - net-snmp increments request-id when generating multiple SMUX-PDUs for a SMUX peer |
|
|
|
Source: upstream, copied from master after commit 3fa0088c63fe0dd73417af94d888333192194093 |
|
(too many individial commits to list) |
|
|
|
diff -up net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.c.rhel net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.c |
|
--- net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.c.rhel 2012-07-31 14:13:18.069018537 +0200 |
|
+++ net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.c 2012-07-31 13:49:55.000000000 +0200 |
|
@@ -66,7 +66,6 @@ |
|
#include <net-snmp/library/tools.h> |
|
|
|
#include "smux.h" |
|
-#include "mibdefs.h" |
|
#include "snmpd.h" |
|
|
|
netsnmp_feature_require(snprint_objid) |
|
@@ -103,10 +102,9 @@ static int smux_pdu_process(int, u_ |
|
static int smux_send_rrsp(int, int); |
|
static smux_reg *smux_find_match(smux_reg *, int, oid *, size_t, long); |
|
static smux_reg *smux_find_replacement(oid *, size_t); |
|
-u_char *var_smux(struct variable *, oid *, size_t *, int, size_t *, |
|
- WriteMethod ** write_method); |
|
-int var_smux_write(int, u_char *, u_char, size_t, u_char *, |
|
- oid *, size_t); |
|
+u_char *var_smux_get(oid *, size_t, oid *, size_t *, int, size_t *, |
|
+ u_char *); |
|
+int var_smux_write(int, u_char *, u_char, size_t, oid *, size_t); |
|
|
|
static smux_reg *ActiveRegs; /* Active registrations */ |
|
static smux_reg *PassiveRegs; /* Currently unused registrations */ |
|
@@ -114,14 +112,6 @@ static smux_reg *PassiveRegs; /* Curre |
|
static smux_peer_auth *Auths[SMUX_MAX_PEERS]; /* Configured peers */ |
|
static int nauths, npeers = 0; |
|
|
|
-struct variable2 smux_variables[] = { |
|
- /* |
|
- * bogus entry, as in pass.c |
|
- */ |
|
- {MIBINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE, |
|
- var_smux, 0, {MIBINDEX}}, |
|
-}; |
|
- |
|
|
|
|
|
void |
|
@@ -244,7 +234,7 @@ real_init_smux(void) |
|
#endif |
|
netsnmp_sockaddr_in( &lo_socket, smux_socket, SMUXPORT ); |
|
|
|
- if ((smux_listen_sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
|
+ if ((smux_listen_sd = (int) socket(AF_INET, SOCK_STREAM, 0)) < 0) { |
|
snmp_log_perror("[init_smux] socket failed"); |
|
return; |
|
} |
|
@@ -291,21 +281,88 @@ real_init_smux(void) |
|
smux_listen_sd, ntohs(lo_socket.sin_port))); |
|
} |
|
|
|
+static int |
|
+smux_handler(netsnmp_mib_handler *handler, |
|
+ netsnmp_handler_registration *reginfo, |
|
+ netsnmp_agent_request_info *reqinfo, |
|
+ netsnmp_request_info *requests) |
|
+{ |
|
+ u_char *access = NULL; |
|
+ size_t var_len; |
|
+ int exact = 1; |
|
+ int status = 0; |
|
+ u_char var_type; |
|
+ static long old_reqid = -1; |
|
+ static long old_sessid = -1; |
|
+ long new_reqid, new_sessid; |
|
+ |
|
+ /* Increment the reqid of outgoing SMUX messages only when processing |
|
+ * new incoming SNMP message, i.e. when reqid or session id chamges */ |
|
+ new_reqid = reqinfo->asp->pdu->reqid; |
|
+ new_sessid = reqinfo->asp->session->sessid; |
|
+ DEBUGMSGTL(("smux", "smux_handler: incoming reqid=%ld, sessid=%ld\n", |
|
+ new_reqid, new_sessid)); |
|
+ if (old_reqid != new_reqid || old_sessid != new_sessid) { |
|
+ smux_reqid++; |
|
+ old_reqid = new_reqid; |
|
+ old_sessid = new_sessid; |
|
+ } |
|
+ |
|
+ switch (reqinfo->mode) { |
|
+ case MODE_GETNEXT: |
|
+ case MODE_GETBULK: |
|
+ exact = 0; |
|
+ } |
|
+ |
|
+ for (; requests; requests = requests->next) { |
|
+ switch(reqinfo->mode) { |
|
+ case MODE_GET: |
|
+ case MODE_GETNEXT: |
|
+ case MODE_SET_RESERVE1: |
|
+ access = var_smux_get(reginfo->rootoid, |
|
+ reginfo->rootoid_len, |
|
+ requests->requestvb->name, |
|
+ &requests->requestvb->name_length, |
|
+ exact, |
|
+ &var_len, |
|
+ &var_type); |
|
+ if (access) |
|
+ if (reqinfo->mode != MODE_SET_RESERVE1) |
|
+ snmp_set_var_typed_value(requests->requestvb, |
|
+ var_type, access, var_len); |
|
+ if (reqinfo->mode != MODE_SET_RESERVE1) |
|
+ break; |
|
+ /* fall through if MODE_SET_RESERVE1 */ |
|
+ |
|
+ default: |
|
+ /* SET processing */ |
|
+ status = var_smux_write(reqinfo->mode, |
|
+ requests->requestvb->val.string, |
|
+ requests->requestvb->type, |
|
+ requests->requestvb->val_len, |
|
+ requests->requestvb->name, |
|
+ requests->requestvb->name_length); |
|
+ if (status != SNMP_ERR_NOERROR) { |
|
+ netsnmp_set_request_error(reqinfo, requests, status); |
|
+ } |
|
+ } |
|
+ } |
|
+ return SNMP_ERR_NOERROR; |
|
+} |
|
+ |
|
u_char * |
|
-var_smux(struct variable * vp, |
|
- oid * name, |
|
- size_t * length, |
|
- int exact, size_t * var_len, WriteMethod ** write_method) |
|
+var_smux_get(oid *root, size_t root_len, |
|
+ oid * name, size_t * length, |
|
+ int exact, size_t * var_len, u_char *var_type) |
|
{ |
|
- u_char *valptr, val_type; |
|
+ u_char *valptr; |
|
smux_reg *rptr; |
|
|
|
- *write_method = var_smux_write; |
|
/* |
|
* search the active registration list |
|
*/ |
|
for (rptr = ActiveRegs; rptr; rptr = rptr->sr_next) { |
|
- if (0 >= snmp_oidtree_compare(vp->name, vp->namelen, rptr->sr_name, |
|
+ if (0 >= snmp_oidtree_compare(root, root_len, rptr->sr_name, |
|
rptr->sr_name_len)) |
|
break; |
|
} |
|
@@ -315,7 +372,7 @@ var_smux(struct variable * vp, |
|
return NULL; |
|
|
|
valptr = smux_snmp_process(exact, name, length, |
|
- var_len, &val_type, rptr->sr_fd); |
|
+ var_len, var_type, rptr->sr_fd); |
|
|
|
if (valptr == NULL) |
|
return NULL; |
|
@@ -328,10 +385,6 @@ var_smux(struct variable * vp, |
|
*/ |
|
return NULL; |
|
} else { |
|
- /* |
|
- * set the type and return the value |
|
- */ |
|
- vp->type = val_type; |
|
return valptr; |
|
} |
|
} |
|
@@ -341,7 +394,7 @@ var_smux_write(int action, |
|
u_char * var_val, |
|
u_char var_val_type, |
|
size_t var_val_len, |
|
- u_char * statP, oid * name, size_t name_len) |
|
+ oid * name, size_t name_len) |
|
{ |
|
smux_reg *rptr; |
|
u_char buf[SMUXMAXPKTSIZE], *ptr, sout[3], type; |
|
@@ -589,7 +642,7 @@ smux_accept(int sd) |
|
*/ |
|
DEBUGMSGTL(("smux", "[smux_accept] Calling accept()\n")); |
|
errno = 0; |
|
- if ((fd = accept(sd, (struct sockaddr *) &in_socket, &alen)) < 0) { |
|
+ if ((fd = (int) accept(sd, (struct sockaddr *) &in_socket, &alen)) < 0) { |
|
snmp_log_perror("[smux_accept] accept failed"); |
|
return -1; |
|
} else { |
|
@@ -1000,6 +1053,7 @@ smux_rreq_process(int sd, u_char * ptr, |
|
int i, result; |
|
u_char type; |
|
smux_reg *rptr, *nrptr; |
|
+ netsnmp_handler_registration *reg; |
|
|
|
oid_name_len = MAX_OID_LEN; |
|
ptr = asn_parse_objid(ptr, len, &type, oid_name, &oid_name_len); |
|
@@ -1157,17 +1211,27 @@ smux_rreq_process(int sd, u_char * ptr, |
|
*/ |
|
if (nrptr->sr_priority == -1) |
|
nrptr->sr_priority = 0; |
|
+ |
|
+ reg = netsnmp_create_handler_registration("smux", |
|
+ smux_handler, |
|
+ nrptr->sr_name, |
|
+ nrptr->sr_name_len, |
|
+ HANDLER_CAN_RWRITE); |
|
+ if (reg == NULL) { |
|
+ snmp_log(LOG_ERR, "SMUX: cannot create new smux peer " |
|
+ "registration\n"); |
|
+ smux_send_rrsp(sd, -1); |
|
+ free(nrptr); |
|
+ return NULL; |
|
+ } |
|
+ if (netsnmp_register_handler(reg) != MIB_REGISTERED_OK) { |
|
+ snmp_log(LOG_ERR, "SMUX: cannot register new smux peer\n"); |
|
+ smux_send_rrsp(sd, -1); |
|
+ free(nrptr); |
|
+ return NULL; |
|
+ } |
|
+ nrptr->reginfo = reg; |
|
smux_list_add(&ActiveRegs, nrptr); |
|
- if (register_mib("smux", (struct variable *) |
|
- smux_variables, sizeof(struct variable2), |
|
- 1, nrptr->sr_name, nrptr->sr_name_len) |
|
- != SNMPERR_SUCCESS) { |
|
- DEBUGMSGTL(("smux", "[smux_rreq_process] Failed to register subtree\n")); |
|
- smux_list_detach(&ActiveRegs, nrptr); |
|
- free(nrptr); |
|
- smux_send_rrsp(sd, -1); |
|
- return NULL; |
|
- } |
|
|
|
done: |
|
smux_send_rrsp(sd, nrptr->sr_priority); |
|
@@ -1214,16 +1278,35 @@ smux_find_match(smux_reg * regs, int sd, |
|
static void |
|
smux_replace_active(smux_reg * actptr, smux_reg * pasptr) |
|
{ |
|
+ netsnmp_handler_registration *reg; |
|
+ |
|
smux_list_detach(&ActiveRegs, actptr); |
|
- unregister_mib(actptr->sr_name, actptr->sr_name_len); |
|
+ if (actptr->reginfo) { |
|
+ netsnmp_unregister_handler(actptr->reginfo); |
|
+ actptr->reginfo = NULL; |
|
+ } |
|
|
|
smux_list_detach(&PassiveRegs, pasptr); |
|
- (void) smux_list_add(&ActiveRegs, pasptr); |
|
|
|
- register_mib("smux", (struct variable *) smux_variables, |
|
- sizeof(struct variable2), 1, pasptr->sr_name, |
|
- pasptr->sr_name_len); |
|
+ (void) smux_list_add(&ActiveRegs, pasptr); |
|
free(actptr); |
|
+ |
|
+ reg = netsnmp_create_handler_registration("smux", |
|
+ smux_handler, |
|
+ pasptr->sr_name, |
|
+ pasptr->sr_name_len, |
|
+ HANDLER_CAN_RWRITE); |
|
+ if (reg == NULL) { |
|
+ snmp_log(LOG_ERR, "SMUX: cannot create new smux peer registration\n"); |
|
+ pasptr->reginfo = NULL; |
|
+ return; |
|
+ } |
|
+ if (netsnmp_register_handler(reg) != MIB_REGISTERED_OK) { |
|
+ snmp_log(LOG_ERR, "SMUX: cannot register new smux peer\n"); |
|
+ pasptr->reginfo = NULL; |
|
+ return; |
|
+ } |
|
+ pasptr->reginfo = reg; |
|
} |
|
|
|
static void |
|
@@ -1373,8 +1456,6 @@ smux_snmp_process(int exact, |
|
/* |
|
* Send the query to the peer |
|
*/ |
|
- smux_reqid++; |
|
- |
|
if (exact) |
|
type = SMUX_GET; |
|
else |
|
@@ -1757,6 +1838,7 @@ smux_peer_cleanup(int sd) |
|
{ |
|
smux_reg *nrptr, *rptr, *rptr2; |
|
int i; |
|
+ netsnmp_handler_registration *reg; |
|
|
|
/* |
|
* close the descriptor |
|
@@ -1781,15 +1863,30 @@ smux_peer_cleanup(int sd) |
|
rptr2 = rptr->sr_next; |
|
if (rptr->sr_fd == sd) { |
|
smux_list_detach(&ActiveRegs, rptr); |
|
- unregister_mib(rptr->sr_name, rptr->sr_name_len); |
|
+ if (rptr->reginfo) { |
|
+ netsnmp_unregister_handler(rptr->reginfo); |
|
+ rptr->reginfo = NULL; |
|
+ } |
|
if ((nrptr = smux_find_replacement(rptr->sr_name, |
|
rptr->sr_name_len)) != |
|
- NULL) { |
|
+ NULL) { |
|
smux_list_detach(&PassiveRegs, nrptr); |
|
+ reg = netsnmp_create_handler_registration("smux", |
|
+ smux_handler, |
|
+ nrptr->sr_name, |
|
+ nrptr->sr_name_len, |
|
+ HANDLER_CAN_RWRITE); |
|
+ if (reg == NULL) { |
|
+ snmp_log(LOG_ERR, "SMUX: cannot create new smux peer " |
|
+ "registration\n"); |
|
+ continue; |
|
+ } |
|
+ if (netsnmp_register_handler(reg) != MIB_REGISTERED_OK) { |
|
+ snmp_log(LOG_ERR, "SMUX: cannot register new smux peer\n"); |
|
+ continue; |
|
+ } |
|
+ nrptr->reginfo = reg; |
|
smux_list_add(&ActiveRegs, nrptr); |
|
- register_mib("smux", (struct variable *) |
|
- smux_variables, sizeof(struct variable2), |
|
- 1, nrptr->sr_name, nrptr->sr_name_len); |
|
} |
|
free(rptr); |
|
} |
|
diff -up net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.h.rhel net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.h |
|
--- net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.h.rhel 2012-07-31 14:13:21.893006290 +0200 |
|
+++ net-snmp-5.7.2.pre2/agent/mibgroup/smux/smux.h 2012-07-31 13:49:55.000000000 +0200 |
|
@@ -60,6 +60,7 @@ typedef struct _smux_reg { |
|
int sr_priority; /* priority of registration */ |
|
int sr_fd; /* descriptor of owner */ |
|
struct _smux_reg *sr_next; /* next one */ |
|
+ netsnmp_handler_registration *reginfo; |
|
} smux_reg; |
|
|
|
extern void init_smux(void);
|
|
|