Introduce a transaction id. This is currently mostly a dummy-variable, but
authormartijn <martijn@openbsd.org>
Fri, 5 Feb 2021 10:30:45 +0000 (10:30 +0000)
committermartijn <martijn@openbsd.org>
Fri, 5 Feb 2021 10:30:45 +0000 (10:30 +0000)
will later on be needed for when we reintroduce agentx master support.

feedback and OK dlg@, rob@

usr.sbin/snmpd/snmpd.h
usr.sbin/snmpd/snmpe.c

index c490ed2..40f0874 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: snmpd.h,v 1.93 2021/01/28 20:45:14 martijn Exp $      */
+/*     $OpenBSD: snmpd.h,v 1.94 2021/02/05 10:30:45 martijn Exp $      */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -399,6 +399,8 @@ struct snmp_message {
        u_int8_t                 sm_data[READ_BUF_SIZE];
        size_t                   sm_datalen;
 
+       uint32_t                 sm_transactionid;
+
        u_int                    sm_version;
 
        /* V1, V2c */
@@ -436,7 +438,11 @@ struct snmp_message {
 
        struct ber_element      *sm_varbind;
        struct ber_element      *sm_varbindresp;
+
+       RB_ENTRY(snmp_message)   sm_entry;
 };
+RB_HEAD(snmp_messages, snmp_message);
+extern struct snmp_messages snmp_messages;
 
 /* Defined in SNMPv2-MIB.txt (RFC 3418) */
 struct snmp_stats {
@@ -642,6 +648,8 @@ struct kif_arp      *karp_getaddr(struct sockaddr *, u_short, int);
 void            snmpe(struct privsep *, struct privsep_proc *);
 void            snmpe_shutdown(void);
 void            snmpe_dispatchmsg(struct snmp_message *);
+int             snmp_messagecmp(struct snmp_message *, struct snmp_message *);
+RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)
 
 /* trap.c */
 void            trap_init(void);
index 4aea2d5..9d06320 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: snmpe.c,v 1.68 2021/01/22 06:33:27 martijn Exp $      */
+/*     $OpenBSD: snmpe.c,v 1.69 2021/02/05 10:30:45 martijn Exp $      */
 
 /*
  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -58,6 +58,8 @@ void   snmp_msgfree(struct snmp_message *);
 struct imsgev  *iev_parent;
 static const struct timeval    snmpe_tcp_timeout = { 10, 0 }; /* 10s */
 
+struct snmp_messages snmp_messages = RB_INITIALIZER(&snmp_messages);
+
 static struct privsep_proc procs[] = {
        { "parent",     PROC_PARENT }
 };
@@ -210,6 +212,11 @@ snmpe_parse(struct snmp_message *msg)
 
        msg->sm_errstr = "invalid message";
 
+       do {
+               msg->sm_transactionid = arc4random();
+       } while (msg->sm_transactionid == 0 ||
+           RB_INSERT(snmp_messages, &snmp_messages, msg) != NULL);
+
        if (ober_scanf_elements(root, "{ie", &ver, &a) != 0)
                goto parsefail;
 
@@ -834,6 +841,8 @@ snmpe_response(struct snmp_message *msg)
 void
 snmp_msgfree(struct snmp_message *msg)
 {
+       if (msg->sm_transactionid != 0)
+               RB_REMOVE(snmp_messages, &snmp_messages, msg);
        event_del(&msg->sm_sockev);
        ober_free(&msg->sm_ber);
        if (msg->sm_req != NULL)
@@ -896,3 +905,12 @@ snmpe_encode(struct snmp_message *msg)
 #endif
        return 0;
 }
+
+int
+snmp_messagecmp(struct snmp_message *m1, struct snmp_message *m2)
+{
+       return (m1->sm_transactionid < m2->sm_transactionid ? -1 :
+           m1->sm_transactionid > m2->sm_transactionid);
+}
+
+RB_GENERATE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)