X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=hippotat.git;a=blobdiff_plain;f=hippotatd;h=05c51bcb58a1c57a682221ad9f5873364a19e5d4;hp=1865dad819a7231b2b743ac071076ec2b0e2f5e6;hb=b3e598b5ea54399982e0183a3e59835b0f82f077;hpb=a571ef2d5e5929225f8874a9e3f819c43d21b534 diff --git a/hippotatd b/hippotatd index 1865dad..05c51bc 100755 --- a/hippotatd +++ b/hippotatd @@ -25,7 +25,7 @@ # the file AGPLv3+CAFv2. If not, email Ian Jackson # . -#@ sys.path.append(@PYBUILD_INSTALL_DIR@) +#@ import sys; sys.path.append('@PYBUILD_INSTALL_DIR@') from hippotatlib import * import os @@ -38,7 +38,6 @@ import twisted.internet from twisted.web.server import NOT_DONE_YET import twisted.web.static -import twisted.python.syslog import hippotatlib.ownsource from hippotatlib.ownsource import SourceShipmentPreparer @@ -65,7 +64,7 @@ def route(packet, iface, saddr, daddr): elif daddr == c.vaddr or daddr not in c.vnetwork: lt('inbound') queue_inbound(ipif, packet) - elif daddr == c.relay: + elif daddr == c.vrelay: lt('discard relay') log_discard(packet, iface, saddr, daddr, 'relay') else: @@ -105,7 +104,8 @@ class Client(): def _req_cancel(self, request): self._log(DBG.HTTP_CTRL, 'cancel', idof=request) - request.finish() + try: request.finish() + except Exception: pass def _req_error(self, err, request): self._log(DBG.HTTP_CTRL, 'error %s' % err, idof=request) @@ -126,7 +126,7 @@ class Client(): nf = request.notifyFinish() nf.addErrback(self._req_error, request) nf.addCallback(self._req_fin, request, cl) - self._rq.append(request) + self._rq.append((request,nf)) self._check_outbound() def _req_write(self, req, d): @@ -136,9 +136,9 @@ class Client(): def _check_outbound(self): log_debug(DBG.HTTP_CTRL, 'CHKO') while True: - try: request = self._rq[0] + try: (request,nf) = self._rq[0] except IndexError: request = None - if request and request.finished: + if request and nf.called: self._log(DBG.HTTP_CTRL, 'CHKO req finished, discard', idof=request) self._rq.popleft() continue @@ -166,7 +166,7 @@ class Client(): # round again, looking for more to do while len(self._rq) > self.cc.target_requests_outstanding: - request = self._rq.popleft() + (request, nf) = self._rq.popleft() self._log(DBG.HTTP, 'CHKO above target, returning empty', idof=request) request.finish() @@ -174,7 +174,7 @@ def process_request(request, desca): # find client, update config, etc. metadata = request.args[b'm'][0] metadata = metadata.split(b'\r\n') - (ci_s, pw, tro, cto) = metadata[0:4] + (ci_s, token, tro, cto) = metadata[0:4] desca['m[0,2:3]'] = [ci_s, tro, cto] ci_s = ci_s.decode('utf-8') tro = int(tro); desca['tro']= tro @@ -182,7 +182,7 @@ def process_request(request, desca): ci = ipaddr(ci_s) desca['ci'] = ci cl = clients[ci] - if pw != cl.cc.password: raise ValueError('bad password') + authtoken_check(cl.cc.secret, token, cl.cc.max_clock_skew) desca['pwok']=True if tro != cl.cc.target_requests_outstanding: @@ -218,7 +218,7 @@ class NotStupidResource(twisted.web.resource.Resource): # why this is not the default is a mystery! def getChild(self, name, request): if name == b'': return self - else: return twisted.web.resource.Resource.getChild(name, request) + else: return twisted.web.resource.Resource.getChild(self, name, request) class IphttpResource(NotStupidResource): def render_POST(self, request): @@ -297,9 +297,10 @@ def process_cfg(_opts, putative_servers, putative_clients): global c c = ConfigResults() - c.server = cfg.get('SERVER','server') + try: c.server = cfg1get('SERVER','server') + except NoOptionError: c.server = 'SERVER' - cfg_process_common(c, c.server) + cfg_process_general(c, c.server) cfg_process_saddrs(c, c.server) cfg_process_vnetwork(c, c.server) cfg_process_vaddr(c, c.server) @@ -310,24 +311,28 @@ def process_cfg(_opts, putative_servers, putative_clients): if not sections: continue cfg_process_client_limited(cc,c.server,sections, 'max_batch_down') cfg_process_client_limited(cc,c.server,sections, 'max_queue_time') + cc.max_clock_skew = cfg_search(cfg.getint, 'max_clock_skew', sections) Client(ci, cc) try: - c.vrelay = cfg.get(c.server, 'vrelay') + c.vrelay = cfg1get(c.server, 'vrelay') except NoOptionError: for search in c.vnetwork.hosts(): if search == c.vaddr: continue c.vrelay = search break + try: c.ifname = cfg1get(c.server, 'ifname_server', raw=True) + except NoOptionError: pass + cfg_process_ipif(c, - [c.server, 'DEFAULT'], + [c.server, 'COMMON'], (('local','vaddr'), ('peer', 'vrelay'), ('rnets','vnetwork'))) if opts.printconfig is not None: - try: val = cfg.get(c.server, opts.printconfig) + try: val = cfg1get(c.server, opts.printconfig) except NoOptionError: pass else: print(val) sys.exit(0) @@ -347,7 +352,9 @@ def catch_termination(): raise RuntimeError('did not die due to signal %s !' % name) for sig in (signal.SIGINT, signal.SIGTERM): - signal.signal(sig, partial(signal_handler, sig.name)) + try: signame = sig.name + except AttributeError: signame = "signal %d" % sig + signal.signal(sig, partial(signal_handler, signame)) def daemonise(): global syslogfacility @@ -360,6 +367,7 @@ def daemonise(): facility=facilnum, logoption=syslog.LOG_PID) def emit(event): + if logevent_is_boringtwisted(event): return m = twisted.logger.formatEvent(event) #print(repr(event), m, file=org_stderr) level = event.get('log_level') @@ -369,6 +377,10 @@ def daemonise(): elif level == LogLevel.warn : sl = syslog.LOG_WARNING else : sl = syslog.LOG_INFO syslog.syslog(sl,m) + failure = event.get('log_failure') + if failure is not None: + for l in failure.getTraceback().split('\n'): + syslog.syslog(sl,l) glp = twisted.logger.globalLogPublisher glp.addObserver(emit) log_debug(DBG.INIT, 'starting to log to syslog') @@ -398,16 +410,15 @@ def daemonise(): if grandchildpid: # we are the intermediate child if opts.pidfile is not None: - print(grandchildpid, file=pfh) - pfh.close() + print(grandchildpid, file=pidfile_h) + pidfile_h.close() os._exit(0) - mypid = os.getpid() - pfh.close() + if opts.pidfile is not None: + pidfile_h.close() logger = subprocess.Popen(['logger','-d', - '-t','hippotat(stderr)', - '--id=%d' % mypid, + '-t','hippotat[%d](stderr)' % os.getpid(), '-p',opts.syslogfacility + '.err'], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL,