Commit 8401ce4e by Killian Lufau Committed by Julien Muchembled

demo: new ping monitoring script and option to stop demo after some time

See "./demo --help" for more information.

/reviewed-on !8
parent 8c4cc9b6
......@@ -58,13 +58,14 @@ Requirements
- Babel_ (with Nexedi patches)
- geoip2: `python library`_ and `country lite database`_ (optional)
- python-miniupnpc for UPnP support (optional)
- for the demo: miniupnpd_, Graphviz, Screen_, Nemu_
- for the demo: miniupnpd_, Graphviz, Screen_, Nemu_, MultiPing_
See also `` for Python dependencies.
.. _Babel:
.. _Nemu:
.. _miniupnpd:
.. _MultiPing:
.. _Screen:
.. _python library:
.. _country lite database:
import math, nemu, os, re, signal, socket, subprocess, sys, time, weakref
import argparse, math, nemu, os, re, signal
import socket, subprocess, sys, time, weakref
from collections import defaultdict
IPTABLES = 'iptables'
SCREEN = 'screen'
......@@ -38,6 +39,22 @@ def _add_interface(node, iface):
return Node__add_interface(node, iface)
nemu.Node._add_interface = _add_interface
parser = argparse.ArgumentParser()
parser.add_argument('port', type = int,
help = 'port used to display tunnels')
parser.add_argument('-d', '--duration', type = int,
help = 'time of the demo execution in seconds')
parser.add_argument('-p', '--ping', action = 'store_true',
help = 'execute ping utility')
args = parser.parse_args()
def handler(signum, frame):
if args.duration:
signal.signal(signal.SIGALRM, handler)
# create nodes
......@@ -225,6 +242,18 @@ if 1:
re6stnet(machine8, 'm8')
for j, machine in enumerate(nodes):
ips = [
'2001:db8:42::1' if i == 0 else
'2001:db8:42:2::' if i == 2 else
# Only 1 address for machine2 because prefix_len = 80,+48 = 128
'2001:db8:42:%s::1' % i
for i in xrange(9)
if i != j]
name = 'm' + machine.short if machine.short != 'R' else 'registry'
machine.screen('python {} {}'.format(name, ' '.join(ips)))
_ll = {}
def node_by_ll(addr):
......@@ -302,7 +331,7 @@ def route_svg(ipv4, z = 4, default = type('', (), {'short': None})):
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
if len(sys.argv) > 1:
if args.port:
import SimpleHTTPServer, SocketServer
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
......@@ -392,6 +421,6 @@ if len(sys.argv) > 1:
class TCPServer(SocketServer.TCPServer):
allow_reuse_address = True
TCPServer(('', int(sys.argv[1])), Handler).serve_forever()
TCPServer(('', args.port), Handler).serve_forever()
import pdb; pdb.set_trace()
# -*- coding: utf-8 -*-
Script launched on machines from the demo with the option -p/--ping
It uses Multiping to ping several IPs passed as arguments.
After Re6st is stable, this script logs when it does not get response from a
machine in a csv file stored in the directory of the machine in this format:
time, sequence number, number of non-responding machines, ip of these machines
import argparse, errno, logging, os, socket, time
from multiping import MultiPing
from threading import Thread, Lock
csv_lock = Lock()
class MultiPing(MultiPing):
# Patch of Multiping because it stays blocked to ipv4
# emission when we want to ping only ipv6 addresses.
# So we only keep the ipv6 part for the demo.
# Bug issued:
def _read_all_from_socket(self, timeout):
pkts = []
if self._ipv6_address_present:
while True:
p = self._sock6.recv(128)
pkts.append((bytearray(p), time.time()))
except socket.timeout:
except socket.error as e:
if e.errno == errno.EWOULDBLOCK:
return pkts
class Ping(Thread):
seq = None
seq_lock = Lock()
def run(self):
mp = MultiPing(addrs)
assert mp._last_used_id is None
cls = self.__class__
with cls.seq_lock:
mp._last_used_id = cls.seq
seq = cls.seq = mp._last_used_id
responses, no_responses = mp.receive(PING_TIMEOUT)
x = list(responses)
x += no_responses
assert sorted(x) == sorted(addrs), (addrs, responses, no_responses)
with csv_lock:
if no_responses:
my_csv.write('%r,%d,%d,%s\n' % (time.time(), seq,
len(no_responses), ' '.join(no_responses)))
else :
# Update modification/access time of csv
os.utime(csv_path, (time.time(), time.time()))
for add in no_responses:
print('No response from %s with seq no %d' % (add, seq))
parser = argparse.ArgumentParser()
parser.add_argument('n', help = 'my machine name (m1,m2...)')
parser.add_argument('a', nargs = '+', help = 'the list of addresses to ping')
args = parser.parse_args()
my_name = args.n
addrs = args.a
print('Waiting for every machine to answer ping..')
while True:
mp = MultiPing(addrs)
_, no_responses = mp.receive(0.5)
if not no_responses:
# Currently useless because MultiPing does not return earlier if it
# couldn't send any ping (e.g. no route to host). Let's hope it will
# improve.
print('Network is stable, starting to ping..')
csv_path = '{}/ping_logs.csv'.format(my_name)
my_csv = open(csv_path, 'w+')
my_csv.write('%r,%s,%d\n' % (time.time(), 0, 0))
while True:
......@@ -6,11 +6,12 @@ def __file__():
from argparse import ArgumentParser
_parse_args = ArgumentParser.parse_args
ArgumentParser.parse_args = lambda self: _parse_args(self, sys.argv[2:])
# Always import to prevent re6st.node.cli from altering the first sys.path
from re6st import registry
if 1:
# Check renewal of certificate.
from random import randrange
from re6st import registry
registry.RENEW_PERIOD = 60
_createCertificate = registry.RegistryServer.createCertificate
def createCertificate(self, client_prefix, *args):
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment