merge in nyc-release history after reset to master
diff --git a/daemon.cc b/daemon.cc
index 195a5e2..ba3f1fd 100644
--- a/daemon.cc
+++ b/daemon.cc
@@ -19,7 +19,6 @@
#include <sysexits.h>
#include <base/logging.h>
-#include <base/message_loop/message_loop_proxy.h>
#include <base/run_loop.h>
namespace dhcp_client {
diff --git a/dhcp_message.cc b/dhcp_message.cc
index 5f585fd..b17dec6 100644
--- a/dhcp_message.cc
+++ b/dhcp_message.cc
@@ -67,7 +67,8 @@
} // namespace
DHCPMessage::DHCPMessage()
- : lease_time_(0),
+ : requested_ip_address_(0),
+ lease_time_(0),
message_type_(0),
server_identifier_(0),
renewal_time_(0),
@@ -92,6 +93,8 @@
ParserContext(new UInt32ListParser(), &router_)));
options_map_.insert(std::make_pair(kDHCPOptionDomainName,
ParserContext(new StringParser(), &domain_name_)));
+ options_map_.insert(std::make_pair(kDHCPOptionVendorSpecificInformation,
+ ParserContext(new ByteArrayParser(), &vendor_specific_info_)));
}
DHCPMessage::~DHCPMessage() {}
@@ -311,6 +314,14 @@
LOG(ERROR) << "Failed to write message type option";
return false;
}
+ if (requested_ip_address_ != 0) {
+ if (options_writer->WriteUInt32Option(data,
+ kDHCPOptionRequestedIPAddr,
+ requested_ip_address_) == -1) {
+ LOG(ERROR) << "Failed to write requested ip address option";
+ return false;
+ }
+ }
if (lease_time_ != 0) {
if (options_writer->WriteUInt32Option(data,
kDHCPOptionLeaseTime,
@@ -374,12 +385,6 @@
return ~static_cast<uint16_t>(sum);
}
-uint32_t DHCPMessage::GenerateTransactionID() {
- // TODO(nywang): use arc4 random number for better security.
- srand(time(NULL));
- return rand() % UINT32_MAX;
-}
-
void DHCPMessage::SetClientIdentifier(
const ByteString& client_identifier) {
client_identifier_ = client_identifier;
@@ -410,6 +415,11 @@
const std::vector<uint8_t>& parameter_request_list) {
parameter_request_list_ = parameter_request_list;
}
+
+void DHCPMessage::SetRequestedIpAddress(uint32_t requested_ip_address) {
+ requested_ip_address_ = requested_ip_address;
+}
+
void DHCPMessage::SetServerIdentifier(uint32_t server_identifier) {
server_identifier_ = server_identifier;
}
@@ -418,26 +428,29 @@
transaction_id_ = transaction_id;
}
-DHCPMessage DHCPMessage::InitRequest() {
- DHCPMessage msg;
- msg.opcode_ = kDHCPMessageBootRequest;
- msg.hardware_address_type_ = ARPHRD_ETHER;
- msg.hardware_address_length_ = IFHWADDRLEN;
- msg.relay_hops_ = 0;
+void DHCPMessage::SetVendorSpecificInfo(
+ const shill::ByteString& vendor_specific_info) {
+ vendor_specific_info_ = vendor_specific_info;
+}
+
+void DHCPMessage::InitRequest(DHCPMessage* message) {
+ message->opcode_ = kDHCPMessageBootRequest;
+ message->hardware_address_type_ = ARPHRD_ETHER;
+ message->hardware_address_length_ = IFHWADDRLEN;
+ message->relay_hops_ = 0;
// Seconds since DHCP process started.
// 0 is also valid according to RFC 2131.
- msg.seconds_ = 0;
+ message->seconds_ = 0;
// Only firewire (IEEE 1394) and InfiniBand interfaces
// require broadcast flag.
- msg.flags_ = 0;
+ message->flags_ = 0;
// Should be zero in client's messages.
- msg.your_ip_address_ = 0;
+ message->your_ip_address_ = 0;
// Should be zero in client's messages.
- msg.next_server_ip_address_ = 0;
+ message->next_server_ip_address_ = 0;
// Should be zero in client's messages.
- msg.agent_ip_address_ = 0;
- msg.cookie_ = kMagicCookie;
- return msg;
+ message->agent_ip_address_ = 0;
+ message->cookie_ = kMagicCookie;
}
} // namespace dhcp_client
diff --git a/dhcp_message.h b/dhcp_message.h
index dc492c9..9ffd8d3 100644
--- a/dhcp_message.h
+++ b/dhcp_message.h
@@ -58,9 +58,8 @@
static bool InitFromBuffer(const unsigned char* buffer,
size_t length,
DHCPMessage* message);
- static DHCPMessage InitRequest();
+ static void InitRequest(DHCPMessage* message);
static uint16_t ComputeChecksum(const uint8_t* data, size_t len);
- static uint32_t GenerateTransactionID();
// Initialize part of the data fields for outbound DHCP message.
// Serialize the message to a buffer
bool Serialize(shill::ByteString* data) const;
@@ -75,8 +74,10 @@
void SetMessageType(uint8_t message_type);
void SetParameterRequestList(
const std::vector<uint8_t>& parameter_request_list);
+ void SetRequestedIpAddress(uint32_t requested_ip_address);
void SetServerIdentifier(uint32_t server_identifier);
void SetTransactionID(uint32_t transaction_id);
+ void SetVendorSpecificInfo(const shill::ByteString& vendor_specific_info);
// DHCP option and field getters
const shill::ByteString& client_hardware_address() const {
@@ -86,6 +87,7 @@
return client_identifier_;
}
uint32_t client_ip_address() const { return client_ip_address_; }
+ const std::vector<uint32_t>& dns_server() const { return dns_server_; }
const std::string& domain_name() const { return domain_name_; }
const std::string& error_message() const { return error_message_; }
uint32_t lease_time() const { return lease_time_; }
@@ -96,8 +98,10 @@
uint32_t server_identifier() const { return server_identifier_; }
uint32_t subnet_mask() const { return subnet_mask_; }
uint32_t transaction_id() const { return transaction_id_; }
+ const shill::ByteString& vendor_specific_info() const {
+ return vendor_specific_info_;
+ }
uint32_t your_ip_address() const { return your_ip_address_; }
- const std::vector<uint32_t>& dns_server() const { return dns_server_; }
private:
bool ParseDHCPOptions(const uint8_t* options, size_t options_length);
@@ -150,6 +154,10 @@
std::vector<uint32_t> dns_server_;
// Option 15: Domain Name.
std::string domain_name_;
+ // Option 43: Vendor Specific Information.
+ shill::ByteString vendor_specific_info_;
+ // Option 50: Requested IP Address.
+ uint32_t requested_ip_address_;
// Option 51: IP address lease time in unit of seconds.
uint32_t lease_time_;
// Option 53: DHCP message type.
diff --git a/dhcp_options.h b/dhcp_options.h
index 8257585..c215253 100644
--- a/dhcp_options.h
+++ b/dhcp_options.h
@@ -24,6 +24,8 @@
const uint8_t kDHCPOptionRouter = 3;
const uint8_t kDHCPOptionDNSServer = 6;
const uint8_t kDHCPOptionDomainName = 15;
+const uint8_t kDHCPOptionVendorSpecificInformation = 43;
+const uint8_t kDHCPOptionRequestedIPAddr = 50;
const uint8_t kDHCPOptionLeaseTime = 51;
const uint8_t kDHCPOptionMessageType = 53;
const uint8_t kDHCPOptionServerIdentifier = 54;
diff --git a/dhcp_options_parser.cc b/dhcp_options_parser.cc
index 075a61e..8686871 100644
--- a/dhcp_options_parser.cc
+++ b/dhcp_options_parser.cc
@@ -24,6 +24,9 @@
#include <base/logging.h>
#include <base/macros.h>
+#include <shill/net/byte_string.h>
+
+using shill::ByteString;
namespace dhcp_client {
@@ -172,4 +175,17 @@
return true;
}
+bool ByteArrayParser::GetOption(const uint8_t* buffer,
+ uint8_t length,
+ void* value) {
+ if (length == 0) {
+ LOG(ERROR) << "Invalid option length field";
+ return false;
+ }
+ ByteString* byte_array =
+ static_cast<ByteString*>(value);
+ *byte_array = ByteString(buffer, length);
+ return true;
+}
+
} // namespace dhcp_client
diff --git a/dhcp_options_parser.h b/dhcp_options_parser.h
index f8e6786..3dbd909 100644
--- a/dhcp_options_parser.h
+++ b/dhcp_options_parser.h
@@ -101,6 +101,12 @@
void* value) override;
};
+class ByteArrayParser : public DHCPOptionsParser {
+ public:
+ bool GetOption(const uint8_t* buffer,
+ uint8_t length,
+ void* value) override;
+};
} // namespace dhcp_client
#endif // DHCP_CLIENT_PARSER_H_
diff --git a/dhcp_options_parser_unittest.cc b/dhcp_options_parser_unittest.cc
index c701099..88d37c0 100644
--- a/dhcp_options_parser_unittest.cc
+++ b/dhcp_options_parser_unittest.cc
@@ -24,6 +24,9 @@
#include <vector>
#include <gtest/gtest.h>
+#include <shill/net/byte_string.h>
+
+using shill::ByteString;
namespace {
const uint8_t kFakeUInt8Option[] = {0x02};
@@ -56,6 +59,9 @@
{'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g'};
const uint8_t kFakeStringOptionLength = 10;
+const unsigned char kFakeByteArrayOption[] =
+ {'f', 'a', 'k', 'e', 'b', 'y', 't', 'e', 'a', 'r', 'r', 'a', 'y'};
+
const uint8_t kFakeBoolOptionEnable[] = {0x01};
const uint8_t kFakeBoolOptionDisable[] = {0x00};
const uint8_t kFakeBoolOptionLength = 1;
@@ -203,4 +209,15 @@
EXPECT_EQ(target_value, value);
}
+TEST_F(ParserTest, ParseByteArray) {
+ parser_.reset(new ByteArrayParser());
+ ByteString value;
+ ByteString target_value(reinterpret_cast<const char*>(kFakeByteArrayOption),
+ sizeof(kFakeByteArrayOption));
+ EXPECT_TRUE(parser_->GetOption(kFakeByteArrayOption,
+ sizeof(kFakeByteArrayOption),
+ &value));
+ EXPECT_TRUE(target_value.Equals(value));
+}
+
} // namespace dhcp_client
diff --git a/dhcpv4.cc b/dhcpv4.cc
index 016d75f..3ef58ed 100644
--- a/dhcpv4.cc
+++ b/dhcpv4.cc
@@ -24,6 +24,8 @@
#include <netinet/ip.h>
#include <netinet/udp.h>
+#include <random>
+
#include <base/bind.h>
#include <base/logging.h>
@@ -86,7 +88,8 @@
from_(INADDR_ANY),
to_(INADDR_BROADCAST),
socket_(kInvalidSocketDescriptor),
- sockets_(new shill::Sockets()) {
+ sockets_(new shill::Sockets()),
+ random_engine_(time(nullptr)) {
}
DHCPV4::~DHCPV4() {
@@ -266,8 +269,9 @@
// so fragmentation is not needed.
ip->frag_off = 0;
// Identification.
- // TODO(nywang) Use arc4 random number.
- ip->id = static_cast<uint16_t>(rand());
+ ip->id = static_cast<uint16_t>(
+ std::uniform_int_distribution<unsigned int>()(
+ random_engine_) % UINT16_MAX + 1);
// Time to live.
ip->ttl = IPDEFTTL;
// Total length.
diff --git a/dhcpv4.h b/dhcpv4.h
index c1ea166..ebe2f5a 100644
--- a/dhcpv4.h
+++ b/dhcpv4.h
@@ -17,6 +17,7 @@
#ifndef DHCP_CLIENT_DHCPV4_H_
#define DHCP_CLIENT_DHCPV4_H_
+#include <random>
#include <string>
#include <base/macros.h>
@@ -94,6 +95,8 @@
// Helper class with wrapped socket relavent functions.
std::unique_ptr<shill::Sockets> sockets_;
+ std::default_random_engine random_engine_;
+
DISALLOW_COPY_AND_ASSIGN(DHCPV4);
};
diff --git a/message_loop_event_dispatcher.cc b/message_loop_event_dispatcher.cc
index 26fcced..095429e 100644
--- a/message_loop_event_dispatcher.cc
+++ b/message_loop_event_dispatcher.cc
@@ -17,7 +17,7 @@
#include "dhcp_client/message_loop_event_dispatcher.h"
#include <base/location.h>
-#include <base/message_loop/message_loop_proxy.h>
+#include <base/message_loop/message_loop.h>
#include <base/time/time.h>
namespace dhcp_client {
@@ -26,13 +26,19 @@
MessageLoopEventDispatcher::~MessageLoopEventDispatcher() {}
bool MessageLoopEventDispatcher::PostTask(const base::Closure& task) {
- return base::MessageLoopProxy::current()->PostTask(FROM_HERE, task);
+ if (!base::MessageLoop::current())
+ return false;
+ base::MessageLoop::current()->PostTask(FROM_HERE, task);
+ return true;
}
bool MessageLoopEventDispatcher::PostDelayedTask(const base::Closure& task,
int64_t delay_ms) {
- return base::MessageLoopProxy::current()->PostDelayedTask(
+ if (!base::MessageLoop::current())
+ return false;
+ base::MessageLoop::current()->PostDelayedTask(
FROM_HERE, task, base::TimeDelta::FromMilliseconds(delay_ms));
+ return true;
}
} // namespace dhcp_client