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