summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-02-15 03:12:29 -0500
committerimarom <imarom@cisco.com>2016-02-15 07:11:26 -0500
commitec369cd722a400130b9b754c2c965ec60beb9d56 (patch)
tree0b6f3bcaaa957983fd148548f09bd1ae4b900cfd /src
parent1f60016f591ebd2e260e501c8c5da10c11d0c7ad (diff)
many bugs uncovered by the PCAP injection:
1. NamedTuple constructor 2. Scappy 3. zlib for server
Diffstat (limited to 'src')
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.cpp55
-rw-r--r--src/rpc-server/trex_rpc_req_resp_server.h4
-rw-r--r--src/rpc-server/trex_rpc_zip.cpp124
-rw-r--r--src/rpc-server/trex_rpc_zip.h60
4 files changed, 231 insertions, 12 deletions
diff --git a/src/rpc-server/trex_rpc_req_resp_server.cpp b/src/rpc-server/trex_rpc_req_resp_server.cpp
index 1e8e177d..da7e8c55 100644
--- a/src/rpc-server/trex_rpc_req_resp_server.cpp
+++ b/src/rpc-server/trex_rpc_req_resp_server.cpp
@@ -22,6 +22,7 @@ limitations under the License.
#include <trex_rpc_server_api.h>
#include <trex_rpc_req_resp_server.h>
#include <trex_rpc_jsonrpc_v2_parser.h>
+#include <trex_rpc_zip.h>
#include <unistd.h>
#include <sstream>
@@ -138,20 +139,33 @@ void TrexRpcServerReqRes::_stop_rpc_thread() {
* respondes to the request
*/
void TrexRpcServerReqRes::handle_request(const std::string &request) {
- std::string response_str = process_request(request);
- zmq_send(m_socket, response_str.c_str(), response_str.size(), 0);
+ std::string response;
+
+ process_request(request, response);
+
+ zmq_send(m_socket, response.c_str(), response.size(), 0);
+}
+
+void TrexRpcServerReqRes::process_request(const std::string &request, std::string &response) {
+
+ if (TrexRpcZip::is_compressed(request)) {
+ process_zipped_request(request, response);
+ } else {
+ process_request_raw(request, response);
+ }
+
}
/**
* main processing of the request
*
*/
-std::string TrexRpcServerReqRes::process_request(const std::string &request) {
+void TrexRpcServerReqRes::process_request_raw(const std::string &request, std::string &response) {
std::vector<TrexJsonRpcV2ParsedObject *> commands;
Json::FastWriter writer;
- Json::Value response;
+ Json::Value response_json;
/* first parse the request using JSON RPC V2 parser */
TrexJsonRpcV2Parser rpc_request(request);
@@ -171,7 +185,7 @@ std::string TrexRpcServerReqRes::process_request(const std::string &request) {
command->execute(single_response);
delete command;
- response[index++] = single_response;
+ response_json[index++] = single_response;
}
@@ -181,17 +195,32 @@ std::string TrexRpcServerReqRes::process_request(const std::string &request) {
}
/* write the JSON to string and sever on ZMQ */
- std::string response_str;
if (response.size() == 1) {
- response_str = writer.write(response[0]);
+ response = writer.write(response_json[0]);
} else {
- response_str = writer.write(response);
+ response = writer.write(response_json);
}
- verbose_json("Server Replied: ", response_str);
+ verbose_json("Server Replied: ", response);
+
+}
+
+void TrexRpcServerReqRes::process_zipped_request(const std::string &request, std::string &response) {
+ std::string unzipped;
+
+ /* try to uncomrpess - if fails, last shot is the JSON RPC */
+ bool rc = TrexRpcZip::uncompress(request, unzipped);
+ if (!rc) {
+ return process_request_raw(request, response);
+ }
+
+ /* process the request */
+ std::string raw_response;
+ process_request_raw(unzipped, raw_response);
+
+ TrexRpcZip::compress(raw_response, response);
- return response_str;
}
/**
@@ -218,7 +247,11 @@ TrexRpcServerReqRes::handle_server_error(const std::string &specific_err) {
std::string
TrexRpcServerReqRes::test_inject_request(const std::string &req) {
- return process_request(req);
+ std::string response;
+
+ process_request(req, response);
+
+ return response;
}
diff --git a/src/rpc-server/trex_rpc_req_resp_server.h b/src/rpc-server/trex_rpc_req_resp_server.h
index 97efbe08..979bf9af 100644
--- a/src/rpc-server/trex_rpc_req_resp_server.h
+++ b/src/rpc-server/trex_rpc_req_resp_server.h
@@ -45,7 +45,9 @@ protected:
bool fetch_one_request(std::string &msg);
void handle_request(const std::string &request);
- std::string process_request(const std::string &request);
+ void process_request(const std::string &request, std::string &response);
+ void process_request_raw(const std::string &request, std::string &response);
+ void process_zipped_request(const std::string &request, std::string &response);
void handle_server_error(const std::string &specific_err);
diff --git a/src/rpc-server/trex_rpc_zip.cpp b/src/rpc-server/trex_rpc_zip.cpp
new file mode 100644
index 00000000..ef5c4834
--- /dev/null
+++ b/src/rpc-server/trex_rpc_zip.cpp
@@ -0,0 +1,124 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include "trex_rpc_zip.h"
+#include <zlib.h>
+#include <arpa/inet.h>
+#include <iostream>
+
+bool
+TrexRpcZip::is_compressed(const std::string &input) {
+ /* check for minimum size */
+ if (input.size() < sizeof(header_st)) {
+ return false;
+ }
+
+ /* cast */
+ const header_st *header = (header_st *)input.c_str();
+
+ /* check magic */
+ uint32_t magic = ntohl(header->magic);
+ if (magic != G_HEADER_MAGIC) {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+TrexRpcZip::uncompress(const std::string &input, std::string &output) {
+
+ /* sanity check first */
+ if (!is_compressed(input)) {
+ return false;
+ }
+
+ /* cast */
+ const header_st *header = (header_st *)input.c_str();
+
+ /* original size */
+ uint32_t uncmp_size = ntohl(header->uncmp_size);
+
+ /* alocate dynamic space for the uncomrpessed buffer */
+ Bytef *u_buffer = new Bytef[uncmp_size];
+ if (!u_buffer) {
+ return false;
+ }
+
+ /* set the target buffer size */
+ uLongf dest_len = uncmp_size;
+
+ /* try to uncompress */
+ int z_err = ::uncompress(u_buffer,
+ &dest_len,
+ (const Bytef *)header->data,
+ (uLong)input.size() - sizeof(header_st));
+
+ if (z_err != Z_OK) {
+ delete [] u_buffer;
+ return false;
+ }
+
+ output.append((const char *)u_buffer, dest_len);
+
+ delete [] u_buffer;
+ return true;
+}
+
+
+bool
+TrexRpcZip::compress(const std::string &input, std::string &output) {
+
+ /* get a bound */
+ int bound_size = compressBound((uLong)input.size()) + sizeof(header_st);
+
+ /* alocate dynamic space for the uncomrpessed buffer */
+ char *buffer = new char[bound_size];
+ if (!buffer) {
+ return false;
+ }
+
+ header_st *header = (header_st *)buffer;
+ uLongf destLen = bound_size;
+
+ int z_err = ::compress((Bytef *)header->data,
+ &destLen,
+ (const Bytef *)input.c_str(),
+ (uLong)input.size());
+
+ if (z_err != Z_OK) {
+ delete [] buffer;
+ return false;
+ }
+
+ /* terminate string */
+ header->data[destLen] = 0;
+
+ /* add the header */
+ header->magic = htonl(G_HEADER_MAGIC);
+ header->uncmp_size = htonl(input.size());
+
+ output.append((const char *)header, bound_size);
+
+ delete [] buffer;
+
+ return true;
+}
diff --git a/src/rpc-server/trex_rpc_zip.h b/src/rpc-server/trex_rpc_zip.h
new file mode 100644
index 00000000..4b9930b4
--- /dev/null
+++ b/src/rpc-server/trex_rpc_zip.h
@@ -0,0 +1,60 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#include <string>
+
+class TrexRpcZip {
+public:
+
+ /**
+ * return true if message is compressed
+ *
+ */
+ static bool is_compressed(const std::string &input);
+
+ /**
+ * uncompress an 'input' to 'output'
+ * on success return true else returns false
+ */
+ static bool uncompress(const std::string &input, std::string &output);
+
+ /**
+ * compress 'input' to 'output'
+ * on success return true else returns false
+ */
+ static bool compress(const std::string &input, std::string &output);
+
+private:
+
+ /**
+ * packed header for reading binary compressed messages
+ *
+ * @author imarom (15-Feb-16)
+ */
+ struct header_st {
+ uint32_t magic;
+ uint32_t uncmp_size;
+ char data[0];
+ } __attribute__((packed));
+
+
+ static const uint32_t G_HEADER_MAGIC = 0xABE85CEA;
+};
+