[PATCH] [dhcp] Use random transaction ID to associate messages

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



RFC2131.txt:
xid 4  Transaction ID, a random number chosen by the
       client, used by the client and server to associate
       messages and responses between a client and a
       server.
The 'xid' field is used by the client to match incoming DHCP messages
with pending requests.  A DHCP client MUST choose 'xid's in such a
way as to minimize the chance of using an 'xid' identical to one used
by another client. For example, a client may choose a different,
random initial 'xid' each time the client is rebooted, and
subsequently use sequential 'xid's until the next reboot.  Selecting
a new 'xid' for each retransmission is an implementation decision.  A
client may choose to reuse the same 'xid' or select a new 'xid' for
each retransmitted message.

This patch generates random id when start dhcp, and record it to
netdev struct.

Signed-off-by: Amos Kong <akong@xxxxxxxxxx>
CC: Eduardo Habkost <ehabkost@xxxxxxxxxx>
CC: Marty Connor <mdc@xxxxxxxxxxxxx>
---
 src/include/gpxe/netdevice.h |    3 +++
 src/net/udp/dhcp.c           |   23 ++++-------------------
 2 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h
index 97bf168..7272cf8 100644
--- a/src/include/gpxe/netdevice.h
+++ b/src/include/gpxe/netdevice.h
@@ -294,6 +294,9 @@ struct net_device {
 	/** Link-layer broadcast address */
 	const uint8_t *ll_broadcast;
 
+	/* DHCP Transaction ID */
+	uint32_t xid;
+
 	/** Current device state
 	 *
 	 * This is the bitwise-OR of zero or more NETDEV_XXX constants.
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
index 4bfcb80..51b7150 100644
--- a/src/net/udp/dhcp.c
+++ b/src/net/udp/dhcp.c
@@ -136,23 +136,6 @@ static inline const char * dhcp_msgtype_name ( unsigned int msgtype ) {
 	}
 }
 
-/**
- * Calculate DHCP transaction ID for a network device
- *
- * @v netdev		Network device
- * @ret xid		DHCP XID
- *
- * Extract the least significant bits of the hardware address for use
- * as the transaction ID.
- */
-static uint32_t dhcp_xid ( struct net_device *netdev ) {
-	uint32_t xid;
-
-	memcpy ( &xid, ( netdev->ll_addr + netdev->ll_protocol->ll_addr_len
-			 - sizeof ( xid ) ), sizeof ( xid ) );
-	return xid;
-}
-
 /****************************************************************************
  *
  * DHCP session
@@ -1070,7 +1053,7 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
 
 	/* Initialise DHCP packet content */
 	memset ( dhcphdr, 0, max_len );
-	dhcphdr->xid = dhcp_xid ( netdev );
+	dhcphdr->xid = netdev->xid;
 	dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE );
 	dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto );
 	dhcphdr->op = dhcp_op[msgtype];
@@ -1313,7 +1296,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
 			&server_id, sizeof ( server_id ) );
 
 	/* Check for matching transaction ID */
-	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
+	if ( dhcphdr->xid != dhcp->netdev->xid ) {
+
 		DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
 		       "ID\n", dhcp, dhcp_msgtype_name ( msgtype ),
 		       inet_ntoa ( peer->sin_addr ),
@@ -1442,6 +1426,7 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) {
 	dhcp = zalloc ( sizeof ( *dhcp ) );
 	if ( ! dhcp )
 		return -ENOMEM;
+	netdev->xid = random();
 	ref_init ( &dhcp->refcnt, dhcp_free );
 	job_init ( &dhcp->job, &dhcp_job_operations, &dhcp->refcnt );
 	xfer_init ( &dhcp->xfer, &dhcp_xfer_operations, &dhcp->refcnt );

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux