Commit aaa2c581 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Merge branch 'multiple-local-interfaces'

parents 21fff6b7 f0c4ea01
...@@ -88,9 +88,6 @@ struct timeval check_neighbours_timeout, check_interfaces_timeout; ...@@ -88,9 +88,6 @@ struct timeval check_neighbours_timeout, check_interfaces_timeout;
static volatile sig_atomic_t exiting = 0, dumping = 0, reopening = 0; static volatile sig_atomic_t exiting = 0, dumping = 0, reopening = 0;
int local_server_socket = -1, local_socket = -1;
int local_server_port = -1;
static int kernel_routes_callback(int changed, void *closure); static int kernel_routes_callback(int changed, void *closure);
static void init_signals(void); static void init_signals(void);
static void dump_tables(FILE *out); static void dump_tables(FILE *out);
...@@ -568,13 +565,15 @@ main(int argc, char **argv) ...@@ -568,13 +565,15 @@ main(int argc, char **argv)
maxfd = MAX(maxfd, kernel_socket); maxfd = MAX(maxfd, kernel_socket);
} }
#ifndef NO_LOCAL_INTERFACE #ifndef NO_LOCAL_INTERFACE
if(local_socket >= 0) { if(local_server_socket >= 0 &&
FD_SET(local_socket, &readfds); num_local_sockets < MAX_LOCAL_SOCKETS) {
maxfd = MAX(maxfd, local_socket);
} else if(local_server_socket >= 0) {
FD_SET(local_server_socket, &readfds); FD_SET(local_server_socket, &readfds);
maxfd = MAX(maxfd, local_server_socket); maxfd = MAX(maxfd, local_server_socket);
} }
for(i = 0; i < num_local_sockets; i++) {
FD_SET(local_sockets[i], &readfds);
maxfd = MAX(maxfd, local_sockets[i]);
}
#endif #endif
rc = select(maxfd + 1, &readfds, NULL, NULL, &tv); rc = select(maxfd + 1, &readfds, NULL, NULL, &tv);
if(rc < 0) { if(rc < 0) {
...@@ -622,27 +621,38 @@ main(int argc, char **argv) ...@@ -622,27 +621,38 @@ main(int argc, char **argv)
#ifndef NO_LOCAL_INTERFACE #ifndef NO_LOCAL_INTERFACE
if(local_server_socket >= 0 && if(local_server_socket >= 0 &&
FD_ISSET(local_server_socket, &readfds)) { FD_ISSET(local_server_socket, &readfds)) {
if(local_socket >= 0) { int s;
close(local_socket); s = accept(local_server_socket, NULL, NULL);
local_socket = -1; if(s < 0) {
}
local_socket = accept(local_server_socket, NULL, NULL);
if(local_socket < 0) {
if(errno != EINTR && errno != EAGAIN) if(errno != EINTR && errno != EAGAIN)
perror("accept(local_server_socket)"); perror("accept(local_server_socket)");
} else if(num_local_sockets >= MAX_LOCAL_SOCKETS) {
/* This should never happen, since we don't select for
the server socket in this case. But I'm paranoid. */
fprintf(stderr, "Internal error: too many local sockets.\n");
close(s);
} else { } else {
local_notify_all(); local_sockets[num_local_sockets++] = s;
local_notify_all_1(s);
} }
} }
if(local_socket >= 0 && FD_ISSET(local_socket, &readfds)) { i = 0;
rc = local_read(local_socket); while(i < num_local_sockets) {
if(rc <= 0) { if(FD_ISSET(local_sockets[i], &readfds)) {
if(rc < 0) rc = local_read(local_sockets[i]);
perror("read(local_socket)"); if(rc <= 0) {
close(local_socket); if(rc < 0) {
local_socket = -1; if(errno == EINTR)
continue;
perror("read(local_socket)");
}
close(local_sockets[i]);
local_sockets[i] = local_sockets[--num_local_sockets];
continue;
}
} }
i++;
} }
#endif #endif
......
...@@ -87,7 +87,6 @@ extern int default_wireless_hello_interval, default_wired_hello_interval; ...@@ -87,7 +87,6 @@ extern int default_wireless_hello_interval, default_wired_hello_interval;
extern int resend_delay; extern int resend_delay;
extern int link_detect; extern int link_detect;
extern int all_wireless; extern int all_wireless;
extern int local_socket;
extern unsigned char myid[8]; extern unsigned char myid[8];
......
...@@ -41,6 +41,10 @@ int dummy; ...@@ -41,6 +41,10 @@ int dummy;
#else #else
int local_server_socket = -1, local_sockets[MAX_LOCAL_SOCKETS];
int num_local_sockets = 0;
int local_server_port = -1;
int int
local_read(int s) local_read(int s)
{ {
...@@ -88,15 +92,12 @@ write_timeout(int fd, const void *buf, int len) ...@@ -88,15 +92,12 @@ write_timeout(int fd, const void *buf, int len)
} }
void void
local_notify_self() local_notify_self_1(int s)
{ {
char buf[512]; char buf[512];
char host[64]; char host[64];
int rc; int rc;
if(local_socket < 0)
return;
rc = gethostname(host, 64); rc = gethostname(host, 64);
if(rc < 0) if(rc < 0)
...@@ -108,13 +109,13 @@ local_notify_self() ...@@ -108,13 +109,13 @@ local_notify_self()
if(rc < 0 || rc >= 512) if(rc < 0 || rc >= 512)
goto fail; goto fail;
rc = write_timeout(local_socket, buf, rc); rc = write_timeout(s, buf, rc);
if(rc < 0) if(rc < 0)
goto fail; goto fail;
return; return;
fail: fail:
shutdown(local_socket, 1); shutdown(s, 1);
return; return;
} }
...@@ -129,14 +130,11 @@ local_kind(int kind) ...@@ -129,14 +130,11 @@ local_kind(int kind)
} }
} }
void static void
local_notify_neighbour(struct neighbour *neigh, int kind) local_notify_neighbour_1(int s, struct neighbour *neigh, int kind)
{ {
char buf[512]; char buf[512];
int rc; int rc;
if(local_socket < 0)
return;
rc = snprintf(buf, 512, rc = snprintf(buf, 512,
"%s neighbour %lx address %s " "%s neighbour %lx address %s "
...@@ -155,53 +153,63 @@ local_notify_neighbour(struct neighbour *neigh, int kind) ...@@ -155,53 +153,63 @@ local_notify_neighbour(struct neighbour *neigh, int kind)
if(rc < 0 || rc >= 512) if(rc < 0 || rc >= 512)
goto fail; goto fail;
rc = write_timeout(local_socket, buf, rc); rc = write_timeout(s, buf, rc);
if(rc < 0) if(rc < 0)
goto fail; goto fail;
return; return;
fail: fail:
shutdown(local_socket, 1); shutdown(s, 1);
return; return;
} }
void void
local_notify_xroute(struct xroute *xroute, int kind) local_notify_neighbour(struct neighbour *neigh, int kind)
{
int i;
for(i = 0; i < num_local_sockets; i++)
local_notify_neighbour_1(local_sockets[i], neigh, kind);
}
static void
local_notify_xroute_1(int s, struct xroute *xroute, int kind)
{ {
char buf[512]; char buf[512];
int rc; int rc;
if(local_socket < 0)
return;
rc = snprintf(buf, 512, "%s xroute %s prefix %s metric %d\n", rc = snprintf(buf, 512, "%s xroute %s prefix %s metric %d\n",
local_kind(kind), local_kind(kind),
format_prefix(xroute->prefix, xroute->plen), format_prefix(xroute->prefix, xroute->plen),
format_prefix(xroute->prefix, xroute->plen), format_prefix(xroute->prefix, xroute->plen),
xroute->metric); xroute->metric);
if(rc < 0 || rc >= 512) if(rc < 0 || rc >= 512)
goto fail; goto fail;
rc = write_timeout(local_socket, buf, rc); rc = write_timeout(s, buf, rc);
if(rc < 0) if(rc < 0)
goto fail; goto fail;
return; return;
fail: fail:
shutdown(local_socket, 1); shutdown(s, 1);
return; return;
} }
void void
local_notify_route(struct babel_route *route, int kind) local_notify_xroute(struct xroute *xroute, int kind)
{
int i;
for(i = 0; i < num_local_sockets; i++)
local_notify_xroute_1(local_sockets[i], xroute, kind);
}
static void
local_notify_route_1(int s, struct babel_route *route, int kind)
{ {
char buf[512]; char buf[512];
int rc; int rc;
if(local_socket < 0)
return;
rc = snprintf(buf, 512, rc = snprintf(buf, 512,
"%s route %s-%lx prefix %s installed %s " "%s route %s-%lx prefix %s installed %s "
"id %s metric %d refmetric %d via %s if %s\n", "id %s metric %d refmetric %d via %s if %s\n",
...@@ -214,59 +222,64 @@ local_notify_route(struct babel_route *route, int kind) ...@@ -214,59 +222,64 @@ local_notify_route(struct babel_route *route, int kind)
route_metric(route), route->refmetric, route_metric(route), route->refmetric,
format_address(route->neigh->address), format_address(route->neigh->address),
route->neigh->ifp->name); route->neigh->ifp->name);
if(rc < 0 || rc >= 512) if(rc < 0 || rc >= 512)
goto fail; goto fail;
rc = write_timeout(local_socket, buf, rc); rc = write_timeout(s, buf, rc);
if(rc < 0) if(rc < 0)
goto fail; goto fail;
return; return;
fail: fail:
shutdown(local_socket, 1); shutdown(s, 1);
return; return;
} }
void
local_notify_route(struct babel_route *route, int kind)
{
int i;
for(i = 0; i < num_local_sockets; i++)
local_notify_route_1(local_sockets[i], route, kind);
}
static void static void
local_notify_xroute_callback(struct xroute *xroute, void *closure) local_notify_xroute_callback(struct xroute *xroute, void *closure)
{ {
local_notify_xroute(xroute, LOCAL_ADD); local_notify_xroute_1(*(int*)closure, xroute, LOCAL_ADD);
} }
static void static void
local_notify_route_callback(struct babel_route *route, void *closure) local_notify_route_callback(struct babel_route *route, void *closure)
{ {
local_notify_route(route, LOCAL_ADD); local_notify_route_1(*(int*)closure, route, LOCAL_ADD);
} }
void void
local_notify_all() local_notify_all_1(int s)
{ {
int rc; int rc;
struct neighbour *neigh; struct neighbour *neigh;
const char *header = "BABEL 0.0\n"; const char *header = "BABEL 0.0\n";
if(local_socket < 0) rc = write_timeout(s, header, strlen(header));
return;
rc = write_timeout(local_socket, header, strlen(header));
if(rc < 0) if(rc < 0)
goto fail; goto fail;
local_notify_self(); local_notify_self_1(s);
FOR_ALL_NEIGHBOURS(neigh) { FOR_ALL_NEIGHBOURS(neigh) {
local_notify_neighbour(neigh, LOCAL_ADD); local_notify_neighbour_1(s, neigh, LOCAL_ADD);
} }
for_all_xroutes(local_notify_xroute_callback, NULL); for_all_xroutes(local_notify_xroute_callback, &s);
for_all_routes(local_notify_route_callback, NULL); for_all_routes(local_notify_route_callback, &s);
rc = write_timeout(local_socket, "done\n", 5); rc = write_timeout(s, "done\n", 5);
if(rc < 0) if(rc < 0)
goto fail; goto fail;
return; return;
fail: fail:
shutdown(local_socket, 1); shutdown(s, 1);
return; return;
} }
......
...@@ -30,16 +30,22 @@ struct xroute; ...@@ -30,16 +30,22 @@ struct xroute;
#ifndef NO_LOCAL_INTERFACE #ifndef NO_LOCAL_INTERFACE
#ifndef MAX_LOCAL_SOCKETS
#define MAX_LOCAL_SOCKETS 4
#endif
extern int local_server_socket, local_sockets[MAX_LOCAL_SOCKETS];
extern int num_local_sockets;
extern int local_server_port;
int local_read(int s); int local_read(int s);
void local_notify_self(void);
void local_notify_neighbour(struct neighbour *neigh, int kind); void local_notify_neighbour(struct neighbour *neigh, int kind);
void local_notify_xroute(struct xroute *xroute, int kind); void local_notify_xroute(struct xroute *xroute, int kind);
void local_notify_route(struct babel_route *route, int kind); void local_notify_route(struct babel_route *route, int kind);
void local_notify_all(void); void local_notify_all_1(int s);
#else #else
#define local_notify_self() do {} while(0)
#define local_notify_neighbour(n, k) do {} while(0) #define local_notify_neighbour(n, k) do {} while(0)
#define local_notify_xroute(x, k) do {} while(0) #define local_notify_xroute(x, k) do {} while(0)
#define local_notify_route(r, k) do {} while(0) #define local_notify_route(r, k) do {} while(0)
......
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