X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=hippotat.git;a=blobdiff_plain;f=server;h=3abebe96bfb69bdf5921dfa64cf1a8da2f70bbf0;hp=775a0c34362458b93dffc0ec3fb6ade28b054e35;hb=8e279651cf76bb0e7d532307c0afbfbd7dc4986b;hpb=ce7f1431dbc8ca547149f6295ae79077e678d03d diff --git a/server b/server index 775a0c3..3abebe9 100755 --- a/server +++ b/server @@ -1,5 +1,8 @@ #!/usr/bin/python3 +import signal +signal.signal(signal.SIGINT, signal.SIG_DFL) + import sys import os @@ -55,7 +58,7 @@ mtu = 1500 [server] ipif = userv root ipif %(host)s,%(relay)s,%(mtu)s,slip %(network)s addrs = 127.0.0.1 ::1 -port = 80 +port = 8099 [limits] max_batch_down = 262144 @@ -63,14 +66,32 @@ max_queue_time = 121 max_request_time = 121 ''' +#---------- error handling ---------- + +def crash(err): + print('CRASH ', err, file=sys.stderr) + try: reactor.stop() + except twisted.internet.error.ReactorNotRunning: pass + +def crash_on_defer(defer): + defer.addErrback(lambda err: crash(err)) + +def crash_on_critical(event): + if event.get('log_level') >= LogLevel.critical: + crash(twisted.logger.formatEvent(event)) + #---------- "router" ---------- -def route(packet, daddr): +def route(packet, saddr, daddr): + print('TRACE ', saddr, daddr, packet) try: client = clients[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 == host or daddr not in network: + print('TRACE INBOUND ', saddr, daddr, packet) queue_inbound(packet) elif daddr == relay: log_discard(packet, saddr, daddr, 'relay') @@ -78,8 +99,9 @@ def route(packet, daddr): log_discard(packet, saddr, daddr, 'no client') def log_discard(packet, saddr, daddr, why): - syslog.syslog(syslog.LOG_DEBUG, - 'discarded packet %s -> %s (%s)' % (saddr, daddr, why)) + print('DROP ', saddr, daddr, why) +# syslog.syslog(syslog.LOG_DEBUG, +# 'discarded packet %s -> %s (%s)' % (saddr, daddr, why)) #---------- ipif (slip subprocess) ---------- @@ -93,8 +115,9 @@ class IpifProcessProtocol(twisted.internet.protocol.ProcessProtocol): packets = slip_decode(self._buffer) self._buffer = packets.pop() for packet in packets: + if not len(packet): continue (saddr, daddr) = packet_addrs(packet) - route(packet, daddr) + route(packet, saddr, daddr) def processEnded(self, status): status.raiseException() @@ -136,8 +159,9 @@ def slip_decode(data): #print('ESC ', repr((pdata, packet, eix))) pdata += packet[0 : eix] ck = packet[eix+1] - if ck == slip_esc_esc: pdata += slip_esc - elif ck == slip_esc_end: pdata += slip_end + #print('ESC... %o' % ck) + if ck == slip_esc_esc[0]: pdata += slip_esc + elif ck == slip_esc_end[0]: pdata += slip_end else: raise ValueError('invalid SLIP escape') packet = packet[eix+2 : ] out.append(pdata) @@ -147,7 +171,20 @@ def slip_decode(data): #---------- packet parsing ---------- def packet_addrs(packet): - pass + version = packet[0] >> 4 + if version == 4: + addrlen = 4 + saddroff = 3*4 + factory = ipaddress.IPv4Address + elif version == 6: + addrlen = 16 + saddroff = 2*4 + factory = ipaddress.IPv6Address + else: + raise ValueError('unsupported IP version %d' % version) + saddr = factory(packet[ saddroff : saddroff + addrlen ]) + daddr = factory(packet[ saddroff + addrlen : saddroff + addrlen*2 ]) + return (saddr, daddr) #---------- client ---------- @@ -173,7 +210,7 @@ class Client(): (saddr, daddr) = packet_addrs(packet) if saddr != self._ip: raise ValueError('wrong source address %s' % saddr) - route(packet, daddr) + route(packet, saddr, daddr) def _req_cancel(self, request): request.finish() @@ -258,6 +295,9 @@ class IphttpResource(twisted.web.resource.Resource): c.process_arriving_data(d) c.new_request(request) + def render_GET(self, request): + return 'hippotit' + def start_http(): resource = IphttpResource() sitefactory = twisted.web.server.Site(resource) @@ -269,7 +309,7 @@ def start_http(): addr = ipaddress.IPv6Address(addrspec) endpointfactory = twisted.internet.endpoints.TCP6ServerEndpoint ep = endpointfactory(reactor, cfg.getint('server','port'), addr) - ep.listen(sitefactory) + crash_on_defer(ep.listen(sitefactory)) #---------- config and setup ---------- @@ -314,14 +354,6 @@ def process_cfg(): ipif_command = cfg.get('server','ipif', vars=iic_vars) -def crash_on_critical(event): - if event.get('log_level') >= LogLevel.critical: - print('crashing: ', twisted.logger.formatEvent(event), file=sys.stderr) - #print('crashing!', file=sys.stderr) - #os._exit(1) - try: reactor.stop() - except twisted.internet.error.ReactorNotRunning: pass - def startup(): global cfg @@ -344,3 +376,4 @@ def startup(): startup() reactor.run() +print('CRASHED (end)', file=sys.stderr)