コード例 #1
0
ファイル: nm-ip6-manager.c プロジェクト: binli/NetworkManager
static gboolean
rdnss_expired (gpointer user_data)
{
	NMIP6Device *device = user_data;
	CallbackInfo info = { device, IP6_DHCP_OPT_NONE, FALSE };

	nm_log_dbg (LOGD_IP6, "(%s): IPv6 RDNSS information expired", device->iface);

	set_rdnss_timeout (device);
	emit_config_changed (&info);
	return FALSE;
}
コード例 #2
0
static gboolean
rdnss_needs_refresh (gpointer user_data)
{
	NMIP6Device *device = user_data;
	gchar *msg;

	msg = g_strdup_printf ("IPv6 RDNSS due to expire in %d seconds",
	                       device->rdnss_timeout);
	device_send_router_solicitation (device, msg);
	g_free (msg);

	set_rdnss_timeout (device);

	return FALSE;
}
コード例 #3
0
ファイル: nm-ip6-manager.c プロジェクト: binli/NetworkManager
static gboolean
process_nduseropt_rdnss (NMIP6Device *device, struct nd_opt_hdr *opt)
{
	size_t opt_len;
	struct nd_opt_rdnss *rdnss_opt;
	time_t now = time (NULL);
	struct in6_addr *addr;
	GArray *new_servers;
	NMIP6RDNSS server, *cur_server;
	gboolean changed = FALSE;
	guint i;

	opt_len = opt->nd_opt_len;

	if (opt_len < 3 || (opt_len & 1) == 0)
		return FALSE;

	rdnss_opt = (struct nd_opt_rdnss *) opt;

	new_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS));

	/* Pad the DNS server expiry somewhat to give a bit of slack in cases
	 * where one RA gets lost or something (which can happen on unreliable
	 * links like WiFi where certain types of frames are not retransmitted).
	 * Note that 0 has special meaning and is therefore not adjusted.
	 */
	server.expires = ntohl (rdnss_opt->nd_opt_rdnss_lifetime);
	if (server.expires > 0)
		server.expires += now + 10;

	for (addr = (struct in6_addr *) (rdnss_opt + 1); opt_len >= 2; addr++, opt_len -= 2) {
		char buf[INET6_ADDRSTRLEN + 1];

		if (!inet_ntop (AF_INET6, addr, buf, sizeof (buf))) {
			nm_log_warn (LOGD_IP6, "(%s): received invalid RA-provided nameserver", device->iface);
			continue;
		}

		/* Update the cached timeout if we already saw this server */
		for (i = 0; i < device->rdnss_servers->len; i++) {
			cur_server = &(g_array_index (device->rdnss_servers, NMIP6RDNSS, i));

			if (!IN6_ARE_ADDR_EQUAL (addr, &cur_server->addr))
				continue;

			cur_server->expires = server.expires;

			if (server.expires > 0) {
				nm_log_dbg (LOGD_IP6, "(%s): refreshing RA-provided nameserver %s (expires in %ld seconds)",
				            device->iface, buf,
				            server.expires - now);
				break;
			}

			nm_log_dbg (LOGD_IP6, "(%s): removing RA-provided nameserver %s on router request",
			            device->iface, buf);

			g_array_remove_index (device->rdnss_servers, i);
			changed = TRUE;
			break;
		}

		if (server.expires == 0)
			continue;
		if (i < device->rdnss_servers->len)
			continue;

		nm_log_dbg (LOGD_IP6, "(%s): found RA-provided nameserver %s (expires in %ld seconds)",
		            device->iface, buf, server.expires - now);

		server.addr = *addr;
		g_array_append_val (new_servers, server);
	}

	/* New servers must be added in the order they are listed in the
	 * RA option and before any existing servers.
	 *
	 * Note: This is the place to remove servers if we want to cap the
	 *       number of resolvers. The RFC states that the one to expire
	 *       first of the existing servers should be removed.
	 */
	if (new_servers->len) {
		g_array_prepend_vals (device->rdnss_servers,
		                      new_servers->data, new_servers->len);
		changed = TRUE;
	}

	g_array_free (new_servers, TRUE);

	/* Timeouts may have changed even if IPs didn't */
	set_rdnss_timeout (device);

	return changed;
}