コード例 #1
0
ファイル: process.c プロジェクト: reubenhwk/radvd
static void process_rs(int sock, struct Interface *iface, unsigned char *msg, int len, struct sockaddr_in6 *addr)
{
    /* validation */
    len -= sizeof(struct nd_router_solicit);

    uint8_t *opt_str = (uint8_t *) (msg + sizeof(struct nd_router_solicit));

    while (len > 0) {
        if (len < 2) {
            flog(LOG_WARNING, "trailing garbage in RS");
            return;
        }

        int const optlen = (opt_str[1] << 3);

        if (optlen == 0) {
            flog(LOG_WARNING, "zero length option in RS");
            return;
        } else if (optlen > len) {
            flog(LOG_WARNING, "option length greater than total length in RS");
            return;
        }

        if (*opt_str == ND_OPT_SOURCE_LINKADDR && IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr)) {
            flog(LOG_WARNING,
                 "received icmpv6 RS packet with unspecified source address and there is a lladdr option");
            return;
        }

        len -= optlen;
        opt_str += optlen;
    }

    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);

    double const delay = (MAX_RA_DELAY_SECONDS * rand() / (RAND_MAX + 1.0));

    if (iface->UnicastOnly) {
        send_ra_forall(sock, iface, &addr->sin6_addr);
    } else if (timespecdiff(&ts, &iface->times.last_multicast) / 1000.0 < iface->MinDelayBetweenRAs) {
        /* last RA was sent only a few moments ago, don't send another immediately. */
        double next =
            iface->MinDelayBetweenRAs - (ts.tv_sec + ts.tv_nsec / 1000000000.0) + (iface->times.last_multicast.tv_sec +
                    iface->times.last_multicast.tv_nsec /
                    1000000000.0) + delay;
        dlog(LOG_DEBUG, 5, "%s: rate limiting RA's, rescheduling RA %f seconds from now", iface->props.name, next);
        reschedule_iface(iface, next);
    } else {
        /* no RA sent in a while, send a multicast reply */
        send_ra_forall(sock, iface, NULL);
        double next = rand_between(iface->MinRtrAdvInterval, iface->MaxRtrAdvInterval);
        reschedule_iface(iface, next);
    }
    dlog(LOG_DEBUG, 2, "%s processed an RS", iface->props.name);
}
コード例 #2
0
ファイル: radvd.c プロジェクト: Distrotech/radvd
static void timer_handler(int sock, struct Interface *iface)
{
	dlog(LOG_DEBUG, 1, "timer_handler called for %s", iface->props.name);

	if (send_ra_forall(sock, iface, NULL) != 0) {
		dlog(LOG_DEBUG, 4, "send_ra_forall failed on interface %s", iface->props.name);
	}

	double next = rand_between(iface->MinRtrAdvInterval, iface->MaxRtrAdvInterval);

	reschedule_iface(iface, next);
}
コード例 #3
0
ファイル: radvd.c プロジェクト: Distrotech/radvd
/*
 *      send initial advertisement and set timers
 */
static void kickoff_adverts(int sock, struct Interface *iface)
{
	clock_gettime(CLOCK_MONOTONIC, &iface->times.last_ra_time);

	if (iface->UnicastOnly)
		return;

	clock_gettime(CLOCK_MONOTONIC, &iface->times.last_multicast);

	/* send an initial advertisement */
	if (send_ra_forall(sock, iface, NULL) != 0) {
		dlog(LOG_DEBUG, 4, "send_ra_forall failed on interface %s", iface->props.name);
	}

	double next = min(MAX_INITIAL_RTR_ADVERT_INTERVAL, iface->MaxRtrAdvInterval);
	reschedule_iface(iface, next);
}