chiark / gitweb /
wip
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 19 Mar 2017 19:39:34 +0000 (19:39 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 19 Mar 2017 19:39:34 +0000 (19:39 +0000)
server

diff --git a/server b/server
index 9d8338616e76c6343a6947e890f870d222eb2e55..a139e6e240d3d19e24847c54ff77c1698bc52459 100755 (executable)
--- a/server
+++ b/server
@@ -1,5 +1,7 @@
 #!/usr/bin/python3
 
+import twisted
+
 import twisted.web.server import Site
 from twisted.web.resource import Resource
 from twisted.web.server import NOT_DONE_YET
@@ -43,7 +45,7 @@ mtu = 1500
 # [relay]
 
 [server]
-ipif_program = userv root ipif %(host),%(relay),%(mtu),slip %(network)
+ipif = userv root ipif %(host),%(relay),%(mtu),slip %(network)
 
 [limits]
 max_batch_down = 262144
@@ -51,15 +53,38 @@ max_queue_time = 121
 max_request_time = 121
 '''
 
+class IpifProcessProtocol(twisted.internet.protocol.ProcessProtocol):
+  def __init__(self):
+    self._buffer = b''
+  def connectionMade(self): pass
+  def outReceived(self, data):
+    buffer += data
+    packets = slip_decode(buffer)
+    buffer = packets.pop()
+    for packet in packets:
+      (saddr, daddr) = packet_addrs(packet)
+      route(packet, daddr)
+
+def start_ipif():
+  reactor.spawnProcess(IpifProcessProtocol(),
+                       '/bin/sh',['-c', ipif_command],
+                       childFDs={0:'w', 1:'r', 2:2})
+
+def log_discard(packet, saddr, daddr, why):
+  syslog.syslog(syslog.LOG_DEBUG,
+                'discarded packet %s -> %s (%s)' % (saddr, daddr, why))
+
 def route(packet. daddr):
   try: client = clients[daddr]
   except KeyError: dclient = None
   if dclient is not None:
     dclient.queue_outbound(packet)
-  else if daddr = server or daddr not in network:
+  else if daddr = host or daddr not in network:
     queue_inbound(packet)
+  else if daddr = relay:
+    log_discard(packet, saddr, daddr, 'relay')
   else:
-    syslog.syslog(syslog.LOG_DEBUG, 'no client for %s' % daddr)
+    log_discard(packet, saddr, daddr, 'no client')
 
 class Client():
   def __init__(self, ip, cs):
@@ -80,7 +105,7 @@ class Client():
 
     def process_arriving_data(self, d):
       for packet in slip_decode(d):
-        (saddr, daddr) = ip_64_addrs(packet)
+        (saddr, daddr) = packet_addrs(packet)
         if saddr != self._ip:
           raise ValueError('wrong source address %s' % saddr)
         route(packet, daddr)
@@ -149,6 +174,7 @@ def process_cfg():
   global network
   global host
   global relay
+  global ipif_command
 
   network = ipnetwork(cfg.get('virtual','network'))
   if network.num_addresses < 3 + 2:
@@ -176,6 +202,12 @@ def process_cfg():
       raise ValueError('multiple client cfg sections for %s' % ci)
     clients[ci] = Client(ci, cs)
 
+  iic_vars = { }
+  for k in ('host','relay','mtu','network'):
+    iic_vars[k] = globals()[k]
+
+  ipif_command = cfg.get('server','ipif', vars=iic_vars)
+
 class FormPage(Resource):
   def render_POST(self, request):
     # find client, update config, etc.
@@ -208,4 +240,9 @@ def startup():
   if len(args): op.error('no non-option arguments please')
 
   cfg = ConfigParser()
-  
+  cfg.read_string(defcfg)
+  cfg.read_file(opts['configfile'])
+  process_cfg()
+
+  start_ipif()
+  start_http()