Whee, multicast sockets work!
Implemented recurrent timers.
This commit is contained in:
parent
140f034105
commit
af847acc27
3 changed files with 36 additions and 8 deletions
|
@ -59,6 +59,10 @@ tm_dump(resource *r)
|
||||||
timer *t = (timer *) r;
|
timer *t = (timer *) r;
|
||||||
|
|
||||||
debug("(code %p, data %p, ");
|
debug("(code %p, data %p, ");
|
||||||
|
if (t->randomize)
|
||||||
|
debug("rand %d, ", t->randomize);
|
||||||
|
if (t->recurrent)
|
||||||
|
debug("recur %d, ", t->recurrent);
|
||||||
if (t->expires)
|
if (t->expires)
|
||||||
debug("expires in %d sec)\n", t->expires - now);
|
debug("expires in %d sec)\n", t->expires - now);
|
||||||
else
|
else
|
||||||
|
@ -99,7 +103,7 @@ tm_start(timer *t, unsigned after)
|
||||||
bird_clock_t when;
|
bird_clock_t when;
|
||||||
|
|
||||||
if (t->randomize)
|
if (t->randomize)
|
||||||
after += random() % t->randomize;
|
after += random() % (t->randomize + 1);
|
||||||
when = now + after;
|
when = now + after;
|
||||||
if (t->expires == when)
|
if (t->expires == when)
|
||||||
return;
|
return;
|
||||||
|
@ -189,11 +193,20 @@ tm_shot(void)
|
||||||
}
|
}
|
||||||
while ((n = HEAD(near_timers)) -> next)
|
while ((n = HEAD(near_timers)) -> next)
|
||||||
{
|
{
|
||||||
|
int delay;
|
||||||
t = SKIP_BACK(timer, n, n);
|
t = SKIP_BACK(timer, n, n);
|
||||||
if (t->expires > now)
|
if (t->expires > now)
|
||||||
break;
|
break;
|
||||||
rem_node(n);
|
rem_node(n);
|
||||||
|
delay = t->expires - now;
|
||||||
t->expires = 0;
|
t->expires = 0;
|
||||||
|
if (t->recurrent)
|
||||||
|
{
|
||||||
|
int i = t->recurrent - delay;
|
||||||
|
if (i < 0)
|
||||||
|
i = 0;
|
||||||
|
tm_start(t, i);
|
||||||
|
}
|
||||||
t->hook(t);
|
t->hook(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,9 +289,12 @@ fill_in_sockaddr(struct sockaddr_in *sa, ip_addr a, unsigned port)
|
||||||
set_inaddr(&sa->sin_addr, a);
|
set_inaddr(&sa->sin_addr, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port)
|
get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port)
|
||||||
{
|
{
|
||||||
|
if (sa->sin_family != AF_INET)
|
||||||
|
die("get_sockaddr called for wrong address family");
|
||||||
|
if (port)
|
||||||
*port = ntohs(sa->sin_port);
|
*port = ntohs(sa->sin_port);
|
||||||
memcpy(a, &sa->sin_addr.s_addr, sizeof(*a));
|
memcpy(a, &sa->sin_addr.s_addr, sizeof(*a));
|
||||||
*a = ipa_ntoh(*a);
|
*a = ipa_ntoh(*a);
|
||||||
|
@ -384,19 +400,22 @@ sk_open(sock *s)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IP_MREQN
|
#ifdef HAVE_IP_MREQN
|
||||||
struct ip_mreqn mreq;
|
struct ip_mreqn mreq;
|
||||||
|
#define mreq_add mreq
|
||||||
mreq.imr_ifindex = s->iface->index;
|
mreq.imr_ifindex = s->iface->index;
|
||||||
if (has_src)
|
if (has_src)
|
||||||
set_inaddr(&mreq.imr_address, s->saddr);
|
set_inaddr(&mreq.imr_address, s->saddr);
|
||||||
else
|
else
|
||||||
set_inaddr(&mreq.imr_address, s->iface->ifa->ip);
|
set_inaddr(&mreq.imr_address, s->iface->ifa->ip);
|
||||||
#else
|
#else
|
||||||
struct ip_mreq mreq;
|
struct in_addr mreq;
|
||||||
|
struct ip_mreq mreq_add;
|
||||||
if (has_src)
|
if (has_src)
|
||||||
set_inaddr(&mreq.imr_interface, s->saddr);
|
set_inaddr(&mreq, s->saddr);
|
||||||
else
|
else
|
||||||
set_inaddr(&mreq.imr_interface, s->iface->ifa->ip);
|
set_inaddr(&mreq, s->iface->ifa->ip);
|
||||||
|
memcpy(&mreq_add.imr_interface, &mreq, sizeof(struct in_addr));
|
||||||
#endif
|
#endif
|
||||||
set_inaddr(&mreq.imr_multiaddr, s->daddr);
|
set_inaddr(&mreq_add.imr_multiaddr, s->daddr);
|
||||||
if (has_dest)
|
if (has_dest)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
@ -414,7 +433,7 @@ sk_open(sock *s)
|
||||||
if (setsockopt(fd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0)
|
if (setsockopt(fd, SOL_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq)) < 0)
|
||||||
ERR("IP_MULTICAST_IF");
|
ERR("IP_MULTICAST_IF");
|
||||||
}
|
}
|
||||||
if (has_src && setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
if (has_src && setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq_add, sizeof(mreq_add)) < 0)
|
||||||
ERR("IP_ADD_MEMBERSHIP");
|
ERR("IP_ADD_MEMBERSHIP");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ typedef struct timer {
|
||||||
void (*hook)(struct timer *);
|
void (*hook)(struct timer *);
|
||||||
void *data;
|
void *data;
|
||||||
unsigned randomize; /* Amount of randomization */
|
unsigned randomize; /* Amount of randomization */
|
||||||
|
unsigned recurrent; /* Timer recurrence */
|
||||||
node n; /* Internal link */
|
node n; /* Internal link */
|
||||||
clock_t expires; /* 0=inactive */
|
clock_t expires; /* 0=inactive */
|
||||||
} timer;
|
} timer;
|
||||||
|
|
|
@ -13,5 +13,13 @@
|
||||||
|
|
||||||
void io_init(void);
|
void io_init(void);
|
||||||
void io_loop(void);
|
void io_loop(void);
|
||||||
|
void get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port);
|
||||||
|
|
||||||
|
/* sync-if.c */
|
||||||
|
|
||||||
|
extern int if_scan_sock;
|
||||||
|
extern int if_scan_period;
|
||||||
|
|
||||||
|
void scan_if_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue