Kea: opaque_data_tuple.cc Source File

| Kea 2.2.0

opaque_data_tuple.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2022 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
9#include <dhcp/opaque_data_tuple.h>
10
11namespace isc {
12namespace dhcp {
13
14OpaqueDataTuple::OpaqueDataTuple(LengthFieldType length_field_type)
15 : length_field_type_(length_field_type) {
16}
17
18void
19 OpaqueDataTuple::append(const std::string& text) {
20 // Don't do anything if text is empty.
21 if (!text.empty()) {
22 append(&text[0], text.size());
23 }
24}
25
26void
27 OpaqueDataTuple::assign(const std::string& text) {
28 // If empty string is being assigned, reset the buffer.
29 if (text.empty()) {
30 clear();
31 } else {
32 assign(&text[0], text.size());
33 }
34}
35
36void
37OpaqueDataTuple::clear() {
38 data_.clear();
39}
40
41bool
42OpaqueDataTuple::equals(const std::string& other) const {
43 return (getText() == other);
44}
45
46std::string
47OpaqueDataTuple::getText() const {
48 // Convert the data carried in the buffer to a string.
49 return (std::string(data_.begin(), data_.end()));
50}
51
52void
53OpaqueDataTuple::pack(isc::util::OutputBuffer& buf) const {
54 if ((1 << (getDataFieldSize() * 8)) <= getLength()) {
55 isc_throw(OpaqueDataTupleError, "failed to create on-wire format of the"
56 " opaque data field, because current data length "
57 << getLength() << " exceeds the maximum size for the length"
58 << " field size " << getDataFieldSize());
59 }
60
61 if (getDataFieldSize() == 1) {
62 buf.writeUint8(static_cast<uint8_t>(getLength()));
63 } else {
64 buf.writeUint16(getLength());
65 }
66
67 if (getLength() > 0) {
68 buf.writeData(&getData()[0], getLength());
69 }
70}
71
72int
73OpaqueDataTuple::getDataFieldSize() const {
74 return (length_field_type_ == LENGTH_1_BYTE ? 1 : 2);
75}
76
77 OpaqueDataTuple&
78OpaqueDataTuple::operator=(const std::string& other) {
79 // Replace existing data with the new data converted from a string.
80 assign(&other[0], other.length());
81 return (*this);
82}
83
84bool
85OpaqueDataTuple::operator==(const std::string& other) const {
86 return (equals(other));
87}
88
89bool
90OpaqueDataTuple::operator!=(const std::string& other) {
91 return (!equals(other));
92}
93
94std::ostream& operator<<(std::ostream& os, const OpaqueDataTuple& tuple) {
95 os << tuple.getText();
96 return (os);
97}
98
99std::istream& operator>>(std::istream& is, OpaqueDataTuple& tuple) {
100 // We will replace the current data with new data.
101 tuple.clear();
102 char buf[256];
103 // Read chunks of data as long as we haven't reached the end of the stream.
104 while (!is.eof()) {
105 is.read(buf, sizeof(buf));
106 // Append the chunk of data we have just read. It is fine if the
107 // gcount is 0, because append() function will check that.
108 tuple.append(buf, is.gcount());
109 }
110 // Clear eof flag, so as the stream can be read again.
111 is.clear();
112 return (is);
113}
114
115void
116OpaqueDataTuple::unpack(OpaqueDataTuple::InputIterator begin, OpaqueDataTuple::InputIterator end) {
117 // The buffer must at least hold the size of the data.
118 if (std::distance(begin, end) < getDataFieldSize()) {
119 isc_throw(OpaqueDataTupleError,
120 "unable to parse the opaque data tuple, the buffer"
121 " length is " << std::distance(begin, end)
122 << ", expected at least " << getDataFieldSize());
123 }
124 // Read the data length from the length field, depending on the
125 // size of the data field (1 or 2 bytes).
126 size_t len = getDataFieldSize() == 1 ? *begin :
127 isc::util::readUint16(&(*begin), std::distance(begin, end));
128 // Now that we have the expected data size, let's check that the
129 // reminder of the buffer is long enough.
130 begin += getDataFieldSize();
131 // Attempt to parse as a length-value pair.
132 if (std::distance(begin, end) < len) {
133 if (Option::lenient_parsing_) {
134 // Fallback to parsing the rest of the option as a single value.
135 len = std::distance(begin, end);
136 } else {
137 isc_throw(OpaqueDataTupleError,
138 "unable to parse the opaque data tuple, "
139 "the buffer length is " << std::distance(begin, end)
140 << ", but the tuple length is " << len);
141 }
142 }
143 // The buffer length is long enough to read the desired amount of data.
144 assign(begin, len);
145}
146
147} // namespace dhcp
148} // namespace isc
isc::dhcp::OpaqueDataTupleError
Exception to be thrown when the operation on OpaqueDataTuple object results in an error.
Definition: opaque_data_tuple.h:24
isc::dhcp::OpaqueDataTuple
Represents a single instance of the opaque data preceded by length.
Definition: opaque_data_tuple.h:47
isc::dhcp::OpaqueDataTuple::operator==
bool operator==(const std::string &other) const
Equality operator.
Definition: opaque_data_tuple.cc:85
isc::dhcp::OpaqueDataTuple::clear
void clear()
Removes the contents of the tuple.
Definition: opaque_data_tuple.cc:37
isc::dhcp::OpaqueDataTuple::getDataFieldSize
int getDataFieldSize() const
Returns the size of the tuple length field.
Definition: opaque_data_tuple.cc:73
isc::dhcp::OpaqueDataTuple::operator=
OpaqueDataTuple & operator=(const std::string &other)
Assignment operator.
Definition: opaque_data_tuple.cc:78
isc::dhcp::OpaqueDataTuple::OpaqueDataTuple
OpaqueDataTuple(LengthFieldType length_field_type)
Default constructor.
Definition: opaque_data_tuple.cc:14
isc::dhcp::OpaqueDataTuple::getData
const Buffer & getData() const
Returns a reference to the buffer holding tuple data.
Definition: opaque_data_tuple.h:171
isc::dhcp::OpaqueDataTuple::LengthFieldType
LengthFieldType
Size of the length field in the tuple.
Definition: opaque_data_tuple.h:57
isc::dhcp::OpaqueDataTuple::LENGTH_1_BYTE
@ LENGTH_1_BYTE
Definition: opaque_data_tuple.h:58
isc::dhcp::OpaqueDataTuple::pack
void pack(isc::util::OutputBuffer &buf) const
Renders the tuple to a buffer in the wire format.
Definition: opaque_data_tuple.cc:53
isc::dhcp::OpaqueDataTuple::InputIterator
Buffer::const_iterator InputIterator
Definition: opaque_data_tuple.h:64
isc::dhcp::OpaqueDataTuple::assign
void assign(const char *data, const size_t len)
Assigns data to the tuple.
Definition: opaque_data_tuple.h:128
isc::dhcp::OpaqueDataTuple::getText
std::string getText() const
Return the tuple data in the textual format.
Definition: opaque_data_tuple.cc:47
isc::dhcp::OpaqueDataTuple::append
void append(const char *data, const size_t len)
Appends data to the tuple.
Definition: opaque_data_tuple.h:103
isc::dhcp::OpaqueDataTuple::equals
bool equals(const std::string &other) const
Checks if the data carried in the tuple match the string.
Definition: opaque_data_tuple.cc:42
isc::dhcp::OpaqueDataTuple::unpack
void unpack(InputIterator begin, InputIterator end)
Parses wire data and creates a tuple from it.
Definition: opaque_data_tuple.cc:116
isc::dhcp::OpaqueDataTuple::operator!=
bool operator!=(const std::string &other)
Inequality operator.
Definition: opaque_data_tuple.cc:90
isc::dhcp::OpaqueDataTuple::getLength
size_t getLength() const
Returns the length of the data in the tuple.
Definition: opaque_data_tuple.h:157
isc::dhcp::Option::lenient_parsing_
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
Definition: option.h:483
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
isc::util::OutputBuffer::writeUint8
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition: buffer.h:466
isc::util::OutputBuffer::writeUint16
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
Definition: buffer.h:490
isc::util::OutputBuffer::writeData
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition: buffer.h:550
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:210
isc::dhcp::operator>>
std::istream & operator>>(std::istream &is, OpaqueDataTuple &tuple)
Inserts data carried in the stream into the tuple.
Definition: opaque_data_tuple.cc:99
isc::dhcp::operator<<
std::ostream & operator<<(std::ostream &os, const OpaqueDataTuple &tuple)
Inserts the OpaqueDataTuple as a string into stream.
Definition: opaque_data_tuple.cc:94
isc::util::readUint16
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Definition: io_utilities.h:28
isc
Defines the logger used by the top-level component of kea-lfc.
Definition: agent_parser.cc:143
opaque_data_tuple.h