+#---------- 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, 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')
+ else:
+ log_discard(packet, saddr, daddr, 'no client')
+
+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))
+
+#---------- ipif (slip subprocess) ----------
+