def addnewNode(self,pac):
		
		print 'Adding Host:', pac.getIPAddress()
		self.nodes[pac.getIPAddress()] = Node(pac.getIPAddress(),self)
			
		#now send a neighbour update to all the adjacent nodes...
		tmp_pac = LinkPacket()
		tmp_pac.setMessageByFields(4,Config.NODE_IP_ADDRESS,pac.getIPAddress()+"+")

		for node in self.nodes:
			if node!=pac.getIPAddress():#don't send to the current node...
				self.soc.sendto(tmp_pac.getRawMessage(), (node, Config.UDP_LISTEN_PORT))
	def secondConfirmReq(self,r_pac):
		if r_pac.getPayload()[0]=="y":
			
			#first send self's neighbours and then
			#add the other end's neighbours if any
			tmp_n_pac = LinkPacket()

			for neigh in self.nodes:
				tmp_n_pac.setMessageByFields(4,
				 Config.NODE_IP_ADDRESS, neigh+"+")
				self.soc.sendto(tmp_n_pac.getRawMessage(), 
					(r_pac.getIPAddress(), Config.UDP_LISTEN_PORT))
			self.addnewNode(r_pac)
			print '*'+r_pac.getPayload()[1:]+'*'
			#add all the neighbours sent in this request
			for neigh in r_pac.getPayload()[1:].split("|"):
				if neigh:
						self.nodes[r_pac.getIPAddress()].add_neighbour(neigh, 1)
Пример #3
0
    def ping_user(self):
        # pings the node after some timeout...
        pac = LinkPacket()
        pac.setMessageByFields(7, self.ip, "")  # 7 => link check packet...
        while 1:
            self.soc.sendto(pac.getRawMessage(), (self.ip, Config.UDP_LISTEN_PORT))

            try:
                dat = self.soc.recvfrom(1024)  # wait for the reply...

            except socket.timeout:
                # the node at the other end is dead..
                pac = LinkPacket()
                print "Node " + self.ip + " went away!"
                # for each neigbhour which is not neigh
                # of current node
                # start a new thread,
                # for sending the hop-count query
                has_node = 0
                for nde in self.neighbours:
                    if nde not in self.main_list.nodes:
                        # start a new thread
                        tmppac = LinkPacket()
                        tmppac.setMessageByFields(3, Config.NODE_IP_ADDRESS, nde + chr(0))
                        for nde2 in self.main_list.nodes:
                            if nde2 != self.ip:
                                # send the path_q to every node
                                self.main_list.soc.sendto(tmppac.getRawMessage(), (nde2, Config.UDP_LISTEN_PORT))
                        has_node = 1

                if has_node == 0:
                    # evry thing is fine now
                    # kill itself
                    # remove the reference in the main_list
                    print "Deleting the Reference.."

                    del self.ip, self.main_list.nodes[self.ip]
                    self.main_list.nodes.remove(self.ip)

                    return
                break

            time.sleep(Config.PATH_Q_TIMEOUT)
	def confirmConnectionRequest(self, pac):
		prev_degree = int(pac.getPayload())

		reply_pac = LinkPacket()

		if (prev_degree == len(self.nodes) or prev_degree <0 )and \
				pac.getIPAddress() not in self.nodes:
			#get the current neighbours
			neigh = ''
			for nde in self.nodes:
				neigh += nde+"|"
			print '^^'+neigh+'^^'+str(len(self.nodes))
			#create a new connection...
			self.addnewNode(pac)
			#neigh = self.getAllNeighbours(pac.getIPAddress())
			reply_pac.setMessageByFields(6, Config.NODE_IP_ADDRESS, "y"+neigh[:-1])
		else:
			#then sent degree and the current one are not equal...
			reply_pac.setMessageByFields(6, Config.NODE_IP_ADDRESS, "n")

		return reply_pac
	def getFirstTwoHosts(self):
		#this method listens for broadcast requests
		#and sends timely broadcast requests to accommodate
		#new hosts and also replies for connection requests

		#set time-out for incoming broadcast requests
		self.soc.settimeout(Config.BROADCAST_TIMEOUT)

		#set the option for sending bcast packet
		self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

		b_pac = LinkPacket()
		
		b_pac.setMessageByFields(1,Config.NODE_IP_ADDRESS,'')
		replyList = [] 
		while len(self.nodes) < 2:
			#stores all the replies for 
			#the broadcasts by the current node
			#(in-degree,ip-address) 
			
			replyList = []
			#send a bcast packet
			self.soc.sendto(b_pac.getRawMessage(), 
				(Config.BROADCAST_IP_ADDRESS, 
					Config.UDP_LISTEN_PORT))
			print 'Sent broadcast request'
			while 1:
				if len(self.nodes) >= 2:
					return
				try:
					pac,addr = self.soc.recvfrom(1024)
					print '**** ***** ***** ****** ****'
					r_pac = LinkPacket(pac)
				except socket.timeout:
					#no requests or replies in the last few seconds
					#check if there are already two neighbours
					if len(self.nodes) >= 2:
						#return from the function
						#since the purpose is fulfilled
						return

					if len(replyList)==0:
						#no node replies for bcasts
						#so repeat it again
						break

					print 'Reply list not empty'
					print replyList
					#get the list, sort them, choose one 
					#with least degree, send a conn. req.
					replyList.sort()
					for tup in replyList:
						#check if its already a neighbour
						if tup[1] not in self.nodes:
							conn_pac = LinkPacket()
							conn_pac.setMessageByFields(2 , 
								Config.NODE_IP_ADDRESS, str(tup[0]))
							self.soc.sendto(conn_pac.getRawMessage(), (tup[1], Config.UDP_LISTEN_PORT))
							break
					break
				
				if addr[0]==Config.NODE_IP_ADDRESS:
					#print 'loopback packet'
					continue

				

				if not r_pac.isValid():
					#print 'Is Invalid'
					continue

				print 'src:',addr

				r_pac.printSegmentedMessage()
				
				rep_pac = LinkPacket()

				if r_pac.getIPAddress() not in self.nodes and \
					r_pac.getRequestType()==10:
					#someone replied for our bcast

					replyList.append([
						int(r_pac.getPayload()), r_pac.getIPAddress()
									])
				elif r_pac.getRequestType()==2:
					#connection request to this machine
					rep_pac = self.confirmConnectionRequest(r_pac)
					self.soc.sendto(rep_pac.getRawMessage(), addr)

				elif r_pac.getRequestType()==1:
					#someone is bcasting for a new
					#connection,reply them with current degree
					rep_pac.setMessageByFields(10, Config.NODE_IP_ADDRESS, str(len(self.nodes)))
					self.soc.sendto(rep_pac.getRawMessage(), addr)

				elif r_pac.getRequestType()==6:
					#got a reply to build a new connection
					#for a conn. req sent previously
					self.secondConfirmReq(r_pac)

				elif r_pac.getRequestType()==4:
					#neighbour updates
					self.addorRemoveNeighbourToEntity(r_pac.getIPAddress(), r_pac.getPayload())

				elif r_pac.getRequestType()==7:
					tp = LinkPacket()
					tp.setMessageByFields(8,self.ip_address,'')
					self.soc.sendto(tp.getRawMessage(), addr)	
	def listen(self):
		
		#initially send a broadcast for joining the network...
		
		while 1:
			
			dat,addr = self.soc.recvfrom(1024)
			#time.sleep(3)
			#handling all possible cases...
			pac = LinkPacket(dat)
			if not pac.isValid():
				print 'Corrupted packet from',addr
				continue

			to_be_replied=0
			r_type = pac.getRequestType()
			reply_pac = LinkPacket()
			print "src:",addr,"type:",r_type 
			if r_type==1:
				# brdcast for conn. request.. so reply with details..
				to_be_replied=1
				reply_pac.setMessageByFields(10, Config.NODE_IP_ADDRESS, str(len(self.nodes)))

			elif r_type==2:
				#conn req for this machine
				to_be_replied=1
				reply_pac = self.confirmConnectionRequest(pac)

			elif r_type==3:
				# a path query...
				to_be_replied=0 #first unset the reply flag...
				target_ip = Converter.get_decoded_ip(pac.getPayload()[:4])
				if target_ip==Config.NODE_IP_ADDRESS:
					#which means the target node has reached...
					reply_pac.setMessageByFields(5, target_ip, target_ip+pac.getPayload()[4:])

				else:
					#check if this has already been seen...
					if pac.getIPAddress()+target_ip in self.query_cache:
						continue
					#increment the hop count by '1'...	
					dat = ord(pac.getPayload()[4:]) + 1
					#form a packet to forward it...
					reply_pac.setMessageByFields(3, pac.getIPAddress() , target_ip+chr(dat))
					path_length = 0
					try:
						path_length = self.path_cache[target_ip]
					except KeyError:
						path_length = 0

					if path_length==0: #which means we dont have it in the query...
						#just forward the packet to all the adjacent nodes...
						#cache the query and path length...
						self.path_cache[pac.getIPAddress()] = dat #store the hop count b/w src and this node..
						self.query_cache[pac.getIPAddress()+target_ip] = ''
						
						#start the threads .. so that they delete the content after a time-out...

						thread.start_new_thread(self.path_cache, (pac.getIPAddress(),))
						thread.start_new_thread(self.query_cache, (pac.getIPAddress()+target_ip,))

						for node in self.nodes:
							self.soc.sendto(reply_pac.getRawMessage(), (node, Config.UDP_LISTEN_PORT))

					else:
						#we have the data from the cache.. so use it!..
						reply_pac.setMessageByFields(9, 
							Config.NODE_IP_ADDRESS,
							target_ip+chr(path_length))
			elif r_type==4:
				pac.printSegmentedMessage()
				#neighbour update ...
				to_be_replied=0
				self.addorRemoveNeighbourToEntity(pac.getIPAddress(), pac.getPayload())

			elif r_type==7:
				to_be_replied=1
				reply_pac.setMessageByFields(8, self.ip_address,'')

			elif r_type==9 or r_type==5:
				print 'Path Query Reply:'
				print pac.getPayload()

			elif r_type==11:
				#its a voluntary disconnect req
				print 'Disconnect request to',pac.getPayload()
				to_be_replied =0
				ip_to_conn = pac.getPayload()
				#del the reference from the entries
				try:
					del self.nodes[pac.getIPAddress()]
				except KeyError:
					#do nothing
					fg=1
				if ip_to_conn in self.nodes:
					#don't send the req. if its already
					#connected
					continue


				reply_pac = LinkPacket()
				reply_pac.setMessageByFields( 2, 
					Config.NODE_IP_ADDRESS,
					str(-1))
				self.soc.sendto(reply_pac.getRawMessage(), (ip_to_conn, 
											Config.UDP_LISTEN_PORT))
			if to_be_replied==1:#reply only if needed...
				self.soc.sendto(reply_pac.getRawMessage(), addr)
Пример #7
0
    def ping_user(self):
        #pings the node after some timeout...
        pac = LinkPacket()
        pac.setMessageByFields(7, self.ip, '')  #7 => link check packet...
        while 1:
            self.soc.sendto(pac.getRawMessage(),
                            (self.ip, Config.UDP_LISTEN_PORT))

            try:
                dat = self.soc.recvfrom(1024)  #wait for the reply...

            except socket.timeout:
                #the node at the other end is dead..
                pac = LinkPacket()
                print 'Node ' + self.ip + ' went away!'
                #for each neigbhour which is not neigh
                #of current node
                #start a new thread,
                #for sending the hop-count query
                has_node = 0
                for nde in self.neighbours:
                    if nde not in self.main_list.nodes:
                        #start a new thread
                        tmppac = LinkPacket()
                        tmppac.setMessageByFields(3, Config.NODE_IP_ADDRESS,
                                                  nde + chr(0))
                        for nde2 in self.main_list.nodes:
                            if nde2 != self.ip:
                                #send the path_q to every node
                                self.main_list.soc.sendto(
                                    tmppac.getRawMessage(),
                                    (nde2, Config.UDP_LISTEN_PORT))
                        has_node = 1

                if has_node == 0:
                    #evry thing is fine now
                    #kill itself
                    #remove the reference in the main_list
                    print 'Deleting the Reference..'

                    del self.ip, self.main_list.nodes[self.ip]
                    self.main_list.nodes.remove(self.ip)

                    return
                break

            time.sleep(Config.PATH_Q_TIMEOUT)