static void fst_plugin_discover_callback (FSTUdpDiscover *discover, FSTUdpNodeState node_state, FSTNode *node) { switch (node_state) { case UdpNodeStateDown: /* remove this node from node cache _if_ we know that udp works. * otherwise just move the node to the back of the cache. */ if (FST_PLUGIN->discover->udp_working) { FST_HEAVY_DBG_2 ("UdpNodeStateDown: %s:%d, UDP works", node->host, node->port); /* remove node if it is not connected. */ if (!node->session) fst_nodecache_remove (FST_PLUGIN->nodecache, node); } else { FST_HEAVY_DBG_2 ("UdpNodeStateDown: %s:%d, UDP not verified", node->host, node->port); /* move the node to back of cache */ fst_nodecache_move (FST_PLUGIN->nodecache, node, NodeInsertBack); } break; case UdpNodeStateUp: FST_HEAVY_DBG_2 ("UdpNodeStateUp: %s:%d", node->host, node->port); /* move the node to back of cache */ fst_nodecache_move (FST_PLUGIN->nodecache, node, NodeInsertBack); break; case UdpNodeStateFree: FST_HEAVY_DBG_2 ("UdpNodeStateFree: %s:%d", node->host, node->port); /* Insert node with new load and last_seen values. This will inevitably * Move the node to the front part of the list so it gets picked the * next time we connect. */ fst_nodecache_move (FST_PLUGIN->nodecache, node, NodeInsertSorted); break; } /* print out some stats if all pings have come back / timed out */ if (FST_PLUGIN->discover->pinged_nodes == 0) { FST_DBG_3 ("discovery cycle complete: %d pings, %d pongs, %d others", discover->sent_pings, discover->received_pongs, discover->received_others); discover->sent_pings = 0; discover->received_pongs = 0; discover->received_others = 0; } }
int fst_cipher_init (FSTCipher *cipher, unsigned int seed, unsigned int enc_type) { int i,j; unsigned int temp; unsigned int sortpos; unsigned char c; cipher->enc_type = enc_type; cipher->wrapcount = 0; cipher->add_to_lookup = 0; cipher->seed = seed; FST_HEAVY_DBG_2 ("init_cipher: seed = 0x%08x, enc_type = 0x%02x", seed, enc_type); if (!pad_init (&seed, enc_type, cipher->pad, sizeof (cipher->pad))) return FALSE; /* adjust pad */ c = 0; for (i = 0; i < sizeof (cipher->pad); i++) c = c | cipher->pad[i]; if (!(c & 1)) cipher->pad[0] = cipher->pad[0] | 0x71; /* init cipher->pos */ temp = seed_step (seed); temp = temp >> 16; cipher->pos = ( (temp << 6) - temp) >> 16; /* init cipher->lookup */ for(i = 0; i <sizeof (cipher->lookup); i++) cipher->lookup[i] = (unsigned char)i; if (enc_type & 0x08) { MD5Context ctx; unsigned char md5[MD5_HASH_LEN]; FST_HEAVY_DBG ("init_cipher: enc_type & 0x08"); MD5Init (&ctx); MD5Update (&ctx, cipher->pad, sizeof(cipher->pad)); MD5Final (md5, &ctx); /* correct md5 byte order on big-endian since it's converted to (unsigned int*) below */ reverse_bytes ( (unsigned int*)&md5, 4); /* modify cipher->lookup */ for (i = 0; i < sizeof (cipher->lookup); i++) { if ( (j = calculate_num( (unsigned int*) &md5, 0x100 - i) + i) != i) { unsigned char a = cipher->lookup[j]; unsigned char b = cipher->lookup[i]; cipher->lookup[i] = a; cipher->lookup[j] = b; } } } if(enc_type & 0x10) { FST_HEAVY_DBG ("init_cipher: enc_type & 0x10"); for (seed = cipher->pos, i=0; i < 20; i++) { seed = seed_step (seed); cipher->pad16[i] = seed; } seed = seed_step (seed); /* CHECKME: endianess? */ EncryptionType2::enc_type_2(cipher->pad16, seed); } /* sort cipher->pad */ sortpos = ( (cipher->pos * cipher->pos) + 2) % (sizeof(cipher->pad)-4); qsort (cipher->pad + sortpos, 5, 1, qsort_cmp_func); /* modify every third byte of cipher->pad */ for (i = 5; i < sizeof (cipher->pad); i += 3) { c = cipher->pad[i]; c = ~c + i; cipher->pad[i] = c | 1; } // print_bin_data(cipher->pad, sizeof(cipher->pad)); // print_bin_data(cipher->lookup, sizeof(cipher->lookup)); return TRUE; }