/*
 * Note: this file originally auto-generated by mib2c using
 *  $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <net-snmp/library/cert_util.h>
#include "tlstm-mib.h"
#include "snmpTlstmAddrTable.h"

/** XXX - move these to table_data header? */
#define FATE_NEWLY_CREATED    1
#define FATE_NO_CHANGE        0
#define FATE_DELETE_ME        -1

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
    /*
     * structure for undo storage and other vars for set processing 
     */
typedef struct tlstmAddrTable_undo_s {
    char            fate;
    char            copied;
    char            is_consistent;
    netsnmp_request_info *req[TLSTMADDRTABLE_MAX_COLUMN + 1];
    /*
     * undo Column space 
     */
    char       tlstmAddrServerFingerprint[TLSTMADDRSERVERFINGERPRINT_MAX_SIZE];
    size_t          tlstmAddrServerFingerprint_len;
    char            tlstmAddrServerIdentity[TLSTMADDRSERVERIDENTITY_MAX_SIZE];
    size_t          tlstmAddrServerIdentity_len;
    char            tlstmAddrStorageType;
    char            tlstmAddrRowStatus;
    char            hashType;
} tlstmAddrTable_undo;

    /*
     * Typical data structure for a row entry 
     */
typedef struct tlstmAddrTable_entry_s {
    /*
     * Index values 
     */
    char            snmpTargetAddrName[SNMPTARGETADDRNAME_MAX_SIZE];
    size_t          snmpTargetAddrName_len;

    /*
     * Column values 
     */
    char        tlstmAddrServerFingerprint[TLSTMADDRSERVERFINGERPRINT_MAX_SIZE];
    size_t          tlstmAddrServerFingerprint_len;
    char            tlstmAddrServerIdentity[TLSTMADDRSERVERIDENTITY_MAX_SIZE];
    size_t          tlstmAddrServerIdentity_len;
    char            tlstmAddrStorageType;
    char            tlstmAddrRowStatus;
    char            hashType;

    /*
     * used during set processing 
     */
    tlstmAddrTable_undo *undo;

    /*
     * user data
     */
    struct netsnmp_cert_s   *cert;
    char                     addr_flags;

} tlstmAddrTable_entry;

netsnmp_tdata_row *tlstmAddrTable_createEntry(netsnmp_tdata * table_data,
                                              char *snmpTargetAddrName,
                                              size_t snmpTargetAddrName_len);
void tlstmAddrTable_removeEntry(netsnmp_tdata * table_data,
                                netsnmp_tdata_row * row);

static Netsnmp_Node_Handler tlstmAddrTable_handler;
static int _cache_load(netsnmp_cache *cache, netsnmp_tdata *table);
static void _cache_free(netsnmp_cache *cache, netsnmp_tdata *table);
static uint32_t _last_changed = 0;
static int _count_handler(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info *reqinfo,
                          netsnmp_request_info *requests);

static void _tlstmAddr_init_persistence(void);
static void _addrs_add(tlstmAddrTable_entry *entry);
static void _addrs_remove(tlstmAddrTable_entry *entry);
static void _addr_tweak_storage(tlstmAddrTable_entry *entry);
static netsnmp_tdata  *_table_data = NULL;

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
/** Initializes the tlstmAddrTable module */
void
init_snmpTlstmAddrTable(void)
{
    oid             reg_oid[] = { SNMP_TLS_TM_ADDR_TABLE };
    const size_t    reg_oid_len = OID_LENGTH(reg_oid);
    netsnmp_handler_registration *reg;
    netsnmp_table_registration_info *table_info;
    netsnmp_cache                   *cache;
    netsnmp_watcher_info            *watcher;

    DEBUGMSGTL(("tlstmAddrTable:init",
                "initializing table tlstmAddrTable\n"));

    reg =
        netsnmp_create_handler_registration("tlstmAddrTable",
                                            tlstmAddrTable_handler,
                                            reg_oid, reg_oid_len,
                                            HANDLER_CAN_RWRITE);

    _table_data = netsnmp_tdata_create_table("tlstmAddrTable", 0);
    if (NULL == _table_data) {
        snmp_log(LOG_ERR, "error creating tdata table for tlstmAddrTable\n");
        return;
    }
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR, "error creating table info for tlstmAddrTable\n");
        netsnmp_tdata_delete_table(_table_data);
        _table_data = NULL;
        return;
    }

    /*
     * cache init
     */
    cache = netsnmp_cache_create(30, (NetsnmpCacheLoad*)_cache_load,
                                 (NetsnmpCacheFree*)_cache_free,
                                 reg_oid, reg_oid_len);
    if (NULL == cache) {
        snmp_log(LOG_ERR,"error creating cache for tlstmCertToTSNTable\n");
        netsnmp_tdata_delete_table(_table_data);
        _table_data = NULL;
        return;
    }
    cache->magic = (void *)_table_data;
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    /*
     * populate index types
     */
    netsnmp_table_helper_add_indexes(table_info,
                                     /* index: snmpTargetAddrName */
                                     ASN_PRIV_IMPLIED_OCTET_STR, 
                                     0);

    table_info->min_column = TLSTMADDRTABLE_MIN_COLUMN;
    table_info->max_column = TLSTMADDRTABLE_MAX_COLUMN;

    netsnmp_tdata_register(reg, _table_data, table_info);

    if (cache) 
        netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get(cache),
                                       "table_container");

    /*
     * register scalars
     */
    reg_oid[10] = 7;
    reg = netsnmp_create_handler_registration("snmpTlstmAddrCount",
                                              _count_handler, reg_oid,
                                              OID_LENGTH(reg_oid),
                                              HANDLER_CAN_RONLY);
    if (NULL == reg)
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmAddrCount\n");
    else {
        netsnmp_register_scalar(reg);
        if (cache) 
            netsnmp_inject_handler_before(reg,
                                          netsnmp_cache_handler_get(cache),
                                          "snmpTlstmAddrCount");
    }
    
    reg_oid[10] = 8;
    reg = netsnmp_create_handler_registration(
        "snmpTlstmAddrTableLastChanged", NULL, reg_oid,
        OID_LENGTH(reg_oid), HANDLER_CAN_RONLY);
    watcher = netsnmp_create_watcher_info((void*)&_last_changed,
                                          sizeof(_last_changed),
                                          ASN_TIMETICKS,
                                          WATCHER_FIXED_SIZE);
    if ((NULL == reg) || (NULL == watcher))
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmAddrTableLastChanged\n");
    else
        netsnmp_register_watched_scalar(reg, watcher);

    /*
     * Initialise the contents of the table here 
     */
    _tlstmAddr_init_persistence();
}

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
/*
 * create a new row in the table 
 */
netsnmp_tdata_row *
tlstmAddrTable_createEntry(netsnmp_tdata * table_data,
                           char *snmpTargetAddrName,
                           size_t snmpTargetAddrName_len)
{
    tlstmAddrTable_entry *entry;
    netsnmp_tdata_row *row;

    if (snmpTargetAddrName_len > sizeof(entry->snmpTargetAddrName))
        return NULL;

    entry = SNMP_MALLOC_TYPEDEF(tlstmAddrTable_entry);
    if (!entry)
        return NULL;

    row = netsnmp_tdata_create_row();
    if (!row) {
        SNMP_FREE(entry);
        return NULL;
    }
    row->data = entry;

    DEBUGIF("tlstmAddrTable:entry:create") {
        char name[sizeof(entry->snmpTargetAddrName)+1];
        snprintf(name, sizeof(name), "%s", snmpTargetAddrName);
        DEBUGMSGT(("tlstmAddrTable:entry:create", "entry %s %p / row %p\n",
                   name, entry, row));
    }

    /*
     * populate index
     */
    memcpy(entry->snmpTargetAddrName, snmpTargetAddrName,
           snmpTargetAddrName_len);
    entry->snmpTargetAddrName_len = snmpTargetAddrName_len;
    netsnmp_tdata_row_add_index(row, ASN_PRIV_IMPLIED_OCTET_STR,
                                entry->snmpTargetAddrName,
                                snmpTargetAddrName_len);

    /*
     * defaults
     */
    entry->tlstmAddrServerFingerprint[0] = '\0';
    entry->tlstmAddrServerFingerprint_len = 0;
    entry->hashType = 0;
    entry->tlstmAddrServerIdentity[0] = '\0';
    entry->tlstmAddrServerIdentity_len = 0;
    entry->tlstmAddrStorageType = ST_NONVOLATILE;
    entry->tlstmAddrRowStatus = RS_NOTREADY;

    if (table_data) {
        DEBUGMSGTL(("tlstmAddrTable:row:insert", "row %p\n",row));
        netsnmp_tdata_add_row(table_data, row);
    }
    return row;
}

/*
 * allocate undo resources 
 */
static tlstmAddrTable_undo *
_allocUndo(tlstmAddrTable_entry * entry)
{
    if (!entry)
        return NULL;

    entry->undo = SNMP_MALLOC_TYPEDEF(tlstmAddrTable_undo);
    if (!entry->undo)
        return NULL;

    entry->undo->is_consistent = -1;    /* don't know */

    return entry->undo;
}

/*
 * free undo resources 
 */
static void
_freeUndo(tlstmAddrTable_entry * entry)
{
    if (!entry || !entry->undo)
        return;

    SNMP_FREE(entry->undo);
}

/*
 * remove a row from the table 
 */
void
tlstmAddrTable_removeEntry(netsnmp_tdata * table_data,
                           netsnmp_tdata_row * row)
{
    tlstmAddrTable_entry *entry;

    if (!row)
        return;                 /* Nothing to remove */

    entry = (tlstmAddrTable_entry *) row->data;

    if (table_data) {
        DEBUGMSGTL(("tlstmAddrTable:row:remove", "row %p\n",row));
        netsnmp_tdata_remove_and_delete_row(table_data, row);
    }
    else
        netsnmp_tdata_delete_row(row);

    DEBUGIF("tlstmAddrTable:entry:delete") {
        char name[sizeof(entry->snmpTargetAddrName)+1];
        snprintf(name, sizeof(name), "%s", entry->snmpTargetAddrName);
        DEBUGMSGT(("tlstmAddrTable:entry:delete", "entry %s %p / row %p\n",
                   name, entry, row));
    }
    if (entry && entry->undo)
        _freeUndo(entry);
    SNMP_FREE(entry);
}


/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
/** handles requests for the tlstmAddrTable table */
static int
tlstmAddrTable_handler(netsnmp_mib_handler *handler,
                       netsnmp_handler_registration *reginfo,
                       netsnmp_agent_request_info *reqinfo,
                       netsnmp_request_info *requests)
{

    netsnmp_request_info *request = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_tdata  *table_data;
    netsnmp_tdata_row *table_row;
    tlstmAddrTable_entry *table_entry;
    int             ret = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("tlstmAddrTable:handler", "Processing mode %s (%d) request\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode),
                reqinfo->mode));

    switch (reqinfo->mode) {
    /** ######################################################### GET #####
     *
     *   Read-support (also covers GetNext requests)
     */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            table_entry = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_info = netsnmp_extract_table_info(request);
            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
            {
                u_char bin[42], *ptr = bin;
                size_t len = sizeof(bin), offset = 1;
                int    rc;

                if ((table_entry->hashType == 0) ||
                    (table_entry->tlstmAddrServerFingerprint_len ==0))
                    offset = 0;
                else {
                    bin[0] = table_entry->hashType;
                    rc = netsnmp_hex_to_binary(
                        &ptr, &len, &offset, 0,
                        table_entry->tlstmAddrServerFingerprint, NULL);
                    if (1 != rc)
                        ret = SNMP_ERR_GENERR;
                }
                if (ret == SNMP_ERR_NOERROR)
                    snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                             bin, offset);
            }
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                snmp_set_var_typed_value
                    (request->requestvb, ASN_OCTET_STR,
                     (u_char *) table_entry->tlstmAddrServerIdentity,
                     table_entry->tlstmAddrServerIdentity_len);
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->tlstmAddrStorageType);
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->tlstmAddrRowStatus);
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                break;
            }                   /* switch colnum */
        }                       /* for requests */
        break;                  /* case MODE_GET */

        /*
         * Write-support
         */
    /** #################################################### RESERVE1 #####
     *
     *   In RESERVE1 we are just checking basic ASN.1 size/type restrictions.
     * You probably don't need to change any of this code. Don't change any
     * of the column values here. Save that for the ACTION phase.
     *
     *   The next phase is RESERVE2 or FREE.
     */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            table_entry = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_info = netsnmp_extract_table_info(request);

            if ((NULL != table_entry) &&
                (ST_READONLY == table_entry->tlstmAddrStorageType)) {
                ret = SNMP_ERR_NOTWRITABLE;
                break;
            }

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR,
                     sizeof(table_entry->tlstmAddrServerFingerprint));
                /** check len/algorithm MIB requirements */
                if (ret == SNMP_ERR_NOERROR)
                    ret = netsnmp_cert_check_vb_fingerprint(request->requestvb);
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR,
                     sizeof(table_entry->tlstmAddrServerIdentity));
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                ret = netsnmp_check_vb_storagetype
                    (request->requestvb,
                     (table_entry ?
                      table_entry->tlstmAddrStorageType : ST_NONE));
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                ret = netsnmp_check_vb_rowstatus_with_storagetype
                    (request->requestvb,
                     (table_entry ?
                      table_entry->tlstmAddrRowStatus : RS_NONEXISTENT),
                     (table_entry ?
                      table_entry->tlstmAddrStorageType : ST_NONE));
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            default:
                ret = SNMP_ERR_NOTWRITABLE;
            }                   /* switch colnum */

            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* for requests */
        break;                  /* case MODE_SET_RESERVE1 */

    /** #################################################### RESERVE2 #####
     *
     *   RESERVE2 is for checking additional restrictions from the MIB.
     * Since these restrictions are often in the description of the object,
     * mib2c can't generate code. It's possible that you need to add
     * additional checks here. However, don't change any of the column
     * values here. Save that for the ACTION phase.
     *
     *   The next phase is ACTION or FREE.
     */
    case MODE_SET_RESERVE2:
        for (request = requests; request; request = request->next) {
            table_entry = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_data = netsnmp_tdata_extract_table(request);
            table_info = netsnmp_extract_table_info(request);
            /*
             * if no table_row, create one
             */
            if (!table_entry) {
                table_row = tlstmAddrTable_createEntry
                    (table_data, (char*)table_info->indexes->val.string,
                     table_info->indexes->val_len);
                if (!table_row) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                table_entry = table_row->data;
                _allocUndo(table_entry);
                if (table_entry && !table_entry->undo) {
                    tlstmAddrTable_removeEntry(table_data, table_row);
                    table_row = NULL;
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                table_entry->undo->fate = FATE_NEWLY_CREATED;
                /** associate row with requests */
                netsnmp_insert_tdata_row(request, table_row);
            }

            /** allocate undo structure, if needed */
            if (!table_entry->undo) {
                _allocUndo(table_entry);
                if (!table_entry->undo) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
            }

            /** don't allow multiple sets of same column */
            if (table_entry->undo->req[table_info->colnum]) {
                DEBUGMSGT(("tlstmAddrTable:reserve2",
                           "multiple sets to col %d in request\n",
                           table_info->colnum));
                ret = SNMP_ERR_INCONSISTENTNAME;
                break;
            }
            table_entry->undo->req[table_info->colnum] = request;

            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* for requests */

        /** make sure rowstatus is used to create rows */
        if (ret == SNMP_ERR_NOERROR) {
            for (request = requests; request; request = request->next) {
                if (request->processed)
                    continue;

                table_entry = (tlstmAddrTable_entry *)
                    netsnmp_tdata_extract_entry(request);
                if ((table_entry->undo->fate != FATE_NEWLY_CREATED) ||
                    (table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS]))
                    continue;
                ret = SNMP_ERR_INCONSISTENTNAME;
                break;
            }                   /* for requests / creation */
        }                       /* if no error */
        break;                  /* case MODE_SET_RESERVE2 */

    /** ######################################################## FREE #####
     *
     *   FREE is for cleaning up after a failed request (during either
     * RESERVE1 or RESERVE2). So any allocated resources need to be
     * released.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_FREE:
        /*
         * release undo resources,  remove any newly created rows
         */
        for (request = requests; request; request = request->next) {
            table_row = netsnmp_tdata_extract_row(request);
            table_data  =  netsnmp_tdata_extract_table(request);
            table_entry =
                (tlstmAddrTable_entry *) table_row ? table_row->
                data : NULL;

            if (!table_entry || !table_entry->undo)
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row(request, table_row);

            if (FATE_NEWLY_CREATED == table_entry->undo->fate)
                tlstmAddrTable_removeEntry(table_data, table_row);
            else
                _freeUndo(table_entry);
        }
        break;                  /* case MODE_SET_FREE */

    /** ###################################################### ACTION #####
     *
     *   In the ACTION phase, we perform any sets that can be undone.
     * (Save anything that can't be undone for the COMMIT phase.)
     *
     *   After individual columns have been done, you should check that the
     * row as a whole is consistent.
     *
     * The next phase is UNDO or COMMIT.
     */
    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            table_entry = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
            {
                u_char *tmp = (u_char*)table_entry->tlstmAddrServerFingerprint;

                memcpy(table_entry->undo->tlstmAddrServerFingerprint,
                       table_entry->tlstmAddrServerFingerprint,
                       sizeof(table_entry->tlstmAddrServerFingerprint));
                table_entry->undo->tlstmAddrServerFingerprint_len =
                    table_entry->tlstmAddrServerFingerprint_len;
                table_entry->undo->hashType = table_entry->hashType;

                table_entry->hashType = request->requestvb->val.string[0];
                table_entry->tlstmAddrServerFingerprint_len =
                    sizeof(table_entry->tlstmAddrServerFingerprint);
                memset(table_entry->tlstmAddrServerFingerprint, 0,
                       sizeof(table_entry->tlstmAddrServerFingerprint));
                table_entry->tlstmAddrServerFingerprint_len =
                    netsnmp_binary_to_hex(&tmp, &table_entry->tlstmAddrServerFingerprint_len,
                                          0, &request->requestvb->val.string[1],
                                          request->requestvb->val_len - 1);
                if (0 == table_entry->tlstmAddrServerFingerprint_len)
                    ret = SNMP_ERR_GENERR;
            }
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                memcpy(table_entry->undo->tlstmAddrServerIdentity,
                       table_entry->tlstmAddrServerIdentity,
                       sizeof(table_entry->tlstmAddrServerIdentity));
                table_entry->undo->tlstmAddrServerIdentity_len =
                    table_entry->tlstmAddrServerIdentity_len;
                memset(table_entry->tlstmAddrServerIdentity, 0,
                       sizeof(table_entry->tlstmAddrServerIdentity));
                memcpy(table_entry->tlstmAddrServerIdentity,
                       request->requestvb->val.string,
                       request->requestvb->val_len);
                table_entry->tlstmAddrServerIdentity_len =
                    request->requestvb->val_len;
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                table_entry->undo->tlstmAddrStorageType =
                    table_entry->tlstmAddrStorageType;
                table_entry->tlstmAddrStorageType =
                    *request->requestvb->val.integer;
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                table_entry->undo->tlstmAddrRowStatus =
                    table_entry->tlstmAddrRowStatus;
                table_entry->tlstmAddrRowStatus =
                    *request->requestvb->val.integer;
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            }                   /* switch colnum */
            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* set values for requests */

        if (ret == SNMP_ERR_NOERROR) {

            /*
             * All columns now have their final values set. check the
             * internal consistency of each row.
             */
            for (request = requests; request; request = request->next) {
                table_entry = (tlstmAddrTable_entry *)
                    netsnmp_tdata_extract_entry(request);
                table_info = netsnmp_extract_table_info(request);

                if (table_entry->undo->is_consistent != -1)
                    continue;   /* already checked */

                /** assume consistency */
                table_entry->undo->is_consistent = 1;

                /*
                 * per mib, can't have empty fingerprint and wildcard id
                 */
                if ( (0 == table_entry->tlstmAddrServerFingerprint_len) &&
                     (1 == table_entry->tlstmAddrServerIdentity_len) &&
                     ('*' == table_entry->tlstmAddrServerIdentity[0]) ) {
                    DEBUGMSGTL(("tlstmAddrTable", "fingerprint must not "
                                "be empty for wildcard (*) identity\n"));
                    table_entry->undo->is_consistent = 0;
                }
                
                if ((RS_IS_ACTIVE(table_entry->tlstmAddrRowStatus)) &&
                    ((!table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS]) ||
                     (RS_IS_ACTIVE(table_entry->undo->tlstmAddrRowStatus)))) {
                    /*
                     * check mib restrictions on active rows.
                     */
                    if (table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT];
                    }
                    else if (table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERIDENTITY]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERIDENTITY];
                    }
                    else if (table_entry->undo->req[COLUMN_SNMPTLSTMADDRSTORAGETYPE]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRSTORAGETYPE];
                    }
                    
                    if (!table_entry->undo->is_consistent)
                        ret = SNMP_ERR_INCONSISTENTVALUE; /* per mib */
                } /* active row */
                else if (RS_IS_GOING_ACTIVE
                         (table_entry->tlstmAddrRowStatus)) {
                    /** if going active, inconsistency is fatal */
                    if (!table_entry->undo->is_consistent) {
                        if (FATE_NEWLY_CREATED == table_entry->undo->fate)
                            ret = SNMP_ERR_INCONSISTENTNAME;
                        else
                            ret = SNMP_ERR_INCONSISTENTVALUE;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS];
                    }
                } /* going active */
                else if (RS_DESTROY == table_entry->tlstmAddrRowStatus) {
                    /** can't delete active row */
                    if (RS_IS_ACTIVE(table_entry->undo->tlstmAddrRowStatus)) {
                        ret = SNMP_ERR_INCONSISTENTVALUE;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS];
                    }
                }               /* destroy */
                if (ret != SNMP_ERR_NOERROR)
                    break;
            }                   /* consistency for requests */
        }                       /* if no error */
        break;                  /* case MODE_SET_ACTION */

    /** ######################################################## UNDO #####
     *
     *   UNDO is for cleaning up any failed requests that went through the
     * ACTION phase.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_UNDO:
        for (request = requests; request; request = request->next) {
            table_row = netsnmp_tdata_extract_row(request);
            table_entry =
                (tlstmAddrTable_entry *) table_row ? table_row->
                data : NULL;
            table_data = netsnmp_tdata_extract_table(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
                /*
                 * restore tlstmAddrServerFingerprint value 
                 */
                memcpy(table_entry->tlstmAddrServerFingerprint,
                       table_entry->undo->tlstmAddrServerFingerprint,
                       sizeof(table_entry->tlstmAddrServerFingerprint));
                table_entry->tlstmAddrServerFingerprint_len =
                    table_entry->undo->tlstmAddrServerFingerprint_len;
                table_entry->hashType = table_entry->undo->hashType;
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                /*
                 * restore tlstmAddrServerIdentity value 
                 */
                memcpy(table_entry->tlstmAddrServerIdentity,
                       table_entry->undo->tlstmAddrServerIdentity,
                       sizeof(table_entry->tlstmAddrServerIdentity));
                table_entry->tlstmAddrServerIdentity_len =
                    table_entry->undo->tlstmAddrServerIdentity_len;
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                /*
                 * restore tlstmAddrStorageType value 
                 */
                table_entry->tlstmAddrStorageType =
                    table_entry->undo->tlstmAddrStorageType;
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                /*
                 * restore tlstmAddrRowStatus value 
                 */
                table_entry->tlstmAddrRowStatus =
                    table_entry->undo->tlstmAddrRowStatus;
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            }                   /* switch colnum */
        }                       /* for requests */

        /*
         * release undo data
         * or remove any newly created rows
         */
        for (request = requests; request; request = request->next) {
            table_row = netsnmp_tdata_extract_row(request);
            table_entry =
                (tlstmAddrTable_entry *) table_row ? table_row->
                data : NULL;

            if (!table_entry || !table_entry->undo)
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row(request, table_row);

            if (FATE_NEWLY_CREATED == table_entry->undo->fate)
                tlstmAddrTable_removeEntry(table_data, table_row);
            else
                _freeUndo(table_entry);
        }                       /* for requests */
        break;                  /* case MODE_SET_UNDO */

    /** ###################################################### COMMIT #####
     *
     *   COMMIT is the final success state, when all changes are finalized.
     * There is not recovery state should something faile here.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_COMMIT:
        for (request = requests; request; request = request->next) {
            table_row = netsnmp_tdata_extract_row(request);
            table_data = netsnmp_tdata_extract_table(request);
            table_info = netsnmp_extract_table_info(request);
            table_entry = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);

            if (!table_entry || !table_entry->undo)
                continue;

            if ((RS_NOTREADY == table_entry->tlstmAddrRowStatus) &&
                table_entry->undo->is_consistent)
                table_entry->tlstmAddrRowStatus = RS_NOTINSERVICE;
            else if ((RS_NOTINSERVICE == table_entry->tlstmAddrRowStatus) &&
                     (0 == table_entry->undo->is_consistent))
                table_entry->tlstmAddrRowStatus = RS_NOTREADY;

            /** release undo data for requests with no rowstatus */
            if (table_entry->undo &&
                !table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS] != 0) {

                _freeUndo(table_entry);

                /** update active addrs */
                if ((0 == table_entry->addr_flags) &&
                    (table_entry->tlstmAddrRowStatus == RS_ACTIVE))
                    _addrs_add(table_entry);
                else if ((0 != table_entry->addr_flags) &&
                         (table_entry->tlstmAddrRowStatus == RS_DESTROY))
                    _addrs_remove(table_entry);
            }

            switch (table_info->colnum) {
                case COLUMN_SNMPTLSTMADDRROWSTATUS:
                    switch (table_entry->tlstmAddrRowStatus) {
                    case RS_CREATEANDGO:
                    /** Fall-through */
                    case RS_ACTIVE:
                        table_entry->tlstmAddrRowStatus = RS_ACTIVE;
                        if (0 == table_entry->addr_flags)
                            _addrs_add(table_entry);
                        break;

                    case RS_CREATEANDWAIT:
                        /** Fall-through */
                    case RS_NOTINSERVICE:
                        /** simply set status based on consistency */
                        if (table_entry->undo->is_consistent)
                            table_entry->tlstmAddrRowStatus =
                                RS_NOTINSERVICE;
                        else
                            table_entry->tlstmAddrRowStatus = RS_NOTREADY;
                        if (0 != table_entry->addr_flags)
                            _addrs_remove(table_entry);
                        break;

                    case RS_DESTROY:
                        if (0 != table_entry->addr_flags)
                            _addrs_remove(table_entry);
                        /** disassociate row with requests */
                        netsnmp_remove_tdata_row(request, table_row);
                        tlstmAddrTable_removeEntry(table_data, table_row);
                        table_row = NULL;
                        table_entry = NULL;
                    }
                    /** release undo data */
                    _freeUndo(table_entry);
                    break;      /* case COLUMN_SNMPTLSTMADDRROWSTATUS */

                case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                    if (RS_ACTIVE == table_entry->tlstmAddrRowStatus)
                        _addr_tweak_storage(table_entry);
                    break;

                case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
                case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                    break;
                }               /* switch colnum */
        }                       /* for requests */

        /** update last changed */
        _last_changed = netsnmp_get_agent_uptime();

        /** set up to save persistent store */
        snmp_store_needed(NULL);

        break;                  /* case MODE_SET_COMMIT */
    }                           /* switch (reqinfo->mode) */

    if (ret != SNMP_ERR_NOERROR)
        netsnmp_set_request_error(reqinfo, request, ret);

    return SNMP_ERR_NOERROR;
}

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
static int
_count_handler(netsnmp_mib_handler *handler,
               netsnmp_handler_registration *reginfo,
               netsnmp_agent_request_info *reqinfo,
               netsnmp_request_info *requests)
{
    int                val;

    if (MODE_GET != reqinfo->mode) {
        snmp_log(LOG_ERR, "bad mode in RO handler");
        return SNMP_ERR_GENERR;
    }

    if ((NULL == _table_data) || (NULL == _table_data->container))
        val = 0;
    else
        val = CONTAINER_SIZE(_table_data->container);

    snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE,
                             (u_char *) &val, sizeof(val));
   
    if (handler->next && handler->next->access_method)
        return netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                         requests);
    
    return SNMP_ERR_NOERROR;
}

/** **************************************************************************
 *
 * handle cache / interactions with tlstmAddr container in snmplib
 *
 ** *************************************************************************/
static void
_addrs_add(tlstmAddrTable_entry *entry)
{
    netsnmp_container *addrs;
    snmpTlstmAddr     *addr;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmAddrTable:addrs:add", "name %s, fp %s\n",
                entry->snmpTargetAddrName, entry->tlstmAddrServerFingerprint));

    /** get current active addrs */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return;

    addr = netsnmp_tlstmAddr_create(entry->snmpTargetAddrName);
    if (NULL == addr)
        return;

    if (entry->tlstmAddrServerFingerprint_len)
        addr->fingerprint = strdup(entry->tlstmAddrServerFingerprint);
    if (entry->tlstmAddrServerIdentity_len)
        addr->identity = strdup(entry->tlstmAddrServerIdentity);
    addr->hashType = entry->hashType;

    addr->flags = TLSTM_ADDR_FROM_MIB;
    if (entry->tlstmAddrStorageType == ST_NONVOLATILE)
        addr->flags |= TLSTM_ADDR_NONVOLATILE;

    if (CONTAINER_INSERT(addrs, addr) != 0) {
        netsnmp_tlstmAddr_free(addr);
        snmp_log(LOG_ERR, "could not insert new tlstm addr");
    }
}

static void
_addrs_remove(tlstmAddrTable_entry *entry)
{
    netsnmp_container *addrs;
    snmpTlstmAddr      addr;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmAddrTable:addr:remove", "name %s, fp %s\n",
                entry->snmpTargetAddrName, entry->tlstmAddrServerFingerprint));

    /** get current active addrs */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return;

    addr.name = entry->snmpTargetAddrName;
    if (CONTAINER_REMOVE(addrs, &addr) != 0) {
        snmp_log(LOG_ERR, "could not remove tlstm addr");
    }
    entry->addr_flags = 0;
}

static void
_addr_tweak_storage(tlstmAddrTable_entry *entry)
{
    netsnmp_container *addrs;
    snmpTlstmAddr     *addr, index;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmAddrTable:addr:tweak", "name %s, st %d\n",
                entry->snmpTargetAddrName, entry->tlstmAddrStorageType));

    /** get current active addrs */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return;

    index.name = entry->snmpTargetAddrName;
    addr = CONTAINER_FIND(addrs, &index);
    if (NULL == addr) {
        DEBUGMSGTL(("tlstmAddrTable:addr:tweak", "couldn't find addr!\n"));
        return;
    }

    if (entry->tlstmAddrStorageType == ST_NONVOLATILE)
        addr->flags |= TLSTM_ADDR_NONVOLATILE;
    else
        addr->flags &= ~TLSTM_ADDR_NONVOLATILE;
}

static netsnmp_tdata_row *
_entry_from_addr(snmpTlstmAddr  *addr)
{
    netsnmp_tdata_row *row;
    tlstmAddrTable_entry *entry;

    row = tlstmAddrTable_createEntry(NULL, addr->name, strlen(addr->name));
    if (NULL == row) {
        snmp_log(LOG_ERR, "can create tlstmAddr row entry\n");
        return NULL;
    }
    entry = row->data;

    if (addr->flags & TLSTM_ADDR_FROM_CONFIG)
        entry->tlstmAddrStorageType = ST_PERMANENT;
    else if (! (addr->flags & TLSTM_ADDR_NONVOLATILE))
        entry->tlstmAddrStorageType = ST_VOLATILE;

    entry->tlstmAddrRowStatus = RS_ACTIVE;

    if (addr->fingerprint) {
        entry->tlstmAddrServerFingerprint_len = strlen(addr->fingerprint);
        if (entry->tlstmAddrServerFingerprint_len >
            sizeof(entry->tlstmAddrServerFingerprint))
            entry->tlstmAddrServerFingerprint_len =
                sizeof(entry->tlstmAddrServerFingerprint) - 1;
        memcpy(entry->tlstmAddrServerFingerprint, addr->fingerprint,
               entry->tlstmAddrServerFingerprint_len);
        entry->tlstmAddrServerFingerprint[sizeof(entry->tlstmAddrServerFingerprint) - 1] = 0;
    }

    if (addr->identity) {
        entry->tlstmAddrServerIdentity_len = strlen(addr->identity);
        if (entry->tlstmAddrServerIdentity_len >
            sizeof(entry->tlstmAddrServerIdentity))
            entry->tlstmAddrServerIdentity_len =
                sizeof(entry->tlstmAddrServerIdentity) - 1;
        memcpy(entry->tlstmAddrServerIdentity, addr->identity,
               entry->tlstmAddrServerIdentity_len);
        entry->tlstmAddrServerIdentity[sizeof(entry->tlstmAddrServerIdentity) - 1] = 0;
    }

    entry->hashType = addr->hashType;
    entry->addr_flags = addr->flags;

    return row;
}

static int
_cache_load(netsnmp_cache *cache, netsnmp_tdata *table)
{
    netsnmp_container *addrs;
    netsnmp_iterator  *itr;
    snmpTlstmAddr     *addr;
    netsnmp_tdata_row *row;
    int                rc = 0;

    DEBUGMSGTL(("tlstmAddrTable:cache:load", "called, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    /** get current active rows */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return 0;

    DEBUGMSGTL(("tlstmAddrTable:cache:load", "tlstmAddr %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(addrs)));
    itr = CONTAINER_ITERATOR(addrs);
    if (NULL == itr) {
        DEBUGMSGTL(("tlstmAddrTable:cache:load",
                    "cant get iterator\n"));
        return -1;
    }

    /*
     * insert rows for active addrs into tbl container
     */
    addr = ITERATOR_FIRST(itr);
    for( ; addr; addr = ITERATOR_NEXT(itr)) {

        row = _entry_from_addr(addr);
        if (NULL == row) {
            rc =-1;
            break;
        }

        if (netsnmp_tdata_add_row(table, row) != SNMPERR_SUCCESS) {
            tlstmAddrTable_removeEntry(NULL, row);
            rc = -1;
            break;
        }
    }
    ITERATOR_RELEASE(itr);

    DEBUGMSGTL(("tlstmAddrTable:cache:load", "done, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    return rc;
}

static void
_cache_free(netsnmp_cache *cache, netsnmp_tdata *table)
{
    netsnmp_tdata_row *row;
    netsnmp_iterator   *tbl_itr;
    tlstmAddrTable_entry   *entry;

    DEBUGMSGTL(("tlstmAddrTable:cache:free", "called, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    tbl_itr = CONTAINER_ITERATOR(table->container);
    if (NULL == tbl_itr) {
        DEBUGMSGTL(("tlstmAddrTable:cache:free",
                    "cant get entry iterator\n"));
        return;
    }

    row = ITERATOR_FIRST(tbl_itr);
    for( ; row; row = ITERATOR_NEXT(tbl_itr)) {
        entry = row->data;

        /*
         * remove all active rows (they are in the addrs container kept
         * by the library). Keep inactive ones for next time.
         */
        if (entry->tlstmAddrRowStatus == RS_ACTIVE) {
            tlstmAddrTable_removeEntry(NULL, row);
            ITERATOR_REMOVE(tbl_itr);
            continue;
        }
    }
    ITERATOR_RELEASE(tbl_itr);

    DEBUGMSGTL(("tlstmAddrTable:cache:free", "done, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));
}

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/

static int  _tlstmAddrTable_save_rows(int majorID, int minorID,
                                                void *serverarg,
                                                void *clientarg);
static void _tlstmAddrTable_row_restore_mib(const char *token,
                                                       char *buf);
static const char mib_token[] = "snmpTlstmAddrEntry";

/************************************************************
 * *_init_persistence should be called from the main table
 * init routine.
 *
 * If your table depends on rows in another table,
 * you should register your callback after the other table,
 * which should ensure the rows on which you depend are saved
 * (and re-created) before the dependent rows.
 */
static void
_tlstmAddr_init_persistence(void)
{
    int             rc;

    if (NULL == _table_data) {
        snmp_log(LOG_ERR, "no table data for tlstmAddr persistence!\n");
        return;
    }

    register_config_handler(NULL, mib_token,
                            _tlstmAddrTable_row_restore_mib, NULL,
                            NULL);
    rc = snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                                SNMP_CALLBACK_STORE_DATA,
                                _tlstmAddrTable_save_rows,
                                _table_data->container);

    if (rc != SNMP_ERR_NOERROR)
        snmp_log(LOG_ERR, "error registering for STORE_DATA callback "
                 "in _tlstmAddrTable_init_persistence\n");
}

static int
_save_entry(tlstmAddrTable_entry *entry, void *type)
{
    char   buf[SNMP_MAXBUF_SMALL], *hashType;

    hashType = se_find_label_in_slist("cert_hash_alg", entry->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 entry->hashType);
        return SNMP_ERR_GENERR;
    }

    /*
     * build the line
     */
    netsnmp_assert(0 == entry->snmpTargetAddrName[
                       entry->snmpTargetAddrName_len]);
    netsnmp_assert(0 == entry->tlstmAddrServerFingerprint[
                       entry->tlstmAddrServerFingerprint_len]);
    snprintf(buf, sizeof(buf), "%s %s --%s %s %s %d", mib_token,
             entry->snmpTargetAddrName, hashType,
             entry->tlstmAddrServerFingerprint,
             entry->tlstmAddrServerIdentity,
             entry->tlstmAddrRowStatus);
    buf[sizeof(buf)-1] = 0;

    read_config_store(type, buf);
    DEBUGMSGTL(("tlstmAddrTable:row:save", "saving entry '%s'\n", buf));

    return SNMP_ERR_NOERROR;
}

static int
_save_addrs(snmpTlstmAddr *addrs, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType;

    if (NULL == addrs)
        return SNMP_ERR_GENERR;

    hashType = se_find_label_in_slist("cert_hash_alg", addrs->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 addrs->hashType);
        return SNMP_ERR_GENERR;
    }
    snprintf(buf, sizeof(buf), "%s %s --%s %s %s %d", mib_token, addrs->name,
             hashType, addrs->fingerprint, addrs->identity, RS_ACTIVE);

    DEBUGMSGTL(("tlstmAddrTable:addrs:save", "saving addrs '%s'\n",
                buf));
    read_config_store(app_type, buf);

    return SNMP_ERR_NOERROR;
}

static int
_tlstmAddrTable_save_rows(int majorID, int minorID, void *serverarg,
                      void *clientarg)
{
    char            sep[] =
        "##############################################################";
    char            buf[] = "#\n" "# tlstmAddr persistent data\n" "#";
    char           *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                                 NETSNMP_DS_LIB_APPTYPE);

    netsnmp_container *mib_addrs = (netsnmp_container *) clientarg;
    netsnmp_container *active_addrs = netsnmp_tlstmAddr_container();
    netsnmp_iterator  *tbl_itr, *addrs_itr = NULL;
    netsnmp_tdata_row *row;
    snmpTlstmAddr     *addr;
    tlstmAddrTable_entry *entry;

    if (((NULL == mib_addrs) || (CONTAINER_SIZE(mib_addrs) == 0)) &&
        ((NULL == active_addrs) || (CONTAINER_SIZE(active_addrs) == 0)))
        return SNMPERR_SUCCESS;

    read_config_store((char *) type, sep);
    read_config_store((char *) type, buf);

    /*
     * save active rows from addr container
     */
    if (NULL != active_addrs) {
        addrs_itr = CONTAINER_ITERATOR(active_addrs);
        if (NULL == addrs_itr) {
            DEBUGMSGTL(("tlstmAddrTable:save", "cant get addrs iterator\n"));
            addr = NULL;
        }
        else
            addr = ITERATOR_FIRST(addrs_itr);

        for( ; addr; addr = ITERATOR_NEXT(addrs_itr)) {
            /** don't store config rows */
            if ((addr->flags & TLSTM_ADDR_FROM_CONFIG) ||
                ! (addr->flags & TLSTM_ADDR_NONVOLATILE))
                continue;
            _save_addrs(addr, type);
        }
    }
    ITERATOR_RELEASE(addrs_itr);

    /*
     * save inactive rows from mib
     */
    tbl_itr = CONTAINER_ITERATOR(mib_addrs);
    if (NULL == tbl_itr)
        DEBUGMSGTL(("tlstmAddrTable:save", "cant get table iterator\n"));
    else {
        row = ITERATOR_FIRST(tbl_itr);
        for( ; row; row = ITERATOR_NEXT(tbl_itr)) {
            entry = row->data;

            /*
             * skip all active rows (should be in active_addrs and thus saved
             * above) and volatile rows.
             */
            if ((entry->tlstmAddrRowStatus == RS_ACTIVE) ||
                (entry->tlstmAddrStorageType != ST_NONVOLATILE))
                continue;

            _save_entry(entry, type);
        }
        ITERATOR_RELEASE(tbl_itr);
    }

    read_config_store((char *) type, sep);
    read_config_store((char *) type, "\n");

    /*
     * never fails 
     */
    return SNMPERR_SUCCESS;
}

static void
_tlstmAddrTable_row_restore_mib(const char *token, char *buf)
{
    char                   name[SNMPADMINLENGTH + 1], id[SNMPADMINLENGTH + 1],
                           fingerprint[SNMPTLSFINGERPRINT_MAX_LEN + 1];
    size_t                 name_len = sizeof(name), id_len = sizeof(id),
                           fp_len = sizeof(fingerprint);
    u_char                 hashType, rowStatus;
    int                    rc;

    /** need somewhere to save rows */
    netsnmp_assert(_table_data && _table_data->container); 

    rc = netsnmp_tlstmAddr_restore_common(&buf, name, &name_len, id, &id_len,
                                          fingerprint, &fp_len, &hashType);
    if (rc < 0)
        return;

    if (NULL == buf) {
        config_perror("incomplete line");
        return;
    }
    rowStatus = atoi(buf);

    /*
     * if row is active, add it to the addrs container so it is available
     * for use. Do not add it to the table, since it will be added
     * during cache_load.
     */
    if (RS_ACTIVE == rowStatus) {
        snmpTlstmAddr *addr;

        addr = netsnmp_tlstmAddr_create(name);
        if (!addr)
            return;

        if (fp_len)
            addr->fingerprint = strdup(fingerprint);
        if (id_len)
            addr->identity = strdup(id);
        addr->hashType = hashType;
        addr->flags = TLSTM_ADDR_FROM_MIB | TLSTM_ADDR_NONVOLATILE;

        netsnmp_tlstmAddr_add(addr);
    }
    else {
        netsnmp_tdata_row     *row;
        tlstmAddrTable_entry  *entry;

        row = tlstmAddrTable_createEntry(_table_data, name, name_len);
        if (!row)
            return;

        entry = row->data;
        
        entry->hashType = hashType;
        memcpy(entry->tlstmAddrServerFingerprint,fingerprint, fp_len);
        entry->tlstmAddrServerFingerprint_len = fp_len;
        memcpy(entry->tlstmAddrServerIdentity, id, id_len);
        entry->tlstmAddrServerIdentity_len = id_len;
        entry->tlstmAddrStorageType = ST_NONVOLATILE;
        entry->tlstmAddrRowStatus = rowStatus;
    }
}
