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