Show
Ignore:
Timestamp:
04/19/10 16:39:13 (3 years ago)
Author:
pcarns
Message:

merging bmi-experimental-branch to trunk

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/io/bmi/bmi_tcp/bmi-tcp.c

    r7819 r8304  
    4949#include "pint-hint.h" 
    5050#include "pint-event.h" 
     51#include "quickhash.h" 
     52 
     53#define BMI_TCP_S2S_MAGIC_NR 51912 
    5154 
    5255static gen_mutex_t interface_mutex = GEN_MUTEX_INITIALIZER; 
     
    6972                    enum bmi_op_type send_recv); 
    7073int BMI_tcp_unexpected_free(void *buffer); 
    71 int BMI_tcp_post_send(bmi_op_id_t * id, 
    72                       bmi_method_addr_p dest, 
    73                       const void *buffer, 
    74                       bmi_size_t size, 
    75                       enum bmi_buffer_type buffer_type, 
    76                       bmi_msg_tag_t tag, 
    77                       void *user_ptr, 
    78                       bmi_context_id context_id, 
    79                       PVFS_hint hints); 
    80 int BMI_tcp_post_sendunexpected(bmi_op_id_t * id, 
    81                                 bmi_method_addr_p dest, 
    82                                 const void *buffer, 
    83                                 bmi_size_t size, 
    84                                 enum bmi_buffer_type buffer_type, 
    85                                 bmi_msg_tag_t tag, 
    86                                 void *user_ptr, 
    87                                 bmi_context_id context_id, 
    88                                 PVFS_hint hints); 
    89 int BMI_tcp_post_recv(bmi_op_id_t * id, 
    90                       bmi_method_addr_p src, 
    91                       void *buffer, 
    92                       bmi_size_t expected_size, 
    93                       bmi_size_t * actual_size, 
    94                       enum bmi_buffer_type buffer_type, 
    95                       bmi_msg_tag_t tag, 
    96                       void *user_ptr, 
    97                       bmi_context_id context_id, 
    98                       PVFS_hint hints); 
    9974int BMI_tcp_test(bmi_op_id_t id, 
    10075                 int *outcount, 
     
    11691                           int *outcount, 
    11792                           struct bmi_method_unexpected_info *info, 
     93                           uint8_t class, 
    11894                           int max_idle_time_ms); 
    11995int BMI_tcp_testcontext(int incount, 
     
    159135                                     enum bmi_buffer_type buffer_type, 
    160136                                     bmi_msg_tag_t tag, 
     137                                     uint8_t class, 
    161138                                     void *user_ptr, 
    162139                                     bmi_context_id context_id, 
     
    169146 
    170147/* size of encoded message header */ 
    171 #define TCP_ENC_HDR_SIZE 24 
     148#define TCP_ENC_HDR_SIZE 25 
    172149 
    173150/* structure internal to tcp for use as a message header */ 
     
    178155    bmi_msg_tag_t tag;          /* user specified message tag */ 
    179156    bmi_size_t size;            /* length of trailing message */ 
     157    uint32_t src_addr_hash;     /* hash of local svr addr (if present) */ 
     158    uint8_t class;              /* class of msg (if unexpected) */ 
    180159    char enc_hdr[TCP_ENC_HDR_SIZE];  /* encoded version of header info */ 
    181160}; 
     
    185164        *((uint32_t*)&((hdr).enc_hdr[0])) = htobmi32((hdr).magic_nr);   \ 
    186165        *((uint32_t*)&((hdr).enc_hdr[4])) = htobmi32((hdr).mode);       \ 
    187         *((uint64_t*)&((hdr).enc_hdr[8])) = htobmi64((hdr).tag);        \ 
     166        *((uint32_t*)&((hdr).enc_hdr[8])) = htobmi64((hdr).tag);        \ 
     167        *((uint32_t*)&((hdr).enc_hdr[12])) = htobmi32((hdr).src_addr_hash);\ 
    188168        *((uint64_t*)&((hdr).enc_hdr[16])) = htobmi64((hdr).size);      \ 
     169        *((uint8_t*)&((hdr).enc_hdr[24])) = (hdr).class;                \ 
    189170    } while(0)                                               
    190171 
     
    193174        (hdr).magic_nr = bmitoh32(*((uint32_t*)&((hdr).enc_hdr[0])));   \ 
    194175        (hdr).mode = bmitoh32(*((uint32_t*)&((hdr).enc_hdr[4])));       \ 
    195         (hdr).tag = bmitoh64(*((uint64_t*)&((hdr).enc_hdr[8])));        \ 
     176        (hdr).tag = bmitoh32(*((uint32_t*)&((hdr).enc_hdr[8])));        \ 
     177        (hdr).src_addr_hash = bmitoh32(*((uint32_t*)&((hdr).enc_hdr[12])));\ 
    196178        (hdr).size = bmitoh64(*((uint64_t*)&((hdr).enc_hdr[16])));      \ 
     179        (hdr).class = *((uint8_t*)&((hdr).enc_hdr[24]));                \ 
    197180    } while(0)                                               
    198181 
     
    285268    bmi_size_t* current_index_complete, enum bmi_op_type send_recv,  
    286269    char* enc_hdr, bmi_size_t* env_amt_complete); 
     270static uint32_t hashlittle( const void *key, size_t length, uint32_t initval); 
     271static int addr_hash_compare(void* key, struct qhash_head* link); 
    287272 
    288273#if defined(USE_TRUSTED) && defined(__PVFS2_CLIENT__) 
     
    305290    .memfree  = BMI_tcp_memfree, 
    306291    .unexpected_free = BMI_tcp_unexpected_free, 
    307     .post_send = BMI_tcp_post_send, 
    308     .post_sendunexpected = BMI_tcp_post_sendunexpected, 
    309     .post_recv = BMI_tcp_post_recv, 
    310292    .test = BMI_tcp_test, 
    311293    .testsome = BMI_tcp_testsome, 
     
    405387static pid_t bmi_tcp_pid; 
    406388 
     389static struct qhash_table* addr_hash_table = NULL; 
     390#define ADDR_HASH_TABLE_SIZE 137 
     391 
    407392/************************************************************************* 
    408393 * Visible Interface  
     
    514499        "%d%d%d%llu%d%d", 
    515500        "%d", &bmi_tcp_recv_event_id); 
     501     
     502    /* create a hash table to store method addresses based on addr hash */ 
     503    addr_hash_table = qhash_init(addr_hash_compare, quickhash_null32_hash, 
     504        ADDR_HASH_TABLE_SIZE); 
     505    if(!addr_hash_table) 
     506    { 
     507        tmp_errno = bmi_tcp_errno_to_pvfs(-ENOMEM); 
     508        goto initialize_failure; 
     509    } 
    516510 
    517511    gen_mutex_unlock(&interface_mutex); 
     
    600594    struct tcp_addr *tcp_addr_data = NULL; 
    601595    int ret = -1; 
     596    uint32_t addr_hash; 
     597    struct qhash_head* tmp_link; 
    602598 
    603599    tcp_string = string_key("tcp", id_string); 
    604600    if (!tcp_string) 
    605601    { 
    606         /* the string doesn't even have our info */ 
    607         return (NULL); 
     602        /* the string doesn't even have our info */ 
     603        return (NULL); 
    608604    } 
    609605 
     
    612608    if ((delim = index(tcp_string, ':')) == NULL) 
    613609    { 
    614         gossip_lerr("Error: malformed tcp address.\n"); 
    615         free(tcp_string); 
    616         return (NULL); 
    617     } 
    618  
    619     /* looks ok, so let's build the method addr structure */ 
    620     new_addr = alloc_tcp_method_addr(); 
    621     if (!new_addr) 
    622     { 
    623         free(tcp_string); 
    624         return (NULL); 
    625     } 
    626     tcp_addr_data = new_addr->method_data; 
     610        gossip_lerr("Error: malformed tcp address.\n"); 
     611        free(tcp_string); 
     612        return (NULL); 
     613    } 
     614 
     615    addr_hash = hashlittle(id_string, strlen(id_string), 3334); 
     616    /* do we already have a connection established from this host? */ 
     617    if(addr_hash_table && (tmp_link = qhash_search(addr_hash_table, 
     618        &addr_hash))) 
     619    { 
     620        /* we have already received an inbound connection from the host that 
     621         * we are looking up.  Re-use the existing method addr rather than 
     622         * creating a new one  
     623         */ 
     624        tcp_addr_data = qlist_entry(tmp_link, struct 
     625            tcp_addr, hash_link); 
     626        new_addr = tcp_addr_data->parent; 
     627        if(tcp_addr_data->hostname) 
     628            free(tcp_addr_data->hostname); 
     629        tcp_addr_data->dont_reconnect = 0; 
     630        assert(new_addr->ref_count == 1); 
     631        new_addr->ref_count++; 
     632    } 
     633    else 
     634    { 
     635        /* looks ok, so let's build the method addr structure */ 
     636        new_addr = alloc_tcp_method_addr(); 
     637        if (!new_addr) 
     638        { 
     639            free(tcp_string); 
     640            return (NULL); 
     641        } 
     642        tcp_addr_data = new_addr->method_data; 
     643    } 
    627644 
    628645    ret = sscanf((delim + 1), "%d", &(tcp_addr_data->port)); 
    629646    if (ret != 1) 
    630647    { 
    631         gossip_lerr("Error: malformed tcp address.\n"); 
    632         dealloc_tcp_method_addr(new_addr); 
    633         free(tcp_string); 
    634         return (NULL); 
     648        gossip_lerr("Error: malformed tcp address.\n"); 
     649        dealloc_tcp_method_addr(new_addr); 
     650        free(tcp_string); 
     651        return (NULL); 
    635652    } 
    636653 
     
    638655    if (!hostname) 
    639656    { 
    640         dealloc_tcp_method_addr(new_addr); 
    641         free(tcp_string); 
    642         return (NULL); 
     657        dealloc_tcp_method_addr(new_addr); 
     658        free(tcp_string); 
     659        return (NULL); 
    643660    } 
    644661    strncpy(hostname, tcp_string, (delim - tcp_string)); 
     
    646663 
    647664    tcp_addr_data->hostname = hostname; 
     665    tcp_addr_data->addr_hash = addr_hash;  
     666    /* add entry to hash table so we can find it later */ 
     667    if(addr_hash_table) 
     668    { 
     669        qhash_add(addr_hash_table, &tcp_addr_data->addr_hash, 
     670            &tcp_addr_data->hash_link); 
     671    } 
     672    gossip_debug(GOSSIP_BMI_DEBUG_TCP, 
     673        "Hashed BMI address %s to %u\n", id_string, 
     674        tcp_addr_data->addr_hash); 
    648675 
    649676    free(tcp_string); 
     677 
    650678    return (new_addr); 
    651679} 
     
    9871015} 
    9881016 
    989  
    990 /* BMI_tcp_post_send() 
    991  *  
    992  * Submits send operations. 
    993  * 
    994  * returns 0 on success that requires later poll, returns 1 on instant 
    995  * completion, -errno on failure 
    996  */ 
    997 int BMI_tcp_post_send(bmi_op_id_t * id, 
    998                       bmi_method_addr_p dest, 
    999                       const void *buffer, 
    1000                       bmi_size_t size, 
    1001                       enum bmi_buffer_type buffer_type, 
    1002                       bmi_msg_tag_t tag, 
    1003                       void *user_ptr, 
    1004                       bmi_context_id context_id, 
    1005                       PVFS_hint hints) 
    1006 { 
    1007     struct tcp_msg_header my_header; 
    1008     int ret = -1; 
    1009  
    1010     /* clear the id field for safety */ 
    1011     *id = 0; 
    1012  
    1013     /* fill in the TCP-specific message header */ 
    1014     if (size > TCP_MODE_REND_LIMIT) 
    1015     { 
    1016         return (bmi_tcp_errno_to_pvfs(-EMSGSIZE)); 
    1017     } 
    1018  
    1019     if (size <= TCP_MODE_EAGER_LIMIT) 
    1020     { 
    1021         my_header.mode = TCP_MODE_EAGER; 
    1022     } 
    1023     else 
    1024     { 
    1025         my_header.mode = TCP_MODE_REND; 
    1026     } 
    1027     my_header.tag = tag; 
    1028     my_header.size = size; 
    1029     my_header.magic_nr = BMI_MAGIC_NR; 
    1030  
    1031     gen_mutex_lock(&interface_mutex); 
    1032  
    1033     ret = tcp_post_send_generic(id, dest, &buffer, 
    1034                                 &size, 1, buffer_type, my_header, 
    1035                                 user_ptr, context_id, hints); 
    1036  
    1037     gen_mutex_unlock(&interface_mutex); 
    1038     return(ret); 
    1039 } 
    1040  
    1041  
    1042 /* BMI_tcp_post_sendunexpected() 
    1043  *  
    1044  * Submits unexpected send operations. 
    1045  * 
    1046  * returns 0 on success that requires later poll, returns 1 on instant 
    1047  * completion, -errno on failure 
    1048  */ 
    1049 int BMI_tcp_post_sendunexpected(bmi_op_id_t * id, 
    1050                                 bmi_method_addr_p dest, 
    1051                                 const void *buffer, 
    1052                                 bmi_size_t size, 
    1053                                 enum bmi_buffer_type buffer_type, 
    1054                                 bmi_msg_tag_t tag, 
    1055                                 void *user_ptr, 
    1056                                 bmi_context_id context_id, 
    1057                                 PVFS_hint hints) 
    1058 { 
    1059     struct tcp_msg_header my_header; 
    1060     int ret = -1; 
    1061  
    1062     /* clear the id field for safety */ 
    1063     *id = 0; 
    1064  
    1065     if (size > TCP_MODE_EAGER_LIMIT) 
    1066     { 
    1067         return (bmi_tcp_errno_to_pvfs(-EMSGSIZE)); 
    1068     } 
    1069  
    1070     my_header.mode = TCP_MODE_UNEXP; 
    1071     my_header.tag = tag; 
    1072     my_header.size = size; 
    1073     my_header.magic_nr = BMI_MAGIC_NR; 
    1074  
    1075     gen_mutex_lock(&interface_mutex); 
    1076  
    1077     ret = tcp_post_send_generic(id, dest, &buffer, 
    1078                                 &size, 1, buffer_type, my_header, 
    1079                                 user_ptr, context_id, hints); 
    1080     gen_mutex_unlock(&interface_mutex); 
    1081     return(ret); 
    1082 } 
    1083  
    1084  
    1085  
    1086 /* BMI_tcp_post_recv() 
    1087  *  
    1088  * Submits recv operations. 
    1089  * 
    1090  * returns 0 on success that requires later poll, returns 1 on instant 
    1091  * completion, -errno on failure 
    1092  */ 
    1093 int BMI_tcp_post_recv(bmi_op_id_t * id, 
    1094                       bmi_method_addr_p src, 
    1095                       void *buffer, 
    1096                       bmi_size_t expected_size, 
    1097                       bmi_size_t * actual_size, 
    1098                       enum bmi_buffer_type buffer_type, 
    1099                       bmi_msg_tag_t tag, 
    1100                       void *user_ptr, 
    1101                       bmi_context_id context_id, 
    1102                       PVFS_hint hints) 
    1103 { 
    1104     int ret = -1; 
    1105  
    1106     /* A few things could happen here: 
    1107      * a) rendez. recv with sender not ready yet 
    1108      * b) rendez. recv with sender waiting 
    1109      * c) eager recv, data not available yet 
    1110      * d) eager recv, some/all data already here 
    1111      * e) rendez. recv with sender in eager mode 
    1112      * 
    1113      * b or d could lead to completion without polling. 
    1114      * we don't look for unexpected messages here. 
    1115      */ 
    1116  
    1117     if (expected_size > TCP_MODE_REND_LIMIT) 
    1118     { 
    1119         return (bmi_tcp_errno_to_pvfs(-EINVAL)); 
    1120     } 
    1121     gen_mutex_lock(&interface_mutex); 
    1122  
    1123     ret = tcp_post_recv_generic(id, src, &buffer, &expected_size, 
    1124                                 1, expected_size, actual_size, 
    1125                                 buffer_type, tag, 
    1126                                 user_ptr, context_id, hints); 
    1127  
    1128     gen_mutex_unlock(&interface_mutex); 
    1129     return (ret); 
    1130 } 
    1131  
    1132  
    11331017/* BMI_tcp_test() 
    11341018 *  
     
    12601144                           int *outcount, 
    12611145                           struct bmi_method_unexpected_info *info, 
     1146                           uint8_t class, 
    12621147                           int max_idle_time) 
    12631148{ 
    12641149    int ret = -1; 
    12651150    method_op_p query_op = NULL; 
     1151    struct op_list_search_key key; 
     1152 
     1153    memset(&key, 0, sizeof(struct op_list_search_key)); 
     1154    key.class = class; 
     1155    key.class_yes = 1; 
    12661156 
    12671157    gen_mutex_lock(&interface_mutex); 
     
    12831173     * stuff and we have room in the info array for it 
    12841174     */ 
    1285     while ((*outcount < incount) && 
    1286            (query_op = 
    1287             op_list_shownext(op_list_array[IND_COMPLETE_RECV_UNEXP]))) 
    1288     { 
    1289         info[*outcount].error_code = query_op->error_code; 
    1290         info[*outcount].addr = query_op->addr; 
     1175    while(*outcount < incount) 
     1176    { 
     1177        query_op = op_list_search(op_list_array[IND_COMPLETE_RECV_UNEXP], 
     1178            &key); 
     1179        if(!query_op) 
     1180        { 
     1181            break; 
     1182        } 
     1183        info[*outcount].error_code = query_op->error_code; 
     1184        /* always show unexpected messages on primary address */ 
     1185        if(query_op->addr->primary) 
     1186            info[*outcount].addr = query_op->addr->primary; 
     1187        else 
     1188            info[*outcount].addr = query_op->addr; 
    12911189        info[*outcount].buffer = query_op->buffer; 
    12921190        info[*outcount].size = query_op->actual_size; 
     
    12961194        (*outcount)++; 
    12971195    } 
     1196 
    12981197    gen_mutex_unlock(&interface_mutex); 
    12991198    return (0); 
     
    14011300    struct tcp_msg_header my_header; 
    14021301    int ret = -1; 
     1302    struct tcp_addr *tcp_addr_data = NULL; 
    14031303 
    14041304    /* clear the id field for safety */ 
     
    14221322    my_header.tag = tag; 
    14231323    my_header.size = total_size; 
    1424     my_header.magic_nr = BMI_MAGIC_NR; 
     1324    my_header.magic_nr = BMI_TCP_S2S_MAGIC_NR; 
     1325    if(tcp_method_params.method_flags & BMI_INIT_SERVER) 
     1326    { 
     1327        /* servers identify themselves to peers with an address hash */ 
     1328        tcp_addr_data = tcp_method_params.listen_addr->method_data; 
     1329        my_header.src_addr_hash = tcp_addr_data->addr_hash; 
     1330    } 
     1331    else 
     1332    { 
     1333        my_header.src_addr_hash = 0; 
     1334    } 
    14251335 
    14261336    gen_mutex_lock(&interface_mutex); 
     
    14891399                                     enum bmi_buffer_type buffer_type, 
    14901400                                     bmi_msg_tag_t tag, 
     1401                                     uint8_t class, 
    14911402                                     void *user_ptr, 
    14921403                                     bmi_context_id context_id, 
     
    14951406    struct tcp_msg_header my_header; 
    14961407    int ret = -1; 
     1408    struct tcp_addr *tcp_addr_data = NULL; 
    14971409 
    14981410    /* clear the id field for safety */ 
     
    15071419    my_header.tag = tag; 
    15081420    my_header.size = total_size; 
    1509     my_header.magic_nr = BMI_MAGIC_NR; 
     1421    my_header.magic_nr = BMI_TCP_S2S_MAGIC_NR; 
     1422    my_header.class = class; 
     1423    if(tcp_method_params.method_flags & BMI_INIT_SERVER) 
     1424    { 
     1425        /* servers identify themselves to peers with an address hash */ 
     1426        tcp_addr_data = tcp_method_params.listen_addr->method_data; 
     1427        my_header.src_addr_hash = tcp_addr_data->addr_hash; 
     1428    } 
     1429    else 
     1430    { 
     1431        my_header.src_addr_hash = 0; 
     1432    } 
    15101433 
    15111434    gen_mutex_lock(&interface_mutex); 
     
    18991822    if (dealloc_flag) 
    19001823    { 
    1901         dealloc_tcp_method_addr(map); 
     1824        map->ref_count--; 
     1825        if(map->ref_count == 0) 
     1826        { 
     1827            if(map->secondary) 
     1828            { 
     1829                dealloc_tcp_method_addr(map->secondary); 
     1830            } 
     1831            if(map->primary) 
     1832            { 
     1833                map->primary->secondary = NULL; 
     1834            } 
     1835            dealloc_tcp_method_addr(map); 
     1836        } 
    19021837    } 
    19031838    else 
    19041839    { 
    1905         /* this will cause the bmi control layer to check to see if  
    1906          * this address can be completely forgotten 
    1907          */ 
    1908         bmi_method_addr_forget_callback(bmi_addr); 
     1840        if(!map->primary) 
     1841        { 
     1842            /* this will cause the bmi control layer to check to see if  
     1843             * this address can be completely forgotten 
     1844             */ 
     1845            bmi_method_addr_forget_callback(bmi_addr); 
     1846        } 
    19091847    } 
    19101848    return; 
     
    19451883        free(tcp_addr_data->peer); 
    19461884 
     1885    if (tcp_addr_data->hash_link.next || tcp_addr_data->hash_link.prev) 
     1886    { 
     1887        qhash_del(&tcp_addr_data->hash_link); 
     1888    } 
     1889 
    19471890    bmi_dealloc_method_addr(map); 
    19481891 
     
    19801923    tcp_addr_data->map = my_method_addr; 
    19811924    tcp_addr_data->sc_index = -1; 
     1925    tcp_addr_data->parent = my_method_addr; 
    19821926 
    19831927    return (my_method_addr); 
     
    29582902     */ 
    29592903    tcp_addr_data->dont_reconnect = 1; 
    2960     /* register this address with the method control layer */ 
    2961     tcp_addr_data->bmi_addr = bmi_method_addr_reg_callback(new_addr); 
    2962     if (ret < 0) 
    2963     { 
    2964         tcp_shutdown_addr(new_addr); 
    2965         dealloc_tcp_method_addr(new_addr); 
    2966         dealloc_tcp_method_addr(map); 
    2967         return (ret); 
    2968     } 
     2904 
    29692905    BMI_socket_collection_add(tcp_socket_collection_p, new_addr); 
    29702906 
     
    31343070 
    31353071    /* check magic number of message */ 
    3136     if(new_header.magic_nr != BMI_MAGIC_NR) 
    3137     { 
    3138         gossip_err("Error: bad magic in BMI TCP message.\n"); 
     3072    if(new_header.magic_nr != BMI_TCP_S2S_MAGIC_NR) 
     3073    { 
     3074        gossip_err("Error: Bad magic in BMI TCP message.\n"); 
     3075        gossip_err("Error: This may be due to port scanning or communication between incompatible versions of BMI.\n"); 
    31393076        tcp_forget_addr(map, 0, bmi_tcp_errno_to_pvfs(-EBADMSG)); 
    31403077        return(0); 
     3078    } 
     3079 
     3080    gossip_debug(GOSSIP_BMI_DEBUG_TCP, 
     3081        "Received a message from hashed address %u\n", 
     3082        new_header.src_addr_hash); 
     3083 
     3084    if(tcp_addr_data->addr_hash == 0) 
     3085    { 
     3086        struct qhash_head* tmp_link; 
     3087        struct tcp_addr* found_tcp_addr_data = NULL; 
     3088        bmi_method_addr_p found_map = NULL; 
     3089 
     3090        /* This is the first incoming message on a new socket */ 
     3091        if(new_header.src_addr_hash == 0) 
     3092        { 
     3093            /* client connection; there is no identifier in the header */ 
     3094            /* register this address with the method control layer */ 
     3095            tcp_addr_data->bmi_addr = bmi_method_addr_reg_callback(map); 
     3096            if (ret < 0) 
     3097            { 
     3098                tcp_shutdown_addr(map); 
     3099                dealloc_tcp_method_addr(map); 
     3100                return (ret); 
     3101            } 
     3102        } 
     3103        else 
     3104        { 
     3105            /* server connection; search to see if we can find an address  
     3106             * that we already explicitly resolved to this host  
     3107             */ 
     3108            tmp_link = qhash_search(addr_hash_table, &new_header.src_addr_hash); 
     3109            if(tmp_link) 
     3110            { 
     3111                /* we found a match; this host has already been looked up 
     3112                 * locally 
     3113                 */ 
     3114                found_tcp_addr_data = qlist_entry(tmp_link, struct 
     3115                    tcp_addr, hash_link); 
     3116                found_map = found_tcp_addr_data->parent; 
     3117 
     3118                /* link the two addresses together */ 
     3119                found_map->secondary = map; 
     3120                map->primary = found_map; 
     3121            } 
     3122            else 
     3123            { 
     3124                /* No lookups on this host yet. */ 
     3125                tcp_addr_data->addr_hash = new_header.src_addr_hash; 
     3126                /* add entry to hash table so we can find it later */ 
     3127                qhash_add(addr_hash_table, &tcp_addr_data->addr_hash, 
     3128                    &tcp_addr_data->hash_link); 
     3129                /* register this address with the method control layer */ 
     3130                tcp_addr_data->bmi_addr = bmi_method_addr_reg_callback(map); 
     3131                if (ret < 0) 
     3132                { 
     3133                    tcp_shutdown_addr(map); 
     3134                    dealloc_tcp_method_addr(map); 
     3135                    return (ret); 
     3136                } 
     3137            } 
     3138        } 
    31413139    } 
    31423140 
     
    31763174        active_method_op->size_list = &(active_method_op->actual_size); 
    31773175        active_method_op->list_count = 1; 
     3176        active_method_op->class = new_header.class; 
    31783177        tcp_op_data = active_method_op->method_data; 
    31793178        tcp_op_data->tcp_op_state = BMI_TCP_INPROGRESS; 
     
    40824081 
    40834082/* 
     4083 * My best guess at if you are big-endian or little-endian.  This may 
     4084 * need adjustment. 
     4085 */ 
     4086#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ 
     4087     __BYTE_ORDER == __LITTLE_ENDIAN) || \ 
     4088    (defined(i386) || defined(__i386__) || defined(__i486__) || \ 
     4089     defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) 
     4090# define HASH_LITTLE_ENDIAN 1 
     4091# define HASH_BIG_ENDIAN 0 
     4092#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ 
     4093       __BYTE_ORDER == __BIG_ENDIAN) || \ 
     4094      (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) 
     4095# define HASH_LITTLE_ENDIAN 0 
     4096# define HASH_BIG_ENDIAN 1 
     4097#else 
     4098# define HASH_LITTLE_ENDIAN 0 
     4099# define HASH_BIG_ENDIAN 0 
     4100#endif 
     4101 
     4102#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) 
     4103 
     4104/* 
     4105------------------------------------------------------------------------------- 
     4106mix -- mix 3 32-bit values reversibly. 
     4107 
     4108This is reversible, so any information in (a,b,c) before mix() is 
     4109still in (a,b,c) after mix(). 
     4110 
     4111If four pairs of (a,b,c) inputs are run through mix(), or through 
     4112mix() in reverse, there are at least 32 bits of the output that 
     4113are sometimes the same for one pair and different for another pair. 
     4114This was tested for: 
     4115* pairs that differed by one bit, by two bits, in any combination 
     4116  of top bits of (a,b,c), or in any combination of bottom bits of 
     4117  (a,b,c). 
     4118* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed 
     4119  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as 
     4120  is commonly produced by subtraction) look like a single 1-bit 
     4121  difference. 
     4122* the base values were pseudorandom, all zero but one bit set, or  
     4123  all zero plus a counter that starts at zero. 
     4124 
     4125Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that 
     4126satisfy this are 
     4127    4  6  8 16 19  4 
     4128    9 15  3 18 27 15 
     4129   14  9  3  7 17  3 
     4130Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing 
     4131for "differ" defined as + with a one-bit base and a two-bit delta.  I 
     4132used http://burtleburtle.net/bob/hash/avalanche.html to choose  
     4133the operations, constants, and arrangements of the variables. 
     4134 
     4135This does not achieve avalanche.  There are input bits of (a,b,c) 
     4136that fail to affect some output bits of (a,b,c), especially of a.  The 
     4137most thoroughly mixed value is c, but it doesn't really even achieve 
     4138avalanche in c. 
     4139 
     4140This allows some parallelism.  Read-after-writes are good at doubling 
     4141the number of bits affected, so the goal of mixing pulls in the opposite 
     4142direction as the goal of parallelism.  I did what I could.  Rotates 
     4143seem to cost as much as shifts on every machine I could lay my hands 
     4144on, and rotates are much kinder to the top and bottom bits, so I used 
     4145rotates. 
     4146------------------------------------------------------------------------------- 
     4147*/ 
     4148#define mix(a,b,c) \ 
     4149{ \ 
     4150  a -= c;  a ^= rot(c, 4);  c += b; \ 
     4151  b -= a;  b ^= rot(a, 6);  a += c; \ 
     4152  c -= b;  c ^= rot(b, 8);  b += a; \ 
     4153  a -= c;  a ^= rot(c,16);  c += b; \ 
     4154  b -= a;  b ^= rot(a,19);  a += c; \ 
     4155  c -= b;  c ^= rot(b, 4);  b += a; \ 
     4156} 
     4157 
     4158/* 
     4159------------------------------------------------------------------------------- 
     4160final -- final mixing of 3 32-bit values (a,b,c) into c 
     4161 
     4162Pairs of (a,b,c) values differing in only a few bits will usually 
     4163produce values of c that look totally different.  This was tested for 
     4164* pairs that differed by one bit, by two bits, in any combination 
     4165  of top bits of (a,b,c), or in any combination of bottom bits of 
     4166  (a,b,c). 
     4167* "differ" is defined as +, -, ^, or ~^.  For + and -, I transformed 
     4168  the output delta to a Gray code (a^(a>>1)) so a string of 1's (as 
     4169  is commonly produced by subtraction) look like a single 1-bit 
     4170  difference. 
     4171* the base values were pseudorandom, all zero but one bit set, or  
     4172  all zero plus a counter that starts at zero. 
     4173 
     4174These constants passed: 
     4175 14 11 25 16 4 14 24 
     4176 12 14 25 16 4 14 24 
     4177and these came close: 
     4178  4  8 15 26 3 22 24 
     4179 10  8 15 26 3 22 24 
     4180 11  8 15 26 3 22 24 
     4181------------------------------------------------------------------------------- 
     4182*/ 
     4183#define final(a,b,c) \ 
     4184{ \ 
     4185  c ^= b; c -= rot(b,14); \ 
     4186  a ^= c; a -= rot(c,11); \ 
     4187  b ^= a; b -= rot(a,25); \ 
     4188  c ^= b; c -= rot(b,16); \ 
     4189  a ^= c; a -= rot(c,4);  \ 
     4190  b ^= a; b -= rot(a,14); \ 
     4191  c ^= b; c -= rot(b,24); \ 
     4192} 
     4193 
     4194 
     4195/* 
     4196------------------------------------------------------------------------------- 
     4197hashlittle() -- hash a variable-length key into a 32-bit value 
     4198  k       : the key (the unaligned variable-length array of bytes) 
     4199  length  : the length of the key, counting by bytes 
     4200  initval : can be any 4-byte value 
     4201Returns a 32-bit value.  Every bit of the key affects every bit of 
     4202the return value.  Two keys differing by one or two bits will have 
     4203totally different hash values. 
     4204 
     4205The best hash table sizes are powers of 2.  There is no need to do 
     4206mod a prime (mod is sooo slow!).  If you need less than 32 bits, 
     4207use a bitmask.  For example, if you need only 10 bits, do 
     4208  h = (h & hashmask(10)); 
     4209In which case, the hash table should have hashsize(10) elements. 
     4210 
     4211If you are hashing n strings (uint8_t **)k, do it like this: 
     4212  for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h); 
     4213 
     4214By Bob Jenkins, 2006.  bob_jenkins@burtleburtle.net.  You may use this 
     4215code any way you wish, private, educational, or commercial.  It's free. 
     4216 
     4217Use for hash table lookup, or anything where one collision in 2^^32 is 
     4218acceptable.  Do NOT use for cryptographic purposes. 
     4219------------------------------------------------------------------------------- 
     4220*/ 
     4221static uint32_t hashlittle( const void *key, size_t length, uint32_t initval) 
     4222{ 
     4223  uint32_t a,b,c;                                          /* internal state */ 
     4224  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */ 
     4225 
     4226  /* Set up the internal state */ 
     4227  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; 
     4228 
     4229  u.ptr = key; 
     4230  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { 
     4231    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */ 
     4232#ifdef VALGRIND 
     4233    const uint8_t  *k8; 
     4234#endif 
     4235 
     4236    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ 
     4237    while (length > 12) 
     4238    { 
     4239      a += k[0]; 
     4240      b += k[1]; 
     4241      c += k[2]; 
     4242      mix(a,b,c); 
     4243      length -= 12; 
     4244      k += 3; 
     4245    } 
     4246 
     4247    /*----------------------------- handle the last (probably partial) block */ 
     4248    /*  
     4249     * "k[2]&0xffffff" actually reads beyond the end of the string, but 
     4250     * then masks off the part it's not allowed to read.  Because the 
     4251     * string is aligned, the masked-off tail is in the same word as the 
     4252     * rest of the string.  Every machine with memory protection I've seen 
     4253     * does it on word boundaries, so is OK with this.  But VALGRIND will 
     4254     * still catch it and complain.  The masking trick does make the hash 
     4255     * noticably faster for short strings (like English words). 
     4256     */ 
     4257#ifndef VALGRIND 
     4258 
     4259    switch(length) 
     4260    { 
     4261    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; 
     4262    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; 
     4263    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; 
     4264    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; 
     4265    case 8 : b+=k[1]; a+=k[0]; break; 
     4266    case 7 : b+=k[1]&0xffffff; a+=k[0]; break; 
     4267    case 6 : b+=k[1]&0xffff; a+=k[0]; break; 
     4268    case 5 : b+=k[1]&0xff; a+=k[0]; break; 
     4269    case 4 : a+=k[0]; break; 
     4270    case 3 : a+=k[0]&0xffffff; break; 
     4271    case 2 : a+=k[0]&0xffff; break; 
     4272    case 1 : a+=k[0]&0xff; break; 
     4273    case 0 : return c;              /* zero length strings require no mixing */ 
     4274    } 
     4275 
     4276#else /* make valgrind happy */ 
     4277 
     4278    k8 = (const uint8_t *)k; 
     4279    switch(length) 
     4280    { 
     4281    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; 
     4282    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */ 
     4283    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */ 
     4284    case 9 : c+=k8[8];                   /* fall through */ 
     4285    case 8 : b+=k[1]; a+=k[0]; break; 
     4286    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */ 
     4287    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */ 
     4288    case 5 : b+=k8[4];                   /* fall through */ 
     4289    case 4 : a+=k[0]; break; 
     4290    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */ 
     4291    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */ 
     4292    case 1 : a+=k8[0]; break; 
     4293    case 0 : return c; 
     4294    } 
     4295 
     4296#endif /* !valgrind */ 
     4297 
     4298  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { 
     4299    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */ 
     4300    const uint8_t  *k8; 
     4301 
     4302    /*--------------- all but last block: aligned reads and different mixing */ 
     4303    while (length > 12) 
     4304    { 
     4305      a += k[0] + (((uint32_t)k[1])<<16); 
     4306      b += k[2] + (((uint32_t)k[3])<<16); 
     4307      c += k[4] + (((uint32_t)k[5])<<16); 
     4308      mix(a,b,c); 
     4309      length -= 12; 
     4310      k += 6; 
     4311    } 
     4312 
     4313    /*----------------------------- handle the last (probably partial) block */ 
     4314    k8 = (const uint8_t *)k; 
     4315    switch(length) 
     4316    { 
     4317    case 12: c+=k[4]+(((uint32_t)k[5])<<16); 
     4318             b+=k[2]+(((uint32_t)k[3])<<16); 
     4319             a+=k[0]+(((uint32_t)k[1])<<16); 
     4320             break; 
     4321    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */ 
     4322    case 10: c+=k[4]; 
     4323             b+=k[2]+(((uint32_t)k[3])<<16); 
     4324             a+=k[0]+(((uint32_t)k[1])<<16); 
     4325             break; 
     4326    case 9 : c+=k8[8];                      /* fall through */ 
     4327    case 8 : b+=k[2]+(((uint32_t)k[3])<<16); 
     4328             a+=k[0]+(((uint32_t)k[1])<<16); 
     4329             break; 
     4330    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */ 
     4331    case 6 : b+=k[2]; 
     4332             a+=k[0]+(((uint32_t)k[1])<<16); 
     4333             break; 
     4334    case 5 : b+=k8[4];                      /* fall through */ 
     4335    case 4 : a+=k[0]+(((uint32_t)k[1])<<16); 
     4336             break; 
     4337    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */ 
     4338    case 2 : a+=k[0]; 
     4339             break; 
     4340    case 1 : a+=k8[0]; 
     4341             break; 
     4342    case 0 : return c;                     /* zero length requires no mixing */ 
     4343    } 
     4344 
     4345  } else {                        /* need to read the key one byte at a time */ 
     4346    const uint8_t *k = (const uint8_t *)key; 
     4347 
     4348    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ 
     4349    while (length > 12) 
     4350    { 
     4351      a += k[0]; 
     4352      a += ((uint32_t)k[1])<<8; 
     4353      a += ((uint32_t)k[2])<<16; 
     4354      a += ((uint32_t)k[3])<<24; 
     4355      b += k[4]; 
     4356      b += ((uint32_t)k[5])<<8; 
     4357      b += ((uint32_t)k[6])<<16; 
     4358      b += ((uint32_t)k[7])<<24; 
     4359      c += k[8]; 
     4360      c += ((uint32_t)k[9])<<8; 
     4361      c += ((uint32_t)k[10])<<16; 
     4362      c += ((uint32_t)k[11])<<24; 
     4363      mix(a,b,c); 
     4364      length -= 12; 
     4365      k += 12; 
     4366    } 
     4367 
     4368    /*-------------------------------- last block: affect all 32 bits of (c) */ 
     4369    switch(length)                   /* all the case statements fall through */ 
     4370    { 
     4371    case 12: c+=((uint32_t)k[11])<<24; 
     4372    case 11: c+=((uint32_t)k[10])<<16; 
     4373    case 10: c+=((uint32_t)k[9])<<8; 
     4374    case 9 : c+=k[8]; 
     4375    case 8 : b+=((uint32_t)k[7])<<24; 
     4376    case 7 : b+=((uint32_t)k[6])<<16; 
     4377    case 6 : b+=((uint32_t)k[5])<<8; 
     4378    case 5 : b+=k[4]; 
     4379    case 4 : a+=((uint32_t)k[3])<<24; 
     4380    case 3 : a+=((uint32_t)k[2])<<16; 
     4381    case 2 : a+=((uint32_t)k[1])<<8; 
     4382    case 1 : a+=k[0]; 
     4383             break; 
     4384    case 0 : return c; 
     4385    } 
     4386  } 
     4387 
     4388  final(a,b,c); 
     4389  return c; 
     4390} 
     4391 
     4392static int addr_hash_compare(void* key, struct qhash_head* link) 
     4393{ 
     4394    uint32_t *addr_hash = key; 
     4395    struct tcp_addr *tcp_addr_data = NULL; 
     4396 
     4397    tcp_addr_data = qhash_entry(link, struct tcp_addr, hash_link); 
     4398    assert(tcp_addr_data); 
     4399 
     4400    if(tcp_addr_data->addr_hash == *addr_hash) 
     4401    { 
     4402        return(1); 
     4403    } 
     4404    return(0); 
     4405} 
     4406 
     4407/* 
    40844408 * Local variables: 
    40854409 *  c-indent-level: 4