summaryrefslogtreecommitdiff
path: root/src/network.c
diff options
context:
space:
mode:
authorElena Tebesoi <elena.tebesoi@gmail.com>2012-05-21 14:49:42 +0200
committerMarcel Holtmann <marcel@holtmann.org>2012-05-22 21:13:32 +0200
commit5bf6e62fa5cdf7d9a19af04948e53b7db07abbc8 (patch)
tree060c07ba757ca3958a03b093def615be15fee232 /src/network.c
parenta880cf2c775982f35f080c207176ecbadf751aa3 (diff)
downloadconnman-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.c66
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;