Commit d2da6d17 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Implement last-ditch send moderation.

parent 18811d3d
...@@ -607,6 +607,8 @@ add_network(char *ifname, int ifindex, int mtu, ...@@ -607,6 +607,8 @@ add_network(char *ifname, int ifindex, int mtu,
} }
nets[numnets].sendbuf = p; nets[numnets].sendbuf = p;
nets[numnets].buffered = 0; nets[numnets].buffered = 0;
nets[numnets].bucket_time = now.tv_sec;
nets[numnets].bucket = 0;
numnets++; numnets++;
return &nets[numnets - 1]; return &nets[numnets - 1];
} }
......
...@@ -70,6 +70,8 @@ struct network { ...@@ -70,6 +70,8 @@ struct network {
struct timeval flush_time; struct timeval flush_time;
int bufsize; int bufsize;
unsigned char *sendbuf; unsigned char *sendbuf;
int bucket_time;
unsigned int bucket;
unsigned char hello_seqno; unsigned char hello_seqno;
unsigned int hello_interval; unsigned int hello_interval;
unsigned int self_update_interval; unsigned int self_update_interval;
......
...@@ -157,6 +157,28 @@ parse_packet(const unsigned char *from, struct network *net, ...@@ -157,6 +157,28 @@ parse_packet(const unsigned char *from, struct network *net,
return; return;
} }
/* Under normal circumstances, there are enough moderation mechanisms
elsewhere in the protocol to make sure that this last-ditch check
should never trigger. But I'm superstitious. */
static int
check_bucket(struct network *net)
{
if(net->bucket > 0 && now.tv_sec > net->bucket_time) {
net->bucket =
MAX(0, net->bucket - 40 * (now.tv_sec - net->bucket_time));
}
net->bucket_time = now.tv_sec;
if(net->bucket < 400) {
net->bucket++;
return 1;
} else {
return 0;
}
}
void void
flushbuf(struct network *net) flushbuf(struct network *net)
{ {
...@@ -171,17 +193,22 @@ flushbuf(struct network *net) ...@@ -171,17 +193,22 @@ flushbuf(struct network *net)
if(net->buffered > 0) { if(net->buffered > 0) {
debugf(" (flushing %d buffered bytes on %s)\n", debugf(" (flushing %d buffered bytes on %s)\n",
net->buffered, net->ifname); net->buffered, net->ifname);
memset(&sin6, 0, sizeof(sin6)); if(check_bucket(net)) {
sin6.sin6_family = AF_INET6; memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6.sin6_addr, protocol_group, 16); sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(protocol_port); memcpy(&sin6.sin6_addr, protocol_group, 16);
sin6.sin6_scope_id = net->ifindex; sin6.sin6_port = htons(protocol_port);
rc = babel_send(protocol_socket, sin6.sin6_scope_id = net->ifindex;
packet_header, sizeof(packet_header), rc = babel_send(protocol_socket,
net->sendbuf, net->buffered, packet_header, sizeof(packet_header),
(struct sockaddr*)&sin6, sizeof(sin6)); net->sendbuf, net->buffered,
if(rc < 0) (struct sockaddr*)&sin6, sizeof(sin6));
perror("send"); if(rc < 0)
perror("send");
} else {
fprintf(stderr, "Warning: bucket full, dropping packet to %s.\n",
net->ifname);
}
} }
VALGRIND_MAKE_MEM_UNDEFINED(net->sendbuf, net->bufsize); VALGRIND_MAKE_MEM_UNDEFINED(net->sendbuf, net->bufsize);
net->buffered = 0; net->buffered = 0;
...@@ -273,17 +300,22 @@ send_unicast_packet(struct neighbour *neigh, unsigned char *buf, int buflen) ...@@ -273,17 +300,22 @@ send_unicast_packet(struct neighbour *neigh, unsigned char *buf, int buflen)
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
int rc; int rc;
memset(&sin6, 0, sizeof(sin6)); if(check_bucket(neigh->network)) {
sin6.sin6_family = AF_INET6; memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6.sin6_addr, neigh->address, 16); sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(protocol_port); memcpy(&sin6.sin6_addr, neigh->address, 16);
sin6.sin6_scope_id = neigh->network->ifindex; sin6.sin6_port = htons(protocol_port);
rc = babel_send(protocol_socket, sin6.sin6_scope_id = neigh->network->ifindex;
packet_header, sizeof(packet_header), rc = babel_send(protocol_socket,
buf, buflen, packet_header, sizeof(packet_header),
(struct sockaddr*)&sin6, sizeof(sin6)); buf, buflen,
if(rc < 0) (struct sockaddr*)&sin6, sizeof(sin6));
perror("send(unicast)"); if(rc < 0)
perror("send(unicast)");
} else {
fprintf(stderr, "Warning: bucket full, dropping packet to %s.\n",
neigh->network->ifname);
}
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment