You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
6.9 KiB

10 years ago
#!/usr/bin/python
10 years ago
import socket, os, time, select, urllib, sys, threading
10 years ago
10 years ago
class Meshenger:
devices = {} #the dictionary of all the nodes this this node has seen
serve_port = "13338"
10 years ago
announce_port = 13337
10 years ago
#own_ip = "0.0.0.0"
msg_dir = os.path.relpath('msg/')
exitapp = False #to kill all threads on
index_last_update = str(int(time.time()))
10 years ago
10 years ago
def __init__(self):
10 years ago
os.system("echo 1 >> /proc/sys/net/ipv6/conf/br-lan/disable_ipv6")
os.system("echo 1 >> /proc/sys/net/ipv6/conf/br-hotspot/disable_ipv6")
10 years ago
self.own_ip = self.get_ip_adress()
10 years ago
if not os.path.exists(self.msg_dir):
os.mkdir(self.msg_dir)
print 'Making message directory'
try:
d = threading.Thread(target=self.discover)
d.daemon = True
d.start()
a = threading.Thread(target=self.announce)
a.daemon = True
a.start()
n = threading.Thread(target=self.nodeserve)
n.daemon = True
n.start()
c = threading.Thread(target=self.clientserve)
c.daemon = True
c.start()
b = threading.Thread(target=self.build_index)
b.daemon = True
b.start()
#os.system("python meshenger_clientserve.py")
except (KeyboardInterrupt, SystemExit):
print 'exiting discovery thread'
d.join()
a.join()
b.join()
n.join()
c.join()
sys.exit()
while True:
print 'Entering main loop'
#
10 years ago
if len(self.devices) > 0:
print 'found', len(self.devices),'device(s)'
10 years ago
for device in self.devices:
nodepath = self.ip_to_hash_path(device) #make a folder for the node (nodes/'hash'/)
nodeupdatepath = os.path.join(self.ip_to_hash_path(device), 'lastupdate')
print 'Checking age of foreign node index'
print self.devices[device], 'Foreign announce timestamp'
10 years ago
try:
foreign_node_update = open(nodeupdatepath).read()
except:
foreign_node_update = 0 #means it was never seen before
print foreign_node_update, 'Locally stored timestamp for device'
10 years ago
10 years ago
10 years ago
if self.devices[device] > foreign_node_update:
print 'Foreign node"s index is newer, proceed to download index'
self.get_index(device, nodepath)
print 'downloading messages'
self.get_messages(device, nodepath)
self.node_timestamp(device)
time.sleep(5) #free process or ctrl+c
10 years ago
def node_timestamp(self, ip):
nodepath = os.path.abspath(os.path.join('nodes', self.hasj(ip)))
10 years ago
updatepath = os.path.join(nodepath, 'lastupdate')
with open(updatepath, 'wb') as lastupdate:
10 years ago
lastupdate.write(self.devices[ip])
#return updatepath
10 years ago
10 years ago
def announce(self):
"""
10 years ago
Announce the node's existance to other nodes
"""
print 'Announcing'
while not self.exitapp:
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.sendto(self.index_last_update, ("ff02::1", self.announce_port))
sock.close()
time.sleep(5)
10 years ago
10 years ago
def discover(self):
"""
10 years ago
Discover other devices by listening to the Meshenger announce port
"""
10 years ago
print 'Discovering'
bufferSize = 1024 # whatever you need?
10 years ago
10 years ago
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind(('::', self.announce_port))
s.setblocking(0)
while not self.exitapp:
10 years ago
result = select.select([s],[],[])[0][0].recvfrom(bufferSize)
ip = result[1][0]
print ip, "*"*45
10 years ago
node_path = os.path.join(os.path.abspath('nodes'), self.hasj(ip))
if not os.path.exists(node_path) and ip != self.own_ip:
10 years ago
#loop for first time
self.ip_to_hash_path(ip) #make a folder /nodes/hash
self.devices[ip] = result[0]
#self.node_timestamp(ip) #make a local copy of the timestamp in /nodes/hash/updatetimestamp
print 'New node', ip
10 years ago
elif os.path.exists(node_path) and ip != self.own_ip:
print 'Known node', ip
self.devices[ip] = result[0]
10 years ago
10 years ago
time.sleep(1)
10 years ago
def nodeserve(self):
"""
Initialize the nodeserver
10 years ago
"""
print 'Serving to nodes'
import meshenger_nodeserve
meshenger_nodeserve.main()
def clientserve(self):
"""
Initialize the clientserver
"""
print 'Serving to client'
import meshenger_clientserve
meshenger_clientserve.main()
10 years ago
10 years ago
def build_index(self):
"""
10 years ago
Make an index file of all the messages present on the node.
Save the time of the last update.
"""
print 'Building own index for the first time\n'
if not os.path.exists('index'):
with open('index','wb') as index:
index.write('')
previous_index = []
else:
previous_index = open('index').readlines()
10 years ago
while not self.exitapp:
current_index = os.listdir(self.msg_dir)
if current_index != previous_index:
with open('index', 'wb') as index:
for message in os.listdir(self.msg_dir):
index.write(message)
index.write('\n')
self.index_last_update = str(int(time.time()))
print 'Index updated:', current_index
with open('index_last_update', 'wb') as indexupdate:
indexupdate.write(self.index_last_update) ### misschien moet dit index_last_update zijn
previous_index = current_index
time.sleep(5)
10 years ago
10 years ago
def get_index(self,ip, path):
"""
10 years ago
Download the indices from other nodes.
"""
10 years ago
os.system('wget http://['+ip+'%adhoc0]:'+self.serve_port+'/index -O '+os.path.join(path,'index'))
10 years ago
10 years ago
def get_messages(self, ip, path):
"""
10 years ago
Get new messages from other node based on it's index file
"""
try:
with open(os.path.join(path,'index')) as index:
index = index.read().split('\n')
for message in index:
messagepath = os.path.join(os.path.abspath(self.msg_dir), message)
if not os.path.exists(messagepath):
print 'downloading', message, 'to', messagepath
os.system('wget http://['+ip+'%adhoc0]:'+self.serve_port+'/msg/'+message+' -O '+messagepath)
except:
print 'Failed to download messages'
pass
10 years ago
def ip_to_hash_path(self, ip):
"""
10 years ago
Convert a node's ip into a hash and make a directory to store it's files
"""
if not os.path.exists('nodes'):
os.mkdir('nodes')
nodepath = os.path.join(os.path.abspath('nodes'), self.hasj(ip))
10 years ago
if not os.path.exists(nodepath):
os.mkdir(nodepath)
10 years ago
10 years ago
return nodepath
10 years ago
def hasj(self, ip):
"""
Convert a node's ip into a hash
"""
import hashlib
hasj = hashlib.md5(ip).hexdigest()
return hasj
10 years ago
10 years ago
def get_ip_adress(self):
"""
10 years ago
Hack to adhoc0's inet6 adress
"""
10 years ago
if not os.path.isfile('interfaceip6adress'):
os.system('ifconfig -a adhoc0 | grep inet6 > /root/meshenger/interfaceip6adress')
10 years ago
with open('interfaceip6adress', 'r') as a:
return a.read().split()[2].split('/')[0]
10 years ago
10 years ago
if __name__ == "__main__":
10 years ago
print "test"
try:
meshenger = Meshenger()
except (KeyboardInterrupt, SystemExit):
exitapp = True
raise