E N D
In peer-to-peer networks such as gnutella, each host must search out other hosts. When a host finds another host, these hosts become neighbors. Often a host will continue to search for peers until a sufficient number of hosts have been found. Lets assume that a host will continue to search for hosts until it has N neighbors. In this project, peer-to-peer neighborhoods are made and maintained. Each host maintains list of neighbors and sends hello packets to these neighbors every 10 seconds. If a host is on the neighbor list, and no hello packet is received from the host for 40 seconds, then this host is removed from the neighbor list. If a node does not have enough neighbors, then it selects an address (e.g., IP and port) at random and tries to become its neighbor.
Objectives • Find N neighbors • A node is a neighbor if two-way communication is possible and verified • Two-communication == bidirectional link • Maintain N neighbors • If two-way communication is no longer verified, the node is no longer a neighbor
Detecting Bidirectional Links • Node A has a bidirectional with node B if • Node A can hear node B • Node B can hear node A • To determine if a link between node A and B is bidirectional • Node A sends a message to node B • Node B sends a message to node A saying that it can hear node A • Now node A believes the link is bidirectional • Node A sends a message to node B saying that it can hear node B • Now node B believes the link is bidirectional • In general, to determine is links are bidirectional • Send hello messages where the message includes a list of all nodes that have been heard • Upon receiving a hello message, • If you are listed as one of the nodes that has been heard, then the link is bidirectional • Add the sender of the hello to the list of nodes that you can hear
Neighbor States nothing Received a hello and this node is not listed as recently heard No hello received for a long time Received a hello with this node listed as recently heard one-way (receivable) Received a hello with this node listed as recently heard Received a hello and this node is not listed as recently heard No hello received for a long time bidirectional
Neighbor States nothing Received a hello and this node is not listed as recently heard No hello received for a long time Received a hello with this node listed as recently heard semiActive Received a hello with this node listed as recently heard Received a hello and this node is not listed as recently heard active No hello received for a long time
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state waiting Hello arrived from node B This node is listed in recently heard nodes Node B is neither list Put B into activeNeighbors Node B is semiActiveNeighbors This node is NOT listed in recently heard nodes Node B is activeNeighbors Put B into semiActiveNeighbors This node is NOT listed in recently heard nodes This node is listed in recently heard nodes Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors
Lists • C++ Standard template library list • Add the following to the top of cpp file #include <list> using namespace std; • E.g., list of ints • making a list of ints list<int> myList; • Add an element to myList myList.push_back(1); myList.push_back(2); myList.push_back(1); • Iterate through the list and print each element for( list<int> iterator it=myList.begin(); it!=myList.end(); ++it) printf(“entry=%d\n”,*it); • Remove an element from the list intelementToRemove = 2; for( list<int> iterator it=myList.begin(); it!=myList.end(); ++it) { if (*it == elementToRemove) { myList.erase(it); break; // not breaking would result in a crash } } • Alternatively myList.remove(1); // removes all elements == 1. But this requires == operator, which exists for int, but might not for other types
Structures structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; structPktStruct { inttype; char senderIP[16]; unsigned intsenderPort; intnumberOfRecentlyHeardNeighbors; structRecentNeighborEntryrecentNeighbors[100]; }; structRecentNeighborEntry { char ip[16]; unsigned int port; };
List structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; boolcheckIfInList(HostID &host, list<HostID> &L) { std::list<structHostID>::iterator it; for (it=listToCheck.begin(); it!=listToCheck.end(); ++it) if (it->ip == hid.ip&& it->port == hid.port) return true; return false; }
List structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; boolcheckIfInList(HostID &host, list<HostID> &L) { std::list<structHostID>::iterator it; for (it=listToCheck.begin(); it!=listToCheck.end(); ++it) if (strcmp(it->ip,hid.ip)==0 && it->port == hid.port) return true; return false; }
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state waiting Hello arrived from node B This node is listed in recently heard nodes Node B is neither list Put B into activeNeighbors Node B is semiActiveNeighbors This node is NOT listed in recently heard nodes Node B is activeNeighbors Put B into semiActiveNeighbors This node is NOT listed in recently heard nodes This node is listed in recently heard nodes Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state waiting Hello arrived from node B This node is listed in recently heard nodes Put B into activeNeighbors else checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in recently heard nodes Put B into semiActiveNeighbors This node is NOT listed in recently heard nodes This node is listed in recently heard nodes Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) else Hello arrived Extract sender from hello This node is listed in recently heard nodes Put B into activeNeighbors else checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in recently heard nodes Put B into semiActiveNeighbors This node is NOT listed in recently heard nodes This node is listed in recently heard nodes Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors
structPktStruct { • int type; • char senderIP[16]; • unsigned intsenderPort; • intnumberOfRecentlyHeardNeighbors; • structRecentNeighborEntryrecentNeighbors[100]; • }; Receiving a Packet • PktStructpkt; • int ret = checkForNewPacket(UDPSock, (char *)&pkt, 2); // time out of 2 seconds • The pkt object is a string or chunk of bytes • &pkt is the pointer to pkt • (char *)&pkt treats this pointer as a string of bytes
Extract Sender from Hello Message • PktStructpkt; • int ret = checkForNewPacket(UDPSock, (char *)&pkt, 2); • HostID sender; • sender.ip = pkt.senderIP; • sender.port = pkt.senderPort; • structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; • structPktStruct { • int type; • char senderIP[16]; • unsigned intsenderPort; • intnumberOfRecentlyHeardNeighbors; • structRecentNeighborEntryrecentNeighbors[100]; • };
Extract Sender from Hello Message • PktStructpkt; • int ret = checkForNewPacket(UDPSock, (char *)&pkt, 2); • HostID sender; • strcpy(sender.ip , pkt.senderIP); • sender.port = pkt.senderPort; • structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; • structPktStruct { • int type; • char senderIP[16]; • unsigned intsenderPort; • intnumberOfRecentlyHeardNeighbors; • structRecentNeighborEntryrecentNeighbors[100]; • };
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) else Hello arrived Extract sender from hello This node is listed in recently heard nodes Put B into activeNeighbors else checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in recently heard nodes Put B into semiActiveNeighbors This node is NOT listed in recently heard nodes This node is listed in recently heard nodes Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors
thisHost int main(intargc, char* argv[]) { HostIDthisHost; fillThisHostIP(thisHost); // provided in helper.cpp thisHost.port = atoi(argv[1]); …
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) else Hello arrived Extract sender from hello This node is listed in recently heard nodes Put B into activeNeighbors else checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in recently heard nodes Put B into semiActiveNeighbors checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors
checkIfThisHostIsInRecentlyHeardNeighbors • structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; • structPktStruct { • int type; • char senderIP[16]; • unsigned intsenderPort; • intnumberOfRecentlyHeardNeighbors; • structRecentNeighborEntryrecentNeighbors[100]; • }; • structRecentNeighborEntry { • char ip[16]; • unsigned int port; • }; for (inti=0; i<pkt.numberOfRecentlyHeardNeighbors; i++) { if (pkt.recentNeighbors[i] == thisHost) return true; } return false;
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) else Hello arrived Extract sender from hello checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==true else Put sender into activeNeighbors checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==false Put sender into semiActiveNeighbors checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false Move sender from semiActiveNeighbors to ActiveNeighbors Move sender from ActiveNeighbors to semiActiveNeighbors
Neighbor List Activity Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) else Hello arrived Extract sender from hello checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==true else Put sender into activeNeighbors checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==false Put sender into semiActiveNeighbors checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false Move sender from semiActiveNeighbors to ActiveNeighbors Move sender from ActiveNeighbors to semiActiveNeighbors
Lists • C++ Standard template library list #include <list> using namespace std; • Making a list of ints list<int> myList; • Add an element to myList myList.push_back(1); myList.push_back(2); myList.push_back(1); • Iterate through the list for( list<int> iterator it=myList.begin(); it!=myList.end(); ++it) printf(“entry=%d\n”,*it); • Remove an element from the list intelementToRemove = 2; for( list<int> iterator it=myList.begin(); it!=myList.end(); ++it) { if (*it == elementToRemove) { myList.erase(it); break; // not breaking would result in a crash } } • Alternatively myList.remove(1); // removes all elements == 1. But this requires == operator, which exists for int, but might not for other types
Objectives • Find N neighbors • A node is a neighbor if two-way communication is possible and verified • Two-communication == bidirectional link • Maintain N neighbors • If two-way communication is no longer verified, the node is no longer a neighbor
To do • While (1) • Receive hello • Process neighbor states (sort of like what we did) • Search for more neighbors? • Check and if so, search • Update neighbor set • If some neighbors have timed out, remove them • Send hello messages to neighbors • Send every 10 sec
To do • While (1) • Receive hello • Process neighbor states (sort of like what we did) • Search for more neighbors? • Check and if so, search • Update neighbor set • If some neighbors have timed out, remove them • Send hello messages to neighbors • Send every 10 sec
Search for more neighbors intmain(intargc, char* argv[]) { boolsearchingForNeighborFlag = false; readAllHostsList(argv[2], allHosts); // provided while (1) { if (activeNeighbors.size() + semiActiveNeighbors.size() < DESIRED_NUMBER_OF_NEIGHBORS && ) { searchingForNeighborFlag=true; tempNeighbor= selectNeighborAtRandom(activeNeighbors, semiActiveNeighbors, allHost, thisHost); // provided } ….
To do • While (1) • Receive hello • Process neighbor states (sort of like what we did) • Search for more neighbors? • Check and if so, search • Update neighbor set • If some neighbors have timed out, remove them • Send hello messages to neighbors • Send every 10 sec
Process Hello intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==true Put sender into activeNeighbors else checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==false Hello arrived Extract sender from hello Put sender into semiActiveNeighbors else checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true sender==tempNeighbor searchingForNeighborFlag = false checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false Move sender from semiActiveNeighbors to ActiveNeighbors Move sender from ActiveNeighbors to semiActiveNeighbors Put sender into activeNeighbors Put sender into semiActiveNeighbors
To do • While (1) • Receive hello • Process neighbor states (sort of like what we did) • Search for more neighbors? • Check and if so, search • Update neighbor set • If some neighbors have timed out, remove them • Send hello messages to neighbors • Send every 10 sec
Process Hello updateLastReceivedTime(sender, activeNeighbors) intcheckForNewPacket(SOCKET UDPSock, char *pkt, intTimeOut) checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==true Put sender into activeNeighbors else checkIfThisHostIsInRecently HeardNeighbors(pkt, thisHost)==false Hello arrived else Extract sender from hello Put sender into semiActiveNeighbors updateLastReceivedTime(sender, semiActiveNeighbors) checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true sender==tempNeighbor searchingForNeighborFlag = false checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost)==true checkIfThisHostIsInRecently HeardNeighbors(pkt,thisHost) ==false Move sender from semiActiveNeighbors to ActiveNeighbors Move sender from ActiveNeighbors to semiActiveNeighbors Put sender into activeNeighbors Put sender into semiActiveNeighbors updateLastReceivedTime(sender, activeNeighbors) updateLastReceivedTime(sender, semiActiveNeighbors) updateLastReceivedTime(sender, activeNeighbors) updateLastReceivedTime(sender, semiActiveNeighbors)
Lists • structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; • structPktStruct { • int type; • char senderIP[16]; • unsigned intsenderPort; • intnumberOfRecentlyHeardNeighbors; • structRecentNeighborEntryrecentNeighbors[100]; • }; • structRecentNeighborEntry { • char ip[16]; • unsigned int port; • }; • C++ Standard template library list • #include <list> • using namespace std; • Making a list of ints • list<int> myList; • Add an element to myList • myList.push_back(1); • myList.push_back(2); • myList.push_back(1); • Iterate through the list • for( list<int> iterator it=myList.begin(); it!=myList.end(); ++it) • printf(“entry=%d\n”,*it); • Remove an element from the list • intelementToRemove = 2; • for( list<int> iterator it=myList.begin(); it!=myList.end(); ++it) • { • if (*it == elementToRemove) • { • myList.erase(it); • break; // not breaking would result in a crash • } • } • Alternatively • myList.remove(1); // removes all elements == 1. But this requires == operator, which exists for int, but might not for other types
To do • While (1) • Receive hello • Process neighbor states (sort of like what we did) • Search for more neighbors? • Check and if so, search • Update neighbor set • If some neighbors have timed out, remove them • Send hello messages to neighbors • Send every 10 sec
Send hello messages to neighbors every 10 sec • #include <time.h> • #include <sys/types.h> • #include <sys/timeb.h> • intmain(intargc, char* argv[]) • { • …. struct_timeblastTimeHellosWereSent; _ftime_s( &lastTimeHellosWereSent ); struct_timebcurrentTime; while (1) { _ftime_s( ¤tTime ); if (currentTime.time > lastTimeHellosWereSent.time + 10) { lastTimeHellosWereSent= currentTime; sendHellos(…) } ….
Send hello messages to neighbors every 10 sec • #include <time.h> • #include <sys/types.h> • #include <sys/timeb.h> • intmain(intargc, char* argv[]) • { • …. struct_timeblastTimeHellosWereSent; lastTimeHellosWereSent.time = 0; _ftime_s( &lastTimeHellosWereSent ); struct_timebcurrentTime; while (1) { _ftime_s( ¤tTime ); if (currentTime.time > lastTimeHellosWereSent.time + 10) { lastTimeHellosWereSent= currentTime; sendHellos(…) } ….
sendHellos(…) • structHostID { char ip[16]; unsigned int port; unsigned intlastTimeHelloRec; }; • structPktStruct { • int type; • char senderIP[16]; • unsigned intsenderPort; • intnumberOfRecentlyHeardNeighbors; • structRecentNeighborEntryrecentNeighbors[100]; • }; • structRecentNeighborEntry { • char ip[16]; • unsigned int port; • }; • sendHelloToANeighbor • Hello must include all heard neighbors • activeNeighbors • semiActiveNeighbors • Not tempNeighbor • void sendHelloToNeighbor( SOCKET UDPSock, HostID destination, list<HostID> &activeNeighbors, list<HostID> &semiActiveNeighbors, HostID&thisHost); • Hello must be sent to • activeNeighbors • semiActiveNeighbors • ANDtempNeighbor • for(it= activeNeighbors.begin(); it!=activeNeighbors.end() ++it) • { sendHelloToNeighbor(UDPSock, *it, activeNeighbors, semiActiveNeighbors, thisHost); } ….