From ec88b1f1080f9adffbe1c4c05c38c01e758f124b Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 19 Mar 2017 12:48:06 +0000 Subject: [PATCH] wip --- PROTOCOL | 28 +++++++++++++++----- server | 79 +++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 85 insertions(+), 22 deletions(-) diff --git a/PROTOCOL b/PROTOCOL index 9969e61..330c01f 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -11,12 +11,23 @@ It's a multipart/form-data. Authentication: for now, plaintext password Sever side configuration: - Per user but normally global - MAX_MAX_BATCH_DOWN MAX_MAX_QUEUE_TIME - Global - MTU - Per user - PASSWORD + + [] or [default] + max_batch_down + max_queue_time + max_request_time + password + + [global] + max_batch_down + max_queue_time + max_request_time + + [virtual] + network # required + server # default is first host in network (eg .1) + mtu # default is 1500 + Client side configuration; MAX_BATCH_DOWN MAX_QUEUE_TIME PASSWORD @@ -24,4 +35,7 @@ Client side configuration; Routing assistance: none needed; secnet polypath will DTRT Client form parameters: - I MBD MQT P D + i ip address (textual) + p password + d data (SLIP format) + mbd mqt mrt config updates diff --git a/server b/server index fcf7a81..1a9049b 100755 --- a/server +++ b/server @@ -6,43 +6,92 @@ from twisted.web.server import NOT_DONE_YET from twisted.internet import reactor import ConfigParser - -import cgi +import ipaddress clients = { } def ipaddress(input): try: - r = IPv4Address(input) + r = ipaddress.IPv4Address(input) except AddressValueError: - r = IPv6Address(input) + r = ipaddress.IPv6Address(input) return r def ipnetwork(input): try: - r = IPv4Network(input) + r = ipaddress.IPv4Network(input) except NetworkValueError: - r = IPv6Network(input) + r = ipaddress.IPv6Network(input) return r +defcfg = u''' +[default] +max_batch_down: 65536 +max_queue_time: 10 +max_request_time: 54 + +[global] +max_batch_down: 262144 +max_queue_time: 121 +max_request_time: 121 +''' + +class Client(): + def __init__(ip, cs): + # instance data members + self._ip = ip + self._cs = cs + self.pw = cfg.get(cs, 'password') + # plus: + # .cfg[] + self.cfg = { } + for k in ('max_batch_down','max_queue_time','max_request_time'): + req = cfg.getint(cs, k) + limit = cfg.getint('global',k) + self.cfg[k] = min(req, limit) + + def process_arriving_data(d): + + def process_cfg(): global network global ourself - network = ipnetwork(cfg.get('virtual','network') + network = ipnetwork(cfg.get('virtual','network')) try: ourself = cfg.get('virtual','server') except ConfigParser.NoOptionError: ourself = network.hosts().next() - - -class Client(): - def __init__(ip): - # instance data members - # ._ip - self._ip = IPv4Address(ip) - clients + for cs in cfg.sections(): + if not (':' in cs or '.' in cs): continue + ci = ipaddress(cs) + if ci not in network: + raise ValueError('client %s not in network' % ci) + if ci in clients: + raise ValueError('multiple client cfg sections for %s' % ci) + clients[ci] = Client(ci, cs) class FormPage(Resource): def render_POST(self, request): + # find client, update config, etc. + ci = ipaddress(request.args['i']) + c = clients[ci] + pw = request.args['pw'] + if pw != c.pw: raise ValueError('bad password') + + # update config + for r, w in (('mbd', 'max_batch_down'), + ('mqt', 'max_queue_time'), + ('mrt', 'max_request_time')): + try: v = request.args[r] + except KeyError: continue + v = int(v) + c.cfg[w] = v + + try: d = request.args['d'] + except KeyError: d = '' + + c.process_arriving_data(d) + + reactor. -- 2.30.2