diff options
author | Elena Tebesoi <elena.tebesoi@gmail.com> | 2012-05-21 14:49:42 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-05-22 21:13:32 +0200 |
commit | 5bf6e62fa5cdf7d9a19af04948e53b7db07abbc8 (patch) | |
tree | 060c07ba757ca3958a03b093def615be15fee232 /src/network.c | |
parent | a880cf2c775982f35f080c207176ecbadf751aa3 (diff) | |
download | connman-5bf6e62fa5cdf7d9a19af04948e53b7db07abbc8.tar.gz connman-5bf6e62fa5cdf7d9a19af04948e53b7db07abbc8.tar.bz2 connman-5bf6e62fa5cdf7d9a19af04948e53b7db07abbc8.zip |
resolver: Send RS before RDNSS lifetime expires
Implemented feature from RFC 6106 section
'5.1. Recursive DNS Server Option':
"Lifetime 32-bit unsigned integer.
...
Hosts MAY send a Router Solicitation to ensure
the RDNSS information is fresh before the interval expires."
Host will send RS when a certain threshold of RDNSS lifetime is reached.
Values which can be adjusted:
- lifetime threshold - set to 80% from lifetime
- number of retries in case RA is not received - set to 0
- time between retries, in case RA is not received - set to 3 seconds
Diffstat (limited to 'src/network.c')
-rw-r--r-- | src/network.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/network.c b/src/network.c index 10f1bf32..6fe1d9c5 100644 --- a/src/network.c +++ b/src/network.c @@ -28,6 +28,19 @@ #include "connman.h" +/* + * How many times to send RS with the purpose of + * refreshing RDNSS entries before they actually expire. + * With a value of 1, one RS will be sent, with no retries. + */ +#define RS_REFRESH_COUNT 1 + +/* + * Value in seconds to wait for RA after RS was sent. + * After this time elapsed, we can send another RS. + */ +#define RS_REFRESH_TIMEOUT 3 + static GSList *network_list = NULL; static GSList *driver_list = NULL; @@ -46,6 +59,7 @@ struct connman_network { char *path; int index; int router_solicit_count; + int router_solicit_refresh_count; struct connman_network_driver *driver; void *driver_data; @@ -1113,6 +1127,58 @@ static void check_dhcpv6(struct nd_router_advert *reply, connman_network_unref(network); } +static void receive_refresh_rs_reply(struct nd_router_advert *reply, + unsigned int length, void *user_data) +{ + struct connman_network *network = user_data; + + DBG("reply %p", reply); + + if (reply == NULL) { + /* + * Router solicitation message seem to get lost easily so + * try to send it again. + */ + if (network->router_solicit_refresh_count > 1) { + network->router_solicit_refresh_count--; + DBG("re-send router solicitation %d", + network->router_solicit_refresh_count); + __connman_inet_ipv6_send_rs(network->index, + RS_REFRESH_TIMEOUT, + receive_refresh_rs_reply, + network); + return; + } + } + + /* RS refresh not in progress anymore */ + network->router_solicit_refresh_count = 0; + + connman_network_unref(network); + return; +} + +int __connman_refresh_rs_ipv6(struct connman_network *network, int index) +{ + int ret = 0; + + DBG("network %p index %d", network, index); + + /* Send only one RS for all RDNSS entries which are about to expire */ + if (network->router_solicit_refresh_count > 0) { + DBG("RS refresh already started"); + return 0; + } + + network->router_solicit_refresh_count = RS_REFRESH_COUNT; + + connman_network_ref(network); + + ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT, + receive_refresh_rs_reply, network); + return ret; +} + static void autoconf_ipv6_set(struct connman_network *network) { struct connman_service *service; |