# Imports
import threading, logging, socket, os, select, re
from threading import Timer
# Defines
AODV_HELLO_INTERVAL = 10
AODV_HELLO_TIMEOUT = 30
AODV_PATH_DISCOVERY_TIME = 30
AODV_ACTIVE_ROUTE_TIMEOUT = 300
# Class Definition
class aodv(threading.Thread):
# Constructor
def __init__(self):
threading.Thread.__init__(self)
self.node_id = ""
self.num_nodes = 0
self.seq_no = 0
self.rreq_id = 0
self.listener_port = 0
self.aodv_port = 0
self.tester_port = 0
self.listener_sock = 0
self.aodv_sock = 0
self.tester_sock = 0
self.log_file = ""
self.command = ""
self.status = ""
self.neighbors = dict()
self.routing_table = dict()
self.message_box = dict()
self.rreq_id_list = dict()
self.pending_msg_q = []
self.status = "Active"
self.hello_timer = 0
# Set the Node ID
def set_node_id(self, nid):
self.node_id = nid
# Set the number of nodes in the network
def set_node_count(self, count):
self.num_nodes = count
# Get the port associated with the listener thread for the given node
def get_listener_thread_port(self, node):
port = {'n1': 1000,
'n2': 1100,
'n3': 1200,
'n4': 1300,
'n5': 1400,
'n6': 1500,
'n7': 1600,
'n8': 1700,
'n9': 1800,
'n10': 1900}[node]
return port
# Get the port used to communicate with the listener thread for this node
def get_listener_port(self, node):
port = {'n1': 2000,
'n2': 2100,
'n3': 2200,
'n4': 2300,
'n5': 2400,
'n6': 2500,
'n7': 2600,
'n8': 2700,
'n9': 2800,
'n10': 2900}[node]
return port
# Get the port associated with sending and receiving AODV messages
def get_aodv_port(self, node):
port = {'n1': 3000,
'n2': 3100,
'n3': 3200,
'n4': 3300,
'n5': 3400,
'n6': 3500,
'n7': 3600,
'n8': 3700,
'n9': 3800,
'n10': 3900}[node]
return port
# Get the tester port associated with this node
def get_tester_port(self, node):
port = {'n1': 5100,
'n2': 5200,
'n3': 5300,
'n4': 5400,
'n5': 5500,
'n6': 5600,
'n7': 5700,
'n8': 5800,
'n9': 5900,
'n10': 6000}[node]
return port
# Create / Restart the lifetime timer for the given route
def aodv_restart_route_timer(self, route, create):
if (create == False):
timer = route['Lifetime']
timer.cancel()
timer = Timer(AODV_ACTIVE_ROUTE_TIMEOUT,
self.aodv_process_route_timeout, [route])
route['Lifetime'] = timer
route['Status'] = 'Active'
timer.start()
# Send a message
def aodv_send(self, destination, destination_port, message):
try:
message_bytes = bytes(message, 'utf-8')
self.aodv_sock.sendto(message_bytes, 0,
('localhost', destination_port))
except:
pass
# Send the hello message to all the neighbors
def aodv_send_hello_message(self):
try:
# Send message to each neighbor
for n in self.neighbors.keys():
message_type = "HELLO_MESSAGE"
sender = self.node_id
message_data = "Hello message from " + str(self.node_id)
message = message_type + ":" + sender + ":" + message_data
port = self.get_aodv_port(n)
self.aodv_send(n, int(port), message)
logging.debug("['" + message_type + "', '" + sender + "', " +
"Sending hello message to " + str(n) + "']")
# Restart the timer
self.hello_timer.cancel()
self.hello_timer = Timer(AODV_HELLO_INTERVAL, self.aodv_send_hello_message, ())
self.hello_timer.start()
except:
pass
# Process incoming hello messages
def aodv_process_hello_message(self, message):
logging.debug(message)
sender = message[1]
# Get the sender's ID and restart its neighbor liveness timer
try:
if (sender in self.neighbors.keys()):
neighbor = self.neighbors[sender]
timer = neighbor['Timer-Callback']
timer.cancel()
timer = Timer(AODV_HELLO_TIMEOUT,
self.aodv_process_neighbor_timeout, [sender])
self.neighbors[sender] = {'Neighbor': sender,
'Timer-Callback': timer}
timer.start()
# Restart the lifetime timer
route = self.routing_table[sender]
self.aodv_restart_route_timer(route, False)
else:
#
# We come here when we get a hello message from a node that
# is not there in our neighbor list. This happens when a
# node times out and comes back up again. Add the node to
# our neighbor table.
#
timer = Timer(AODV_HELLO_TIMEOUT,
self.aodv_process_neighbor_timeout, [sender])
self.neighbors[sender] = {'Neighbor': sender,
'Timer-Callback': timer}
timer.start()
# Update the routing table as well
if (sender in self.routing_table.keys()):
route = self.routing_table[sender]
self.aodv_restart_route_timer(route, False)
else:
self.routing_table[sender] = {'Destination': sender,
'Destination-Port': self.get_aodv_port(sender),
'Next-Hop': sender,
'Next-Hop-Port': self.get_aodv_port(sender),
'Seq-No': '1',
'Hop-Count': '1',
'Status': 'Active'}
self.aodv_restart_route_timer(self.routing_table[sender], True)
except KeyError:
# This neighbor has not been added yet. Ignore the message.
pass
# Process incoming application message
def aodv_process_user_message(self, message):
# Get the message contents, sender and receiver
sender = message[1]
receiver = message[2]
msg = message[3]
# Check if the message is for us
if (receiver == self.node_id):
# Add the message to the message box
self.message_box[msg] = {'Sender': sender, 'Message': msg}
# Log the message and notify the user
logging.debug(message)
print("New message arrived. Issue 'view_messages' to see the contents")
else:
#
# Forward the message by looking up the next-hop. We should have a
# route for the destination.
#
# TODO update lifetime for the route
route = self.routing_table[receiver]
评论3