#!/usr/bin/env python # Author: # Rudiger Birkner (Networked Systems Group ETH Zurich) import argparse import json from multiprocessing import Queue from Queue import Empty from threading import Thread from time import sleep, time import socket import os import sys np = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) if np not in sys.path: sys.path.append(np) import util.log ''' LogClient for Reference Monitor ''' class LogClient(object): def __init__(self, address, port, authkey, input_file, debug = False, timing = False): self.logger = util.log.getLogger('log_client') self.logger.info('server: start') self.timing = timing self.address = address self.port = int(port) self.authkey = authkey self.input_file = input_file self.real_start_time = time() self.simulation_start_time = 0 self.fp_thread = None self.fs_thread = None self.flow_mod_queue = Queue() def start(self): self.run = True self.fp_thread = Thread(target=self.file_processor) self.fp_thread.setDaemon(True) self.fp_thread.start() self.logger.debug('file processor started') self.fs_thread = Thread(target=self.flow_mod_sender) self.fs_thread.setDaemon(True) self.fs_thread.start() self.logger.debug('flow mod sender started') def stop(self): self.run = False self.fs_thread.join() self.logger.debug('flow mod sender terminated') self.fp_thread.join() self.logger.debug('file processor terminated') self.flow_mod_queue.close() ''' receiver ''' def file_processor(self): with open(self.input_file) as infile: flag = 0 tmp = {} for line in infile: if line.startswith("BURST"): flag = 1 tmp = {"flow_mods": []} x = line.split("\n")[0].split(": ")[1] tmp["time"] = float(x) elif line.startswith("PARTICIPANT") and flag == 1: flag = 2 x = line.split("\n")[0].split(": ")[1] tmp["auth_info"] = {"participant": int(x), "auth_key": "secrect"} elif flag == 2: if line.startswith("\n"): if not self.run: break self.logger.debug('processed one burst') self.flow_mod_queue.put(tmp) while self.flow_mod_queue.qsize() > 32000: self.logger.debug('queue is full - taking a break') sleep(self.sleep_time(tmp["time"])/2) if not self.run: break flag = 0 else: tmp["flow_mods"].append(json.loads(line)) self.logger.debug('finished processing the log') def flow_mod_sender(self): while self.run: try: flow_mod = self.flow_mod_queue.get(True, 0.5) except Empty: continue if self.timing: if self.simulation_start_time == 0: self.real_start_time = time() self.simulation_start_time = flow_mod["time"] sleep_time = self.sleep_time(flow_mod["time"]) self.logger.debug('sleep for ' + str(sleep_time) + ' seconds') sleep(sleep_time) self.send(flow_mod) def send(self, flow_mod): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((self.address, self.port)) sock.sendall(json.dumps(flow_mod)) sock.close() def sleep_time(self, flow_mod_time): time_diff = flow_mod_time - self.simulation_start_time wake_up_time = self.real_start_time + time_diff sleep_time = wake_up_time - time() if sleep_time < 0: sleep_time = 0 return sleep_time def main(argv): log_client_instance = LogClient(args.ip, args.port, args.key, args.input, True, args.timing) log_client_instance.start() while log_client_instance.run: try: sleep(0.5) except KeyboardInterrupt: log_client_instance.stop() ''' main ''' if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('ip', help='ip address of the refmon') parser.add_argument('port', help='port of the refmon') parser.add_argument('key', help='authkey of the refmon') parser.add_argument('input', help='flow mod input file') parser.add_argument('-t', '--timing', help='enable timed replay of flow mods', action='store_true') args = parser.parse_args() main(args)