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.

227 lines
6.1 KiB

11 years ago
#!/usr/bin/python
11 years ago
import socket, os, time, select, urllib, sys, threading
11 years ago
11 years ago
class Meshenger:
devices = {} #the dictionary of all the nodes this this node has seen
serve_port = "13338"
11 years ago
announce_port = 13337
11 years ago
#own_ip = "0.0.0.0"
msg_dir = os.path.relpath('msg/')
exitapp = False #to kill all threads on
11 years ago
index_last_update = str(time.time())
11 years ago
11 years ago
def __init__(self):
11 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")
11 years ago
self.own_ip = self.get_ip_adress()
11 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()
s = threading.Thread(target=self.serve)
s.daemon = True
s.start()
b = threading.Thread(target=self.build_index)
b.daemon = True
b.start()
except (KeyboardInterrupt, SystemExit):
print 'exiting discovery thread'
d.join()
a.join()
b.join()
s.join()
sys.exit()
while True:
print 'Entering main loop'
#
11 years ago
if len(self.devices) > 0:
print 'found', len(self.devices),'device(s)'
11 years ago
for device in self.devices:
11 years ago
nodepath = self.ip_to_hash(device) #make a folder for the node (nodes/'hash'/)
nodeupdatepath = os.path.join(self.ip_to_hash(device), 'lastupdate')
11 years ago
print 'Checking age of foreign node index'
print self.devices[device], 'Foreign announce timestamp'
11 years ago
foreign_node_update = open(nodeupdatepath).read()
print foreign_node_update, 'Locally stored timestamp for device'
11 years ago
11 years ago
11 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)
self.node_timestamp(device)
print 'downloading messages'
self.get_messages(device, nodepath)
time.sleep(5) #free process or ctrl+c
11 years ago
def node_timestamp(self, ip):
11 years ago
updatepath = os.path.join(self.ip_to_hash(ip), 'lastupdate')
with open(updatepath, 'wb') as lastupdate:
11 years ago
lastupdate.write(self.devices[ip])
#return updatepath
11 years ago
11 years ago
def announce(self):
"""
11 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)
11 years ago
11 years ago
def discover(self):
"""
11 years ago
Discover other devices by listening to the Meshenger announce port
"""
11 years ago
print 'Discovering'
11 years ago
bufferSize = 1024 # whatever you need
11 years ago
11 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:
11 years ago
result = select.select([s],[],[])[0][0].recvfrom(bufferSize)
11 years ago
if result[1][0] in self.devices and result[1][0] != self.own_ip:
print 'Known node', result[1][0]
11 years ago
self.devices[result[1][0]] = result[0]
#self.devices.append(result[1][0])
11 years ago
elif result[1][0] not in self.devices and result[1][0] != self.own_ip:
#loop for first time
self.devices[result[1][0]] = result[0]
self.node_timestamp(result[1][0])
print 'New node', result[1][0]
11 years ago
11 years ago
time.sleep(1)
11 years ago
11 years ago
def serve(self):
"""
11 years ago
Initialize the server
"""
print 'Serving'
import meshenger_serve
meshenger_serve.main()
11 years ago
11 years ago
def build_index(self):
"""
11 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('')
11 years ago
previous_index = []
11 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: ### misschien is dit overbodig
indexupdate.write(str(int(time.time())))
previous_index = current_index
time.sleep(5)
11 years ago
11 years ago
def get_index(self,ip, path):
"""
11 years ago
Download the indices from other nodes.
"""
11 years ago
os.system('wget http://['+ip+'%adhoc0]:'+self.serve_port+'/index -O '+os.path.join(path,'index'))
11 years ago
11 years ago
def get_messages(self, ip, path):
"""
11 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:
pass
11 years ago
11 years ago
def ip_to_hash(self, ip):
"""
11 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')
11 years ago
import hashlib
hasj = hashlib.md5(ip).hexdigest()
nodepath = os.path.join(os.path.abspath('nodes'), hasj)
11 years ago
if not os.path.exists(nodepath):
os.mkdir(nodepath)
11 years ago
11 years ago
return nodepath
11 years ago
11 years ago
def clientsite(self):
a = ''
11 years ago
11 years ago
#tools
11 years ago
11 years ago
def get_ip_adress(self):
"""
11 years ago
Hack to adhoc0's inet6 adress
"""
11 years ago
if not os.path.isfile('interfaceip6adress'):
os.system('ifconfig -a adhoc0 | grep inet6 > /root/meshenger/interfaceip6adress')
11 years ago
with open('interfaceip6adress', 'r') as a:
return a.read().split()[2].split('/')[0]
11 years ago
11 years ago
if __name__ == "__main__":
11 years ago
print "test"
try:
meshenger = Meshenger()
except (KeyboardInterrupt, SystemExit):
exitapp = True
raise
11 years ago