respondd: max multicast delay is now interface based
This commit is contained in:
parent
a856465520
commit
5d27574616
|
@ -52,6 +52,14 @@
|
||||||
|
|
||||||
#define SCHEDULE_LEN 8
|
#define SCHEDULE_LEN 8
|
||||||
#define REQUEST_MAXLEN 256
|
#define REQUEST_MAXLEN 256
|
||||||
|
#define MAX_MULTICAST_DELAY_DEFAULT 10000
|
||||||
|
|
||||||
|
struct interface_delay_info {
|
||||||
|
struct interface_delay_info *next;
|
||||||
|
|
||||||
|
unsigned int ifindex;
|
||||||
|
uint64_t max_multicast_delay;
|
||||||
|
};
|
||||||
|
|
||||||
struct provider_list {
|
struct provider_list {
|
||||||
struct provider_list *next;
|
struct provider_list *next;
|
||||||
|
@ -95,7 +103,8 @@ static void usage() {
|
||||||
puts(" -p <int> port number to listen on");
|
puts(" -p <int> port number to listen on");
|
||||||
puts(" -g <ip6> multicast group, e.g. ff02::2:1001");
|
puts(" -g <ip6> multicast group, e.g. ff02::2:1001");
|
||||||
puts(" -i <string> interface on which the group is joined");
|
puts(" -i <string> interface on which the group is joined");
|
||||||
puts(" -t <int> maximum delay seconds before multicast responses (default: 10)");
|
puts(" -t <int> maximum delay seconds before multicast responses");
|
||||||
|
puts(" for the last specified mulicast interface (default: 10)");
|
||||||
puts(" -d <string> data provider directory (default: current directory)");
|
puts(" -d <string> data provider directory (default: current directory)");
|
||||||
puts(" -h this help\n");
|
puts(" -h this help\n");
|
||||||
}
|
}
|
||||||
|
@ -443,13 +452,14 @@ void serve_request(struct request_task *task, int sock) {
|
||||||
* will be also sent immediately.
|
* will be also sent immediately.
|
||||||
*/
|
*/
|
||||||
static void accept_request(struct request_schedule *schedule, int sock,
|
static void accept_request(struct request_schedule *schedule, int sock,
|
||||||
uint64_t max_multicast_delay) {
|
struct interface_delay_info *if_delay_info_list) {
|
||||||
char input[REQUEST_MAXLEN];
|
char input[REQUEST_MAXLEN];
|
||||||
ssize_t input_bytes;
|
ssize_t input_bytes;
|
||||||
struct sockaddr_in6 addr;
|
struct sockaddr_in6 addr;
|
||||||
char control[256];
|
char control[256];
|
||||||
struct in6_addr destaddr = {};
|
struct in6_addr destaddr = {};
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
unsigned int ifindex;
|
||||||
|
|
||||||
int64_t timeout = schedule_idle_time(schedule);
|
int64_t timeout = schedule_idle_time(schedule);
|
||||||
if (timeout < 0)
|
if (timeout < 0)
|
||||||
|
@ -498,19 +508,29 @@ static void accept_request(struct request_schedule *schedule, int sock,
|
||||||
|
|
||||||
struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg);
|
struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg);
|
||||||
destaddr = pi->ipi6_addr;
|
destaddr = pi->ipi6_addr;
|
||||||
|
ifindex = pi->ipi6_ifindex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[input_bytes] = 0;
|
input[input_bytes] = 0;
|
||||||
|
|
||||||
|
// get the max delay
|
||||||
|
uint64_t max_multicast_delay = MAX_MULTICAST_DELAY_DEFAULT;
|
||||||
|
struct interface_delay_info *tmp = if_delay_info_list;
|
||||||
|
for (; tmp; tmp = tmp->next) {
|
||||||
|
if (tmp->ifindex == ifindex)
|
||||||
|
max_multicast_delay = tmp->max_multicast_delay;
|
||||||
|
}
|
||||||
|
|
||||||
struct request_task *new_task = malloc(sizeof(*new_task));
|
struct request_task *new_task = malloc(sizeof(*new_task));
|
||||||
new_task->scheduled_time = now + rand() % max_multicast_delay;
|
// the ternary operator avoids division by 0
|
||||||
|
new_task->scheduled_time = max_multicast_delay ? now + rand() % max_multicast_delay : 0;
|
||||||
strncpy(new_task->request, input, input_bytes + 1);
|
strncpy(new_task->request, input, input_bytes + 1);
|
||||||
new_task->request[input_bytes] = 0;
|
new_task->request[input_bytes] = 0;
|
||||||
new_task->client_addr = addr;
|
new_task->client_addr = addr;
|
||||||
|
|
||||||
bool is_scheduled;
|
bool is_scheduled;
|
||||||
if(IN6_IS_ADDR_MULTICAST(&destaddr))
|
if(new_task->scheduled_time && IN6_IS_ADDR_MULTICAST(&destaddr))
|
||||||
// scheduling could fail because the schedule is full
|
// scheduling could fail because the schedule is full
|
||||||
is_scheduled = schedule_push_request(schedule, new_task);
|
is_scheduled = schedule_push_request(schedule, new_task);
|
||||||
else
|
else
|
||||||
|
@ -557,7 +577,9 @@ int main(int argc, char **argv) {
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
|
|
||||||
int group_set = 0;
|
int group_set = 0;
|
||||||
uint64_t max_multicast_delay = 10000;
|
bool iface_set = false;
|
||||||
|
unsigned int last_ifindex = 0;
|
||||||
|
struct interface_delay_info *if_delay_info_list = NULL;
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
while ((c = getopt(argc, argv, "p:g:t:i:d:h")) != -1) {
|
while ((c = getopt(argc, argv, "p:g:t:i:d:h")) != -1) {
|
||||||
|
@ -580,15 +602,31 @@ int main(int argc, char **argv) {
|
||||||
fprintf(stderr, "Multicast group must be given before interface.\n");
|
fprintf(stderr, "Multicast group must be given before interface.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
iface_set = true;
|
||||||
|
last_ifindex = if_nametoindex(optarg);
|
||||||
join_mcast(sock, mgroup_addr, optarg);
|
join_mcast(sock, mgroup_addr, optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
max_multicast_delay = 1000 * strtoul(optarg, &endptr, 10);
|
if (!iface_set) {
|
||||||
|
fprintf(stderr, "Interface must be given before max response delay.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t max_multicast_delay = 1000 * strtoul(optarg, &endptr, 10);
|
||||||
if (!*optarg || *endptr || max_multicast_delay > INT64_MAX) {
|
if (!*optarg || *endptr || max_multicast_delay > INT64_MAX) {
|
||||||
fprintf(stderr, "Invalid multicast delay\n");
|
fprintf(stderr, "Invalid multicast delay\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface_delay_info **pos = &if_delay_info_list;
|
||||||
|
// walk to the end of the list
|
||||||
|
for(; *pos; pos = &((*pos)->next)) {}
|
||||||
|
*pos = malloc(sizeof(*if_delay_info_list));
|
||||||
|
(*pos)->ifindex = last_ifindex;
|
||||||
|
(*pos)->max_multicast_delay = max_multicast_delay;
|
||||||
|
(*pos)->next = NULL;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -618,7 +656,7 @@ int main(int argc, char **argv) {
|
||||||
struct request_schedule schedule = {};
|
struct request_schedule schedule = {};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
accept_request(&schedule, sock, max_multicast_delay);
|
accept_request(&schedule, sock, if_delay_info_list);
|
||||||
|
|
||||||
struct request_task *task = schedule_pop_request(&schedule);
|
struct request_task *task = schedule_pop_request(&schedule);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue