1998-05-24 14:50:18 +00:00
|
|
|
/*
|
|
|
|
* BIRD Internet Routing Daemon -- Unix I/O
|
|
|
|
*
|
2004-05-31 21:48:19 +00:00
|
|
|
* (c) 1998--2004 Martin Mares <mj@ucw.cz>
|
2004-05-31 13:25:00 +00:00
|
|
|
* (c) 2004 Ondrej Filip <feela@network.cz>
|
1998-05-24 14:50:18 +00:00
|
|
|
*
|
|
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
|
|
*/
|
|
|
|
|
2010-04-14 13:35:08 +00:00
|
|
|
/* Unfortunately, some glibc versions hide parts of RFC 3542 API
|
|
|
|
if _GNU_SOURCE is not defined. */
|
2016-11-08 16:46:29 +00:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif
|
2010-04-14 13:35:08 +00:00
|
|
|
|
1998-05-24 14:50:18 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2001-03-06 13:40:39 +00:00
|
|
|
#include <time.h>
|
2023-08-24 15:00:54 +00:00
|
|
|
#include <sys/mman.h>
|
1998-05-24 14:50:18 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
2023-08-21 16:44:10 +00:00
|
|
|
#include <sys/stat.h>
|
1998-05-24 14:50:18 +00:00
|
|
|
#include <sys/socket.h>
|
2010-04-03 08:45:21 +00:00
|
|
|
#include <sys/uio.h>
|
1999-10-29 12:09:29 +00:00
|
|
|
#include <sys/un.h>
|
2016-03-09 11:12:02 +00:00
|
|
|
#include <poll.h>
|
1998-05-24 14:50:18 +00:00
|
|
|
#include <unistd.h>
|
2013-07-24 12:20:46 +00:00
|
|
|
#include <fcntl.h>
|
1998-05-24 14:50:18 +00:00
|
|
|
#include <errno.h>
|
2014-05-18 09:42:26 +00:00
|
|
|
#include <net/if.h>
|
2011-03-23 16:15:11 +00:00
|
|
|
#include <netinet/in.h>
|
2014-02-06 16:46:01 +00:00
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <netinet/udp.h>
|
2011-03-13 10:33:50 +00:00
|
|
|
#include <netinet/icmp6.h>
|
2023-12-13 02:48:12 +00:00
|
|
|
#include <netdb.h>
|
1998-05-24 14:50:18 +00:00
|
|
|
|
|
|
|
#include "nest/bird.h"
|
|
|
|
#include "lib/lists.h"
|
|
|
|
#include "lib/resource.h"
|
|
|
|
#include "lib/socket.h"
|
1999-02-11 21:18:26 +00:00
|
|
|
#include "lib/event.h"
|
2021-02-04 14:52:42 +00:00
|
|
|
#include "lib/locking.h"
|
2017-05-30 17:12:35 +00:00
|
|
|
#include "lib/timer.h"
|
1999-12-01 11:59:00 +00:00
|
|
|
#include "lib/string.h"
|
1998-05-24 14:50:18 +00:00
|
|
|
#include "nest/iface.h"
|
2017-06-06 14:47:30 +00:00
|
|
|
#include "conf/conf.h"
|
1998-05-24 14:50:18 +00:00
|
|
|
|
2016-04-12 09:14:54 +00:00
|
|
|
#include "sysdep/unix/unix.h"
|
2021-06-19 18:50:18 +00:00
|
|
|
#include "sysdep/unix/io-loop.h"
|
1998-05-24 14:50:18 +00:00
|
|
|
|
2009-10-11 16:56:16 +00:00
|
|
|
/* Maximum number of calls of tx handler for one socket in one
|
2016-03-09 11:12:02 +00:00
|
|
|
* poll iteration. Should be small enough to not monopolize CPU by
|
2009-06-19 22:59:32 +00:00
|
|
|
* one protocol instance.
|
|
|
|
*/
|
|
|
|
#define MAX_STEPS 4
|
|
|
|
|
2016-03-09 11:12:02 +00:00
|
|
|
/* Maximum number of calls of rx handler for all sockets in one poll
|
2009-10-11 16:56:16 +00:00
|
|
|
iteration. RX callbacks are often much more costly so we limit
|
|
|
|
this to gen small latencies */
|
|
|
|
#define MAX_RX_STEPS 4
|
|
|
|
|
2024-08-28 13:43:15 +00:00
|
|
|
#if 0
|
|
|
|
/**********
|
|
|
|
* Internal event log for the mainloop only makes no sense.
|
|
|
|
* To be replaced by a lockless event log keeping much more information
|
|
|
|
* about all the logs throughout all the threads.
|
|
|
|
*/
|
2018-11-13 17:13:11 +00:00
|
|
|
|
2015-03-02 08:41:14 +00:00
|
|
|
/*
|
|
|
|
* Internal event log and watchdog
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define EVENT_LOG_LENGTH 32
|
|
|
|
|
|
|
|
struct event_log_entry
|
|
|
|
{
|
|
|
|
void *hook;
|
|
|
|
void *data;
|
|
|
|
btime timestamp;
|
|
|
|
btime duration;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct event_log_entry event_log[EVENT_LOG_LENGTH];
|
|
|
|
static struct event_log_entry *event_open;
|
|
|
|
static int event_log_pos, event_log_num, watchdog_active;
|
2021-08-04 20:48:51 +00:00
|
|
|
static btime last_io_time;
|
2015-03-02 08:41:14 +00:00
|
|
|
static btime loop_time;
|
|
|
|
|
|
|
|
static void
|
|
|
|
io_update_time(void)
|
|
|
|
{
|
2021-08-04 20:48:51 +00:00
|
|
|
last_io_time = current_time();
|
2015-03-02 08:41:14 +00:00
|
|
|
|
|
|
|
if (event_open)
|
|
|
|
{
|
2021-08-04 20:48:51 +00:00
|
|
|
event_open->duration = last_io_time - event_open->timestamp;
|
2015-03-02 08:41:14 +00:00
|
|
|
|
2024-06-13 14:30:51 +00:00
|
|
|
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
|
|
|
|
if (event_open->duration > gr->latency_limit)
|
2022-06-04 15:54:08 +00:00
|
|
|
log(L_WARN "Event 0x%p 0x%p took %u.%03u ms",
|
|
|
|
event_open->hook, event_open->data, (uint) (event_open->duration TO_MS), (uint) (event_open->duration % 1000));
|
2015-03-02 08:41:14 +00:00
|
|
|
|
|
|
|
event_open = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* io_log_event - mark approaching event into event log
|
|
|
|
* @hook: event hook address
|
|
|
|
* @data: event data address
|
|
|
|
*
|
|
|
|
* Store info (hook, data, timestamp) about the following internal event into
|
|
|
|
* a circular event log (@event_log). When latency tracking is enabled, the log
|
|
|
|
* entry is kept open (in @event_open) so the duration can be filled later.
|
|
|
|
*/
|
|
|
|
void
|
2024-06-07 10:12:00 +00:00
|
|
|
io_log_event(void *hook, void *data, uint flag)
|
2015-03-02 08:41:14 +00:00
|
|
|
{
|
2024-06-13 14:30:51 +00:00
|
|
|
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
|
|
|
|
if (gr->latency_debug & flag)
|
2015-03-02 08:41:14 +00:00
|
|
|
io_update_time();
|
|
|
|
|
|
|
|
struct event_log_entry *en = event_log + event_log_pos;
|
|
|
|
|
|
|
|
en->hook = hook;
|
|
|
|
en->data = data;
|
2021-08-04 20:48:51 +00:00
|
|
|
en->timestamp = last_io_time;
|
2015-03-02 08:41:14 +00:00
|
|
|
en->duration = 0;
|
|
|
|
|
|
|
|
event_log_num++;
|
|
|
|
event_log_pos++;
|
|
|
|
event_log_pos %= EVENT_LOG_LENGTH;
|
|
|
|
|
2024-06-13 14:30:51 +00:00
|
|
|
event_open = (gr->latency_debug & flag) ? en : NULL;
|
2015-03-02 08:41:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
io_close_event(void)
|
|
|
|
{
|
|
|
|
if (event_open)
|
|
|
|
io_update_time();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
io_log_dump(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
log(L_DEBUG "Event log:");
|
|
|
|
for (i = 0; i < EVENT_LOG_LENGTH; i++)
|
|
|
|
{
|
|
|
|
struct event_log_entry *en = event_log + (event_log_pos + i) % EVENT_LOG_LENGTH;
|
|
|
|
if (en->hook)
|
|
|
|
log(L_DEBUG " Event 0x%p 0x%p at %8d for %d ms", en->hook, en->data,
|
2021-08-04 20:48:51 +00:00
|
|
|
(int) ((last_io_time - en->timestamp) TO_MS), (int) (en->duration TO_MS));
|
2015-03-02 08:41:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-28 13:43:15 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static btime last_io_time, loop_time;
|
|
|
|
static int watchdog_active;
|
|
|
|
|
2015-03-02 08:41:14 +00:00
|
|
|
void
|
|
|
|
watchdog_sigalrm(int sig UNUSED)
|
|
|
|
{
|
2021-08-04 20:48:51 +00:00
|
|
|
/* Update last_io_time and duration, but skip latency check */
|
2024-06-13 14:30:51 +00:00
|
|
|
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
|
|
|
|
gr->latency_limit = 0xffffffff;
|
2024-08-28 13:43:15 +00:00
|
|
|
|
|
|
|
last_io_time = current_time_now();
|
2015-03-02 08:41:14 +00:00
|
|
|
|
2023-01-12 16:40:53 +00:00
|
|
|
debug_safe("Watchdog timer timed out\n");
|
|
|
|
|
2015-03-02 08:41:14 +00:00
|
|
|
/* We want core dump */
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
watchdog_start1(void)
|
|
|
|
{
|
2024-08-28 13:43:15 +00:00
|
|
|
loop_time = last_io_time = current_time_now();
|
2015-03-02 08:41:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
watchdog_start(void)
|
|
|
|
{
|
2024-08-28 13:43:15 +00:00
|
|
|
loop_time = last_io_time = current_time_now();
|
|
|
|
// event_log_num = 0;
|
2015-03-02 08:41:14 +00:00
|
|
|
|
2024-08-27 15:50:30 +00:00
|
|
|
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
|
2024-06-13 14:30:51 +00:00
|
|
|
if (gr->watchdog_timeout)
|
2015-03-02 08:41:14 +00:00
|
|
|
{
|
2024-06-13 14:30:51 +00:00
|
|
|
alarm(gr->watchdog_timeout);
|
2015-03-02 08:41:14 +00:00
|
|
|
watchdog_active = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
watchdog_stop(void)
|
|
|
|
{
|
2024-08-28 13:43:15 +00:00
|
|
|
last_io_time = current_time_now();
|
2015-03-02 08:41:14 +00:00
|
|
|
|
|
|
|
if (watchdog_active)
|
|
|
|
{
|
|
|
|
alarm(0);
|
|
|
|
watchdog_active = 0;
|
|
|
|
}
|
|
|
|
|
2021-08-04 20:48:51 +00:00
|
|
|
btime duration = last_io_time - loop_time;
|
2024-08-27 15:50:30 +00:00
|
|
|
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
|
2024-08-28 13:43:15 +00:00
|
|
|
/*
|
2024-06-13 14:30:51 +00:00
|
|
|
if (duration > gr->watchdog_warning)
|
2022-06-04 15:54:08 +00:00
|
|
|
log(L_WARN "I/O loop cycle took %u.%03u ms for %d events",
|
|
|
|
(uint) (duration TO_MS), (uint) (duration % 1000), event_log_num);
|
2024-08-28 13:43:15 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
if (duration > gr->watchdog_warning)
|
|
|
|
log(L_WARN "I/O loop cycle took %u.%03u ms",
|
|
|
|
(uint) (duration TO_MS), (uint) (duration % 1000));
|
2015-03-02 08:41:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-05-24 14:50:18 +00:00
|
|
|
/*
|
|
|
|
* Main I/O Loop
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
io_init(void)
|
|
|
|
{
|
2023-02-24 08:13:35 +00:00
|
|
|
init_list(&main_birdloop.sock_list);
|
2021-06-19 18:50:18 +00:00
|
|
|
ev_init_list(&global_event_list, &main_birdloop, "Global event list");
|
|
|
|
ev_init_list(&global_work_list, &main_birdloop, "Global work list");
|
|
|
|
ev_init_list(&main_birdloop.event_list, &main_birdloop, "Global fast event list");
|
1999-03-26 21:44:38 +00:00
|
|
|
krt_io_init();
|
2017-06-01 10:33:20 +00:00
|
|
|
// XXX init_times();
|
|
|
|
// XXX update_times();
|
|
|
|
boot_time = current_time();
|
2018-05-03 15:07:39 +00:00
|
|
|
|
|
|
|
u64 now = (u64) current_real_time();
|
|
|
|
srandom((uint) (now ^ (now >> 32)));
|
1998-05-24 14:50:18 +00:00
|
|
|
}
|
|
|
|
|
2009-10-11 16:56:16 +00:00
|
|
|
static int short_loops = 0;
|
|
|
|
#define SHORT_LOOP_MAX 10
|
2021-03-12 14:35:56 +00:00
|
|
|
#define WORK_EVENTS_MAX 10
|
2009-10-11 16:56:16 +00:00
|
|
|
|
2024-08-27 13:04:32 +00:00
|
|
|
extern sock *stored_sock; /* mainloop hack */
|
2023-04-02 17:15:22 +00:00
|
|
|
|
2024-08-22 16:55:53 +00:00
|
|
|
int sk_read(sock *s, int revents);
|
|
|
|
int sk_write(sock *s);
|
|
|
|
void sk_err(sock *s, int revents);
|
|
|
|
|
1998-05-24 14:50:18 +00:00
|
|
|
void
|
|
|
|
io_loop(void)
|
|
|
|
{
|
2017-05-31 13:46:04 +00:00
|
|
|
int poll_tout, timeout;
|
2023-02-24 08:13:35 +00:00
|
|
|
int events, pout;
|
2017-11-28 16:43:20 +00:00
|
|
|
timer *t;
|
2023-02-24 08:13:35 +00:00
|
|
|
struct pfd pfd;
|
|
|
|
BUFFER_INIT(pfd.pfd, &root_pool, 16);
|
|
|
|
BUFFER_INIT(pfd.loop, &root_pool, 16);
|
1998-05-24 14:50:18 +00:00
|
|
|
|
2015-03-02 08:41:14 +00:00
|
|
|
watchdog_start1();
|
1998-05-24 14:50:18 +00:00
|
|
|
for(;;)
|
|
|
|
{
|
2021-08-04 20:48:51 +00:00
|
|
|
times_update();
|
2023-10-04 15:36:03 +00:00
|
|
|
ev_run_list(&global_event_list);
|
|
|
|
ev_run_list_limited(&global_work_list, WORK_EVENTS_MAX);
|
2024-01-28 12:40:23 +00:00
|
|
|
ev_run_list(&main_birdloop.event_list);
|
2024-08-28 13:43:15 +00:00
|
|
|
timers_fire(&main_birdloop.time);
|
|
|
|
// io_close_event();
|
2015-03-02 08:41:14 +00:00
|
|
|
|
2024-01-28 12:40:23 +00:00
|
|
|
events =
|
|
|
|
!ev_list_empty(&global_event_list) ||
|
|
|
|
!ev_list_empty(&global_work_list) ||
|
|
|
|
!ev_list_empty(&main_birdloop.event_list);
|
|
|
|
|
2017-06-01 10:33:20 +00:00
|
|
|
poll_tout = (events ? 0 : 3000); /* Time in milliseconds */
|
2021-06-19 18:50:18 +00:00
|
|
|
if (t = timers_first(&main_birdloop.time))
|
2017-05-31 13:46:04 +00:00
|
|
|
{
|
2021-08-04 20:48:51 +00:00
|
|
|
times_update();
|
2017-11-28 16:43:20 +00:00
|
|
|
timeout = (tm_remains(t) TO_MS) + 1;
|
2017-05-31 13:46:04 +00:00
|
|
|
poll_tout = MIN(poll_tout, timeout);
|
|
|
|
}
|
|
|
|
|
2023-02-24 08:13:35 +00:00
|
|
|
BUFFER_FLUSH(pfd.pfd);
|
|
|
|
BUFFER_FLUSH(pfd.loop);
|
2021-02-08 08:51:59 +00:00
|
|
|
|
2023-02-24 08:13:35 +00:00
|
|
|
pipe_pollin(&main_birdloop.thread->wakeup, &pfd);
|
|
|
|
sockets_prepare(&main_birdloop, &pfd);
|
1998-05-24 14:50:18 +00:00
|
|
|
|
1999-02-13 19:43:21 +00:00
|
|
|
/*
|
|
|
|
* Yes, this is racy. But even if the signal comes before this test
|
2016-03-09 11:12:02 +00:00
|
|
|
* and entering poll(), it gets caught on the next timer tick.
|
1999-02-13 19:43:21 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
if (async_config_flag)
|
|
|
|
{
|
2024-08-28 13:43:15 +00:00
|
|
|
// io_log_event(async_config, NULL, DL_EVENTS);
|
1999-02-13 19:43:21 +00:00
|
|
|
async_config();
|
|
|
|
async_config_flag = 0;
|
1999-02-13 20:15:36 +00:00
|
|
|
continue;
|
1999-02-13 19:43:21 +00:00
|
|
|
}
|
|
|
|
if (async_dump_flag)
|
|
|
|
{
|
2024-08-28 13:43:15 +00:00
|
|
|
// io_log_event(async_dump, NULL, DL_EVENTS);
|
1999-02-13 19:43:21 +00:00
|
|
|
async_dump();
|
|
|
|
async_dump_flag = 0;
|
1999-02-13 20:15:36 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (async_shutdown_flag)
|
|
|
|
{
|
2024-08-28 13:43:15 +00:00
|
|
|
// io_log_event(async_shutdown, NULL, DL_EVENTS);
|
1999-02-13 20:15:36 +00:00
|
|
|
async_shutdown();
|
|
|
|
async_shutdown_flag = 0;
|
|
|
|
continue;
|
1999-02-13 19:43:21 +00:00
|
|
|
}
|
|
|
|
|
2016-03-09 11:12:02 +00:00
|
|
|
/* And finally enter poll() to find active sockets */
|
2015-03-02 08:41:14 +00:00
|
|
|
watchdog_stop();
|
2021-06-19 18:50:18 +00:00
|
|
|
birdloop_leave(&main_birdloop);
|
2023-02-24 08:13:35 +00:00
|
|
|
pout = poll(pfd.pfd.data, pfd.pfd.used, poll_tout);
|
2021-06-19 18:50:18 +00:00
|
|
|
birdloop_enter(&main_birdloop);
|
2015-03-02 08:41:14 +00:00
|
|
|
watchdog_start();
|
2009-10-11 16:56:16 +00:00
|
|
|
|
2016-03-30 14:21:32 +00:00
|
|
|
if (pout < 0)
|
1998-05-24 14:50:18 +00:00
|
|
|
{
|
|
|
|
if (errno == EINTR || errno == EAGAIN)
|
|
|
|
continue;
|
2022-10-05 14:26:13 +00:00
|
|
|
bug("poll: %m");
|
1998-05-24 14:50:18 +00:00
|
|
|
}
|
2016-03-30 14:21:32 +00:00
|
|
|
if (pout)
|
1998-05-24 14:50:18 +00:00
|
|
|
{
|
2023-02-24 08:13:35 +00:00
|
|
|
if (pfd.pfd.data[0].revents & POLLIN)
|
2021-02-08 08:51:59 +00:00
|
|
|
{
|
|
|
|
/* IO loop reload requested */
|
2023-01-19 09:49:47 +00:00
|
|
|
pipe_drain(&main_birdloop.thread->wakeup);
|
2023-02-24 08:13:35 +00:00
|
|
|
atomic_fetch_and_explicit(&main_birdloop.thread_transition, ~LTT_PING, memory_order_acq_rel);
|
2021-02-08 08:51:59 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-08-04 20:48:51 +00:00
|
|
|
times_update();
|
2017-05-31 13:46:04 +00:00
|
|
|
|
2009-10-11 16:56:16 +00:00
|
|
|
/* guaranteed to be non-empty */
|
2023-04-02 17:15:22 +00:00
|
|
|
main_birdloop.sock_active = SKIP_BACK(sock, n, HEAD(main_birdloop.sock_list));
|
2009-10-11 16:56:16 +00:00
|
|
|
|
2023-04-02 17:15:22 +00:00
|
|
|
while (main_birdloop.sock_active)
|
|
|
|
{
|
|
|
|
sock *s = main_birdloop.sock_active;
|
|
|
|
if (s->index != -1)
|
1998-05-24 14:50:18 +00:00
|
|
|
{
|
2004-05-31 21:48:19 +00:00
|
|
|
int e;
|
2009-10-11 16:56:16 +00:00
|
|
|
int steps;
|
|
|
|
|
|
|
|
steps = MAX_STEPS;
|
2023-02-24 08:13:35 +00:00
|
|
|
if (s->fast_rx && (pfd.pfd.data[s->index].revents & POLLIN) && s->rx_hook)
|
2004-05-31 21:48:19 +00:00
|
|
|
do
|
|
|
|
{
|
2009-06-19 22:59:32 +00:00
|
|
|
steps--;
|
2024-08-28 13:43:15 +00:00
|
|
|
// io_log_event(s->rx_hook, s->data, DL_SOCKETS);
|
2023-02-24 08:13:35 +00:00
|
|
|
e = sk_read(s, pfd.pfd.data[s->index].revents);
|
2004-05-31 21:48:19 +00:00
|
|
|
}
|
2023-04-02 17:15:22 +00:00
|
|
|
while (e && (main_birdloop.sock_active == s) && s->rx_hook && steps);
|
|
|
|
|
|
|
|
if (s != main_birdloop.sock_active)
|
|
|
|
continue;
|
2009-06-19 22:59:32 +00:00
|
|
|
|
|
|
|
steps = MAX_STEPS;
|
2023-02-24 08:13:35 +00:00
|
|
|
if (pfd.pfd.data[s->index].revents & POLLOUT)
|
2004-05-31 21:48:19 +00:00
|
|
|
do
|
|
|
|
{
|
2009-06-19 22:59:32 +00:00
|
|
|
steps--;
|
2024-08-28 13:43:15 +00:00
|
|
|
// io_log_event(s->tx_hook, s->data, DL_SOCKETS);
|
2004-05-31 21:48:19 +00:00
|
|
|
e = sk_write(s);
|
|
|
|
}
|
2023-04-02 17:15:22 +00:00
|
|
|
while (e && (main_birdloop.sock_active == s) && steps);
|
2016-05-30 12:28:22 +00:00
|
|
|
|
2023-04-02 17:15:22 +00:00
|
|
|
if (s != main_birdloop.sock_active)
|
|
|
|
continue;
|
1998-05-24 14:50:18 +00:00
|
|
|
}
|
2009-10-11 16:56:16 +00:00
|
|
|
|
2023-04-02 17:15:22 +00:00
|
|
|
main_birdloop.sock_active = sk_next(s);
|
|
|
|
}
|
|
|
|
|
2009-10-11 16:56:16 +00:00
|
|
|
short_loops++;
|
|
|
|
if (events && (short_loops < SHORT_LOOP_MAX))
|
|
|
|
continue;
|
|
|
|
short_loops = 0;
|
|
|
|
|
|
|
|
int count = 0;
|
2023-04-02 17:15:22 +00:00
|
|
|
main_birdloop.sock_active = stored_sock;
|
|
|
|
if (main_birdloop.sock_active == NULL)
|
|
|
|
main_birdloop.sock_active = SKIP_BACK(sock, n, HEAD(main_birdloop.sock_list));
|
2009-10-11 16:56:16 +00:00
|
|
|
|
2023-04-02 17:15:22 +00:00
|
|
|
while (main_birdloop.sock_active && count < MAX_RX_STEPS)
|
2009-10-11 16:56:16 +00:00
|
|
|
{
|
2023-04-02 17:15:22 +00:00
|
|
|
sock *s = main_birdloop.sock_active;
|
2016-03-09 11:12:02 +00:00
|
|
|
if (s->index == -1)
|
2023-04-02 17:15:22 +00:00
|
|
|
goto next2;
|
2009-10-11 16:56:16 +00:00
|
|
|
|
2023-02-24 08:13:35 +00:00
|
|
|
if (!s->fast_rx && (pfd.pfd.data[s->index].revents & POLLIN) && s->rx_hook)
|
2009-10-11 16:56:16 +00:00
|
|
|
{
|
|
|
|
count++;
|
2024-08-28 13:43:15 +00:00
|
|
|
// io_log_event(s->rx_hook, s->data, DL_SOCKETS);
|
2023-02-24 08:13:35 +00:00
|
|
|
sk_read(s, pfd.pfd.data[s->index].revents);
|
2023-04-02 17:15:22 +00:00
|
|
|
if (s != main_birdloop.sock_active)
|
|
|
|
continue;
|
2009-10-11 16:56:16 +00:00
|
|
|
}
|
2016-05-30 12:28:22 +00:00
|
|
|
|
2023-02-24 08:13:35 +00:00
|
|
|
if (pfd.pfd.data[s->index].revents & (POLLHUP | POLLERR))
|
2016-05-30 12:28:22 +00:00
|
|
|
{
|
2023-02-24 08:13:35 +00:00
|
|
|
sk_err(s, pfd.pfd.data[s->index].revents);
|
2023-04-02 17:15:22 +00:00
|
|
|
if (s != main_birdloop.sock_active)
|
|
|
|
continue;
|
2009-10-11 16:56:16 +00:00
|
|
|
}
|
2016-05-30 12:28:22 +00:00
|
|
|
|
2009-10-11 16:56:16 +00:00
|
|
|
next2: ;
|
2023-04-02 17:15:22 +00:00
|
|
|
main_birdloop.sock_active = sk_next(s);
|
2009-10-11 16:56:16 +00:00
|
|
|
}
|
|
|
|
|
2016-05-30 12:28:22 +00:00
|
|
|
|
2023-04-02 17:15:22 +00:00
|
|
|
stored_sock = main_birdloop.sock_active;
|
1998-05-24 14:50:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-06-06 17:05:25 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
test_old_bird(char *path)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
struct sockaddr_un sa;
|
|
|
|
|
|
|
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (fd < 0)
|
|
|
|
die("Cannot create socket: %m");
|
2010-03-17 11:19:22 +00:00
|
|
|
if (strlen(path) >= sizeof(sa.sun_path))
|
|
|
|
die("Socket path too long");
|
2004-06-06 17:05:25 +00:00
|
|
|
bzero(&sa, sizeof(sa));
|
|
|
|
sa.sun_family = AF_UNIX;
|
|
|
|
strcpy(sa.sun_path, path);
|
|
|
|
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == 0)
|
|
|
|
die("I found another BIRD running.");
|
|
|
|
close(fd);
|
|
|
|
}
|
2023-12-13 02:48:12 +00:00
|
|
|
|