This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]