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
+
+ [<client-ipaddr>] 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 <network>.1)
+ mtu # default is 1500
+
Client side configuration;
MAX_BATCH_DOWN MAX_QUEUE_TIME PASSWORD
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
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[<config-key>]
+ 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.