/* Portions of this file are subject to the following copyright(s).  See
 * the Net-SNMP's COPYING file for more details and other copyrights
 * that may apply:
 */
/*
 * Portions of this file are copyrighted by:
 * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 * Use is subject to license terms specified in the COPYING file
 * distributed with the Net-SNMP package.
 */
/* 
 * See the following web pages for useful documentation on this transport:
 * http://www.net-snmp.org/wiki/index.php/TUT:Using_TLS
 * http://www.net-snmp.org/wiki/index.php/Using_DTLS
 */

#include <net-snmp/net-snmp-config.h>

#ifdef HAVE_LIBSSL_DTLS

#include <net-snmp/net-snmp-features.h>

netsnmp_feature_require(cert_util)
netsnmp_feature_require(sockaddr_size)

#include <net-snmp/library/snmpDTLSUDPDomain.h>
#include <net-snmp/library/snmpUDPIPv6Domain.h>

#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#if HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif

#if HAVE_DMALLOC_H
#include <dmalloc.h>
#endif

#include <net-snmp/types.h>
#include <net-snmp/output_api.h>
#include <net-snmp/config_api.h>

#include <net-snmp/library/snmp_transport.h>
#include <net-snmp/library/system.h>
#include <net-snmp/library/tools.h>
#include <net-snmp/library/callback.h>

#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/rand.h"

#include <net-snmp/library/snmpSocketBaseDomain.h>
#include <net-snmp/library/snmpTLSBaseDomain.h>
#include <net-snmp/library/snmpUDPDomain.h>
#include <net-snmp/library/cert_util.h>
#include <net-snmp/library/snmp_openssl.h>

#ifndef INADDR_NONE
#define INADDR_NONE	-1
#endif

#define WE_ARE_SERVER 0
#define WE_ARE_CLIENT 1

oid             netsnmpDTLSUDPDomain[] = { TRANSPORT_DOMAIN_DTLS_UDP_IP };
size_t          netsnmpDTLSUDPDomain_len = OID_LENGTH(netsnmpDTLSUDPDomain);

static netsnmp_tdomain dtlsudpDomain;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
static int openssl_addr_index6 = 0;
#endif

/* this stores openssl credentials for each connection since openssl
   can't do it for us at the moment; hopefully future versions will
   change */
typedef struct bio_cache_s {
   BIO *read_bio;  /* OpenSSL will read its incoming SSL packets from here */
   BIO *write_bio; /* OpenSSL will write its outgoing SSL packets to here */
   netsnmp_sockaddr_storage sas;
   u_int flags;
   struct bio_cache_s *next;
   int msgnum;
   char *write_cache;
   size_t write_cache_len;
   _netsnmpTLSBaseData *tlsdata;
} bio_cache;

/** bio_cache flags */
#define NETSNMP_BIO_HAVE_COOKIE        0x0001 /* verified cookie */
#define NETSNMP_BIO_CONNECTED          0x0002 /* recieved decoded data */
#define NETSNMP_BIO_DISCONNECTED       0x0004 /* peer shutdown */

static bio_cache *biocache = NULL;

static int openssl_addr_index = 0;

static int netsnmp_dtls_verify_cookie(SSL *ssl, unsigned char *cookie,
                                      unsigned int cookie_len);
static int netsnmp_dtls_gen_cookie(SSL *ssl, unsigned char *cookie,
                                   unsigned int *cookie_len);

/* this stores remote connections in a list to search through */
/* XXX: optimize for searching */
/* XXX: handle state issues for new connections to reduce DOS issues */
/*      (TLS should do this, but openssl can't do more than one ctx per sock */
/* XXX: put a timer on the cache for expirary purposes */
static bio_cache *find_bio_cache(netsnmp_sockaddr_storage *from_addr) {
    bio_cache *cachep = NULL;
    
    for(cachep = biocache; cachep; cachep = cachep->next) {

        if (cachep->sas.sa.sa_family != from_addr->sa.sa_family)
            continue;

        if ((from_addr->sa.sa_family == AF_INET) &&
            ((cachep->sas.sin.sin_addr.s_addr !=
              from_addr->sin.sin_addr.s_addr) ||
             (cachep->sas.sin.sin_port != from_addr->sin.sin_port)))
                continue;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
        else if ((from_addr->sa.sa_family == AF_INET6) &&
                 ((cachep->sas.sin6.sin6_port != from_addr->sin6.sin6_port) ||
                  (cachep->sas.sin6.sin6_scope_id !=
                   from_addr->sin6.sin6_scope_id) ||
                  (memcmp(cachep->sas.sin6.sin6_addr.s6_addr,
                          from_addr->sin6.sin6_addr.s6_addr,
                          sizeof(from_addr->sin6.sin6_addr.s6_addr)) != 0)))
            continue;
#endif
        /* found an existing connection */
        break;
    }
    return cachep;
}

/* removes a single cache entry and returns SUCCESS on finding and
   removing it. */
static int remove_bio_cache(bio_cache *thiscache) {
    bio_cache *cachep = NULL, *prevcache = NULL;
    cachep = biocache;
    while(cachep) {
        if (cachep == thiscache) {

            /* remove it from the list */
            if (NULL == prevcache) {
                /* at the first cache in the list */
                biocache = thiscache->next;
            } else {
                prevcache->next = thiscache->next;
            }

            return SNMPERR_SUCCESS;
        }
        prevcache = cachep;
        cachep = cachep->next;
    }
    return SNMPERR_GENERR;
}

/* frees the contents of a bio_cache */
static void free_bio_cache(bio_cache *cachep) {
/* These are freed by the SSL_free() call */
/*
        BIO_free(cachep->read_bio);
        BIO_free(cachep->write_bio);
*/
    DEBUGMSGTL(("9:dtlsudp:bio_cache", "releasing %p\n", cachep));
        SNMP_FREE(cachep->write_cache);
        netsnmp_tlsbase_free_tlsdata(cachep->tlsdata);
}

static void remove_and_free_bio_cache(bio_cache *cachep) {
    /** no debug, remove_bio_cache does it */
    remove_bio_cache(cachep);
    free_bio_cache(cachep);
}


/* XXX: lots of malloc/state cleanup needed */
#define DIEHERE(msg) do { snmp_log(LOG_ERR, "%s\n", msg); return NULL; } while(0)

static bio_cache *
start_new_cached_connection(netsnmp_transport *t,
                            netsnmp_sockaddr_storage *remote_addr,
                            int we_are_client) {
    bio_cache *cachep = NULL;
    _netsnmpTLSBaseData *tlsdata;

    DEBUGTRACETOK("9:dtlsudp");

    /* RFC5953: section 5.3.1, step 1:
       1)  The snmpTlstmSessionOpens counter is incremented.
    */
    if (we_are_client)
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENS);

    if (!t->sock)
        DIEHERE("no socket passed in to start_new_cached_connection\n");
    if (!remote_addr)
        DIEHERE("no remote_addr passed in to start_new_cached_connection\n");
        
    cachep = SNMP_MALLOC_TYPEDEF(bio_cache);
    if (!cachep)
        return NULL;
    
    /* allocate our TLS specific data */
    if (NULL == (tlsdata = netsnmp_tlsbase_allocate_tlsdata(t, !we_are_client))) {
        SNMP_FREE(cachep);
        return NULL;
    }
    cachep->tlsdata = tlsdata;

    /* RFC5953: section 5.3.1, step 1:
       2)  The client selects the appropriate certificate and cipher_suites
           for the key agreement based on the tmSecurityName and the
           tmRequestedSecurityLevel for the session.  For sessions being
           established as a result of a SNMP-TARGET-MIB based operation, the
           certificate will potentially have been identified via the
           snmpTlstmParamsTable mapping and the cipher_suites will have to
           be taken from system-wide or implementation-specific
           configuration.  If no row in the snmpTlstmParamsTable exists then
           implementations MAY choose to establish the connection using a
           default client certificate available to the application.
           Otherwise, the certificate and appropriate cipher_suites will
           need to be passed to the openSession() ASI as supplemental
           information or configured through an implementation-dependent
           mechanism.  It is also implementation-dependent and possibly
           policy-dependent how tmRequestedSecurityLevel will be used to
           influence the security capabilities provided by the (D)TLS
           connection.  However this is done, the security capabilities
           provided by (D)TLS MUST be at least as high as the level of
           security indicated by the tmRequestedSecurityLevel parameter.
           The actual security level of the session is reported in the
           tmStateReference cache as tmSecurityLevel.  For (D)TLS to provide
           strong authentication, each principal acting as a command
           generator SHOULD have its own certificate.
    */
    /* Implementation notes:
       + This Information is passed in via the transport and default
         paremeters
    */
    /* see if we have base configuration to copy in to this new one */
    if (NULL != t->data && t->data_length == sizeof(_netsnmpTLSBaseData)) {
        _netsnmpTLSBaseData *parentdata = t->data;
        if (parentdata->our_identity)
            tlsdata->our_identity = strdup(parentdata->our_identity);
        if (parentdata->their_identity)
            tlsdata->their_identity = strdup(parentdata->their_identity);
        if (parentdata->their_fingerprint)
            tlsdata->their_fingerprint = strdup(parentdata->their_fingerprint);
        if (parentdata->trust_cert)
            tlsdata->trust_cert = strdup(parentdata->trust_cert);
        if (parentdata->their_hostname)
            tlsdata->their_hostname = strdup(parentdata->their_hostname);
    }
    
    DEBUGMSGTL(("dtlsudp", "starting a new connection\n"));
    cachep->next = biocache;
    biocache = cachep;

    if (remote_addr->sa.sa_family == AF_INET)
        memcpy(&cachep->sas.sin, &remote_addr->sin, sizeof(remote_addr->sin));
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    else if (remote_addr->sa.sa_family == AF_INET6)
        memcpy(&cachep->sas.sin6, &remote_addr->sin6, sizeof(remote_addr->sin6));
#endif
    else
        DIEHERE("unknown address family");

    /* create caching memory bios for OpenSSL to read and write to */

    cachep->read_bio = BIO_new(BIO_s_mem()); /* openssl reads from */
    if (!cachep->read_bio)
        DIEHERE("failed to create the openssl read_bio");

    cachep->write_bio = BIO_new(BIO_s_mem()); /* openssl writes to */
    if (!cachep->write_bio) {
        BIO_free(cachep->read_bio);
        cachep->read_bio = NULL;
        DIEHERE("failed to create the openssl write_bio");
    }

    BIO_set_mem_eof_return(cachep->read_bio, -1);
    BIO_set_mem_eof_return(cachep->write_bio, -1);

    if (we_are_client) {
        /* we're the client */
        DEBUGMSGTL(("dtlsudp",
                    "starting a new connection as a client to sock: %d\n",
                    t->sock));
        tlsdata->ssl = SSL_new(sslctx_client_setup(DTLSv1_method(), tlsdata));

        /* XXX: session setting 735 */
    } else {
        /* we're the server */
        SSL_CTX *ctx = sslctx_server_setup(DTLSv1_method());
        if (!ctx) {
            BIO_free(cachep->read_bio);
            BIO_free(cachep->write_bio);
            cachep->read_bio = NULL;
            cachep->write_bio = NULL;
            DIEHERE("failed to create the SSL Context");
        }

        /* turn on cookie exchange */
        /* Set DTLS cookie generation and verification callbacks */
        SSL_CTX_set_cookie_generate_cb(ctx, netsnmp_dtls_gen_cookie);
        SSL_CTX_set_cookie_verify_cb(ctx, netsnmp_dtls_verify_cookie);

        tlsdata->ssl = SSL_new(ctx);
    }

    if (!tlsdata->ssl) {
        BIO_free(cachep->read_bio);
        BIO_free(cachep->write_bio);
        cachep->read_bio = NULL;
        cachep->write_bio = NULL;
        DIEHERE("failed to create the SSL session structure");
    }
        
    SSL_set_mode(tlsdata->ssl, SSL_MODE_AUTO_RETRY);

    /* set the bios that openssl should read from and write to */
    /* (and we'll do the opposite) */
    SSL_set_bio(tlsdata->ssl, cachep->read_bio, cachep->write_bio);

    /* RFC5953: section 5.3.1, step 1:
       3)  Using the destTransportDomain and destTransportAddress values,
           the client will initiate the (D)TLS handshake protocol to
           establish session keys for message integrity and encryption.

           If the attempt to establish a session is unsuccessful, then
           snmpTlstmSessionOpenErrors is incremented, an error indication is
           returned, and processing stops.  If the session failed to open
           because the presented server certificate was unknown or invalid
           then the snmpTlstmSessionUnknownServerCertificate or
           snmpTlstmSessionInvalidServerCertificates MUST be incremented and
           a snmpTlstmServerCertificateUnknown or
           snmpTlstmServerInvalidCertificate notification SHOULD be sent as
           appropriate.  Reasons for server certificate invalidation
           includes, but is not limited to, cryptographic validation
           failures and an unexpected presented certificate identity.
    */
    /* Implementation notes:
       + Because we're working asyncronously the real "end" point of
         opening a connection doesn't occur here as certificate
         verification and other things needs to happen first in the
         verify callback, etc.  See the netsnmp_dtlsudp_recv()
         function for the final processing.
    */
    /* set the SSL notion of we_are_client/server */
    if (we_are_client)
        SSL_set_connect_state(tlsdata->ssl);
    else {
        /* XXX: we need to only create cache entries when cookies succeed */

        SSL_set_options(tlsdata->ssl, SSL_OP_COOKIE_EXCHANGE);

        SSL_set_ex_data(tlsdata->ssl, openssl_addr_index, cachep);

        SSL_set_accept_state(tlsdata->ssl);
    }

    /* RFC5953: section 5.3.1, step 1:
       6)  The TLSTM-specific session identifier (tlstmSessionID) is set in
           the tmSessionID of the tmStateReference passed to the TLS
           Transport Model to indicate that the session has been established
           successfully and to point to a specific (D)TLS connection for
           future use.  The tlstmSessionID is also stored in the LCD for
           later lookup during processing of incoming messages
           (Section 5.1.2).
    */
    /* Implementation notes:
       + our sessionID is stored as the transport's data pointer member
    */
    DEBUGMSGT(("9:dtlsudp:bio_cache:created", "%p\n", cachep));

    return cachep;
}

static bio_cache *
find_or_create_bio_cache(netsnmp_transport *t,
                         netsnmp_sockaddr_storage *from_addr,
                         int we_are_client) {
    bio_cache *cachep = find_bio_cache(from_addr);
    if (NULL == cachep) {
        /* none found; need to start a new context */
        cachep = start_new_cached_connection(t, from_addr, we_are_client);
        if (NULL == cachep) {
            snmp_log(LOG_ERR, "failed to open a new dtls connection\n");
        }
    } else {
        DEBUGMSGT(("9:dtlsudp:bio_cache:found", "%p\n", cachep));
    }
    return cachep;
}

static netsnmp_indexed_addr_pair *
_extract_addr_pair(netsnmp_transport *t, void *opaque, int olen)
{
    netsnmp_indexed_addr_pair *addr_pair = NULL;

    if (opaque && olen == sizeof(netsnmp_tmStateReference)) {
        netsnmp_tmStateReference *tmStateRef =
            (netsnmp_tmStateReference *) opaque;

        if (tmStateRef->have_addresses)
            addr_pair = &(tmStateRef->addresses);
    }
    if ((NULL == addr_pair) && (NULL != t)) {
        if (t->data != NULL &&
            t->data_length == sizeof(netsnmp_indexed_addr_pair))
            addr_pair = (netsnmp_indexed_addr_pair *) (t->data);
        else if (t->data != NULL &&
                 t->data_length == sizeof(_netsnmpTLSBaseData)) {
            _netsnmpTLSBaseData *tlsdata = (_netsnmpTLSBaseData *) t->data;
            addr_pair = (netsnmp_indexed_addr_pair *) (tlsdata->addr);
        }
    }

    return addr_pair;
}

static struct sockaddr *
_find_remote_sockaddr(netsnmp_transport *t, void *opaque, int olen, int *socklen)
{
    netsnmp_indexed_addr_pair *addr_pair = _extract_addr_pair(t, opaque, olen);
    struct sockaddr *sa = NULL;

    if (NULL == addr_pair)
        return NULL;

    sa = &addr_pair->remote_addr.sa;
    *socklen = netsnmp_sockaddr_size(sa);
    return sa;
}


/*
 * Reads data from our internal openssl outgoing BIO and sends any
 * queued packets out the UDP port
 */
static int
_netsnmp_send_queued_dtls_pkts(netsnmp_transport *t, bio_cache *cachep) {
    int outsize, rc2;
    u_char outbuf[65535];
    
    DEBUGTRACETOK("9:dtlsudp");

    /* for memory bios, we now read from openssl's write
       buffer (ie, the packet to go out) and send it out
       the udp port manually */

    outsize = BIO_read(cachep->write_bio, outbuf, sizeof(outbuf));
    if (outsize > 0) {
        DEBUGMSGTL(("dtlsudp", "have %d bytes to send\n", outsize));

        /* should always be true. */
        int socksize;
        struct sockaddr *sa;
        sa = _find_remote_sockaddr(t, NULL, 0, &socksize);
        if (NULL == sa)
            sa = &cachep->sas.sa;
        socksize = netsnmp_sockaddr_size(sa);
        rc2 = t->base_transport->f_send(t, outbuf, outsize, (void**)&sa,
                                        &socksize);
        if (rc2 == -1) {
            snmp_log(LOG_ERR, "failed to send a DTLS specific packet\n");
        }
    } else
        DEBUGMSGTL(("9:dtlsudp", "have 0 bytes to send\n"));

    return outsize;
}

/*
 * If we have any outgoing SNMP data queued that OpenSSL/DTLS couldn't send
 * (likely due to DTLS control packets needing to go out first)
 * then this function attempts to send them.
 */
/* returns SNMPERR_SUCCESS if we succeeded in getting the data out */
/* returns SNMPERR_GENERR if we still need more time */
static int
_netsnmp_bio_try_and_write_buffered(netsnmp_transport *t, bio_cache *cachep) {
    int rc;
    _netsnmpTLSBaseData *tlsdata;
    
    DEBUGTRACETOK("9:dtlsudp");

    tlsdata = cachep->tlsdata;

    /* make sure we have something to write */
    if (!cachep->write_cache || cachep->write_cache_len == 0)
        return SNMPERR_SUCCESS;

    DEBUGMSGTL(("dtlsudp", "Trying to write %" NETSNMP_PRIz "d of buffered data\n",
                cachep->write_cache_len));

    /* try and write out the cached data */
    rc = SSL_write(tlsdata->ssl, cachep->write_cache, cachep->write_cache_len);

    while (rc == -1) {
        int errnum = SSL_get_error(tlsdata->ssl, rc);
        int bytesout;

        /* don't treat want_read/write errors as real errors */
        if (errnum != SSL_ERROR_WANT_READ &&
            errnum != SSL_ERROR_WANT_WRITE) {
            DEBUGMSGTL(("dtlsudp", "ssl_write error (of buffered data)\n")); 
            _openssl_log_error(rc, tlsdata->ssl, "SSL_write");
            return SNMPERR_GENERR;
        }

        /* check to see if we have outgoing DTLS packets to send */
        /* (SSL_write could have created DTLS control packets) */ 
        bytesout = _netsnmp_send_queued_dtls_pkts(t, cachep);

        /* If want_read/write but failed to actually send anything
           then we need to wait for the other side, so quit */
        if ((errnum == SSL_ERROR_WANT_READ ||
             errnum == SSL_ERROR_WANT_WRITE) &&
            bytesout <= 0) {
            /* we've failed; must need to wait longer */
            return SNMPERR_GENERR;
        }

        /* retry writing */
        DEBUGMSGTL(("9:dtlsudp", "recalling ssl_write\n")); 
        rc = SSL_write(tlsdata->ssl, cachep->write_cache,
                       cachep->write_cache_len);
    }

    if (rc > 0)
        cachep->msgnum++;
    
    if (_netsnmp_send_queued_dtls_pkts(t, cachep) > 0) {
        SNMP_FREE(cachep->write_cache);
        cachep->write_cache_len = 0;
        DEBUGMSGTL(("dtlsudp", "  Write was successful\n"));
        return SNMPERR_SUCCESS;
    }
    DEBUGMSGTL(("dtlsudp", "  failed to send over UDP socket\n"));
    return SNMPERR_GENERR;
}

static int
_netsnmp_add_buffered_data(bio_cache *cachep, char *buf, size_t size) {
    if (cachep->write_cache && cachep->write_cache_len > 0) {
        size_t newsize = cachep->write_cache_len + size;

        char *newbuf = realloc(cachep->write_cache, newsize);
        if (NULL == newbuf) {
            /* ack! malloc failure */
            /* XXX: free and close */
            return SNMPERR_GENERR;
        }
        cachep->write_cache = newbuf;

        /* write the new packet to the end */
        memcpy(cachep->write_cache + cachep->write_cache_len,
               buf, size);
        cachep->write_cache_len = newsize;
    } else {
        cachep->write_cache = netsnmp_memdup(buf, size);
        if (!cachep->write_cache) {
            /* ack! malloc failure */
            /* XXX: free and close */
            return SNMPERR_GENERR;
        }
        cachep->write_cache_len = size;
    }
    return SNMPERR_SUCCESS;
}

static int
netsnmp_dtlsudp_recv(netsnmp_transport *t, void *buf, int size,
                     void **opaque, int *olength)
{
    int             rc = -1;
    netsnmp_indexed_addr_pair *addr_pair = NULL;
    struct sockaddr *from;
    netsnmp_tmStateReference *tmStateRef = NULL;
    _netsnmpTLSBaseData *tlsdata;
    bio_cache *cachep;

    DEBUGTRACETOK("9:dtlsudp");

    if (NULL == t || t->sock == 0)
        return -1;

    /* create a tmStateRef cache for slow fill-in */
    tmStateRef = SNMP_MALLOC_TYPEDEF(netsnmp_tmStateReference);

    if (tmStateRef == NULL) {
        *opaque = NULL;
        *olength = 0;
        return -1;
    }

    /* Set the transportDomain */
    memcpy(tmStateRef->transportDomain,
           netsnmpDTLSUDPDomain, sizeof(netsnmpDTLSUDPDomain[0]) *
           netsnmpDTLSUDPDomain_len);
    tmStateRef->transportDomainLen = netsnmpDTLSUDPDomain_len;

    addr_pair = &tmStateRef->addresses;
    tmStateRef->have_addresses = 1;
    from = (struct sockaddr *) &(addr_pair->remote_addr);

    while (rc < 0) {
        char *opaque = NULL;
        int olen;
        rc = t->base_transport->f_recv(t, buf, size, (void**)&opaque, &olen);
        if (rc > 0)
            memcpy(from, opaque, olen);
        SNMP_FREE(opaque);
        if (rc < 0 && errno != EINTR) {
            break;
        }
    }

    DEBUGMSGTL(("dtlsudp", "received %d raw bytes on way to dtls\n", rc));
    if (rc < 0) {
        DEBUGMSGTL(("dtlsudp", "recvfrom fd %d err %d (\"%s\")\n",
                    t->sock, errno, strerror(errno)));
        SNMP_FREE(tmStateRef);
        return -1;
    }

    /* now that we have the from address filled in, we can look up
       the openssl context and have openssl read and process
       appropriately */

    /* RFC5953: section 5.1, step 1:
    1)  Determine the tlstmSessionID for the incoming message.  The
        tlstmSessionID MUST be a unique session identifier for this
        (D)TLS connection.  The contents and format of this identifier
        are implementation-dependent as long as it is unique to the
        session.  A session identifier MUST NOT be reused until all
        references to it are no longer in use.  The tmSessionID is equal
        to the tlstmSessionID discussed in Section 5.1.1. tmSessionID
        refers to the session identifier when stored in the
        tmStateReference and tlstmSessionID refers to the session
        identifier when stored in the LCD.  They MUST always be equal
        when processing a given session's traffic.

        If this is the first message received through this session and
        the session does not have an assigned tlstmSessionID yet then the
        snmpTlstmSessionAccepts counter is incremented and a
        tlstmSessionID for the session is created.  This will only happen
        on the server side of a connection because a client would have
        already assigned a tlstmSessionID during the openSession()
        invocation.  Implementations may have performed the procedures
        described in Section 5.3.2 prior to this point or they may
        perform them now, but the procedures described in Section 5.3.2
        MUST be performed before continuing beyond this point.
    */

    /* RFC5953: section 5.1, step 2:
       2)  Create a tmStateReference cache for the subsequent reference and
           assign the following values within it:

           tmTransportDomain  = snmpTLSTCPDomain or snmpDTLSUDPDomain as
              appropriate.

           tmTransportAddress  = The address the message originated from.

           tmSecurityLevel  = The derived tmSecurityLevel for the session,
              as discussed in Section 3.1.2 and Section 5.3.

           tmSecurityName  = The derived tmSecurityName for the session as
              discussed in Section 5.3.  This value MUST be constant during
              the lifetime of the session.

           tmSessionID  = The tlstmSessionID described in step 1 above.
    */

    /* if we don't have a cachep for this connection then
       we're receiving something new and are the server
       side */
    cachep =
        find_or_create_bio_cache(t, &addr_pair->remote_addr, WE_ARE_SERVER);
    if (NULL == cachep) {
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONACCEPTS);
        SNMP_FREE(tmStateRef);
        return -1;
    }
    tlsdata = cachep->tlsdata;
    if (NULL == tlsdata->ssl) {
        /*
         * this happens when the server starts but doesn't have an
         * identity and a client connects...
         */
        snmp_log(LOG_ERR,
                 "DTLSUDP: missing tlsdata!\n");
        /*snmp_increment_statistic( XXX-rks ??? );*/
        SNMP_FREE(tmStateRef);
        return -1;
    }

    /* Implementation notes:
       - we use the t->data memory pointer as the session ID
       - the transport domain is already the correct type if we got here
       - if we don't have a session yet (eg, no tmSessionID from the
         specs) then we create one automatically here.
    */

    /* write the received buffer to the memory-based input bio */
    BIO_write(cachep->read_bio, buf, rc);

    /* RFC5953: section 5.1, step 3:
       3)  The incomingMessage and incomingMessageLength are assigned values
           from the (D)TLS processing.
     */
    /* Implementation notes:
       + rc = incomingMessageLength
       + buf = IncomingMessage
    */

    /* XXX: in Wes' other example we do a SSL_pending() call
       too to ensure we're ready to read...  it's possible
       that buffered stuff in openssl won't be caught by the
       net-snmp select loop because it's already been pulled
       out; need to deal with this) */
    rc = SSL_read(tlsdata->ssl, buf, size);

    /*
     * moved netsnmp_openssl_null_checks to netsnmp_tlsbase_wrapup_recv.
     * currently netsnmp_tlsbase_wrapup_recv is where we check for
     * algorithm compliance, but we (sometimes) know the algorithms
     * at this point, so we could bail earlier (here)...
     */

    while (rc == -1) {
        int errnum = SSL_get_error(tlsdata->ssl, rc);
        int bytesout;

        /* don't treat want_read/write errors as real errors */
        if (errnum != SSL_ERROR_WANT_READ &&
            errnum != SSL_ERROR_WANT_WRITE) {
            _openssl_log_error(rc, tlsdata->ssl, "SSL_read");
            break;
        }

        /* check to see if we have outgoing DTLS packets to send */
        /* (SSL_read could have created DTLS control packets) */ 
        bytesout = _netsnmp_send_queued_dtls_pkts(t, cachep);

        /* If want_read/write but failed to actually send
           anything then we need to wait for the other side,
           so quit */
        if ((errnum == SSL_ERROR_WANT_READ ||
             errnum == SSL_ERROR_WANT_WRITE) &&
            bytesout <= 0)
            break;

        /* retry reading */
        DEBUGMSGTL(("9:dtlsudp", "recalling ssl_read\n")); 
        rc = SSL_read(tlsdata->ssl, buf, size);
    }

    if (rc == -1) {
        SNMP_FREE(tmStateRef);

        DEBUGMSGTL(("9:dtlsudp", "no decoded data from dtls\n"));

        if (SSL_get_error(tlsdata->ssl, rc) == SSL_ERROR_WANT_READ) {
            DEBUGMSGTL(("9dtlsudp","here: want read!\n"));

            /* see if we have buffered write date to send out first */
            if (cachep->write_cache) {
                _netsnmp_bio_try_and_write_buffered(t, cachep);
                /* XXX: check error or not here? */
                /* (what would we do differently?) */
            }

            rc = -1; /* XXX: it's ok, but what's the right return? */
        }
        else
            _openssl_log_error(rc, tlsdata->ssl, "SSL_read");

#if 0 /* to dump cache if we don't have a cookie, this is where to do it */
        if (!(cachep->flags & NETSNMP_BIO_HAVE_COOKIE))
            remove_and_free_bio_cache(cachep);
#endif
        return rc;
    }

    DEBUGMSGTL(("dtlsudp", "received %d decoded bytes from dtls\n", rc));

    if ((0 == rc) && (SSL_get_shutdown(tlsdata->ssl) & SSL_RECEIVED_SHUTDOWN)) {
        DEBUGMSGTL(("dtlsudp", "peer disconnected\n"));
        cachep->flags |= NETSNMP_BIO_DISCONNECTED;
        remove_and_free_bio_cache(cachep);
        SNMP_FREE(tmStateRef);
        return rc;
    }
    cachep->flags |= NETSNMP_BIO_CONNECTED;

    /* Until we've locally assured ourselves that all is well in
       certificate-verification-land we need to be prepared to stop
       here and ensure all our required checks have been done. */ 
    if (0 == (tlsdata->flags & NETSNMP_TLSBASE_CERT_FP_VERIFIED)) {
        int verifyresult;

        if (tlsdata->flags & NETSNMP_TLSBASE_IS_CLIENT) {

            /* verify that the server's certificate is the correct one */

    	    /* RFC5953: section 5.3.1, step 1:
    	       3)  Using the destTransportDomain and
    	           destTransportAddress values, the client will
    	           initiate the (D)TLS handshake protocol to establish
    	           session keys for message integrity and encryption.

    	           If the attempt to establish a session is
    	           unsuccessful, then snmpTlstmSessionOpenErrors is
    	           incremented, an error indication is returned, and
    	           processing stops.  If the session failed to open
    	           because the presented server certificate was
    	           unknown or invalid then the
    	           snmpTlstmSessionUnknownServerCertificate or
    	           snmpTlstmSessionInvalidServerCertificates MUST be
    	           incremented and a snmpTlstmServerCertificateUnknown
    	           or snmpTlstmServerInvalidCertificate notification
    	           SHOULD be sent as appropriate.  Reasons for server
    	           certificate invalidation includes, but is not
    	           limited to, cryptographic validation failures and
    	           an unexpected presented certificate identity.
    	    */
    	    /* RFC5953: section 5.3.1, step 1:
    	       4)  The (D)TLS client MUST then verify that the (D)TLS
    	           server's presented certificate is the expected
    	           certificate.  The (D)TLS client MUST NOT transmit
    	           SNMP messages until the server certificate has been
    	           authenticated, the client certificate has been
    	           transmitted and the TLS connection has been fully
    	           established.

    	           If the connection is being established from
    	           configuration based on SNMP-TARGET-MIB
    	           configuration, then the snmpTlstmAddrTable
    	           DESCRIPTION clause describes how the verification
    	           is done (using either a certificate fingerprint, or
    	           an identity authenticated via certification path
    	           validation).

    	           If the connection is being established for reasons
    	           other than configuration found in the
    	           SNMP-TARGET-MIB then configuration and procedures
    	           outside the scope of this document should be
    	           followed.  Configuration mechanisms SHOULD be
    	           similar in nature to those defined in the
    	           snmpTlstmAddrTable to ensure consistency across
    	           management configuration systems.  For example, a
    	           command-line tool for generating SNMP GETs might
    	           support specifying either the server's certificate
    	           fingerprint or the expected host name as a command
    	           line argument.
    	    */
    	    /* RFC5953: section 5.3.1, step 1:
    	       5)  (D)TLS provides assurance that the authenticated
    	           identity has been signed by a trusted configured
    	           certification authority.  If verification of the
    	           server's certificate fails in any way (for example
    	           because of failures in cryptographic verification
    	           or the presented identity did not match the
    	           expected named entity) then the session
    	           establishment MUST fail, the
    	           snmpTlstmSessionInvalidServerCertificates object is
    	           incremented.  If the session can not be opened for
    	           any reason at all, including cryptographic
    	           verification failures and snmpTlstmCertToTSNTable
    	           lookup failures, then the
    	           snmpTlstmSessionOpenErrors counter is incremented
    	           and processing stops.
    	    */

	    /* Implementation notes:
	       + in the following function the server's certificate and
	         presented commonname or subjectAltName is checked
	         according to the rules in the snmpTlstmAddrTable.
	    */ 
            if ((verifyresult = netsnmp_tlsbase_verify_server_cert(tlsdata->ssl, tlsdata))
                != SNMPERR_SUCCESS) {
                if (verifyresult == SNMPERR_TLS_NO_CERTIFICATE) {
                    /* assume we simply haven't received it yet and there
                       is more data to wait-for or send */
                    /* XXX: probably need to check for whether we should
                       send stuff from our end to continue the transaction
                    */
                    SNMP_FREE(tmStateRef);
                    return -1;
                } else {
                    /* XXX: free needed memory */
                    snmp_log(LOG_ERR,
                             "DTLSUDP: failed to verify ssl certificate (of the server)\n");
		    snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONUNKNOWNSERVERCERTIFICATE);
		    /* Step 5 says these are always incremented */
		    snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONINVALIDSERVERCERTIFICATES);
		    snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
                    SNMP_FREE(tmStateRef);
                    return -1;
                }
            }
            tlsdata->flags |= NETSNMP_TLSBASE_CERT_FP_VERIFIED;
            DEBUGMSGTL(("dtlsudp", "Verified the server's certificate\n"));
        } else {
#ifndef NETSNMP_NO_LISTEN_SUPPORT
            /* verify that the client's certificate is the correct one */
        
            if ((verifyresult = netsnmp_tlsbase_verify_client_cert(tlsdata->ssl, tlsdata))
                != SNMPERR_SUCCESS) {
                if (verifyresult == SNMPERR_TLS_NO_CERTIFICATE) {
                    /* assume we simply haven't received it yet and there
                       is more data to wait-for or send */
                    /* XXX: probably need to check for whether we should
                       send stuff from our end to continue the transaction
                    */
                    SNMP_FREE(tmStateRef);
                    return -1;
                } else {
                    /* XXX: free needed memory */
                    snmp_log(LOG_ERR,
                             "DTLSUDP: failed to verify ssl certificate (of the client)\n");
                    snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONINVALIDCLIENTCERTIFICATES);
                    SNMP_FREE(tmStateRef);
                    return -1;
                }
            }
            tlsdata->flags |= NETSNMP_TLSBASE_CERT_FP_VERIFIED;
            DEBUGMSGTL(("dtlsudp", "Verified the client's certificate\n"));
#else /* NETSNMP_NO_LISTEN_SUPPORT */
            return NULL;
#endif /* NETSNMP_NO_LISTEN_SUPPORT */
        }
    }

    if (rc > 0)
        cachep->msgnum++;

    if (BIO_ctrl_pending(cachep->write_bio) > 0) {
        _netsnmp_send_queued_dtls_pkts(t, cachep);
    }

    DEBUGIF ("9:dtlsudp") {
        char *str =
            t->base_transport->f_fmtaddr(t, addr_pair,
                                        sizeof(netsnmp_indexed_addr_pair));
        DEBUGMSGTL(("9:dtlsudp",
                    "recvfrom fd %d got %d bytes (from %s)\n",
                    t->sock, rc, str));
        free(str);
    }

    /* see if we have buffered write date to send out first */
    if (cachep->write_cache) {
        if (SNMPERR_GENERR ==
            _netsnmp_bio_try_and_write_buffered(t, cachep)) {
            /* we still have data that can't get out in the buffer */
            /* XXX: nothing to do here? */
        }
    }

    if (netsnmp_tlsbase_wrapup_recv(tmStateRef, tlsdata, opaque, olength) !=
        SNMPERR_SUCCESS)
        return SNMPERR_GENERR;

    /* RFC5953: section 5.1, step 4:
       4)  The TLS Transport Model passes the transportDomain,
           transportAddress, incomingMessage, and incomingMessageLength to
           the Dispatcher using the receiveMessage ASI:

          statusInformation =
          receiveMessage(
          IN   transportDomain     -- snmpTLSTCPDomain or snmpDTLSUDPDomain,
          IN   transportAddress    -- address for the received message
          IN   incomingMessage        -- the whole SNMP message from (D)TLS
          IN   incomingMessageLength  -- the length of the SNMP message
          IN   tmStateReference    -- transport info
           )
    */
    /* Implementation notes: those pamateres are all passed outward
       using the functions arguments and the return code below (the length) */

    return rc;
}



static int
netsnmp_dtlsudp_send(netsnmp_transport *t, void *buf, int size,
		 void **opaque, int *olength)
{
    int rc = -1;
    netsnmp_indexed_addr_pair *addr_pair = NULL;
    bio_cache *cachep = NULL;
    netsnmp_tmStateReference *tmStateRef = NULL;
    u_char outbuf[65535];
    _netsnmpTLSBaseData *tlsdata = NULL;
    int socksize;
    struct sockaddr *sa;
    
    DEBUGTRACETOK("9:dtlsudp");
    DEBUGMSGTL(("dtlsudp", "sending %d bytes\n", size));

    if (NULL == t || t->sock <= 0) {
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONINVALIDCACHES);
        snmp_log(LOG_ERR, "invalid netsnmp_dtlsudp_send usage\n");
        return -1;
    }

    /* determine remote addresses */
    addr_pair = _extract_addr_pair(t, opaque ? *opaque : NULL,
                                   olength ? *olength : 0);
    if (NULL == addr_pair) {
      /* RFC5953: section 5.2, step 1:
       1)  If tmStateReference does not refer to a cache containing values
           for tmTransportDomain, tmTransportAddress, tmSecurityName,
           tmRequestedSecurityLevel, and tmSameSecurity, then increment the
           snmpTlstmSessionInvalidCaches counter, discard the message, and
           return the error indication in the statusInformation.  Processing
           of this message stops.
      */
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONINVALIDCACHES);
        snmp_log(LOG_ERR, "dtlsudp_send: can't get address to send to\n");
        return -1;
    }

    /* RFC5953: section 5.2, step 2:
       2)  Extract the tmSessionID, tmTransportDomain, tmTransportAddress,
           tmSecurityName, tmRequestedSecurityLevel, and tmSameSecurity
           values from the tmStateReference.  Note: The tmSessionID value
           may be undefined if no session exists yet over which the message
           can be sent.
    */
    /* Implementation notes:
       - we use the t->data memory pointer as the session ID
       - the transport domain is already the correct type if we got here
       - if we don't have a session yet (eg, no tmSessionID from the
         specs) then we create one automatically here.
    */
    if (opaque != NULL && *opaque != NULL &&
        olength != NULL && *olength == sizeof(netsnmp_tmStateReference))
        tmStateRef = (netsnmp_tmStateReference *) *opaque;


    /* RFC5953: section 5.2, step 3:
       3)  If tmSameSecurity is true and either tmSessionID is undefined or
           refers to a session that is no longer open then increment the
           snmpTlstmSessionNoSessions counter, discard the message and
           return the error indication in the statusInformation.  Processing
           of this message stops.
    */
    /* RFC5953: section 5.2, step 4:
       4)  If tmSameSecurity is false and tmSessionID refers to a session
           that is no longer available then an implementation SHOULD open a
           new session using the openSession() ASI (described in greater
           detail in step 5b).  Instead of opening a new session an
           implementation MAY return a snmpTlstmSessionNoSessions error to
           the calling module and stop processing of the message.
    */
    /* Implementation Notes:
       - We would never get here if the sessionID was different.  We
         tie packets directly to the transport object and it could
         never be sent back over a different transport, which is what
         the above text is trying to prevent.
       - Auto-connections are handled higher in the Net-SNMP library stack
     */

    /* RFC5953: section 5.2, step 5:
       5)  If tmSessionID is undefined, then use tmTransportDomain,
           tmTransportAddress, tmSecurityName and tmRequestedSecurityLevel
           to see if there is a corresponding entry in the LCD suitable to
           send the message over.

           5a)  If there is a corresponding LCD entry, then this session
                will be used to send the message.

           5b)  If there is no corresponding LCD entry, then open a session
                using the openSession() ASI (discussed further in
                Section 5.3.1).  Implementations MAY wish to offer message
                buffering to prevent redundant openSession() calls for the
                same cache entry.  If an error is returned from
                openSession(), then discard the message, discard the
                tmStateReference, increment the snmpTlstmSessionOpenErrors,
                return an error indication to the calling module and stop
                processing of the message.
    */

    /* we're always a client if we're sending to something unknown yet */
    if (NULL ==
        (cachep = find_or_create_bio_cache(t, &addr_pair->remote_addr,
                                           WE_ARE_CLIENT))) {
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
        return -1;
    }

    tlsdata = cachep->tlsdata;
    if (NULL == tlsdata || NULL == tlsdata->ssl) {
        /** xxx mem lean? free created bio cache? */
        snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONNOSESSIONS);
        snmp_log(LOG_ERR, "bad tls data or ssl ptr in netsnmp_dtlsudp_send\n");
        return -1;
    }
        
    if (!tlsdata->securityName && tmStateRef &&
	tmStateRef->securityNameLen > 0) {
        tlsdata->securityName = strdup(tmStateRef->securityName);
    }

    /* see if we have previous outgoing data to send */
    if (cachep->write_cache) {
        if (SNMPERR_GENERR == _netsnmp_bio_try_and_write_buffered(t, cachep)) {
            /* we still have data that can't get out in the buffer */

            /* add the new data to the end of the existing cache */
            if (_netsnmp_add_buffered_data(cachep, buf, size) !=
                SNMPERR_SUCCESS) {
                /* XXX: free and close */
            }
            return -1;
        }
    }

    DEBUGIF ("9:dtlsudp") {
        char *str = t->base_transport->f_fmtaddr(t, (void *) addr_pair,
                                        sizeof(netsnmp_indexed_addr_pair));
        DEBUGMSGTL(("9:dtlsudp", "send %d bytes from %p to %s on fd %d\n",
                    size, buf, str, t->sock));
        free(str);
    }

    /* RFC5953: section 5.2, step 6:
       6)  Using either the session indicated by the tmSessionID if there
           was one or the session resulting from a previous step (4 or 5),
           pass the outgoingMessage to (D)TLS for encapsulation and
           transmission.
    */
    rc = SSL_write(tlsdata->ssl, buf, size);

    while (rc == -1) {
        int bytesout;
        int errnum = SSL_get_error(tlsdata->ssl, rc);

        /* don't treat want_read/write errors as real errors */
        if (errnum != SSL_ERROR_WANT_READ &&
            errnum != SSL_ERROR_WANT_WRITE) {
            DEBUGMSGTL(("dtlsudp", "ssl_write error\n")); 
            _openssl_log_error(rc, tlsdata->ssl, "SSL_write");
            break;
        }

        /* check to see if we have outgoing DTLS packets to send */
        /* (SSL_read could have created DTLS control packets) */ 
        bytesout = _netsnmp_send_queued_dtls_pkts(t, cachep);

        /* If want_read/write but failed to actually send
           anything then we need to wait for the other side,
           so quit */
        if ((errnum == SSL_ERROR_WANT_READ ||
             errnum == SSL_ERROR_WANT_WRITE) &&
            bytesout <= 0) {
            /* We need more data written to or read from the socket
               but we're failing to do so and need to wait till the
               socket is ready again; unfortunately this means we need
               to buffer the SNMP data temporarily in the mean time */

            /* remember the packet */
            if (_netsnmp_add_buffered_data(cachep, buf, size) !=
                SNMPERR_SUCCESS) {

                /* XXX: free and close */
                return -1;
            }

            /* exit out of the loop until we get caled again from
               socket data */ 
            break;
        }
        DEBUGMSGTL(("9:dtlsudp", "recalling ssl_write\n")); 
        rc = SSL_write(tlsdata->ssl, buf, size);
    }

    if (rc > 0)
        cachep->msgnum++;

    /* for memory bios, we now read from openssl's write buffer (ie,
       the packet to go out) and send it out the udp port manually */
    rc = BIO_read(cachep->write_bio, outbuf, sizeof(outbuf));
    if (rc <= 0) {
        /* in theory an ok thing */
        return 0;
    }
    socksize = netsnmp_sockaddr_size(&cachep->sas.sa);
    sa = &cachep->sas.sa;
    rc = t->base_transport->f_send(t, outbuf, rc, (void**)&sa, &socksize);

    return rc;
}



static int
netsnmp_dtlsudp_close(netsnmp_transport *t)
{
    /* XXX: issue a proper dtls closure notification(s) */

    bio_cache *cachep = NULL;
    _netsnmpTLSBaseData *tlsbase = NULL;

    DEBUGTRACETOK("9:dtlsudp");

    DEBUGMSGTL(("dtlsudp:close", "closing dtlsudp transport %p\n", t));

    /* RFC5953: section 5.4, step 1:
        1)  Increment either the snmpTlstmSessionClientCloses or the
            snmpTlstmSessionServerCloses counter as appropriate.
    */
    snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONCLIENTCLOSES);

    /* RFC5953: section 5.4, step 2:
        2)  Look up the session using the tmSessionID.
    */
    /* Implementation notes:
       + Our session id is stored as the t->data pointer
    */
    if (NULL != t->data && t->data_length == sizeof(_netsnmpTLSBaseData)) {
        tlsbase = (_netsnmpTLSBaseData *) t->data;

        if (tlsbase->addr)
            cachep = find_bio_cache(&tlsbase->addr->remote_addr);
    }

    /* RFC5953: section 5.4, step 3:
        3)  If there is no open session associated with the tmSessionID, then
            closeSession processing is completed.
    */
    if (NULL == cachep)
        return netsnmp_socketbase_close(t);

    /* if we have any remaining packtes to send, try to send them */
    if (cachep->write_cache_len > 0) {
        int i = 0;
        char buf[8192];
        int rc;
        void *opaque = NULL;
        int opaque_len = 0;
        fd_set readfs;
        struct timeval tv;
 
        DEBUGMSGTL(("dtlsudp:close",
		    "%" NETSNMP_PRIz "d bytes remain in write_cache\n",
                    cachep->write_cache_len));
 
        /*
         * if negotiations have completed and we've received data, try and
         * send any queued packets.
         */
        if (cachep->flags & NETSNMP_BIO_CONNECTED) {
            /* make configurable:
               - do this at all?
               - retries
               - timeout
            */
            for (i = 0; i < 6 && cachep->write_cache_len != 0; ++i) {

                /* first see if we can send out what we have */
                _netsnmp_bio_try_and_write_buffered(t, cachep);
                if (cachep->write_cache_len == 0)
                    break;
 
                /* if we've failed that, we probably need to wait for packets */
                FD_ZERO(&readfs);
                FD_SET(t->sock, &readfs);
                tv.tv_sec = 0;
                tv.tv_usec = 50000;
                rc = select(t->sock+1, &readfs, NULL, NULL, &tv);
                if (rc > 0) {
                    /* junk recv for catching negotations still in play */
                    opaque_len = 0;
                    netsnmp_dtlsudp_recv(t, buf, sizeof(buf),
                                         &opaque, &opaque_len);
                    SNMP_FREE(opaque);
                }
            } /* for loop */
        }

        /** dump anything that wasn't sent */
        if (cachep->write_cache_len > 0) {
            DEBUGMSGTL(("dtlsudp:close",
			"dumping %" NETSNMP_PRIz "d bytes from write_cache\n",
                        cachep->write_cache_len));
            SNMP_FREE(cachep->write_cache);
            cachep->write_cache_len = 0;
        }
    }

    /* RFC5953: section 5.4, step 4:
        4)  Have (D)TLS close the specified connection.  This MUST include
            sending a close_notify TLS Alert to inform the other side that
            session cleanup may be performed.
    */
    if (NULL != cachep->tlsdata && NULL != cachep->tlsdata->ssl) {

        DEBUGMSGTL(("dtlsudp:close", "closing SSL socket\n"));
        SSL_shutdown(cachep->tlsdata->ssl);

        /* send the close_notify we maybe generated in step 4 */
        if (BIO_ctrl_pending(cachep->write_bio) > 0)
            _netsnmp_send_queued_dtls_pkts(t, cachep);
    }

    remove_and_free_bio_cache(cachep);

    return netsnmp_socketbase_close(t);
}

char *
netsnmp_dtlsudp_fmtaddr(netsnmp_transport *t, void *data, int len)
{
    int              sa_len;
    struct sockaddr *sa = _find_remote_sockaddr(t, data, len, &sa_len);
    if (sa) {
        data = sa;
        len = sa_len;
    }

    return netsnmp_ipv4_fmtaddr("DTLSUDP", t, data, len);
}

/*
 * Open a DTLS-based transport for SNMP.  Local is TRUE if addr is the local
 * address to bind to (i.e. this is a server-type session); otherwise addr is 
 * the remote address to send things to.  
 */

static netsnmp_transport *
_transport_common(netsnmp_transport *t, int local)
{
    char *tmp = NULL;
    int tmp_len;

    DEBUGTRACETOK("9:dtlsudp");

    if (NULL == t)
        return NULL;

    /** save base transport for clients; need in send/recv functions later */
    if (t->data) { /* don't copy data */
        tmp = t->data;
        tmp_len = t->data_length;
        t->data = NULL;
    }
    t->base_transport = netsnmp_transport_copy(t);

    if (tmp) {
        t->data = tmp;
        t->data_length = tmp_len;
    }
    if (NULL != t->data &&
        t->data_length == sizeof(netsnmp_indexed_addr_pair)) {
        _netsnmpTLSBaseData *tlsdata =
            netsnmp_tlsbase_allocate_tlsdata(t, local);
        tlsdata->addr = t->data;
        t->data = tlsdata;
        t->data_length = sizeof(_netsnmpTLSBaseData);
    }

    /*
     * Set Domain
     */
    t->domain = netsnmpDTLSUDPDomain;                                     
    t->domain_length = netsnmpDTLSUDPDomain_len;     

    t->f_recv          = netsnmp_dtlsudp_recv;
    t->f_send          = netsnmp_dtlsudp_send;
    t->f_close         = netsnmp_dtlsudp_close;
    t->f_config        = netsnmp_tlsbase_config;
    t->f_setup_session = netsnmp_tlsbase_session_init;
    t->f_accept        = NULL;
    t->f_fmtaddr       = netsnmp_dtlsudp_fmtaddr;

    t->flags = NETSNMP_TRANSPORT_FLAG_TUNNELED;

    return t;
}

netsnmp_transport *
netsnmp_dtlsudp_transport(struct sockaddr_in *addr, int local)
{
    netsnmp_transport *t = NULL;

    DEBUGTRACETOK("dtlsudp");

    t = netsnmp_udp_transport(addr, local);
    if (NULL == t)
        return NULL;

    _transport_common(t, local);

    if (!local) {
        /* dtls needs to bind the socket for SSL_write to work */
        if (connect(t->sock, (struct sockaddr *) addr, sizeof(*addr)) == -1)
            snmp_log(LOG_ERR, "dtls: failed to connect\n");
    }

    return t;
}


#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN

char *
netsnmp_dtlsudp6_fmtaddr(netsnmp_transport *t, void *data, int len)
{
    int              sa_len;
    struct sockaddr *sa = _find_remote_sockaddr(t, data, len, &sa_len);
    if (sa) {
        data = sa;
        len = sa_len;
    }

    return netsnmp_ipv6_fmtaddr("DTLSUDP6", t, data, len);
}

/*
 * Open a DTLS-based transport for SNMP.  Local is TRUE if addr is the local
 * address to bind to (i.e. this is a server-type session); otherwise addr is 
 * the remote address to send things to.  
 */

netsnmp_transport *
netsnmp_dtlsudp6_transport(struct sockaddr_in6 *addr, int local)
{
    netsnmp_transport *t = NULL;

    DEBUGTRACETOK("dtlsudp");

    t = netsnmp_udp6_transport(addr, local);
    if (NULL == t)
        return NULL;

    _transport_common(t, local);

    if (!local) {
        /* dtls needs to bind the socket for SSL_write to work */
        if (connect(t->sock, (struct sockaddr *) addr, sizeof(*addr)) == -1)
            snmp_log(LOG_ERR, "dtls: failed to connect\n");
    }

    /* XXX: Potentially set sock opts here (SO_SNDBUF/SO_RCV_BUF) */      
    /* XXX: and buf size */        

    t->f_fmtaddr       = netsnmp_dtlsudp6_fmtaddr;

    return t;
}
#endif


netsnmp_transport *
netsnmp_dtlsudp_create_tstring(const char *str, int isserver,
                               const char *default_target)
{
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    struct sockaddr_in6 addr6;
#endif
    struct sockaddr_in addr;
    netsnmp_transport *t;
    _netsnmpTLSBaseData *tlsdata;
    char buf[SPRINT_MAX_LEN], *cp;

    if (netsnmp_sockaddr_in2(&addr, str, default_target))
        t = netsnmp_dtlsudp_transport(&addr, isserver);
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    else if (netsnmp_sockaddr_in6_2(&addr6, str, default_target))
        t = netsnmp_dtlsudp6_transport(&addr6, isserver);
#endif
    else
        return NULL;


    /* see if we can extract the remote hostname */
    if (!isserver && t && t->data && str) {
        tlsdata = (_netsnmpTLSBaseData *) t->data;
        /* search for a : */
        if (NULL != (cp = strrchr(str, ':'))) {
            sprintf(buf, "%.*s", (int) SNMP_MIN(cp - str, sizeof(buf) - 1),
                    str);
        } else {
            /* else the entire spec is a host name only */
            strlcpy(buf, str, sizeof(buf));
        }
        tlsdata->their_hostname = strdup(buf);
    }
    return t;
}


netsnmp_transport *
netsnmp_dtlsudp_create_ostring(const u_char * o, size_t o_len, int local)
{
    struct sockaddr_in addr;

    if (o_len == 6) {
        unsigned short porttmp = (o[4] << 8) + o[5];
        addr.sin_family = AF_INET;
        memcpy((u_char *) & (addr.sin_addr.s_addr), o, 4);
        addr.sin_port = htons(porttmp);
        return netsnmp_dtlsudp_transport(&addr, local);
    }
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    else if (o_len == 18) {
        struct sockaddr_in6 addr6;
        unsigned short porttmp = (o[16] << 8) + o[17];
        addr6.sin6_family = AF_INET6;
        memcpy((u_char *) & (addr6.sin6_addr.s6_addr), o, 4);
        addr6.sin6_port = htons(porttmp);
        return netsnmp_dtlsudp6_transport(&addr6, local);
    }
#endif
    return NULL;
}

void
netsnmp_dtlsudp_ctor(void)
{
    char indexname[] = "_netsnmp_addr_info";
    static const char *prefixes[] = { "dtlsudp", "dtls"
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
                                      , "dtlsudp6", "dtls6"
#endif
    };
    int i, num_prefixes = sizeof(prefixes) / sizeof(char *);
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    char indexname6[] = "_netsnmp_addr_info6";
#endif

    DEBUGMSGTL(("dtlsudp", "registering DTLS constructor\n"));

    /* config settings */

#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    if (!openssl_addr_index6)
        openssl_addr_index6 =
            SSL_get_ex_new_index(0, indexname6, NULL, NULL, NULL);
#endif

    dtlsudpDomain.name = netsnmpDTLSUDPDomain;
    dtlsudpDomain.name_length = netsnmpDTLSUDPDomain_len;
    dtlsudpDomain.prefix = (const char**)calloc(num_prefixes + 1,
                                                sizeof(char *));
    for (i = 0; i < num_prefixes; ++ i)
        dtlsudpDomain.prefix[i] = prefixes[i];

    dtlsudpDomain.f_create_from_tstring     = NULL;
    dtlsudpDomain.f_create_from_tstring_new = netsnmp_dtlsudp_create_tstring;
    dtlsudpDomain.f_create_from_ostring     = netsnmp_dtlsudp_create_ostring;

    if (!openssl_addr_index)
        openssl_addr_index =
            SSL_get_ex_new_index(0, indexname, NULL, NULL, NULL);

    netsnmp_tdomain_register(&dtlsudpDomain);
}

/*
 * Much of the code below was taken from the OpenSSL example code
 * and is subject to the OpenSSL copyright.
 */
#define	NETSNMP_COOKIE_SECRET_LENGTH	16
int cookie_initialized=0;
unsigned char cookie_secret[NETSNMP_COOKIE_SECRET_LENGTH];

typedef union {
       struct sockaddr sa;
       struct sockaddr_in s4;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
       struct sockaddr_in6 s6;
#endif
} _peer_union;

int netsnmp_dtls_gen_cookie(SSL *ssl, unsigned char *cookie,
                            unsigned int *cookie_len)
{
    unsigned char *buffer, result[EVP_MAX_MD_SIZE];
    unsigned int length, resultlength;
    bio_cache *cachep = NULL;
    _peer_union *peer;

    /* Initialize a random secret */
    if (!cookie_initialized) {
        if (!RAND_bytes(cookie_secret, NETSNMP_COOKIE_SECRET_LENGTH)) {
            snmp_log(LOG_ERR, "dtls: error setting random cookie secret\n");
            return 0;
        }
        cookie_initialized = 1;
    }

    DEBUGMSGT(("dtlsudp:cookie", "generating cookie...\n"));

    /* Read peer information */
    cachep = SSL_get_ex_data(ssl, openssl_addr_index);
    if (!cachep) {
        snmp_log(LOG_ERR, "dtls: failed to get the peer address\n");
        return 0;
    }
    peer = (_peer_union *)&cachep->sas;

    /* Create buffer with peer's address and port */
    length = 0;
    switch (peer->sa.sa_family) {
    case AF_INET:
        length += sizeof(struct in_addr);
        length += sizeof(peer->s4.sin_port);
        break;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    case AF_INET6:
        length += sizeof(struct in6_addr);
        length += sizeof(peer->s6.sin6_port);
        break;
#endif
    default:
        snmp_log(LOG_ERR, "dtls generating cookie: unknown family: %d\n",
                 peer->sa.sa_family);
        return 0;
    }
    buffer = malloc(length);
    if (buffer == NULL) {
        snmp_log(LOG_ERR,"dtls: out of memory\n");
        return 0;
    }

    switch (peer->sa.sa_family) {
    case AF_INET:
        memcpy(buffer,
               &peer->s4.sin_port,
               sizeof(peer->s4.sin_port));
        memcpy(buffer + sizeof(peer->s4.sin_port),
               &peer->s4.sin_addr,
               sizeof(struct in_addr));
        break;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    case AF_INET6:
        memcpy(buffer,
               &peer->s6.sin6_port,
               sizeof(peer->s6.sin6_port));
        memcpy(buffer + sizeof(peer->s6.sin6_port),
               &peer->s6.sin6_addr,
               sizeof(struct in6_addr));
        break;
#endif
    default:
        snmp_log(LOG_ERR, "dtls: unknown address family generating a cookie\n");
        return 0;
    }

    /* Calculate HMAC of buffer using the secret */
    HMAC(EVP_sha1(), cookie_secret, NETSNMP_COOKIE_SECRET_LENGTH,
         buffer, length, result, &resultlength);
    OPENSSL_free(buffer);

    memcpy(cookie, result, resultlength);
    *cookie_len = resultlength;

    DEBUGMSGT(("9:dtlsudp:cookie", "generated %d byte cookie\n", *cookie_len));

    return 1;
}

int netsnmp_dtls_verify_cookie(SSL *ssl, unsigned char *cookie,
                               unsigned int cookie_len)
{
    unsigned char *buffer, result[EVP_MAX_MD_SIZE];
    unsigned int length, resultlength, rc;
    bio_cache *cachep = NULL;
    _peer_union *peer;

    /* If secret isn't initialized yet, the cookie can't be valid */
    if (!cookie_initialized)
        return 0;

    DEBUGMSGT(("9:dtlsudp:cookie", "verifying %d byte cookie\n", cookie_len));

    cachep = SSL_get_ex_data(ssl, openssl_addr_index);
    if (!cachep) {
        snmp_log(LOG_ERR, "dtls: failed to get the peer address\n");
        return 0;
    }
    peer = (_peer_union *)&cachep->sas;

    /* Create buffer with peer's address and port */
    length = 0;
    switch (peer->sa.sa_family) {
    case AF_INET:
        length += sizeof(struct in_addr);
        length += sizeof(peer->s4.sin_port);
        break;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    case AF_INET6:
        length += sizeof(struct in6_addr);
        length += sizeof(peer->s6.sin6_port);
        break;
#endif
    default:
        snmp_log(LOG_ERR,
                 "dtls: unknown address family %d generating a cookie\n",
                 peer->sa.sa_family);
        return 0;
    }
    buffer = malloc(length);
    if (buffer == NULL) {
        snmp_log(LOG_ERR, "dtls: unknown address family generating a cookie\n");
        return 0;
    }

    switch (peer->sa.sa_family) {
    case AF_INET:
        memcpy(buffer,
               &peer->s4.sin_port,
               sizeof(peer->s4.sin_port));
        memcpy(buffer + sizeof(peer->s4.sin_port),
               &peer->s4.sin_addr,
               sizeof(struct in_addr));
        break;
#ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
    case AF_INET6:
        memcpy(buffer,
               &peer->s6.sin6_port,
               sizeof(peer->s6.sin6_port));
        memcpy(buffer + sizeof(peer->s6.sin6_port),
               &peer->s6.sin6_addr,
               sizeof(struct in6_addr));
        break;
#endif
    default:
        snmp_log(LOG_ERR,
                 "dtls: unknown address family %d generating a cookie\n",
                 peer->sa.sa_family);
        return 0;
    }

    /* Calculate HMAC of buffer using the secret */
    HMAC(EVP_sha1(), cookie_secret, NETSNMP_COOKIE_SECRET_LENGTH,
         buffer, length, result, &resultlength);
    OPENSSL_free(buffer);

    if (cookie_len != resultlength || memcmp(result, cookie, resultlength) != 0)
        rc = 0;
    else {
        rc = 1;
        cachep->flags |= NETSNMP_BIO_HAVE_COOKIE;
    }

    DEBUGMSGT(("dtlsudp:cookie", "verify cookie: %d\n", rc));

    return rc;
}

#endif /* HAVE_LIBSSL_DTLS */
