diff options
author | imarom <imarom@cisco.com> | 2016-02-15 03:12:29 -0500 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-02-15 07:11:26 -0500 |
commit | ec369cd722a400130b9b754c2c965ec60beb9d56 (patch) | |
tree | 0b6f3bcaaa957983fd148548f09bd1ae4b900cfd /scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py | |
parent | 1f60016f591ebd2e260e501c8c5da10c11d0c7ad (diff) |
many bugs uncovered by the PCAP injection:
1. NamedTuple constructor
2. Scappy
3. zlib for server
Diffstat (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py')
-rw-r--r-- | scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py | 99 |
1 files changed, 75 insertions, 24 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py index ab3c7282..96d1854d 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py @@ -3,10 +3,12 @@ import zmq import json import re -from time import sleep from collections import namedtuple from trex_stl_types import * from utils.common import random_id_gen +import zlib +import struct + class bcolors: BLUE = '\033[94m' @@ -35,12 +37,15 @@ class BatchMessage(object): msg = json.dumps(self.batch_list) - return self.rpc_client.send_raw_msg(msg) + return self.rpc_client.send_msg(msg) # JSON RPC v2.0 client class JsonRpcClient(object): + MSG_COMPRESS_THRESHOLD = 4096 + MSG_COMPRESS_HEADER_MAGIC = 0xABE85CEA + def __init__ (self, default_server, default_port, logger): self.logger = logger self.connected = False @@ -109,14 +114,64 @@ class JsonRpcClient(object): id, msg = self.create_jsonrpc_v2(method_name, params) - return self.send_raw_msg(msg) + return self.send_msg(msg) + + + def compress_msg (self, msg): + # compress + compressed = zlib.compress(msg) + new_msg = struct.pack(">II", self.MSG_COMPRESS_HEADER_MAGIC, len(msg)) + compressed + return new_msg + + + def decompress_msg (self, msg): + if len(msg) < 8: + return None + + t = struct.unpack(">II", msg[:8]) + if (t[0] != self.MSG_COMPRESS_HEADER_MAGIC): + return None + + x = zlib.decompress(msg[8:]) + if len(x) != t[1]: + return None + + return x + + def send_msg (self, msg): + # print before + if self.logger.check_verbose(self.logger.VERBOSE_HIGH): + self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n") + + if len(msg) > self.MSG_COMPRESS_THRESHOLD: + response = self.send_raw_msg(self.compress_msg(msg)) + if response: + response = self.decompress_msg(response) + else: + response = self.send_raw_msg(msg) + + if response == None: + return RC_ERR("*** [RPC] - Failed to decode response from server") + + + # print after + if self.logger.check_verbose(self.logger.VERBOSE_HIGH): + self.verbose_msg("Server Response:\n\n" + self.pretty_json(response) + "\n") + + # process response (batch and regular) + + response_json = json.loads(response) + + if isinstance(response_json, list): + return self.process_batch_response(response_json) + else: + return self.process_single_response(response_json) + # low level send of string message def send_raw_msg (self, msg): - self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n") - tries = 0 while True: try: @@ -141,26 +196,11 @@ class JsonRpcClient(object): return RC_ERR("*** [RPC] - Failed to get server response at {0}".format(self.transport)) - self.verbose_msg("Server Response:\n\n" + self.pretty_json(response) + "\n") - - # decode - - # batch ? - response_json = json.loads(response) - - if isinstance(response_json, list): - rc_batch = RC() - - for single_response in response_json: - rc = self.process_single_response(single_response) - rc_batch.add(rc) - - return rc_batch - - else: - return self.process_single_response(response_json) - + return response + + + # processs a single response from server def process_single_response (self, response_json): if (response_json.get("jsonrpc") != "2.0"): @@ -182,6 +222,17 @@ class JsonRpcClient(object): + # process a batch response + def process_batch_response (self, response_json): + rc_batch = RC() + + for single_response in response_json: + rc = self.process_single_response(single_response) + rc_batch.add(rc) + + return rc_batch + + def disconnect (self): if self.connected: self.socket.close(linger = 0) |