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.

Slides:



Advertisements
Similar presentations
Linked Lists CSE 2451 Matt Boggus. Dynamic memory reminder Allocate memory during run-time malloc() and calloc() – return a void pointer to memory or.
Advertisements

Computer Net Lab/Praktikum Datenverarbeitung 2 1 Overview Sockets Sockets in C Sockets in Delphi.
OSPF Header OSPF HEADER OSPF HEADER for this project Types we will use
Computer Networking A Top-Down Approach Chapter 4.7.
1 Chapter 10 Strings and Pointers. 2 Introduction  String Constant  Example: printf(“Hello”); “Hello” : a string constant oA string constant is a series.
Lab tutorial Lab assignment 2 Fall 2006
Socket Programming Application Programming Interface.
MPI Program Structure Self Test with solution. Self Test 1.How would you modify "Hello World" so that only even-numbered processors print the greeting.
Enforcing Mutual Exclusion Message Passing. Peterson’s Algorithm for Processes P0 and P1 void P0() { while( true ) { flag[ 0 ] = false; /* remainder */
1 Java Networking – Part I CS , Spring 2008/9.
Cache Table. ARP Modules Output Module Sleep until IP packet is received from IP Software Check cache table for entry corresponding to the destination.
1 Standard Containers: Lists Gordon College Resource:
Client Server Model The client machine (or the client process) makes the request for some resource or service, and the server machine (the server process)
CMPT 471 Networking II Address Resolution IPv6 Neighbor Discovery 1© Janice Regan, 2012.
Project 2: A P2P Chat Application Review Ananth Rao.
Socket programming in C. Socket programming Socket API introduced in BSD4.1 UNIX, 1981 explicitly created, used, released by apps client/server paradigm.
1 Ch 3. Network Programming. 2 Network Programming (1)  Network allows arbitrary applications to communicate E.g., client-server computing such as WEB.
Assignment 3 A Client/Server Application: Chatroom.
Review C++ exception handling mechanism Try-throw-catch block How does it work What is exception specification? What if a exception is not caught?
Dsr – dynamics source routing. basics Two types of routing –On-demand / reactive Information is only collected when required, I.e., when a packet needs.
Ad hoc On-demand Distance Vector (AODV) Routing Protocol ECE 695 Spring 2006.
1 Huffman Codes Drozdek Chapter Objectives You will be able to Construct an optimal variable bit length code for an alphabet with known probability.
COP3530 Data Structures600 Stack Stack is one the most useful ADTs. Like list, it is a collection of data items. Supports “LIFO” (Last In First Out) discipline.
CS 1031 Linked Lists Definition of Linked Lists Examples of Linked Lists Operations on Linked Lists Linked List as a Class Linked Lists as Implementations.
Implementation of the Hangman Game in C++
CS 453 Computer Networks Lecture 9 Layer 2 – Data Link Layer.
Networking Tutorial Special Interest Group for Software Engineering Luke Rajlich.
Cli/Serv.: sockets 3/91 Client/Server Distributed Systems v Objectives –describe iterative clients and servers using the UDP protocol ,
C++ / G4MICE Course Session 2 Basic C++ types. Control and Looping Functions in C Function/method signatures and scope.
Sockets Socket = abstraction of the port concept: –Application programs request that the operating system create a socket when one is needed –O.S. returns.
Lecture 7 : Intro. to STL (Standard Template Library)
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.
University of Texas at Austin CS 378 – Game Technology Don Fussell CS 378: Computer Game Technology SDL_net Client-Server Example Spring 2012.
CSCI 330 UNIX and Network Programming Unit XV: Transmission Control Protocol.
EIToolkit stub doc. main.cpp file int main(int argc, char* argv[]) { EIProperties::UseStandards(); // create the stub ExampleStub stub; stub.Start();
CSCI 330 UNIX and Network Programming Unit XIV: User Datagram Protocol.
Transport Protocols.
CSE 332: C++ template examples Today: Using Class and Function Templates Two examples –Function template for printing different types –Class template for.
Data Link Layer. Data link layer The communication between two machines that can directly communicate with each other. Basic property – If bit A is sent.
TCP/IP1 Address Resolution Protocol Internet uses IP address to recognize a computer. But IP address needs to be translated to physical address (NIC).
1 Homework Continue with K&R Chapter 5 –Skipping sections for now –Not covering section 5.12 Continue on HW5.
Socket programming in C. Socket programming with TCP Client must contact server server process must first be running server must have created socket (door)
CSE 232: Moving Data Within a C++ Program Moving Data Within a C++ Program Input –Getting data from the command line (we’ve looked at this) –Getting data.
“Success consists of going from failure to failure without loss of enthusiasm.” Winston Churchill.
C++ Lesson 1.
Socket programming in C
5.13 Recursion Recursive functions Functions that call themselves
Onward with Chat! Networking CS 3470, Section 1.
To do While (1) Receive hello Search for more neighbors?
Lists C++ Standard template library list
Stack and Queue APURBO DATTA.
Introduction of Transport Protocols
Chapter 20: Binary Trees.
Recursion.
Chapter 16-2 Linked Structures
Chapter 21: Binary Trees.
C++ Functions, Classes, and Templates
Client-side Networking CSE 333 Spring 2018
Anup Mathur Anusha Sheelavant Prakhar Srivastava
اصول کامپیوتر ۱ مبانی کامپیوتر و برنامه‌سازی
CSS432 (Link Level Protocols) Reliable Transmission Textbook Ch 2.5
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.
Client-side Networking CSE 333 Summer 2018
Then this information is wrong
Data Structures & Algorithms
An Introduction to STL.
I am A I have heard: no one A B Have heard list Have heard list.
Socket programming in C
Data Structures & Programming
Presentation transcript:

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 Maintain 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

I am A I have heard: no one A B Have heard list Have heard list

I am A I have heard: no one A B Have heard list Have heard list A

I am B I have heard: A A B Have heard list Have heard list A

A B A I am B I have heard: A Have heard list Have heard list B and B hears me A

A B A I am A I have heard: B Have heard list Have heard list B and B hears me A

A B I am A I have heard: B Have heard list Have heard list B and B hears me A and A hears me

Neighbor States nothing one-way (receivable) bidirectional Received a hello and this node is not listed in the hello as a recently heard node 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 semiActive active 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 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

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); 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 int elementToRemove = 2; { 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

for( list<int>::iterator it=myList. begin(); it. =myList 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);

Structures 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 {

List struct HostID { char ip[16]; unsigned int port; unsigned int lastTimeHelloRec; }; 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; }

List struct HostID { char ip[16]; unsigned int port; unsigned int lastTimeHelloRec; }; 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; }

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 the hello as a recently heard node Node B is neither list Put B into activeNeighbors Node B is semiActiveNeighbors This node is NOT listed in the hello as a recently heard node Node B is activeNeighbors Put B into semiActiveNeighbors 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 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 the hello as a recently heard node else Put B into activeNeighbors checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in the hello as a recently heard node Put B into semiActiveNeighbors 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 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 int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) else Hello arrived Extract sender from hello This node is listed in the hello as a recently heard node else Put B into activeNeighbors checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in the hello as a recently heard node Put B into semiActiveNeighbors 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 Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors

Receiving a Packet PktStruct pkt; struct PktStruct { int type; char senderIP[16]; unsigned int senderPort; int numberOfRecentlyHeardNeighbors; struct RecentNeighborEntry recentNeighbors[100]; }; 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

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 Diagram activeNeighbors – list of nodes in active state semiActiveNeighbors – list of nodes in semi-active state int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) else Hello arrived Extract sender from hello This node is listed in the hello as a recently heard node else Put B into activeNeighbors checkIfInList(sender, semiActiveNeighbors) ==true checkIfInList(sender, activeNeighbors) ==true This node is NOT listed in the hello as a recently heard node Put B into semiActiveNeighbors 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 Move B from semiActiveNeighbors to ActiveNeighbors Move B from ActiveNeighbors to semiActiveNeighbors

thisHost int main(int argc, char* argv[]) { HostID thisHost; 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 int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) else Hello arrived Extract sender from hello This node is listed in recently heard nodes else Put B into activeNeighbors 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 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 { for (int i=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 int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) 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 int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) 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 Making a list of ints #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); 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

Objectives Find N neighbors Maintain 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 Search for more neighbors? 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 Search for more neighbors? 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 int 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 Search for more neighbors? 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 Put sender into activeNeighbors int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) 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 Search for more neighbors? 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) int checkForNewPacket(SOCKET UDPSock, char *pkt, int TimeOut) 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 C++ Standard template library list #include <list> 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 { 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); 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; { 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 Search for more neighbors? 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( &currentTime ); 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( &currentTime ); if (currentTime.time > lastTimeHellosWereSent.time + 10) lastTimeHellosWereSent = currentTime; sendHellos(…) }

sendHellos(…) sendHelloToANeighbor 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 { 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 AND tempNeighbor for(it= activeNeighbors.begin(); it!=activeNeighbors.end() ++it) { sendHelloToNeighbor(UDPSock, *it, activeNeighbors, semiActiveNeighbors, thisHost); } ….