This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: DHCP crash with Novell Server
On Tue, Jun 19, 2001 at 03:44:51PM -0500, Grant Edwards wrote:
> > However, when used with a Novell Netware 5.0 server it crashes
> > (the board resets) when the IP lease expires (600 seconds in
> > the example below).
Patch corresponding to previously described fixes is attached.
Gauranteed to work or your money back!
(Seems to work well for me.)
--
Grant Edwards
grante@visi.com
Index: dhcp_prot.c
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/tcpip/current/src/lib/dhcp_prot.c,v
retrieving revision 1.4
diff -U6 -r1.4 dhcp_prot.c
--- dhcp_prot.c 2000/09/19 05:54:00 1.4
+++ dhcp_prot.c 2001/06/19 22:00:31
@@ -268,27 +268,28 @@
static cyg_alarm_t alarm_function;
static void alarm_function(cyg_handle_t alarm, cyg_addrword_t data)
{
struct dhcp_lease *lease = (struct dhcp_lease *)data;
lease->which |= lease->next;
+
cyg_semaphore_post( &dhcp_needs_attention );
// Step the lease on into its next state of being alarmed ;-)
if ( lease->next & DHCP_LEASE_EX ) {
cyg_alarm_disable( alarm );
}
else if ( lease->next & DHCP_LEASE_T2 ) {
+ lease->next = DHCP_LEASE_EX;
cyg_alarm_initialize( lease->alarm, lease->expiry, 0 );
cyg_alarm_enable( lease->alarm );
- lease->next = DHCP_LEASE_EX;
}
else if ( lease->next & DHCP_LEASE_T1 ) {
+ lease->next = DHCP_LEASE_T2;
cyg_alarm_initialize( lease->alarm, lease->t2, 0 );
cyg_alarm_enable( lease->alarm );
- lease->next = DHCP_LEASE_T2;
}
}
static inline void no_lease( struct dhcp_lease *lease )
{
if ( lease->alarm ) {
@@ -301,56 +302,70 @@
static inline void new_lease( struct bootp *bootp, struct dhcp_lease *lease )
{
cyg_tick_count_t now = cyg_current_time();
cyg_tick_count_t then;
cyg_uint32 tag = 0;
+ cyg_uint32 expiry_then;
cyg_resolution_t resolution =
cyg_clock_get_resolution(cyg_real_time_clock());
cyg_handle_t h;
// Silence any jabbering from past lease on this interface
no_lease( lease );
lease->which = lease->next = 0;
cyg_clock_to_counter(cyg_real_time_clock(), &h);
cyg_alarm_create( h, alarm_function, (cyg_addrword_t)lease,
&lease->alarm, &lease->alarm_obj );
// extract the lease time and scale it &c to now.
- get_bootp_option( bootp, TAG_DHCP_LEASE_TIME, &tag );
+ if(!get_bootp_option( bootp, TAG_DHCP_LEASE_TIME, &tag ))
+ tag = 0xffffffff;
if ( 0xffffffff == tag ) {
lease->expiry = 0xffffffffffffffff;
lease->t2 = 0xffffffffffffffff;
lease->t1 = 0xffffffffffffffff;
return; // it's an infinite lease, hurrah!
}
-
+
then = (cyg_uint64)(ntohl(tag));
+ expiry_then = then;
then *= 1000000000; // into nS - we know there is room in a tick_count_t
then = (then / resolution.dividend) * resolution.divisor; // into system ticks
lease->expiry = now + then;
- get_bootp_option( bootp, TAG_DHCP_REBIND_TIME, &tag );
- then = (cyg_uint64)(ntohl(tag));
+ if (get_bootp_option( bootp, TAG_DHCP_REBIND_TIME, &tag ))
+ then = (cyg_uint64)(ntohl(tag));
+ else
+ then = expiry_then - expiry_then/4;
then *= 1000000000; // into nS - we know there is room in a tick_count_t
then = (then / resolution.dividend) * resolution.divisor; // into system ticks
lease->t2 = now + then;
-
- get_bootp_option( bootp, TAG_DHCP_RENEWAL_TIME, &tag );
- then = (cyg_uint64)(ntohl(tag));
+
+ if (get_bootp_option( bootp, TAG_DHCP_RENEWAL_TIME, &tag ))
+ then = (cyg_uint64)(ntohl(tag));
+ else
+ then = expiry_then/2;
then *= 1000000000; // into nS - we know there is room in a tick_count_t
then = (then / resolution.dividend) * resolution.divisor; // into system ticks
lease->t1 = now + then;
-
+
#if 0 // for testing this mechanism
lease->expiry = now + 5000; // 1000 here makes for failure in the DHCP test
lease->t2 = now + 3500;
lease->t1 = now + 2500;
#endif
+
+#ifdef DHCP_CHATTER
+ diag_printf("new_lease:\n");
+ diag_printf(" expiry = %d\n",lease->expiry);
+ diag_printf(" t1 = %d\n",lease->t1);
+ diag_printf(" t2 = %d\n",lease->t2);
+#endif
lease->next = DHCP_LEASE_T1;
cyg_alarm_initialize( lease->alarm, lease->t1, 0 );
cyg_alarm_enable( lease->alarm );
}
@@ -455,13 +470,13 @@
cyg_uint8 lease_state;
cyg_scheduler_lock();
lease_state = lease->which;
lease->which = 0; // flag that we have noticed it
cyg_scheduler_unlock();
-
+
if ( lease_state & DHCP_LEASE_EX ) {
// then the lease has expired completely!
*pstate = DHCPSTATE_NOTBOUND;
}
else if ( lease_state & DHCP_LEASE_T2 ) {
// Time to renew