static bool ketama_continuum_generate(struct cluster_config *config, const struct server_item *servers, size_t num_servers, struct continuum_item **continuum, size_t *continuum_len) { char nodename[MAX_NODE_NAME_LENGTH] = ""; int nodenlen; int pp, hh, ss, nn; unsigned char digest[16]; *continuum = calloc(NUM_NODE_HASHES * num_servers, sizeof(struct continuum_item)); if (*continuum == NULL) { config->logger->log(EXTENSION_LOG_WARNING, NULL, "calloc failed: continuum\n"); return false; } for (ss=0, pp=0; ss<num_servers; ss++) { for (hh=0; hh<NUM_OF_HASHES; hh++) { nodenlen = snprintf(nodename, MAX_NODE_NAME_LENGTH, "%s-%u", servers[ss].hostport, hh); hash_md5(nodename, nodenlen, digest); for (nn=0; nn<NUM_PER_HASH; nn++, pp++) { (*continuum)[pp].index = ss; (*continuum)[pp].point = ((uint32_t) (digest[3 + nn * NUM_PER_HASH] & 0xFF) << 24) | ((uint32_t) (digest[2 + nn * NUM_PER_HASH] & 0xFF) << 16) | ((uint32_t) (digest[1 + nn * NUM_PER_HASH] & 0xFF) << 8) | ( (digest[0 + nn * NUM_PER_HASH] & 0xFF) ); } } } qsort(*continuum, pp, sizeof(struct continuum_item), continuum_item_cmp); *continuum_len = pp; return true; }
hash_stat hash_plugin_check_hash(const char *hash, const char *password[VECTORSIZE], const char *salt, char *salt2[VECTORSIZE], const char *username, int *num, int threadid) { char *saltpass[VECTORSIZE]; int a; int saltlen,passlen;//,lens[VECTORSIZE]; passlen=0; saltlen = strlen(salt); passlen = strlen(password[0]); for (a=0;a<vectorsize;a+=2) { saltpass[a] = alloca(64); bzero(saltpass[a],64); memcpy(saltpass[a],(char *)password[a],passlen); memcpy(saltpass[a]+passlen, (char *)salt, saltlen); saltpass[a+1] = alloca(64); bzero(saltpass[a+1],64); passlen = strlen(password[a+1]); memcpy(saltpass[a+1],(char *)password[a+1],passlen); memcpy(saltpass[a+1]+passlen, (char *)salt, saltlen); } (void)hash_md5((const char **)saltpass, salt2, passlen+saltlen, THREAD_LENPROVIDED); for (a=0;a<vectorsize;a++) if (memcmp((const char *)salt2[a],hash,16)==0) { *num=a; return hash_ok; } return hash_err; }
static void build_self_continuum(struct continuum_item *continuum, const char *hostport) { char nodename[MAX_NODE_NAME_LENGTH] = ""; int nodenlen; int hh, nn, pp; unsigned char digest[16]; /* build sorted hash map */ pp = 0; for (hh=0; hh<NUM_OF_HASHES; hh++) { nodenlen= snprintf(nodename, MAX_NODE_NAME_LENGTH, "%s-%u", hostport, hh); hash_md5(nodename, nodenlen, digest); for (nn=0; nn<NUM_PER_HASH; nn++, pp++) { continuum[pp].index = 0; continuum[pp].point = ((uint32_t) (digest[3 + nn * NUM_PER_HASH] & 0xFF) << 24) | ((uint32_t) (digest[2 + nn * NUM_PER_HASH] & 0xFF) << 16) | ((uint32_t) (digest[1 + nn * NUM_PER_HASH] & 0xFF) << 8) | ( (digest[0 + nn * NUM_PER_HASH] & 0xFF) ); } } qsort(continuum, pp, sizeof(struct continuum_item), continuum_item_cmp); /* build hash index */ for (pp=0; pp<NUM_NODE_HASHES; pp++) { continuum[pp].index = (uint32_t)pp; //fprintf(stderr, "continuum[%u] hash=%x\n", continuum[pp].index, continuum[pp].point); } }
void KetamaSelector::addServers(Connection* conns, size_t nConns) { // from: libmemcached/libmemcached/hosts.cc +303 char sort_host[MC_NI_MAXHOST + 1 + MC_NI_MAXSERV + 1 + MC_NI_MAXSERV]= ""; for (size_t i = 0; i < nConns; i++) { Connection* conn = &conns[i]; int sort_host_len = 0; for (size_t pointer_idx= 0; pointer_idx < s_pointerPerServer / s_pointerPerHash; pointer_idx++) { if (conn->port() != MC_DEFAULT_PORT) { sort_host_len = snprintf(sort_host, sizeof(sort_host), "%s:%u-%zu", conn->host(), conn->port(), pointer_idx); } else { sort_host_len = snprintf(sort_host, sizeof(sort_host), "%s-%zu", conn->host(), pointer_idx); } continuum_item_t item; // Equivalent to `MEMCACHED_BEHAVIOR_KETAMA_HASH` behavior in libmemcached, // but here it always use hash_md5. item.hash_value = hash_md5(sort_host, sort_host_len); item.pool_idx = i; item.conn = conn; m_continuum.push_back(item); } } m_nServers = nConns; std::sort(m_continuum.begin(), m_continuum.end(), continuum_item_t::compare); #ifndef NDEBUG m_sorted = true; #endif }
/* * andna_32bit_hash * * It returns the 32bit hash of the md5 hash of the `hname' string. */ u_int andna_32bit_hash(char *hname) { u_char hashm5[ANDNA_HASH_SZ]; hash_md5((u_char *) hname, strlen(hname), hashm5); return fnv_32_buf(hashm5, ANDNA_HASH_SZ, FNV1_32_INIT); }
static gfxhash_t gfximage_hash(gfximage_t*img) { int t; int size = img->width*img->height*4; U8*data = (U8*)img->data; gfxhash_t hash; hash_md5(data, size, hash.d); return hash; }
static uint32_t hash_ketama(const char *key, size_t key_length) { unsigned char digest[16]; hash_md5(key, key_length, digest); return (uint32_t)((digest[3] << 24) |(digest[2] << 16) |(digest[1] << 8) | digest[0]); }
static bool ketama_continuum_generate(struct cluster_config *config, const struct server_item *servers, size_t num_servers, struct continuum_item **continuum, size_t *continuum_len) { char host[MAX_SERVER_ITEM_COUNT+10] = ""; int host_len; int pp, hh, ss, nn; unsigned char digest[16]; // 40 hashes, 4 numbers per hash = 160 points per server int points_per_server = NUM_OF_HASHES * NUM_PER_HASH; *continuum = calloc(points_per_server * num_servers, sizeof(struct continuum_item)); if (*continuum == NULL) { config->logger->log(EXTENSION_LOG_WARNING, NULL, "calloc failed: continuum\n"); return false; } for (ss=0, pp=0; ss<num_servers; ss++) { for (hh=0; hh<NUM_OF_HASHES; hh++) { host_len = snprintf(host, MAX_SERVER_ITEM_COUNT+10, "%s-%u", servers[ss].hostport, hh); hash_md5(host, host_len, digest); for (nn=0; nn<NUM_PER_HASH; nn++, pp++) { (*continuum)[pp].index = ss; (*continuum)[pp].point = ((uint32_t) (digest[3 + nn * NUM_PER_HASH] & 0xFF) << 24) | ((uint32_t) (digest[2 + nn * NUM_PER_HASH] & 0xFF) << 16) | ((uint32_t) (digest[1 + nn * NUM_PER_HASH] & 0xFF) << 8) | ( (digest[0 + nn * NUM_PER_HASH] & 0xFF) ); } } } qsort(*continuum, pp, sizeof(struct continuum_item), continuum_item_cmp); *continuum_len = pp; return true; }
static void update_ketama_continuum(VBUCKET_CONFIG_HANDLE vb) { char host[MAX_AUTORITY_SIZE+10] = ""; int nhost; int pp, hh, ss, nn; unsigned char digest[16]; struct continuum_item_st *new_continuum, *old_continuum; new_continuum = calloc(160 * vb->num_servers, sizeof(struct continuum_item_st)); /* 40 hashes, 4 numbers per hash = 160 points per server */ for (ss = 0, pp = 0; ss < vb->num_servers; ++ss) { /* we can add more points to server which have more memory */ for (hh = 0; hh < 40; ++hh) { nhost = snprintf(host, MAX_AUTORITY_SIZE+10, "%s-%u", vb->servers[ss].authority, hh); hash_md5(host, nhost, digest); for (nn = 0; nn < 4; ++nn, ++pp) { new_continuum[pp].index = ss; new_continuum[pp].point = ((uint32_t) (digest[3 + nn * 4] & 0xFF) << 24) | ((uint32_t) (digest[2 + nn * 4] & 0xFF) << 16) | ((uint32_t) (digest[1 + nn * 4] & 0xFF) << 8) | (digest[0 + nn * 4] & 0xFF); } } } qsort(new_continuum, pp, sizeof(struct continuum_item_st), continuum_item_cmp); old_continuum = vb->continuum; vb->continuum = new_continuum; vb->num_continuum = pp; if (old_continuum) { free(old_continuum); } }
int process_handle(cvm_common_wqe_t * swp) { int res = 1; list1_entry_t * list1 = list1_lookup(swp); if(list1 != NULL) { //printf("in list1 \n"); //cvm_tcp_tcphdr_t is tcp head,defined in Cvm-tcp.h cvm_tcp_tcphdr_t *th; th = ((cvm_tcp_tcphdr_t *) & (swp->hw_wqe.packet_data[swp->l4_offset])); //如果为拆链接数据包,则需要删除相应规则列表项 if(th->th_flags & 0x05)// fin is 0x01; rst is 0x04 { printf("find TCP rst or fin\n"); list1_discard_lookup_entry(swp); list1 = NULL; return res; } //非拆链接数据包 http_data * http_entry = NULL; http_entry = http_parse(swp, list1->status); //检查是否为http协议数据包 if(http_entry->is_http) { //服务器回复登录确认,说明用户成功登录 if(list1->status == S1) { if(http_entry->login_done == true) { printf("login_done \n"); hash_md5(list1->secret_key, (uint8_t*)list1->username, strlen(list1->username)); uint8_t tmp[256]; RC4_KEY rkey; int i=0; for(i=0;i<256;i++) tmp[i]=i; for(i=0;i<256;i++) { RC4_set_key (&rkey, 16, list1->secret_key); RC4 (&rkey, 1, tmp+i, list1->enc_map+i); } list1->status = S2; } cvm_common_free_fpa_buffer ((void*)http_entry, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE / CVMX_CACHE_LINE_SIZE); http_entry = NULL; return res; } //用户发送上传数据命令put if(list1->status == S2) { //Clietn->Server if(http_entry->put_content == true) { printf("put content \n"); list1->status = S3;//将list1结构体的状态设置为数据上传S3 if(http_entry->there_is_data)//如果包含数据部分,则对数据进行加密,否则直接返回 { printf("put content, encrypt first packet\n"); encryption(list1->enc_map, swp, http_entry->pos); res = 0; } } //Server->Client else if(http_entry->get_content == true) { printf("get content \n"); list1->status = S4; if(http_entry->there_is_data) { printf("get content, decrypt first packet\n"); encryption(list1->enc_map, swp, http_entry->pos); res = 0; } } cvm_common_free_fpa_buffer ((void*)http_entry, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE / CVMX_CACHE_LINE_SIZE); http_entry = NULL; return res; } //下载数据结束 //上传数据成功 if((list1->status == S4 && http_entry->get_done == true) || (list1->status == S3 && http_entry->put_done)) { printf("put or get done!\n"); list1->status = S2; cvm_common_free_fpa_buffer ((void*)http_entry, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE / CVMX_CACHE_LINE_SIZE); http_entry = NULL; return res; } //printf("Waring\n"); } else//在list1中,非拆链接数据包,也不带http头,应该为需要加解密的数据包,根据list1_entry.state状态机进行加解密 { //数据上传过程,需要对数据进行加密 //数据下载过程,需要对数据进行解密 if(list1->status == S3 || list1->status == S4) { res = 0; //54 is the length of MAC+IP+TCP //printf("encryption! \n"); encryption(list1->enc_map, swp, 54); //printf("after encryption\n"); cvm_common_free_fpa_buffer ((void*)http_entry, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE / CVMX_CACHE_LINE_SIZE); http_entry = NULL; return res; } } if(http_entry != NULL) cvm_common_free_fpa_buffer ((void*)http_entry, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE / CVMX_CACHE_LINE_SIZE); http_entry = NULL; return res; } else//链接不在规则列表中 { //printf("not in list1\n"); //是否为服务器与客户端之间的新建链接 http_data * http_entry; http_entry = http_parse(swp, S2); if(http_entry->is_http == true) { if(http_entry->put_content == true)//PUT test { printf("put test\n"); list1_entry_t * list1 = make_list1_entry(swp); list1->tag1 = swp->hw_wqe.tag; memcpy(list1->username, "put test", 8); hash_md5(list1->secret_key, (uint8_t*)list1->username, strlen(list1->username)); uint8_t tmp[256]; RC4_KEY rkey; int i=0; for(i=0;i<256;i++) tmp[i]=i; for(i=0;i<256;i++) { RC4_set_key (&rkey, 16, list1->secret_key); RC4 (&rkey, 1, tmp+i, list1->enc_map+i); } //hash_md5(list1->secret_key, (uint8_t*)list1->username, strlen(list1->username)); list1->status = S3; list1->inport = swp->hw_wqe.ipprt; if( list1->inport >= portbase + portnum) list1->outport = list1->inport - portnum; else list1->outport = list1->inport + portnum; if(http_entry->there_is_data)//如果包含数据部分,则对数据进行加密,否则直接返回 { encryption(list1->enc_map, swp, http_entry->pos); res = 0; } } else if(http_entry->get_content == true) { printf("get test\n"); list1_entry_t * list1 = make_list1_entry(swp); list1->tag1 = swp->hw_wqe.tag; memcpy(list1->username, "get test", 8); hash_md5(list1->secret_key, (uint8_t*)list1->username, strlen(list1->username)); uint8_t tmp[256]; RC4_KEY rkey; int i=0; for(i=0;i<256;i++) tmp[i]=i; for(i=0;i<256;i++) { RC4_set_key (&rkey, 16, list1->secret_key); RC4 (&rkey, 1, tmp+i, list1->enc_map+i); } //hash_md5(list1->secret_key, (uint8_t*)list1->username, strlen(list1->username)); list1->status = S3; list1->inport = swp->hw_wqe.ipprt; if( list1->inport >= portbase + portnum) list1->outport = list1->inport - portnum; else list1->outport = list1->inport + portnum; if(http_entry->there_is_data)//如果包含数据部分,则对数据进行加密,否则直接返回 { encryption(list1->enc_map, swp, http_entry->pos); res = 0; } } } cvm_common_free_fpa_buffer ((void*)http_entry, CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE / CVMX_CACHE_LINE_SIZE); return res; } }
hash_stat hash_plugin_check_hash(const char *hash, const char *password[VECTORSIZE], const char *salt, char *salt2[VECTORSIZE], const char *username, int *num, int threadid) { int len = strlen(password[0]); return hash_md5(password, salt2, len, THREAD_LENPROVIDED); }