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