Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 600669 Details for
Bug 662254
dhclient fails to renew lease; lease-time of 0xffffffff (infinity) causes exit 1
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
Condensed testcase of original code (without patch from #789601)
lease.c (text/plain), 7.31 KB, created by
Dan Williams
on 2012-07-27 02:09:06 UTC
(
hide
)
Description:
Condensed testcase of original code (without patch from #789601)
Filename:
MIME Type:
Creator:
Dan Williams
Created:
2012-07-27 02:09:06 UTC
Size:
7.31 KB
patch
obsolete
>#include <sys/time.h> >#include <stdio.h> >#include <limits.h> >#include <stdlib.h> > >#define TIME_MAX 2147483647 > >/* maximum value for usec */ >#define USEC_MAX 1000000 >#define DHCP_SEC_MAX 0xFFFFFFFF >#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */ >#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */ >#define US_PER_S 1000000 /*%< Microseconds per second. */ > >static struct timeval cur_tv = { 0, 0 }; > >typedef struct { > unsigned int seconds; > unsigned int nanoseconds; >} isc_interval_t; > >typedef struct { > unsigned int seconds; > unsigned int nanoseconds; >} isc_time_t; > >static void >isc_interval_set (isc_interval_t *t, unsigned int seconds, unsigned int nano) >{ > t->seconds = seconds; > t->nanoseconds = nano; >} > >static inline void >fix_tv_usec(struct timeval *tv) { > if (tv->tv_usec < 0) { > fprintf (stdout, "%s: unfixed!\n", __func__); > do { > tv->tv_sec -= 1; > tv->tv_usec += US_PER_S; > } while (tv->tv_usec < 0); > } else if (tv->tv_usec >= US_PER_S) { > fprintf (stdout, "%s: fixed!\n", __func__); > do { > tv->tv_sec += 1; > tv->tv_usec -= US_PER_S; > } while (tv->tv_usec >=US_PER_S); > } >} > >typedef time_t TIME; > >typedef struct { > TIME expiry; > TIME renewal; > TIME rebind; >} client_lease; > >static int >isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) >{ > struct timeval tv; > > if (gettimeofday(&tv, NULL) == -1) > return -1; > >fprintf (stdout, "%s: now sec %zu\n", __func__, tv.tv_sec); >fprintf (stdout, "%s: interval sec %u\n", __func__, i->seconds); > > /* > * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not, > * then this test will generate warnings for platforms on which it is > * unsigned. In any event, the chances of any of these problems > * happening are pretty much zero, but since the libisc library ensures > * certain things to be true ... > */ > fix_tv_usec(&tv); > if (tv.tv_sec < 0) > return -2; >fprintf (stdout, "%s: fixed now sec %zu\n", __func__, tv.tv_sec); > > /* > * Ensure the resulting seconds value fits in the size of an > * unsigned int. (It is written this way as a slight optimization; > * note that even if both values == INT_MAX, then when added > * and getting another 1 added below the result is UINT_MAX.) > */ >fprintf (stdout, "%s: (2) now sec %zu (INT_MAX %d)\n", __func__, tv.tv_sec, (int) INT_MAX); >fprintf (stdout, "%s: (2) interval sec %u (INT_MAX %d)\n", __func__, i->seconds, (int) INT_MAX); >fprintf (stdout, "%s: (2) now (%lld) + interval sec (%u) = %lld (UINT_MAX %u)\n", __func__, >(long long) tv.tv_sec, i->seconds, >(long long)tv.tv_sec + i->seconds, (unsigned int) UINT_MAX); > if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) && > ((long long)tv.tv_sec + i->seconds > UINT_MAX)) > return -3; > > t->seconds = tv.tv_sec + i->seconds; >fprintf (stdout, "%s: time seconds %u\n", __func__, t->seconds); > t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds; > if (t->nanoseconds >= NS_PER_S) { > t->seconds++; > t->nanoseconds -= NS_PER_S; > } > >fprintf (stdout, "%s: SUCCESS!\n", __func__); > return 0; >} > >static void add_timeout (struct timeval *when) >{ > int status; > int64_t sec; > int usec; > isc_interval_t interval; > isc_time_t expires; > > /* > * The value passed in is a time from an epoch but we need a relative > * time so we need to do some math to try and recover the period. > * This is complicated by the fact that not all of the calls cared > * about the usec value, if it's zero we assume the caller didn't care. > * > * The ISC timer library doesn't seem to like negative values > * and can't accept any values above 4G-1 seconds so we limit > * the values to 0 <= value < 4G-1. We do it before > * checking the trace option so that both the trace code and > * the working code use the same values. > */ > >fprintf (stdout, "%s: when sec %zu\n", __func__, when->tv_sec); >fprintf (stdout, "%s: cur_tv sec %zu\n", __func__, cur_tv.tv_sec); > sec = when->tv_sec - cur_tv.tv_sec; > usec = when->tv_usec - cur_tv.tv_usec; >fprintf (stdout, "%s: sec %ld\n", __func__, sec); > > if ((when->tv_usec != 0) && (usec < 0)) { > sec--; > usec += USEC_MAX; > } > > if (sec < 0) { > sec = 0; > usec = 0; > } else if (sec > DHCP_SEC_MAX) { > fprintf(stdout, "Timeout requested too large " > "reducing to 2^^32-1\n"); > sec = DHCP_SEC_MAX; > usec = 0; > } else if (usec < 0) { > usec = 0; > } else if (usec >= USEC_MAX) { > usec = USEC_MAX - 1; > } > >fprintf (stdout, "%s: set interval sec %ld\n", __func__, sec & DHCP_SEC_MAX); > isc_interval_set(&interval, sec & DHCP_SEC_MAX, usec * 1000); >fprintf (stdout, "%s: interval sec %u\n", __func__, interval.seconds); > status = isc_time_nowplusinterval(&expires, &interval); >fprintf (stdout, "%s: nowplusinterval expires sec %u\n", __func__, expires.seconds); > if (status != 0) { > /* > * The system time function isn't happy or returned > * a value larger than isc_time_t can hold. > */ > fprintf(stdout, "Unable to set up timer: %d\n", status); > } >} > >static void bind_lease (client_lease *client) >{ > struct timeval tv; > > gettimeofday (&cur_tv, NULL); > > /* Set up a timeout to start the renewal process. */ > tv.tv_sec = client->renewal; > tv.tv_usec = ((client->renewal - cur_tv.tv_sec) > 1) ? > random() % 1000000 : cur_tv.tv_usec; > >fprintf (stdout, "%s: timeout interval secs %zu\n", __func__, tv.tv_sec); > add_timeout(&tv); >} > >#define cur_time tv.tv_sec > >static void dhcpack (client_lease *client) >{ > struct timeval tv; > > gettimeofday (&tv, NULL); > > client -> expiry = 0xFFFFFFFF; > > /* > * A number that looks negative here is really just very large, > * because the lease expiry offset is unsigned. > */ > if (client->expiry < 0) > client->expiry = TIME_MAX; > > client -> renewal = 0xFFFFFFFF; > > /* If it wasn't specified by the server, calculate it. */ > if (!client -> renewal) > client -> renewal = client -> expiry / 2 + 1; > > if (client -> renewal <= 0) > client -> renewal = TIME_MAX; > > /* Now introduce some randomness to the renewal time: */ > if (client->renewal <= ((TIME_MAX / 3) - 3)) > client->renewal = (((client->renewal * 3) + 3) / 4) + > (((random() % client->renewal) + 3) / 4); > > client -> rebind = 0xFFFFFFFF; > > if (client -> rebind <= 0) { > if (client -> expiry <= TIME_MAX / 7) > client -> rebind = > client -> expiry * 7 / 8; > else > client -> rebind = > client -> expiry / 8 * 7; > } > > /* Make sure our randomness didn't run the renewal time past the > rebind time. */ > if (client -> renewal > client -> rebind) { > if (client -> rebind <= TIME_MAX / 3) > client -> renewal = > client -> rebind * 3 / 4; > else > client -> renewal = > client -> rebind / 4 * 3; > } > >fprintf (stdout, "%s: cur_time %lu\n", __func__, cur_time); >fprintf (stdout, "%s: expiry %zu\n", __func__, client->expiry); >fprintf (stdout, "%s: renewal %zu\n", __func__, client->renewal); >fprintf (stdout, "%s: rebind %zu\n", __func__, client->rebind); > > client -> expiry += cur_time; > /* Lease lengths can never be negative. */ > if (client -> expiry < cur_time) > client -> expiry = TIME_MAX; > client -> renewal += cur_time; > if (client -> renewal < cur_time) > client -> renewal = TIME_MAX; > client -> rebind += cur_time; > if (client -> rebind < cur_time) > client -> rebind = TIME_MAX; > >fprintf (stdout, "%s: after expiry %zu\n", __func__, client->expiry); >fprintf (stdout, "%s: after renewal %zu\n", __func__, client->renewal); >fprintf (stdout, "%s: after rebind %zu\n", __func__, client->rebind); > bind_lease (client); >} > >int main(int argc, char **argv) >{ > client_lease client = { 0, 0 , 0 }; > > dhcpack (&client); > return 0; >} >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 662254
:
468545
|
600475
|
600483
| 600669 |
600672