From: wkozaczuk <jwkozac...@gmail.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master
Changed DHCP client logic to properly broadcast DHCPREQUEST during
The patch addressing issue #816 changed dhcp_mbuf::compose_request() method
to
make it unicast DHCPREQUEST message to a DHCP server. This is incorrect per
RCF-2131
which requires DHCP clients to broadcast messages until IP address is bound
which
is a case during RENEWING phase but not SELECTING one. Now the
dhcp_mbuf::compose_request()
takes extra enum parameter which specifies which phase (per page 34 of
https://www.ietf.org/rfc/rfc2131.txt)
the message is being composed for.
Fixes #864
Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
Message-Id: <1490187468-6838-1-git-send-email-jwkozac...@gmail.com>
---
diff --git a/core/dhcp.cc b/core/dhcp.cc
--- a/core/dhcp.cc
+++ b/core/dhcp.cc
@@ -81,11 +81,26 @@ namespace dhcp {
const char * dhcp_options_magic = "\x63\x82\x53\x63";
+ static std::map<dhcp_message_type,const char*>
dhcp_message_type_name_by_id = {
+ {DHCP_MT_DISCOVER, "DHCPDISCOVER"},
+ {DHCP_MT_OFFER, "DHCPOFFER"},
+ {DHCP_MT_REQUEST, "DHCPREQUEST"},
+ {DHCP_MT_DECLINE, "DHCPDECLINE"},
+ {DHCP_MT_ACK, "DHCPACK"},
+ {DHCP_MT_NAK, "DHCPNAK"},
+ {DHCP_MT_RELEASE, "DHCPRELEASE"},
+ {DHCP_MT_INFORM, "DHCPINFORM"},
+ {DHCP_MT_LEASEQUERY, "DHCPLEASEQUERY"},
+ {DHCP_MT_LEASEUNASSIGNED, "DHCPLEASEUNASSIGNED"},
+ {DHCP_MT_LEASEUNKNOWN, "DHCPLEASEUNKNOWN"},
+ {DHCP_MT_LEASEACTIVE, "DHCPLEASEACTIVE"},
+ {DHCP_MT_INVALID, "DHCPINVALID"}
+ };
+
///////////////////////////////////////////////////////////////////////////
bool dhcp_socket::dhcp_send(dhcp_mbuf& packet)
{
-
struct bsd_sockaddr dst = {};
struct mbuf *m = packet.get();
@@ -205,7 +220,8 @@ namespace dhcp {
void dhcp_mbuf::compose_request(struct ifnet* ifp,
u32 xid,
ip::address_v4 yip,
- ip::address_v4 sip)
+ ip::address_v4 sip,
+ dhcp_request_packet_type
request_packet_type)
{
size_t dhcp_len = sizeof(struct dhcp_packet);
struct dhcp_packet* pkt = pdhcp();
@@ -222,7 +238,11 @@ namespace dhcp {
memcpy(pkt->chaddr, IF_LLADDR(ifp), ETHER_ADDR_LEN);
ulong yip_n = htonl(yip.to_ulong());
ulong sip_n = htonl(sip.to_ulong());
- memcpy(&pkt->ciaddr.s_addr, &yip_n, 4);
+ if(request_packet_type == DHCP_REQUEST_RENEWING ||
request_packet_type == DHCP_REQUEST_REBINDING) {
+ // ciaddr should only be set to if RENEWING or REBINDING
+ // See pages 21 and 30-31 in
https://www.ietf.org/rfc/rfc2131.txt
+ memcpy(&pkt->ciaddr.s_addr, &yip_n, 4);
+ }
// Options
u8* options_start = reinterpret_cast<u8*>(pkt+1);
@@ -244,7 +264,14 @@ namespace dhcp {
*options++ = DHCP_OPTION_END;
dhcp_len += options - options_start;
- build_udp_ip_headers(dhcp_len, yip_n, sip_n);
+
+ // See page 33 in https://www.ietf.org/rfc/rfc2131.txt
+ if(request_packet_type == DHCP_REQUEST_RENEWING) {
+ build_udp_ip_headers(dhcp_len, yip_n, sip_n);
+ }
+ else {
+ build_udp_ip_headers(dhcp_len, INADDR_ANY, INADDR_BROADCAST);
+ }
}
void dhcp_mbuf::compose_release(struct ifnet* ifp,
@@ -420,6 +447,9 @@ namespace dhcp {
options += op_len;
}
+ dhcp_i( "Received %s message from DHCP server: %s regarding
offerred IP address: %s",
+ dhcp_message_type_name_by_id[_message_type],
_dhcp_server_ip.to_string().c_str(),
+ _your_ip.to_string().c_str());
return true;
}
@@ -519,6 +549,7 @@ namespace dhcp {
// Save transaction id & send
_xid = dm.get_xid();
_client_addr = _server_addr = ipv4_zero;
+ dhcp_i( "Broadcasting DHCPDISCOVER message with xid: [%d]",_xid);
_sock->dhcp_send(dm);
}
@@ -533,6 +564,8 @@ namespace dhcp {
// Save transaction id & send
_xid = dm.get_xid();
+ dhcp_i( "Unicasting DHCPRELEASE message with xid: [%d] from
client: %s to server: %s",
+ _xid, _client_addr.to_string().c_str(),
_server_addr.to_string().c_str());
_sock->dhcp_send(dm);
// IP and routes have to be removed
osv::stop_if(_ifp->if_xname, _client_addr.to_string().c_str());
@@ -553,9 +586,13 @@ namespace dhcp {
_xid = rand();
dm.compose_request(_ifp,
_xid,
- _client_addr, _server_addr);
+ _client_addr,
+ _server_addr,
+ dhcp_mbuf::DHCP_REQUEST_RENEWING);
// Send
+ dhcp_i( "Unicasting DHCPREQUEST message with xid: [%d] from
client: %s to server: %s in order to RENEW lease of: %s",
+ _xid, _client_addr.to_string().c_str(),
_server_addr.to_string().c_str(), _client_addr.to_string().c_str());
_sock->dhcp_send(dm);
}
@@ -600,14 +637,18 @@ namespace dhcp {
dm_req.compose_request(_ifp,
_xid,
dm.get_your_ip(),
- dm.get_dhcp_server_ip());
+ dm.get_dhcp_server_ip(),
+ dhcp_mbuf::DHCP_REQUEST_SELECTING);
+ dhcp_i( "Broadcasting DHCPREQUEST message with xid: [%d] to SELECT
offered IP: %s",
+ _xid, dm.get_your_ip().to_string().c_str());
_sock->dhcp_send(dm_req);
}
void dhcp_interface_state::state_request(dhcp_mbuf &dm)
{
if (dm.get_message_type() == DHCP_MT_ACK) {
- dhcp_i("Server acknowledged IP for interface %s",
_ifp->if_xname);
+ dhcp_i("Server acknowledged IP %s for interface %s with time
to lease in seconds: %d",
+ dm.get_your_ip().to_string().c_str(), _ifp->if_xname,
dm.get_lease_time_sec());
_state = DHCP_ACKNOWLEDGE;
_client_addr = dm.get_your_ip();
_server_addr = dm.get_dhcp_server_ip();
diff --git a/include/osv/dhcp.hh b/include/osv/dhcp.hh
--- a/include/osv/dhcp.hh
+++ b/include/osv/dhcp.hh
@@ -117,6 +117,13 @@ namespace dhcp {
DHCP_REPLY = 2,
};
+ enum dhcp_request_packet_type {
+ DHCP_REQUEST_INIT_REBOOT = 1,
+ DHCP_REQUEST_SELECTING = 2,
+ DHCP_REQUEST_RENEWING = 3,
+ DHCP_REQUEST_REBINDING = 4,
+ };
+
dhcp_mbuf(bool attached = true, struct mbuf* m = nullptr);
~dhcp_mbuf();
@@ -129,7 +136,8 @@ namespace dhcp {
void compose_request(struct ifnet* ifp,
u32 xid,
boost::asio::ip::address_v4 yip,
- boost::asio::ip::address_v4 sip);
+ boost::asio::ip::address_v4 sip,
+ dhcp_request_packet_type request_packet_type);
void compose_release(struct ifnet* ifp,
boost::asio::ip::address_v4 yip,
boost::asio::ip::address_v4 sip);
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.