platform: refactor calculating valid/preferred times when adding address

Replace the calls to subtract_guint32() by _rebase_relative_time_on_now()
and _address_get_lifetime().

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-03-31 11:19:45 +02:00
parent d90b9ff2c8
commit e1410b5a88

View file

@ -1559,14 +1559,53 @@ array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address
return FALSE;
}
/* Compute (a - b) in an overflow-safe manner. */
/**
* Takes a pair @timestamp and @duration, and returns the remaining duration based
* on the new timestamp @now.
*/
static guint32
subtract_guint32 (guint32 a, guint32 b)
_rebase_relative_time_on_now (guint32 timestamp, guint32 duration, guint32 now)
{
if (a == G_MAXUINT32)
return G_MAXUINT32;
gint64 t;
return a > b ? a - b : 0;
if (duration == NM_PLATFORM_LIFETIME_PERMANENT)
return NM_PLATFORM_LIFETIME_PERMANENT;
/* For timestamp>now, just accept it and calculate the expected(?) result. */
t = (gint64) timestamp + (gint64) duration - (gint64) now;
/* Pad the timestamp by 5 seconds to avoid potential races. */
t += 5;
if (t <= 0)
return 0;
if (t >= NM_PLATFORM_LIFETIME_PERMANENT)
return NM_PLATFORM_LIFETIME_PERMANENT - 1;
return t;
}
static gboolean
_address_get_lifetime (const NMPlatformIPAddress *address, guint32 now, guint32 *out_lifetime, guint32 *out_preferred)
{
gint32 lifetime, preferred;
if (address->lifetime == 0) {
*out_lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
*out_preferred = NM_PLATFORM_LIFETIME_PERMANENT;
} else {
lifetime = _rebase_relative_time_on_now (address->timestamp, address->lifetime, now);
if (!lifetime)
return FALSE;
preferred = _rebase_relative_time_on_now (address->timestamp, address->preferred, now);
if (preferred > lifetime) {
g_warn_if_reached ();
preferred = lifetime;
}
*out_lifetime = lifetime;
*out_preferred = preferred;
}
return TRUE;
}
/**
@ -1606,16 +1645,8 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses)
const NMPlatformIP4Address *known_address = &g_array_index (known_addresses, NMPlatformIP4Address, i);
guint32 lifetime, preferred;
if (known_address->lifetime) {
/* Pad the timestamp by 5 seconds to avoid potential races. */
guint32 shift = subtract_guint32 (now, known_address->timestamp + 5);
lifetime = subtract_guint32 (known_address->lifetime, shift);
preferred = subtract_guint32 (known_address->preferred, shift);
g_warn_if_fail (known_address->preferred <= known_address->lifetime);
} else
lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT;
if (!_address_get_lifetime ((NMPlatformIPAddress *) known_address, now, &lifetime, &preferred))
continue;
if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred, known_address->label))
return FALSE;
@ -1665,16 +1696,8 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses)
const NMPlatformIP6Address *known_address = &g_array_index (known_addresses, NMPlatformIP6Address, i);
guint32 lifetime, preferred;
if (known_address->lifetime) {
/* Pad the timestamp by 5 seconds to avoid potential races. */
guint32 shift = subtract_guint32 (now, known_address->timestamp + 5);
lifetime = subtract_guint32 (known_address->lifetime, shift);
preferred = subtract_guint32 (known_address->preferred, shift);
g_warn_if_fail (known_address->preferred <= known_address->lifetime);
} else
lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT;
if (!_address_get_lifetime ((NMPlatformIPAddress *) known_address, now, &lifetime, &preferred))
continue;
if (!nm_platform_ip6_address_add (ifindex, known_address->address,
known_address->peer_address, known_address->plen,