Kea 2.7.6
tcp_stream_msg.cc
Go to the documentation of this file.
1// Copyright (C) 2022-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
10#include <util/str.h>
11
12#include <iomanip>
13#include <sstream>
14#include <functional>
15
16namespace isc {
17namespace tcp {
18
19bool
21 return (!expected_size_ || (wire_data_.size() < expected_size_));
22}
23
24size_t
25TcpStreamRequest::postBuffer(const void* buf, const size_t nbytes) {
26 if (!nbytes) {
27 // Nothing to do.
28 return (0);
29 }
30
31 const char* bufptr = static_cast<const char*>(buf);
32 size_t bytes_left = nbytes;
33 size_t wire_size = wire_data_.size();
34 size_t bytes_used = 0;
35 while (bytes_left) {
36 if (expected_size_) {
37 // We have the length, copy as much of what we still need as we can.
38 size_t need_bytes = expected_size_ - wire_size;
39 size_t copy_bytes = (need_bytes <= bytes_left ? need_bytes : bytes_left);
40 wire_data_.insert(wire_data_.end(), bufptr, bufptr + copy_bytes);
41 // bytes_left -= copy_bytes; // Since we break, we don't need to do this anymore.
42 bytes_used += copy_bytes;
43 break;
44 }
45
46 // Otherwise we don't know the length yet.
47 while (wire_size < 2 && bytes_left) {
48 wire_data_.push_back(*bufptr);
49 ++bufptr;
50 --bytes_left;
51 ++bytes_used;
52 ++wire_size;
53 }
54
55 // If we have enough to do it, calculate the expected length.
56 if (wire_size == 2 ) {
57 const uint8_t* cp = static_cast<const uint8_t*>(wire_data_.data());
58 uint16_t len = static_cast<unsigned int>(cp[0]) << 8;
59 len |= static_cast<unsigned int>(cp[1]);
60 expected_size_ = len + sizeof(len);
61 }
62 }
63
64 // Return how much we used.
65 return (bytes_used);
66}
67
68std::string
69TcpStreamRequest::logFormatRequest(const size_t limit) const {
70 std::stringstream output;
71 try {
72 size_t max = (limit && (limit < wire_data_.size()) ? limit : wire_data_.size());
73 output << "expected_size_: " << expected_size_ << ", current size: " << wire_data_.size()
74 << ", data: "
76 } catch (const std::exception& ex) {
77 output = std::stringstream();
78 output << "logFormatRequest error: " << ex.what();
79 }
80
81 return (output.str());
82}
83
85 if (needData()) {
86 isc_throw(InvalidOperation, "Cannot unpack an incomplete request");
87 }
88
89 if (wire_data_.size() < sizeof(uint16_t)) {
90 isc_throw(Unexpected, "Request is malformed, too short");
91 }
92
93 request_ = std::vector<uint8_t>(wire_data_.begin() + sizeof(uint16_t), wire_data_.end());
94}
95
96void
97TcpStreamResponse::setResponseData(const uint8_t* data, size_t length) {
98 response_.assign(data, data + length);
99}
100
101void
102TcpStreamResponse::appendResponseData(const uint8_t* data, size_t length) {
103 response_.insert(response_.end(), data, data + length);
104}
105
106void
107TcpStreamResponse::setResponseData(const std::string& str) {
108 response_.assign(str.begin(), str.end());
109}
110
111void
113 response_.insert(response_.end(), str.begin(), str.end());
114}
115
116void
118 wire_data_.clear();
119 // Prepend the length of the request.
120 uint16_t size = static_cast<uint16_t>(response_.size());
121 wire_data_.push_back(static_cast<uint8_t>((size & 0xff00U) >> 8));
122 wire_data_.push_back(static_cast<uint8_t>(size & 0x00ffU));
123 wire_data_.insert(wire_data_.end(), response_.begin(), response_.end());
124}
125
126} // end of namespace isc::tcp
127} // end of namespace isc
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
WireData wire_data_
Buffer used for data in wire format data.
virtual std::string logFormatRequest(const size_t limit=0) const
Returns request contents formatted for log output.
virtual void unpack()
Unpacks the wire data into a string request.
virtual size_t postBuffer(const void *buf, const size_t nbytes)
Adds data to an incomplete request.
virtual bool needData() const
Returns true if the request is incomplete.
std::vector< uint8_t > request_
Unpacked request content.
virtual void appendResponseData(const uint8_t *data, size_t length)
Appends a data to the response content.
virtual void setResponseData(const uint8_t *data, size_t length)
Replaces the response content .
virtual void pack()
Packs the response content into wire data buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
string dumpAsHex(const uint8_t *data, size_t length)
Dumps a buffer of bytes as a string of hexadecimal digits.
Definition str.cc:330
Defines the logger used by the top-level component of kea-lfc.