Blame SOURCES/net-snmp-5.7-smux-reqid.patch

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