1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

sunrpc: Improvements for UDP client timeout handling [BZ #20257]

This commit fixes various aspects in the UDP client timeout handling.
Timeouts are now applied in a more consistent fashion.  Discarded UDP
packets no longer prevent the timeout from happening at all.
This commit is contained in:
Florian Weimer
2017-02-28 15:28:45 +01:00
parent 37fb019cb0
commit cf0bd2f73b
10 changed files with 1346 additions and 58 deletions

View File

@ -20,11 +20,100 @@
#define _NET_INTERNAL_H 1
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/time.h>
int __inet6_scopeid_pton (const struct in6_addr *address,
const char *scope, uint32_t *result)
internal_function attribute_hidden;
libc_hidden_proto (__inet6_scopeid_pton)
/* Deadline handling for enforcing timeouts.
Code should call __deadline_current_time to obtain the current time
and cache it locally. The cache needs updating after every
long-running or potentially blocking operation. Deadlines relative
to the current time can be computed using __deadline_from_timeval.
The deadlines may have to be recomputed in response to certain
events (such as an incoming packet), but they are absolute (not
relative to the current time). A timeout suitable for use with the
poll function can be computed from such a deadline using
__deadline_to_ms.
The fields in the structs defined belowed should only be used
within the implementation. */
/* Cache of the current time. Used to compute deadlines from relative
timeouts and vice versa. */
struct deadline_current_time
{
struct timespec current;
};
/* Return the current time. Terminates the process if the current
time is not available. */
struct deadline_current_time __deadline_current_time (void)
internal_function attribute_hidden;
/* Computed absolute deadline. */
struct deadline
{
struct timespec absolute;
};
/* For internal use only. */
static inline bool
__deadline_is_infinite (struct deadline deadline)
{
return deadline.absolute.tv_nsec < 0;
}
/* Return true if the current time is at the deadline or past it. */
static inline bool
__deadline_elapsed (struct deadline_current_time current,
struct deadline deadline)
{
return !__deadline_is_infinite (deadline)
&& (current.current.tv_sec > deadline.absolute.tv_sec
|| (current.current.tv_sec == deadline.absolute.tv_sec
&& current.current.tv_nsec >= deadline.absolute.tv_nsec));
}
/* Return the deadline which occurs first. */
static inline struct deadline
__deadline_first (struct deadline left, struct deadline right)
{
if (__deadline_is_infinite (right)
|| left.absolute.tv_sec < right.absolute.tv_sec
|| (left.absolute.tv_sec == right.absolute.tv_sec
&& left.absolute.tv_nsec < right.absolute.tv_nsec))
return left;
else
return right;
}
/* Add TV to the current time and return it. Returns a special
infinite absolute deadline on overflow. */
struct deadline __deadline_from_timeval (struct deadline_current_time,
struct timeval tv)
internal_function attribute_hidden;
/* Compute the number of milliseconds until the specified deadline,
from the current time in the argument. The result is mainly for
use with poll. If the deadline has already passed, return 0. If
the result would overflow an int, return INT_MAX. */
int __deadline_to_ms (struct deadline_current_time, struct deadline)
internal_function attribute_hidden;
/* Return true if TV.tv_sec is non-negative and TV.tv_usec is in the
interval [0, 999999]. */
static inline bool
__is_timeval_valid_timeout (struct timeval tv)
{
return tv.tv_sec >= 0 && tv.tv_usec >= 0 && tv.tv_usec < 1000 * 1000;
}
#endif /* _NET_INTERNAL_H */