summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-10-19 10:43:47 +0200
committerAlon Levy <alevy@redhat.com>2011-10-19 10:43:58 +0200
commitcc89a6357bb0bb9261920778fec07fb2ec6ed757 (patch)
tree031435bdbd552a65874f02e7ee51f7092ebe2966
parent2e4e7ed0032b1335a1dbc74be7d820ba6fc30e84 (diff)
proxy now works standaloneHEADmaster
some other changes that were laying around here. made sure it's still operational. Get breakage when running proxy.py (and spicedump.py) under trickle: $ trickle -u 500 -d 500 -s ./proxy.py -l 7778 -p 10005 proxying from 7778 to ('localhost', 10005) Traceback (most recent call last): File "./proxy.py", line 156, in <module> main() File "./proxy.py", line 151, in main for ret in p: File "./proxy.py", line 66, in __iter__ for x in self._proxy: File "./proxy.py", line 98, in _proxy data = s.recv(MAX_PACKET_SIZE) socket.error: [Errno 11] Resource temporarily unavailable
-rw-r--r--client.py15
-rw-r--r--client_proto.py19
-rwxr-xr-xproxy.py31
-rwxr-xr-xspicedump.py47
4 files changed, 79 insertions, 33 deletions
diff --git a/client.py b/client.py
index 30ee1b9..192c8ae 100644
--- a/client.py
+++ b/client.py
@@ -8,6 +8,15 @@ import client_proto
logger = logging.getLogger('client')
+DEBUG_ENABLE_PDB=False
+
+if DEBUG_ENABLE_PDB:
+ def debug_break():
+ import pdb; pdb.set_trace()
+else:
+ def debug_break():
+ pass
+
# TODO - parse spice/protocol.h directly (to keep in sync automatically)
SPICE_MAGIC = "REDQ"
SPICE_VERSION_MAJOR = 2
@@ -47,15 +56,15 @@ class SpiceDataHeader(Struct):
inst = cls(*args, **kw)
if inst.e.sub_list != 0 and inst.e.sub_list >= inst.e.size:
logger.error('too large sub_list packet - %s' % inst)
- import pdb; pdb.set_trace()
+ debug_break()
return None
if inst.e.type < 0 or inst.e.type >= 400:
logger.error('bad type of packet - %s' % inst)
- import pdb; pdb.set_trace()
+ debug_break()
return None
if inst.e.size > 2000000:
logger.error('too large packet - %s' % inst)
- import pdb; pdb.set_trace()
+ debug_break()
return None
return inst
diff --git a/client_proto.py b/client_proto.py
index d5d4515..4f66852 100644
--- a/client_proto.py
+++ b/client_proto.py
@@ -2,18 +2,23 @@
Decode spice protocol using spice demarshaller.
"""
-ANNOTATE = False
+ANNOTATE = True
NO_PRINT_PROTECTION = False
import logging
-
-logger = logging.getLogger('client_proto')
-
+import os
from collections import namedtuple
import struct
import sys
+
+# we assume we are side by side with spice. hopefully, that is so.
+spice_dir = os.path.join(os.path.dirname(sys.modules[__name__].__file__),
+ '../spice')
+
+logger = logging.getLogger('client_proto')
+
if not 'proto' in locals():
- sys.path.append('../spice/python_modules')
+ sys.path.append(os.path.join(spice_dir, 'python_modules'))
import spice_parser
import ptypes
proto = None
@@ -346,9 +351,9 @@ def set_proto(major_version, minor_version):
return
globals().update(dict(major_version=major_version, minor_version=minor_version))
if major_version == 1 :
- proto = spice_parser.parse('../spice/spice1.proto')
+ proto = spice_parser.parse(os.path.join(spice_dir, 'spice1.proto'))
else:
- proto = spice_parser.parse('../spice/spice.proto')
+ proto = spice_parser.parse(os.path.join(spice_dir, 'spice.proto'))
channels = make_channels_dict(proto)
num_spice_messages = sum(len(ch.client) + len(ch.server) for ch in
diff --git a/proxy.py b/proxy.py
index 03af6d6..227d88c 100755
--- a/proxy.py
+++ b/proxy.py
@@ -40,9 +40,9 @@ class twowaydict(dict):
BROKEN_PIPE_ERRNO, TRANSPORT_NOT_CONNECTED_ERRNO = 32, 107
-def make_accepter(port):
+def make_accepter(port, host='127.0.0.1'):
accepter = Socket(AF_INET, SOCK_STREAM)
- accepter.bind(('0.0.0.0', port))
+ accepter.bind((host, port))
accepter.listen(1)
return accepter
@@ -53,9 +53,9 @@ def connect(addr):
return s
class Proxy(object):
- def __init__(self, local_port, remote_addr):
+ def __init__(self, local_port, remote_addr, host='127.0.0.1'):
self._drop_next = False
- self._proxy = _proxy(self, local_port, remote_addr)
+ self._proxy = _proxy(self, local_port, remote_addr, host)
def drop_next(self):
self._drop_next = True
def check_drop_next(self):
@@ -66,9 +66,9 @@ class Proxy(object):
for x in self._proxy:
yield x
-def _proxy(proxy, local_port, remote_addr):
+def _proxy(proxy, local_port, remote_addr, host = '127.0.0.1'):
print "proxying from %s to %s" % (local_port, remote_addr)
- accepter = make_accepter(local_port)
+ accepter = make_accepter(local_port, host)
open_socks = twowaydict()
close_errnos = set([BROKEN_PIPE_ERRNO, TRANSPORT_NOT_CONNECTED_ERRNO])
while True:
@@ -136,6 +136,21 @@ def tests():
from_port, to_port = port_num, port_num+1000
proxy(port_num, ('localhost', port_num+1000))
-if __name__ == '__main__':
- tests()
+def main():
+ import argparse
+ import sys
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-l', '--local-port', type=int, required=True, help='set proxy local port')
+ parser.add_argument('-H', '--remote-host', default='localhost', help='set proxy remote address')
+ parser.add_argument('-p', '--remote-port', type=int, required=True, help='set proxy remote address')
+ parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='verbosity', default=0)
+ opts, rest = parser.parse_known_args(sys.argv[1:])
+ local_port = opts.local_port
+ remote_addr = (opts.remote_host, opts.remote_port)
+ p = proxy(local_port=local_port, remote_addr=remote_addr)
+ for ret in p:
+ if opts.verbose:
+ print repr(ret)
+if __name__ == '__main__':
+ main()
diff --git a/spicedump.py b/spicedump.py
index aac6ff3..9f7c8bb 100755
--- a/spicedump.py
+++ b/spicedump.py
@@ -3,9 +3,10 @@ import sys
from collections import defaultdict
from itertools import izip_longest
from time import time
-from optparse import OptionParser
+import argparse
import textwrap
import logging
+import re
import pcaputil
from proxy import proxy, closeallsockets
@@ -68,14 +69,26 @@ class SurfaceStatistics(object):
for i, l in enumerate(textwrap.wrap(','.join(map(str, v)), width=40)):
yield '%20s: %s' % (k if i == 0 else '', l)
+def debug_break():
+ import rpdb2; rpdb2.start_embedded_debugger('a')
+
def spicedump(p, opts, stdscr=None):
+ show_every_command = True
+ periodic_hist = False
import pcapspice
spice = pcapspice.spice_iter(p)
hist = Histogram()
surface_stat = SurfaceStatistics()
last_print = start_time = time()
messages = []
- filter = opts.filter
+ filter_exp = opts.filter
+ if filter_exp:
+ if filter_exp[0] == '-':
+ def filter(result_name, exp=re.compile(filter_exp[1:])):
+ return exp.match(result_name)
+ else:
+ def filter(result_name, exp=re.compile(filter_exp)):
+ return not exp.match(result_name)
if stdscr:
stdscr.erase()
# replace the "for d in spice:" loop with a select
@@ -87,7 +100,7 @@ def spicedump(p, opts, stdscr=None):
d = spice.next()
result_name = d.msg.data.result_name
result_value = d.msg.data.result_value
- if filter and result_name not in filter:
+ if filter_exp and filter(result_name):
continue
if hasattr(p, 'drop_next'):
pass
@@ -108,7 +121,9 @@ def spicedump(p, opts, stdscr=None):
messages.extend(str(d).split('\n'))
old_time, old_count = hist[result_name]
hist[result_name] = (cur_time, old_count + 1)
- if True or cur_time - last_print > dt:
+ if show_every_command:
+ print result_name
+ if periodic_hist and cur_time - last_print > dt:
show(hist.show(), surface_stat.show())
print '\n'.join(messages[-20:])
last_print = cur_time
@@ -122,22 +137,24 @@ def fromproxy(stdscr, local_port, remote_addr, opts):
return spicedump(p, opts, stdscr=stdscr)
if __name__ == '__main__':
- parser = OptionParser()
- parser.add_option('-p', '--proxy', dest='proxy', help='use proxy',
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-p', '--proxy', dest='proxy', help='use proxy',
action='store_true')
- parser.add_option('-l', '--localport', dest='local_port', help='set proxy local port')
- parser.add_option('-r', '--remoteaddr', dest='remote_addr', help='set proxy remote address')
- parser.add_option('-v', '--verbose', dest='verbose', action='count', help='verbosity', default=0)
- parser.add_option('-c', '--curses', dest='curses', action='store_true', help='use curses')
- parser.add_option('-f', '--filter', dest='filter', help='filter messages')
- opts, rest = parser.parse_args(sys.argv[1:])
+ parser.add_argument('-l', '--local-port', type=int, help='set proxy local port')
+ parser.add_argument('-H', '--remote-host', default='localhost', help='set proxy remote address')
+ parser.add_argument('-p', '--remote-port', type=int, required=True, help='set proxy remote address')
+ parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='verbosity', default=0)
+ parser.add_argument('-c', '--curses', dest='curses', action='store_true', help='use curses')
+ parser.add_argument('-f', '--filter', dest='filter', help='filter messages')
+ parser.add_argument('--record', dest='record', help='TODO: record to file, can be used to playback')
+ parser.add_argument('--playback', dest='playback', help='TODO: playback a previously recorded file')
+ opts, rest = parser.parse_known_args(sys.argv[1:])
if opts.verbose >= 2 in sys.argv:
logging.basicConfig(filename='spicedump.log', level=logging.DEBUG)
print "saving debug log to spicedump.log"
if opts.proxy:
- local_port = int(opts.local_port)
- remote_addr = opts.remote_addr.split(':')
- remote_addr = (remote_addr[0], int(remote_addr[1]))
+ local_port = opts.local_port
+ remote_addr = (opts.remote_host, opts.remote_port)
main = (lambda stdscr, opts, local_port=local_port, remote_addr=remote_addr:
fromproxy(stdscr, local_port, remote_addr, opts))
else: