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);