[ECOS] RedBoot DHCP failure due to race condition.
Grant Edwards
grant.b.edwards@gmail.com
Thu Mar 17 15:43:00 GMT 2011
We've been having intermittent problems with RedBoot's DHCP client
failing to acquire an address. I've tracked it down to what looks
like a race condition in RedBoot's DHCP code.
The failure mostly happens when the DHCP state machine has reached the
"ACK" state and the "ACK" BOOTP packet has been stored at *bp_info.
If another BOOTP packet arrives before the foreground loop has had a
chance to process the stuff stored at bp_info, that packet will
overwrite what's stored at *bp_info even though the rx state machine
will later decide to "ignore" the packet -- it's already blown away
the packet we care about. Since we're in the ACK state, the
foreground loop decides we're done, and it doesn't retry.
The basic problem is that _all_ received BOOTP packets are stored at
*bp_info by the code starting at bootp.c line 92:
82 static void
83 bootp_handler(udp_socket_t *skt, char *buf, int len,
84 ip_route_t *src_route, word src_port)
85 {
86 bootp_header_t *b;
87 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
88 unsigned char *p, expected = 0;
89 #endif
90
91 b = (bootp_header_t *)buf;
92 if (bp_info) {
93 memset(bp_info,0,sizeof *bp_info);
94 if (len > sizeof *bp_info)
95 len = sizeof *bp_info;
96 memcpy(bp_info, b, len);
97 }
98
99 // Only accept pure REPLY responses
100 if (b->bp_op != BOOTREPLY)
101 return;
102
103 // Must be sent to me, as well!
104 if (memcmp(b->bp_chaddr, __local_enet_addr, 6))
105 return;
106
[...] [ ... DHCP state machine stuff ... ]
AFAICT, received BOOTP packets overwrite *bp_info regardless of what
state we're in, whether or not they're BOOTP "REPLY" packets, and
*bp_info even gets overwritten by packets that aren't addressed to us.
Am I misunderstanding the code?
I've gotten RedBoot DHCP to work more reliably by changing line 92 to:
92 if (bp_info && (dhcpState != DHCP_ACK)) {
While that's an improvement, I don't think that fix is sufficient
since bogus BOOTP packets can still incorrectly overwrite *bp_info in
other states.
Shouldn't we store the received packet in *bp_info only after we've
checked to make sure it's a BOOTP REPLY packet and it's addressed to
us?
Better yet, only store it if the DHCP type is what we're expecting for
the current state?
--
Grant
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
More information about the Ecos-discuss
mailing list