Date post: | 19-Dec-2015 |
Category: |
Documents |
View: | 218 times |
Download: | 1 times |
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 recently heard, then the link is bidirectional
• Add the sender of the hello to the list of nodes that you can hear
Neighbor States
nothing
one-way (receivable)
bidirectional
Received a hello and this node is not listed
in the hello as a recently heard node
Received a hello with this node listed as
recently heard
No hello received for a long time
Received a hello with this node listed as
recently heard
No hello received for a long time
Received a hello and this node is not listed
as recently heard
Neighbor States
nothing
semiActive
active
Received a hello and this node is not listed
as recently heard
Received a hello with this node listed as
recently heard
No hello received for a long time
Received a hello with this node listed as
recently heard
No hello received for a long time
Received a hello and this node is not listed
as recently heard
Neighbor List Activity Diagram
activeNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
waiting
Hello arrived from node B
Node B is semiActiveNeighbors Node B is activeNeighbors
Node B is neither list
This node is listed in the hello as a recently heard
node
Move B from semiActiveNeighbors to ActiveNeighbors
Move B from ActiveNeighbors to
semiActiveNeighbors
This node is NOT listed in the hello as a recently heard node
Put B into semiActiveNeighbors
Put B into activeNeighbors
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
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 intslist<int> myList;
– Add an element to myListmyList.push_back(1);myList.push_back(2);myList.push_back(1);
– Iterate through the list and print each elementfor( list<int>::iterator it=myList.begin(); it!=myList.end(); ++it)
printf(“entry=%d\n”,*it);
– Remove an element from the listint elementToRemove = 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
}}
– AlternativelymyList.remove(1); // removes all elements == 1. But this requires == operator, which exists for int, but might not for other types
• for( list<int>::iterator it=myList.begin(); it!=myList.end(); ++it)– printf(“entry=%d\n”,*it);
• Boost foreach.hpp
• foreach( int x, mylist)– printf(“entry=%d\n”,x);
Structuresstruct HostID { char ip[16];
unsigned int port;unsigned int lastTimeHelloRec;
};
struct PktStruct {int type;char senderIP[16];unsigned int senderPort;int numberOfRecentlyHeardNeighbors;struct RecentNeighborEntry recentNeighbors[100];
};
struct RecentNeighborEntry {char ip[16];unsigned int port;
};
List
bool checkIfInList(HostID &hid, list<HostID> &L){
list<struct HostID>::iterator it;for (it=listToCheck.begin(); it!=listToCheck.end(); ++it)
if (it->ip == hid.ip && it->port == hid.port)return true;
return false;}
struct HostID { char ip[16];
unsigned int port;unsigned int lastTimeHelloRec;
};
List
bool checkIfInList(HostID &hid, list<HostID> &L){
std::list<struct HostID>::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;}
struct HostID { char ip[16];
unsigned int port;unsigned int lastTimeHelloRec;
};
Neighbor List Activity Diagram
activeNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
waiting
Hello arrived from node B
Node B is semiActiveNeighbors Node B is activeNeighbors
Node B is neither list
Move B from semiActiveNeighbors to ActiveNeighbors
Move B from ActiveNeighbors to
semiActiveNeighbors
Put B into semiActiveNeighbors
Put B into activeNeighbors
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
Neighbor List Activity Diagram
activeNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
waiting
Hello arrived from node B
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move B from semiActiveNeighbors to ActiveNeighbors
Move B from ActiveNeighbors to
semiActiveNeighbors
Put B into semiActiveNeighbors
Put B into activeNeighbors
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
checkIfInList(sender, activeNeighbors)
==true
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
Neighbor List Activity DiagramactiveNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move B from semiActiveNeighbors to ActiveNeighbors
Move B from ActiveNeighbors to
semiActiveNeighbors
Put B into semiActiveNeighbors
Put B into activeNeighbors
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
Receiving a Packet
• PktStruct pkt;• 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
• struct PktStruct {• int type;• char senderIP[16];• unsigned int senderPort;• int numberOfRecentlyHeardNeighbors;• struct RecentNeighborEntry
recentNeighbors[100];• };
Extract Sender from Hello Message• PktStruct pkt;• int ret = checkForNewPacket(UDPSock, (char *)&pkt, 2);
• HostID sender;• sender.ip = pkt.senderIP;• sender.port = pkt.senderPort; • struct HostID {
char ip[16];unsigned int port;unsigned int lastTimeHelloRec;
};
• struct PktStruct {• int type;• char senderIP[16];• unsigned int senderPort;• int numberOfRecentlyHeardNeighbors;• struct RecentNeighborEntry recentNeighbors[100];• };
Extract Sender from Hello Message• PktStruct pkt;• int ret = checkForNewPacket(UDPSock, (char *)&pkt, 2);
• HostID sender;• strcpy(sender.ip , pkt.senderIP);• sender.port = pkt.senderPort; • struct HostID {
char ip[16];unsigned int port;unsigned int lastTimeHelloRec;
};
• struct PktStruct {• int type;• char senderIP[16];• unsigned int senderPort;• int numberOfRecentlyHeardNeighbors;• struct RecentNeighborEntry recentNeighbors[100];• };
Neighbor List Activity DiagramactiveNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move B from semiActiveNeighbors to ActiveNeighbors
Move B from ActiveNeighbors to
semiActiveNeighbors
Put B into semiActiveNeighbors
Put B into activeNeighbors
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
This node is listed in the hello as a recently heard
node
This node is NOT listed in the hello as a recently heard node
thisHost
int main(int argc, char* argv[]){
HostID thisHost;fillThisHostIP(thisHost); // provided in helper.cppthisHost.port = atoi(argv[1]);…
Neighbor List Activity DiagramactiveNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move B from semiActiveNeighbors to ActiveNeighbors
Move B from ActiveNeighbors to
semiActiveNeighbors
Put B into semiActiveNeighbors
Put B into activeNeighbors
This node is listed in recently heard
nodes
This node is NOT listed in recently
heard nodes
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors
• struct HostID { char ip[16];
unsigned int port;unsigned int lastTimeHelloRec;
};
• struct PktStruct {• int type;• char senderIP[16];• unsigned int senderPort;• int numberOfRecentlyHeardNeighbors;• struct RecentNeighborEntry recentNeighbors[100];• };
• struct RecentNeighborEntry {• char ip[16];• unsigned int port;• };
for (int i=0; i<pkt.numberOfRecentlyHeardNeighbors; i++){
if (pkt.recentNeighbors[i] == thisHost)return true;
}return false;
Neighbor List Activity DiagramactiveNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move sender from semiActiveNeighbors to ActiveNeighbors
Move sender from ActiveNeighbors to
semiActiveNeighbors
Put sender into semiActiveNeighbors
Put sender into activeNeighbors
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==true
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==false
Neighbor List Activity DiagramactiveNeighbors – list of nodes in active statesemiActiveNeighbors – list of nodes in semi-active state
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move sender from semiActiveNeighbors to ActiveNeighbors
Move sender from ActiveNeighbors to
semiActiveNeighbors
Put sender into semiActiveNeighbors
Put sender into activeNeighbors
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==true
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==false
Lists• C++ Standard template library list
#include <list>using namespace std;
• Making a list of intslist<int> myList;
• Add an element to myListmyList.push_back(1);myList.push_back(2);myList.push_back(1);
• Iterate through the listfor( list<int>::iterator it=myList.begin(); it!=myList.end(); ++it)
printf(“entry=%d\n”,*it);
• Remove an element from the listint elementToRemove = 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
}}
• AlternativelymyList.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 neighborsint main(int argc, char* argv[]){
bool searchingForNeighborFlag = false;readAllHostsList(argv[2], allHosts); // provided
while (1){
if (activeNeighbors.size() + semiActiveNeighbors.size() < DESIRED_NUMBER_OF_NEIGHBORS && searchingForNeighborFlag ==false){
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
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move sender from semiActiveNeighbors to ActiveNeighbors
Move sender from ActiveNeighbors to
semiActiveNeighbors
Put sender into semiActiveNeighbors
Put sender into activeNeighbors
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==true
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==false
sender==tempNeighbor
searchingForNeighborFlag = false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
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
int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut)
Hello arrived
checkIfInList(sender,semiActiveNeighbors)
==true
else
Move sender from semiActiveNeighbors to ActiveNeighbors
Move sender from ActiveNeighbors to
semiActiveNeighbors
Put sender into semiActiveNeighbors
Put sender into activeNeighbors
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==true
checkIfInList(sender, activeNeighbors)
==true
Extract sender from hello
else
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,
thisHost)==false
sender==tempNeighbor
searchingForNeighborFlag = false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==false
checkIfThisHostIsInRecentlyHeardNeighbors(pkt,thisHost)
==true
Put sender into activeNeighbors
Put sender into semiActiveNeighbors
updateLastReceivedTime(sender,
activeNeighbors)
updateLastReceivedTime(sender,
semiActiveNeighbors)
updateLastReceivedTime(sender,
activeNeighbors)
updateLastReceivedTime(sender,
semiActiveNeighbors)
updateLastReceivedTime(sender,
semiActiveNeighbors)
updateLastReceivedTime(sender,
activeNeighbors)
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– int elementToRemove = 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
• struct HostID { char ip[16];
unsigned int port;unsigned int lastTimeHelloRec;
};
• struct PktStruct {• int type;• char senderIP[16];• unsigned int senderPort;• int numberOfRecentlyHeardNeighbors;• struct RecentNeighborEntry recentNeighbors[100];• };
• struct RecentNeighborEntry {• char ip[16];• unsigned int port;• };
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>• int main(int argc, char* argv[])• {• ….
struct _timeb lastTimeHellosWereSent;_ftime_s( &lastTimeHellosWereSent ); struct _timeb currentTime;
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>• int main(int argc, char* argv[])• {• ….
struct _timeb lastTimeHellosWereSent;lastTimeHellosWereSent.time = 0;_ftime_s( &lastTimeHellosWereSent ); struct _timeb currentTime;
while (1){ _ftime_s( ¤tTime );if (currentTime.time > lastTimeHellosWereSent.time + 10){
lastTimeHellosWereSent = currentTime;sendHellos(…)
}….
sendHellos(…)
• 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– AND tempNeighbor
• struct HostID { char ip[16];
unsigned int port;unsigned int lastTimeHelloRec;
};
• struct PktStruct {• int type;• char senderIP[16];• unsigned int senderPort;• int numberOfRecentlyHeardNeighbors;• struct RecentNeighborEntry recentNeighbors[100];• };
• struct RecentNeighborEntry {• char ip[16];• unsigned int port;• };
for(it= activeNeighbors.begin(); it!=activeNeighbors.end() ++it){
sendHelloToNeighbor(UDPSock, *it, activeNeighbors, semiActiveNeighbors, thisHost);
}….