From ca732796fd94e7bc50750c11377da63880e4beff Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 21 Mar 2017 22:40:03 +0000 Subject: [PATCH] wip config reorg --- PROTOCOL | 37 ++++++++----------------------------- client | 43 +++++++++++++++++++++---------------------- hippotat/__init__.py | 43 +++++++++++++++++++++++++++++++++++++++++++ server | 31 ++++--------------------------- 4 files changed, 76 insertions(+), 78 deletions(-) diff --git a/PROTOCOL b/PROTOCOL index c7033af..c1ef03b 100644 --- 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: - - [] 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 .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 --- 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) - -# [] -# 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() diff --git a/hippotat/__init__.py b/hippotat/__init__.py index 1baaed3..f51caf5 100644 --- a/hippotat/__init__.py +++ b/hippotat/__init__.py @@ -19,6 +19,46 @@ from configparser import NoOptionError import collections +defcfg = ''' +[DEFAULT] +#[] 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 [] 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 [virtual]server [virtual]routes + +[virtual] +mtu = 1500 +routes = '' +# network = / # mandatory for server +# server = # used by both, default is computed from `network' +# relay = # 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' + +# [] +# 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 --- 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'), -- 2.30.2