TODO: * More work on KademliaManager * Is there a way for new nodes to actually get into their neighbors' lists -- m_keys and m_nodes? * When the node wants to find its way in, we should add them -- assuming we can contact them and they belong in our list. * What can we do to ensure that they're in the neighbors' lists? * How do we in general ensure that our neighbors' lists are in sync with our own? We need regular sync checks based on the popular vote. The frequency with which we allow these sync checks needs to be limited. * Make it so that a new node alerts all of its neighbors that it exists in find_location. * Need a way to restore missing core keys and otherwise adjust positions in idle. * Make sure that anything called in idle can't stall while waiting on network traffic. If it can, it needs to be a thread instead. * The packets used by KademliaManager and any helper functions that they need. * Said packets: one type requres that we store its replies in an array, and we're currently passing the packets the address for the return, by reference. Rather, we should be giving them a randomly generated u_int64_t id. * Check our session_ids and make sure that there wouldn't be problems with people forging them. * For a RegisterClient request packet, we need to verify that the packet isn't forged with a quick ack/response mechanism before calling register_client. * Follow up on the READMEs * Make it save the last nodes neighboring us when we log out and use those for when we log in. Should make finding our position very fast. * If the SuperFastHash author doesn't respond... hey, they only have a copyright, not a patent. We can always implement the algorithm ourselves. :) * Start work on the "KademliaDmoge" class, which layers all of the Dmoge- specific functionality onto our Kademlia network. Below is how the overall process will work: * We're *not* going to use any "always on" encryption; only hashing to keep things like passwords safe. * We need to get a certificate for our avatar. This implies talking to the metadata table owners for our client and sending them a certificate request. They have our blowfish public key on file. The returned request will provide us with salt. We will then send the salt plus our password encrypted with our private key and their public key. They will be able to validate us, then, and will accept a bit of random salt that we provide them as our certificate (they will verify in a reply). To use this certificate, when we want to authenticate ourselves with another region, the region sends us salt of their own, and we xor it with our certificate's salt and MD5 the whole thing. It sends the same salt to the authoritative region server for our user. The MD5s will match. Anyways, if the login fails, we bail. If it succeeds, we continue. * New character creation is similar; we provide our public key and character meta-info. They keep it on file. There should be a reasonable limit to the number of characters on file. Any login of a different character should invalidate the old running certificate and alert the regions that the old avatar is a client to that they're no longer valid. I.e., the metadata table needs to know all regions that we're connected to. We'll make that the region's responsibility, not the avatar's, since the avatar is one point of failure, while the region is five or so redundant points of failure. * The main goal of the connection attempt is to receive shared servership of a whole bunch of regions, to know who the co-servers of those regions are, and to cache that information. * We also need to authenticate as a client to the region where our avatar is using our certificate. * Recruit Elaine to help calculate the probabilities of attacker success with various configuration options, such as varying amounts of servers for each region with M clients and N attackers. :) 22-01-2008: * Resumed work. 2/3 done with a function to allow new nodes to be registered with a client. 30-12-2007: * Stopped try_to_kick_client from running ad nauseum if its peers think the client is okay. 29-12-2007: * Wrote try_to_kick_client(). 28-12-2007: * Had eyes cut on. Can read the screen. That's a good start. Too bright to be comfortable, though, so not going to work on it. But will think about the TODOs. 26-12-2007: * Completed logoff_client() 25-12-2007: * Mostly completed the surprisingly difficult logoff_client() function 24-12-2007: * Finished find_location. * Created the requisite find_location that can search based on hash alone * These two function completions denote the end of the original coding phase of KademliaManager (apart for corrections/additions needed in the next stage, the packets it uses, plus any potential problems we think up). * Problems thought up :P So, more to do. 23-12-2007: * Lots of work. Almost finished find_region_sharing_nodes_at_hash(), which is now simply called "find_location". 22-12-2007: * More work on find_region_sharing_nodes_at_hash() 21-12-2007: * Work on find_region_sharing_nodes_at_hash() 18-12-2007: * Only had time to lay out a more detailed approach to writing find_region_sharing_nodes_at_hash(). At least the truffles are done. 16-12-2007: * More mutex locking * Create_core_keys() finished 15-12-2007: * Revised find_our_location finished. Still has one unimplemented helper function (create_core_keys()) remaining. 14-12-2007: * Lots more work on the location finding process. Just a couple more TODOs, and the revised find_our_location will be done. 13-12-2007: * Finished KademliaManager::find_neighbors_for_other_node() * Lots of work on the location finding process (revising find_our_location so that we no longer need to implement an additional continue function) 11-12-2007: * Restructured existing KademliaManager code to use a single two-layered ring cache instead of a cache and a neighbors list. Now we use key nodes that keep their neighbor lists up to date. 10-12-2007: * KademliaManager::find_our_location finished. 09-12-2007: * Wrote KademliaManager::idle * Wrote a framework for KademliaManager::find_our_location. 08-12-2007: * Implemented a filler fast hash function until we can get the license for SuperFastHash. * Hooked in libgmp to be our Hash type for arbitrary precision integer mathematics. * Wrote a framework for a kademlia manager cache. 07-12-2007: * Fixed "crash" (not a crash at all; the program was just exiting because we mistakenly told it to) * RadioGatun hashing, check. 06-12-2007 * Config-system debugging complete. Still need to figure out why this new crash is happening, but it doesn't seem to have anything to with the config system. 05-12-2007 * Fixed an inexplicable zombie-hang by rebooting and random build process tweaks * More work on config system debugging 04-12-2007 * Created a config file loading/saving system * Set it to be used. * Started debugging it. 03-12-2007 * Got it running right with our basic send-reply test case. On to creating a proper Kademlia network! * Did most of the Kademlia design TODOs. 02-12-2007 * Got it to compile 01-12-2007: * Changed things that address nodes by IP,PORT to only address by IP. We need the port, but only one client allowed per IP. * Made sure sends/replies timeout. * Made it so that replies get sent out. * Reformatted away the four space indent to a two space indent. * Converted "complex functions" into classes. * Replaced semaphores (the "lock_*"s) with mutexes. * Extended stl classes to group variables together. * Made a debugging flag that treats ports as IPs * Made our packet types inherit properly. 31-11-2007: * Renamed their_packets to something more accurate. * Made it so that requisite_reply isn't stored in queue_element, but as a base packet function. 30-11-2007: * Eliminated "their_packets". We should handle all incoming packets immediately. All we need to keep in memory is what we need to ack. * Restored being_acked as "acks_sent_so_far" * Made use of ip and port in the acks queue. * Told acks to queue up with the new system * Made a framework "handle_error" 29-11-2007: * More structure simplifying, although restoring some previously deleted functionality in an easier-to-use manner. 28-11-2007: * Resumed work. * Took out all NS-2/GEA stuff that we stalled on. * Started simplifying structure. No ack-acking, no packet templates, etc. * Removed all "using namespace" statements. * Added in an MD5 context 16-08-2005: * Ready to start debugging NS-2/GEA packet receipt 08-08-2005: * Got started on NS-2/GEA packet receipt 27-07-2005: * Started writing our NS-2/GEA wrapper inside our network object, which can be enabled at will to replace the standard network object. 22-07-2005: * Got NS-2 installed (yeay!). Verified that the sampple NS code works. Now we need to see GEA working. 21-07-2005: * Working on installing NS and all of its app requirements. Tcl is being problematic; I'm going to have to get files from its source. 20-07-2005: * ack_received and reply_received functions are getting called correctly now. Time to hook up NS! 18-07-2005: * Figured out why we were getting AskRSAKey serialization in the middle of AskRSAKeyReply deserialization, and why we were locked: It started preparing to transmit before the deserialization began. * Made debugging statements more fine-grained * Aha! Our "continue" statements were not advancing the iterator, making our loops be stuck until they no longer me the continue conditions! 17-07-2005: * Tossed out another stall-causing delay * Fixed out an early packet loss due to packets getting sent before we were fully initialized. 12-07-2005: * Got rid of a problematic delay in add_their_packets by stopping it from passing control back to the system at the end of the function with a 50us sleep (which equated to thousands of us) * Did the same for pick_a_few_acks. 11-07-2005: * Added in sleeps after unlocking statements to allow the system to transfer control. 10-07-2005: * Fixed a semaphore lock error * Adjusted packet timings * Added a delay into the listening thread so that the transmission thread gets a chance to read. * We were creating a packet (and thus picking acks) *before* we added the response packet to their_packets, and thus it couldn't pick to ack what it was replying to. * Stopped BulkAck from sending more than once (again!) 08-07-2005: * Made pick_a_few_acks only get called once per packet. Otherwise, packets think they're being acked when the received packets are going to be ignored as duplicates. * A "our_packets" entry was being deleted in the middle of iteration over our_packets by a separate thread. To fix this, I implemented semaphores for our_packets and their_packets. There may be problems with it, though. 06-07-2005: * Got it to stop forming new BulkAck packets: we hadn't put any way in previously to know if a packet was queued up that would take care of the ack for us. New problem, though: While we're still BulkAckWithAck-ing, we're getting no response. 31-06-2005; * Got the proper number of BulkAck sends per packet. 30-06-2005: * Got to build on the laptop 24-06-2005: * Got the initiating node to work completely properly (excepting some timing issues). Now to stop the responder from sending too many times. 23-06-2005: * Didn't get packet acking fully fixed, but made significant progress! I think once we implement the has_ack function, our initiator side will be functioning perfectly. Then we'll need to stop BulkAcks from sending four times. Then, we'll need to make bulk acks go off faster, so that we don't get four AskForRSAKeyReply sends before we get the reply. Lastly, we need to look for any other anomalies. 22-06-2005: * Fixed another packet-time limiting bug: this time it was due to our stand-in operator< for PacketType. Replaced with a real operator<. It took forever to figure out. :P * Put in "ack_needs_ack" check into packets, to stop repeating bulk-acks-bulk loops. 21-06-2005: * Fixed SerializableVector (aka, standard acks) serialization. We were calling u_int16_t size=htonl(this->size()). The htonl put the significant digits into a place in the number that was truncated upon conversion. Changed to u_int16_t size=htons((u_int16_t)(this->size())) * Fixed the dreaded segfaults: they were due to the last packet in their_packets being deleted, and the iter then equalling the end. However, the iterator increment then occurred, shooting it *past* the end. * Fixed erroneous condition on packet time limiting: we were making packets have to be *within* the time limit, instead of outside. 20-06-2005: * Got a bulk ack to send for the first time by adjusting the boundary condition * Made a more reasonable ack-choosing method 19-06-2005: * Fixed a bug where deserialize_custom wasn't being called on receipt of AskForRSAKeyReply because we were iterating over their_packets, not ours. * Got rid of an incorrectly-called reply_not_received * Removed "dest" field in queue_element, as it wasn't being used often/well. * Reply-to packets are only deserializing once, yeay! * The side launched first had two AskForRSAKeyReplies added to its their_packets queue because it was passing the packetID order check. Our check forgot about the case where the two ids were equal; fixed. 18-06-2005: * Fixed RSA contexts so that copy constructors work (were forgetting to add in the length of the size header on deserialization of bignums) * Fixed all serialization issues (yeay!): when we changed it to make it have better error reporting and such, we lost the ability to capture the newly created BIGNUM* in the return value; fixed. * Switch to serializing/deserializing of public key only * Make delay resonable * Increase the delay after each send - 2x? * Made it so that we only deal with received packets on expected packet IDs. * We were sending packets one-too-many times. * Received reply packets which don't have a source are ignored. * Fixed a bug preventing packet validation: we were overloading last_packet_id_map to mean both the received ID from a given IP, and the last sent IP to that address. Split. * Made a packet ID always get generated on new packets 17-06-2005: * Fixed the cause of our AskForRSAKeyReply packets being deleted after we called to add them into the queue: we were adding the wrong shared pointer into the queue! :) * Fixed lack of sending: even though we don't need a reply, we still need to *send*. Changed "reply_tries_left" to "send_tries_left", and dealt with appropriately. * Modified rsa and blowfish context serialization/deserialization for improved error handling (and to prevent crash on bad data), but it no longer encrypts accurately (will fix). 16-06-2005: * Fixed the length of received packets being wrong: we weren't using the return value of recvfrom. * Fixed packetid of incoming packet (we were deserialzing to the replyid instead) * Incoming packet was getting deleted because it wasn't making it into the sending queue properly, because of that old "making a shared pointer from "this" doesn't preserve count) * Fixed a minor bug that was casing the first packet from a given IP to be dropped, because of our response time limiting function had one wrong response_time return value. * Corrected the prototype for custom deserialization so that the inherited version gets called, not its parent. 15-06-2005: * Made it receive incoming packets off the wire (our IP class already was doing htonl, so it ended up being called twice. * Fixed debugging statements that used + instead of << and were causing segfault. 14-06-2005: * Made packets be created on the heap instead of the stack (whoops!) * Got rid of all shared_ptr packet(this) cases, because they simply don't work. Replaced with arguments passed into the function. * Made it so that packets that get sent their max allotted times get deleted, regardless of whether or not they were acked. * Modified erase calls so that the iterator is recaptured afterwards, pointing to the next valid entry. Now things are behaving exactly as expected with server-only running. 13-06-2005: * Vastly improved our function insturmentation - now function names and almost all arguments are displayed. * Fixed segfault from invalid string conversion call * Changed ambiguous queue names "needed" and "need_to" to "our_packets" and "their_packets" * Fixed bug that was looking for excessive delays before sending/acking 12-06-2005: * network_listening_thread takes all packets off the wire and deserializes them * read_datagram also retrieves IP and Port info * Made our bulk ack serialization/deserialization handle its acks * Handled packet type in deserialization. Ready to debug :) * Fixed network start bug: we don't need listen() for datagrams. * Did basic function insturmentation 11-06-2005: * network_transmission_thread monitors need_to_reply, signals acks that stick around for an extra cycle, and sends them in bulk the time after that. Creates packets by create_reply_packet, then calls reply, serialize, and send. Packet goes in needed_acks, and possibly needed_replies 10-06-2005: * Use namespaces * Hooked in everybody's favorites - smart pointers :) * Launched AskForRSAKey; modified packet ID generation to autoclean * queue_up function added. 09-06-2005: * Two types of bulk acks: one that needs replies, and one that doesn't * Split up the network thread into a transmission and receiving thread * Merged library-end client and server code, since it was mostly duplicated, and just used a variable to distinguish whether it's client or server. * Simplifed the queues - merging from four to two. Major restructuring of queue elements. 08-06-2005: * Finished the packet flow document for key exchange * Layed out the TODOs based on that; made the decision to use smart pointers 07-06-2005: * Made PacketID generation no longer random, but sequential for each IP * Partly finished the packet flow document for key exchange 06-06-2005 * Improved encryption validation to prevent certain kinds of attacks * Reduced ack packet overhead * Made not all custom data need to be in the encrypted section * Added in bulk ack types and optional acks * Got it to compile :) 05-06-2005 * Finished all of the TODOs, including UDP networking. Working on compiling it. 04-06-2005 * Got the rough framework of the full program to compile (next: the finalized framework) 02-06-2005 * Using libds for crossplatform threading and networking * Preliminary compiling and running, layout is proper * Mailed the libds author to ask about UDP datagrams * Started on our packet layout 28-04-2005 * Restarted, to make use of libnet and my C++ packet methodology.