aboutsummaryrefslogtreecommitdiff
path: root/potpourri
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-07-11 18:29:31 +0000
committerRob Austein <sra@hactrn.net>2014-07-11 18:29:31 +0000
commit00369f84c1c730094ea33847d08e276181dc76e8 (patch)
treebf226833ad42b91d1d0eb561cf174c7cb4966e4c /potpourri
parentcea7193a43011bc4d47cffa6a6cd7ac19ccce5ad (diff)
First cut at a generic rpki-rtr replay script, including support for
multiple protocol versions. Not tested yet. svn path=/trunk/; revision=5893
Diffstat (limited to 'potpourri')
-rwxr-xr-xpotpourri/rpki-rtr-replay135
1 files changed, 135 insertions, 0 deletions
diff --git a/potpourri/rpki-rtr-replay b/potpourri/rpki-rtr-replay
new file mode 100755
index 00000000..be0de062
--- /dev/null
+++ b/potpourri/rpki-rtr-replay
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+
+# $Id$
+#
+# Copyright (C) 2014 Dragon Research Labs ("DRL")
+# Portions copyright (C) 2009-2013 Internet Systems Consortium ("ISC")
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notices and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND DRL AND ISC DISCLAIM ALL
+# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL OR
+# ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+import asyncore
+import bisect
+import glob
+import logging
+import os
+import shutil
+import sqlite3
+import subprocess
+import sys
+import time
+
+import rpki.POW
+import rpki.oids
+import rpki.rtr.channels
+import rpki.rtr.client
+import rpki.rtr.generator
+import rpki.rtr.pdus
+import rpki.rtr.server
+
+from rpki.rtr.channels import Timestamp
+
+
+class ReplayClock(object):
+ """
+ Internal clock for replaying a set of rpki-rtr database files.
+
+ This class replaces the normal on-disk serial number mechanism with
+ an in-memory version based on pre-computed data.
+
+ DO NOT USE THIS IN PRODUCTION.
+
+ You have been warned.
+ """
+
+ def __init__(self):
+ self.timestamps = dict((v, sorted(set(Timestamp(int(f.split(".")[0]))
+ for f in glob.iglob("*.ax.v%d" % v))))
+ for v in rpki.rtr.pdus.PDU.version_map)
+ self.offset = min(t[0] for t in self.timestamps.itervalues()) - Timestamp.now()
+ self.nonce = rpki.rtr.generator.new_nonce()
+
+ def __nonzero__(self):
+ return sum(len(t) for t in self.timestamps.itervalues()) > 0
+
+ def now(self):
+ return Timestamp.now(self.offset)
+
+ def read_current(self, version):
+ now = self.now()
+ while len(self.timestamps[version]) > 1 and now >= self.timestamps[version][1]:
+ del self.timestamps[version][0]
+ return self.timestamps[version][0], self.nonce
+
+ def siesta(self):
+ try:
+ when = min(t[1] for t in self.timestamps.itervalues() if len(t) > 1)
+ except ValueError:
+ return None
+ now = self.now()
+ if now < when:
+ return when - now
+ else:
+ return 1
+
+
+def server_main(args):
+ """
+ Reply rpki-data from a historical database.
+
+ This is a clone of server_main() which replaces the external serial
+ number updates triggered via the kickme channel by cronjob_main with
+ an internal clocking mechanism to replay historical test data.
+
+ DO NOT USE THIS IN PRODUCTION.
+
+ You have been warned.
+ """
+
+ logger = logging.LoggerAdapter(logging.root, dict(connection = rpki.rtr.server._hostport_tag()))
+
+ logger.debug("[Starting]")
+
+ if args.rpki_rtr_dir:
+ try:
+ os.chdir(args.rpki_rtr_dir)
+ except OSError, e:
+ sys.exit(e)
+
+ # Yes, this really does replace a global function defined in another
+ # module with a bound method to our clock object. Fun stuff, huh?
+
+ clock = ReplayClock()
+ rpki.rtr.server.read_current = clock.read_current
+
+ try:
+ server = rpki.rtr.server.ServerChannel(logger = logger, refresh = args.refresh, retry = args.retry, expire = args.expire)
+ old_serial = server.get_serial()
+ logger.debug("[Starting at serial %d (%s)]", old_serial, old_serial)
+ while clock:
+ new_serial = server.get_serial()
+ if old_serial != new_serial:
+ logger.debug("[Serial bumped from %d (%s) to %d (%s)]", old_serial, old_serial, new_serial, new_serial)
+ server.notify()
+ old_serial = new_serial
+ asyncore.loop(timeout = clock.siesta(), count = 1)
+ except KeyboardInterrupt:
+ sys.exit(0)
+
+
+# Splice our extensions into server
+rpki.rtr.server.server_main = server_main
+
+# And run the program
+import rpki.rtr.main
+rpki.rtr.main.main()