chiark / gitweb /
wip
[hippotat.git] / hippotat / __init__.py
index f51caf555bb0bc844be37d89d5757e3cd4e34c47..8f8a4479a1619727b3b633cf55a5c1889f16bef7 100644 (file)
@@ -3,6 +3,8 @@
 import signal
 signal.signal(signal.SIGINT, signal.SIG_DFL)
 
+import sys
+
 import twisted
 from twisted.internet import reactor
 from twisted.logger import LogLevel
@@ -11,14 +13,16 @@ import twisted.internet.endpoints
 import ipaddress
 from ipaddress import AddressValueError
 
-import hippotat.slip as slip
-
 from optparse import OptionParser
 from configparser import ConfigParser
 from configparser import NoOptionError
 
 import collections
 
+import re as regexp
+
+import hippotat.slip as slip
+
 defcfg = '''
 [DEFAULT]
 #[<client>] overrides
@@ -28,6 +32,7 @@ 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
+http_timeout = 30                # used by client
 
 #[server] or [<client>] overrides
 ipif = userv root ipif %(local)s,%(peer)s,%(mtu)s,slip %(rnets)s
@@ -63,6 +68,12 @@ target_requests_outstanding = 10  # used by server
 cfg = ConfigParser()
 optparser = OptionParser()
 
+_mimetrans = str.maketrans(b'-'+slip.esc, slip.esc+'-')
+def mime_translate(s):
+  # SLIP-encoded packets cannot contain ESC ESC.
+  # Swap `-' and ESC.  The result cannot contain `--'
+  return s.translate(_mimetrans)
+
 class ConfigResults:
   def __init__(self, d = { }):
     self.__dict__ = d
@@ -71,6 +82,11 @@ class ConfigResults:
 
 c = ConfigResults()
 
+def log_discard(packet, saddr, daddr, why):
+  print('DROP ', saddr, daddr, why)
+#  syslog.syslog(syslog.LOG_DEBUG,
+#                'discarded packet %s -> %s (%s)' % (saddr, daddr, why))
+
 #---------- packet parsing ----------
 
 def packet_addrs(packet):
@@ -162,11 +178,23 @@ class PacketQueue():
 
       return True
 
-  def popleft(self):
-    # caller must have checked nonempty
-    try: (dummy, packet) = self._pq[0]
-    except IndexError: return None
-    return packet
+  def process(self, sizequery, moredata, max_batch):
+    # sizequery() should return size of batch so far
+    # moredata(s) should add s to batch
+    while True:
+      try: (dummy, packet) = self._pq[0]
+      except IndexError: break
+
+      encoded = slip.encode(packet)
+      sofar = sizequery()  
+
+      if sofar > 0:
+        if sofar + len(slip.delimiter) + len(encoded) > max_batch:
+          break
+        moredata(slip.delimiter)
+
+      moredata(encoded)
+      self._pq.popLeft()
 
 #---------- error handling ----------
 
@@ -178,7 +206,7 @@ def crash(err):
 def crash_on_defer(defer):
   defer.addErrback(lambda err: crash(err))
 
-def crash_on_critical(event):
+vdef crash_on_critical(event):
   if event.get('log_level') >= LogLevel.critical:
     crash(twisted.logger.formatEvent(event))
 
@@ -249,7 +277,7 @@ def process_cfg_clients(constructor):
 
 #---------- startup ----------
 
-def common_startup(defcfg):
+def common_startup():
   twisted.logger.globalLogPublisher.addObserver(crash_on_critical)
 
   optparser.add_option('-c', '--config', dest='configfile',
@@ -257,7 +285,8 @@ def common_startup(defcfg):
   (opts, args) = optparser.parse_args()
   if len(args): optparser.error('no non-option arguments please')
 
-  cfg.read_string(defcfg)
+  re = regexp.compile('#.*')
+  cfg.read_string(re.sub('', defcfg))
   cfg.read(opts.configfile)
 
 def common_run():