Commit 9388cae1 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[master] Merge branch 'trac2264'

DHCP packet pack methods now throw exceptions on error, rather then
returning bool result value.
parents b8fa96e3 27d057a7
......@@ -149,11 +149,6 @@ This error is output if the IPv4 DHCP server fails to send an assembled
DHCP message to a client. The reason for the error is included in the
message.
% DHCP4_PACK_FAIL failed to assemble response correctly
This error is output if the server failed to assemble the data to be
returned to the client into a valid packet. The cause is most likely
to be a programming error: please raise a bug report.
% DHCP4_PARSER_COMMIT_EXCEPTION parser failed to commit changes
On receipt of message containing details to a change of the IPv4 DHCP
server configuration, a set of parsers were successfully created, but one
......
......@@ -320,14 +320,12 @@ Dhcpv4Srv::run() {
DHCP4_RESPONSE_DATA)
.arg(rsp->getType()).arg(rsp->toText());
if (rsp->pack()) {
try {
sendPacket(rsp);
} catch (const std::exception& e) {
LOG_ERROR(dhcp4_logger, DHCP4_PACKET_SEND_FAIL).arg(e.what());
}
} else {
LOG_ERROR(dhcp4_logger, DHCP4_PACK_FAIL);
try {
rsp->pack();
sendPacket(rsp);
} catch (const std::exception& e) {
LOG_ERROR(dhcp4_logger, DHCP4_PACKET_SEND_FAIL)
.arg(e.what());
}
}
}
......
......@@ -165,11 +165,6 @@ This error is output if the IPv6 DHCP server fails to send an assembled
DHCP message to a client. The reason for the error is included in the
message.
% DHCP6_PACK_FAIL failed to assemble response correctly
This error is output if the server failed to assemble the data to be
returned to the client into a valid packet. The reason is most likely
to be to a programming error: please raise a bug report.
% DHCP6_PARSER_COMMIT_EXCEPTION parser failed to commit changes
On receipt of message containing details to a change of the IPv6 DHCP
server configuration, a set of parsers were successfully created, but one
......
......@@ -324,14 +324,12 @@ bool Dhcpv6Srv::run() {
DHCP6_RESPONSE_DATA)
.arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
if (rsp->pack()) {
try {
sendPacket(rsp);
} catch (const std::exception& e) {
LOG_ERROR(dhcp6_logger, DHCP6_PACKET_SEND_FAIL).arg(e.what());
}
} else {
LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL);
try {
rsp->pack();
sendPacket(rsp);
} catch (const std::exception& e) {
LOG_ERROR(dhcp6_logger, DHCP6_PACKET_SEND_FAIL)
.arg(e.what());
}
}
}
......
......@@ -102,55 +102,60 @@ Pkt4::len() {
return (length);
}
bool
void
Pkt4::pack() {
if (!hwaddr_) {
isc_throw(InvalidOperation, "Can't build Pkt4 packet. HWAddr not set.");
}
size_t hw_len = hwaddr_->hwaddr_.size();
bufferOut_.writeUint8(op_);
bufferOut_.writeUint8(hwaddr_->htype_);
bufferOut_.writeUint8(hw_len < MAX_CHADDR_LEN ? hw_len : MAX_CHADDR_LEN);
bufferOut_.writeUint8(hops_);
bufferOut_.writeUint32(transid_);
bufferOut_.writeUint16(secs_);
bufferOut_.writeUint16(flags_);
bufferOut_.writeUint32(ciaddr_);
bufferOut_.writeUint32(yiaddr_);
bufferOut_.writeUint32(siaddr_);
bufferOut_.writeUint32(giaddr_);
if (hw_len <= MAX_CHADDR_LEN) {
// write up to 16 bytes of the hardware address (CHADDR field is 16
// bytes long in DHCPv4 message).
bufferOut_.writeData(&hwaddr_->hwaddr_[0],
(hw_len < MAX_CHADDR_LEN ? hw_len : MAX_CHADDR_LEN) );
hw_len = MAX_CHADDR_LEN - hw_len;
} else {
hw_len = MAX_CHADDR_LEN;
try {
size_t hw_len = hwaddr_->hwaddr_.size();
bufferOut_.writeUint8(op_);
bufferOut_.writeUint8(hwaddr_->htype_);
bufferOut_.writeUint8(hw_len < MAX_CHADDR_LEN ?
hw_len : MAX_CHADDR_LEN);
bufferOut_.writeUint8(hops_);
bufferOut_.writeUint32(transid_);
bufferOut_.writeUint16(secs_);
bufferOut_.writeUint16(flags_);
bufferOut_.writeUint32(ciaddr_);
bufferOut_.writeUint32(yiaddr_);
bufferOut_.writeUint32(siaddr_);
bufferOut_.writeUint32(giaddr_);
if (hw_len <= MAX_CHADDR_LEN) {
// write up to 16 bytes of the hardware address (CHADDR field is 16
// bytes long in DHCPv4 message).
bufferOut_.writeData(&hwaddr_->hwaddr_[0],
(hw_len < MAX_CHADDR_LEN ?
hw_len : MAX_CHADDR_LEN) );
hw_len = MAX_CHADDR_LEN - hw_len;
} else {
hw_len = MAX_CHADDR_LEN;
}
// write (len) bytes of padding
vector<uint8_t> zeros(hw_len, 0);
bufferOut_.writeData(&zeros[0], hw_len);
// bufferOut_.writeData(chaddr_, MAX_CHADDR_LEN);
bufferOut_.writeData(sname_, MAX_SNAME_LEN);
bufferOut_.writeData(file_, MAX_FILE_LEN);
// write DHCP magic cookie
bufferOut_.writeUint32(DHCP_OPTIONS_COOKIE);
LibDHCP::packOptions(bufferOut_, options_);
// add END option that indicates end of options
// (End option is very simple, just a 255 octet)
bufferOut_.writeUint8(DHO_END);
} catch(const Exception& e) {
// An exception is thrown and message will be written to Logger
isc_throw(InvalidOperation, e.what());
}
// write (len) bytes of padding
vector<uint8_t> zeros(hw_len, 0);
bufferOut_.writeData(&zeros[0], hw_len);
// bufferOut_.writeData(chaddr_, MAX_CHADDR_LEN);
bufferOut_.writeData(sname_, MAX_SNAME_LEN);
bufferOut_.writeData(file_, MAX_FILE_LEN);
// write DHCP magic cookie
bufferOut_.writeUint32(DHCP_OPTIONS_COOKIE);
LibDHCP::packOptions(bufferOut_, options_);
// add END option that indicates end of options
// (End option is very simple, just a 255 octet)
bufferOut_.writeUint8(DHO_END);
return (true);
}
void
......
......@@ -72,8 +72,8 @@ public:
/// Options must be stored in options_ field.
/// Output buffer will be stored in bufferOut_.
///
/// @return true if packing procedure was successful
bool
/// @throw InvalidOperation if packing fails
void
pack();
/// @brief Parses on-wire form of DHCPv4 packet.
......
......@@ -181,20 +181,21 @@ uint16_t Pkt6::directLen() const {
}
bool
void
Pkt6::pack() {
switch (proto_) {
case UDP:
return packUDP();
packUDP();
break;
case TCP:
return packTCP();
packTCP();
break;
default:
isc_throw(BadValue, "Invalid protocol specified (non-TCP, non-UDP)");
}
return (false); // never happens
}
bool
void
Pkt6::packUDP() {
try {
......@@ -252,16 +253,15 @@ Pkt6::packUDP() {
LibDHCP::packOptions(bufferOut_, options_);
}
catch (const Exception& e) {
/// @todo: throw exception here once we turn this function to void.
return (false);
// An exception is thrown and message will be written to Logger
isc_throw(InvalidOperation, e.what());
}
return (true);
}
bool
void
Pkt6::packTCP() {
/// TODO Implement this function.
isc_throw(Unexpected, "DHCPv6 over TCP (bulk leasequery and failover)"
isc_throw(NotImplemented, "DHCPv6 over TCP (bulk leasequery and failover)"
"not implemented yet.");
}
......
......@@ -116,8 +116,10 @@ public:
/// Output buffer will be stored in data_. Length
/// will be set in data_len_.
///
/// @return true if packing procedure was successful
bool pack();
/// @throw BadValue if packet protocol is invalid, InvalidOperation
/// if packing fails, or NotImplemented if protocol is TCP (IPv6 over TCP is
/// not yet supported).
void pack();
/// @brief Dispatch method that handles binary packet parsing.
///
......@@ -415,13 +417,13 @@ protected:
///
/// TODO This function is not implemented yet.
///
/// @return true, if build was successful
bool packTCP();
/// @throw NotImplemented, IPv6 over TCP is not yet supported.
void packTCP();
/// Builds on wire packet for UDP transmission.
///
/// @return true, if build was successful
bool packUDP();
/// @throw InvalidOperation if packing fails
void packUDP();
/// @brief Parses on-wire form of TCP DHCPv6 packet.
///
......
......@@ -221,7 +221,7 @@ TEST_F(Pkt6Test, packUnpack) {
EXPECT_EQ(Pkt6::DHCPV6_PKT_HDR_LEN + 3 * Option::OPTION6_HDR_LEN,
parent->len());
EXPECT_TRUE(parent->pack());
EXPECT_NO_THROW(parent->pack());
EXPECT_EQ(Pkt6::DHCPV6_PKT_HDR_LEN + 3 * Option::OPTION6_HDR_LEN,
parent->len());
......@@ -515,7 +515,7 @@ TEST_F(Pkt6Test, relayPack) {
EXPECT_EQ(DHCPV6_ADVERTISE, parent->getType());
EXPECT_TRUE(parent->pack());
EXPECT_NO_THROW(parent->pack());
EXPECT_EQ(Pkt6::DHCPV6_PKT_HDR_LEN + 3 * Option::OPTION6_HDR_LEN // ADVERTISE
+ Pkt6::DHCPV6_RELAY_HDR_LEN // Relay header
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment