chiark / gitweb /
wip config reorg
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 21 Mar 2017 22:40:03 +0000 (22:40 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 21 Mar 2017 22:40:03 +0000 (22:40 +0000)
PROTOCOL
client
hippotat/__init__.py
server

index c7033af..c1ef03b 100644 (file)
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -1,41 +1,20 @@
 Server maintains a queue of outbound packets for each user
 
-Packets which are older than MAX_QUEUE_TIME are discarded
+Packets which are older than the applicable max_queue_time are discarded
 
-Each incoming request to the server takes up to MAX_BATCH_DOWN bytes
+Each incoming request to the server takes up to max_batch_down bytes
 from the queue and returns them as the POST response body payload
 
-Each incoming request contains up to MAX_BATCH_UP bytes of payload.
+Each incoming request contains up to max_batch_up bytes of payload.
 It's a multipart/form-data.
 
 Authentication: for now, plaintext password
 
-Sever side configuration:
-
- [<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
- host              # default is first host in network (eg <network>.1)
- relay             # default is first host in network not equal to server
- 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             ip address (textual)
- p             password
+Client form parameters (multipart/form-data):
+ m             metadata, newline-separated list (text file) of
+                       client ip address (textual)
+                       password
+                       target_requests_outstanding
  d              data (SLIP format)
- mbd mqt mrt   config updates
diff --git a/client b/client
index 7684cf3..b60f3d1 100755 (executable)
--- a/client
+++ b/client
@@ -2,22 +2,6 @@
 
 from hippotat import *
 
-defcfg = '''
-[DEFAULT]
-max_requests_outstanding = 4
-
-[virtual]
-mtu = 1500
-# [server]  # maybe computed from `network' (see server defaults)
-# [routes]  # default is none
-
-[server]
-# url     # maybe computed from `addrs' and `port' (see server defaults)
-
-# [<my ip address>]
-# password = <password>
-'''
-
 client_cs = None
 
 def set_client(ci,cs,pw):
@@ -44,19 +28,34 @@ def process_cfg():
 
   process_cfg_clients(set_client)
 
-  try:
-    c.routes = cfg.get('virtual','routes')
-  except NoOptionError:
-    c.routes = ''
+  c.routes = cfg.get('virtual','routes')
+  c.max_queue_time = cfg.get(client_cs, 'max_queue_time')
 
   process_cfg_ipif(client_cs,
                    (('local', 'client'),
                     ('peer',  'server'),
                     ('rnets', 'routes')))
 
+outstanding = 0
+
+def start_client():
+  global queue
+  queue = PacketQueue(c.max_queue_time)
+
 def outbound(packet, saddr, daddr):
-  print('OUT ', saddr, daddr, repr(packet))
-  pass
+  #print('OUT ', saddr, daddr, repr(packet))
+  queue.append(packet)
+  check_outbound()
+
+def check_outbound():
+  while True:
+    if outstanding >= c.max_outstanding: break
+    elements = { }
+    if not queue.nonempty():
+      if outstanding >= c.target_
+
+  while (outstanding <  and
+         (queue.notempty() or outstanding < c.
 
 common_startup(defcfg)
 process_cfg()
index 1baaed3..f51caf5 100644 (file)
@@ -19,6 +19,46 @@ from configparser import NoOptionError
 
 import collections
 
+defcfg = '''
+[DEFAULT]
+#[<client>] overrides
+max_batch_down = 65536           # used by server, subject to [limits]
+max_queue_time = 10              # used by server, subject to [limits]
+max_request_time = 54            # used by server, subject to [limits]
+target_requests_outstanding = 3  # must match; subject to [limits] on server
+max_requests_outstanding = 4     # used by client
+max_batch_up = 4000              # used by client
+
+#[server] or [<client>] overrides
+ipif = userv root ipif %(local)s,%(peer)s,%(mtu)s,slip %(rnets)s
+# extra interpolations:  %(local)s        %(peer)s          %(rnet)s
+#  obtained   on server  [virtual]server  [virtual]relay    [virtual]network
+#      from   on client  <client>         [virtual]server   [virtual]routes
+
+[virtual]
+mtu = 1500
+routes = ''
+# network = <prefix>/<len>  # mandatory for server
+# server  = <ipaddr>   # used by both, default is computed from `network'
+# relay   = <ipaddr>   # used by server, default from `network' and `server'
+#  default server is first host in network
+#  default relay is first host which is not server
+
+[server]
+# addrs = 127.0.0.1 ::1    # mandatory for server
+port = 80                  # used by server
+# url              # used by client; default from first `addrs' and `port'
+
+# [<client-ip4-or-ipv6-address>]
+# password = <password>    # used by both, must match
+
+[limits]
+max_batch_down = 262144           # used by server
+max_queue_time = 121              # used by server
+max_request_time = 121            # used by server
+target_requests_outstanding = 10  # used by server
+'''
+
 # these need to be defined here so that they can be imported by import *
 cfg = ConfigParser()
 optparser = OptionParser()
@@ -80,6 +120,9 @@ class _IpifProcessProtocol(twisted.internet.protocol.ProcessProtocol):
     for packet in packets:
       if not len(packet): continue
       (saddr, daddr) = packet_addrs(packet)
+      if saddr.is_link_local or daddr.is_link_local:
+        log_discard(packet, saddr, daddr, 'link-local')
+        continue
       self._router(packet, saddr, daddr)
   def processEnded(self, status):
     status.raiseException()
diff --git a/server b/server
index 0bbac6d..d36a84e 100755 (executable)
--- a/server
+++ b/server
@@ -15,31 +15,6 @@ import syslog
 
 clients = { }
 
-defcfg = '''
-[DEFAULT]
-max_batch_down = 65536
-max_queue_time = 10
-max_request_time = 54
-target_requests_outstanding = 3
-ipif = userv root ipif %(local)s,%(peer)s,%(mtu)s,slip %(rnets)s
-
-[virtual]
-mtu = 1500
-# network
-# [server]
-# [relay]
-
-[server]
-addrs = 127.0.0.1 ::1
-port = 8099
-
-[limits]
-max_batch_down = 262144
-max_queue_time = 121
-max_request_time = 121
-target_requests_outstanding = 10
-'''
-
 #---------- "router" ----------
 
 def route(packet, saddr, daddr):
@@ -48,8 +23,6 @@ def route(packet, saddr, daddr):
   except KeyError: dclient = None
   if dclient is not None:
     dclient.queue_outbound(packet)
-  elif saddr.is_link_local or daddr.is_link_local:
-    log_discard(packet, saddr, daddr, 'link-local')
   elif daddr == c.server or daddr not in c.network:
     print('TRACE INBOUND ', saddr, daddr, packet)
     queue_inbound(packet)
@@ -87,6 +60,7 @@ class Client():
       req = cfg.getint(cs, k)
       limit = cfg.getint('limits',k)
       self.__dict__[k] = min(req, limit)
+
     self._pq = PacketQueue(self.max_queue_time)
 
     if ip in clients:
@@ -108,6 +82,7 @@ class Client():
 
   def queue_outbound(self, packet):
     self._pq.append(packet)
+    self._check_outbound()
 
   def http_request(self, request):
     request.setHeader('Content-Type','application/octet-stream')
@@ -167,6 +142,8 @@ class IphttpResource(twisted.web.resource.Resource):
     if pw != c.pw: raise ValueError('bad password')
 
     # update config
+    
+    xxx check sanity, do not update
     for r, w in (('mbd', 'max_batch_down'),
                  ('mqt', 'max_queue_time'),
                  ('mrt', 'max_request_time'),