Blob Blame History Raw
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);