mirror of
https://github.com/neocturne/fastd.git
synced 2025-05-14 20:25:08 +02:00
Refactor bind address configuration
This commit is contained in:
parent
921485a5bc
commit
80cbd0c9bd
5 changed files with 172 additions and 188 deletions
43
src/config.c
43
src/config.c
|
@ -224,6 +224,22 @@ bool fastd_config_crypto(fastd_context *ctx, fastd_config *conf, const char *alg
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fastd_config_bind_address(fastd_context *ctx, fastd_config *conf, const fastd_peer_address *address, const char *bindtodev, bool default_v4, bool default_v6) {
|
||||||
|
fastd_bind_address *addr = malloc(sizeof(fastd_bind_address));
|
||||||
|
addr->next = conf->bind_addrs;
|
||||||
|
conf->bind_addrs = addr;
|
||||||
|
conf->n_bind_addrs++;
|
||||||
|
|
||||||
|
addr->addr = *address;
|
||||||
|
addr->bindtodev = bindtodev ? strdup(bindtodev) : NULL;
|
||||||
|
|
||||||
|
if (address->sa.sa_family != AF_INET6 && (default_v4 || !conf->bind_addr_default_v4))
|
||||||
|
conf->bind_addr_default_v4 = addr;
|
||||||
|
|
||||||
|
if (address->sa.sa_family != AF_INET && (default_v6 || !conf->bind_addr_default_v6))
|
||||||
|
conf->bind_addr_default_v6 = addr;
|
||||||
|
}
|
||||||
|
|
||||||
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level) {
|
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level) {
|
||||||
char *name2 = strdup(name);
|
char *name2 = strdup(name);
|
||||||
char *name3 = strdup(name);
|
char *name3 = strdup(name);
|
||||||
|
@ -418,6 +434,7 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
|
||||||
}
|
}
|
||||||
|
|
||||||
static void count_peers(fastd_context *ctx, fastd_config *conf) {
|
static void count_peers(fastd_context *ctx, fastd_config *conf) {
|
||||||
|
conf->n_peers = 0;
|
||||||
conf->n_floating = 0;
|
conf->n_floating = 0;
|
||||||
conf->n_v4 = 0;
|
conf->n_v4 = 0;
|
||||||
conf->n_v6 = 0;
|
conf->n_v6 = 0;
|
||||||
|
@ -427,6 +444,8 @@ static void count_peers(fastd_context *ctx, fastd_config *conf) {
|
||||||
|
|
||||||
fastd_peer_config *peer;
|
fastd_peer_config *peer;
|
||||||
for (peer = conf->peers; peer; peer = peer->next) {
|
for (peer = conf->peers; peer; peer = peer->next) {
|
||||||
|
conf->n_peers++;
|
||||||
|
|
||||||
switch (peer->address.sa.sa_family) {
|
switch (peer->address.sa.sa_family) {
|
||||||
case AF_UNSPEC:
|
case AF_UNSPEC:
|
||||||
if (peer->hostname)
|
if (peer->hostname)
|
||||||
|
@ -629,35 +648,29 @@ static void option_bind(fastd_context *ctx, fastd_config *conf, const char *arg)
|
||||||
l = 0;
|
l = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fastd_bind_address *addr = calloc(1, sizeof(fastd_bind_address));
|
fastd_peer_address addr = {};
|
||||||
addr->next = conf->bind_addrs;
|
|
||||||
conf->bind_addrs = addr;
|
|
||||||
|
|
||||||
if (strcmp(addrstr, "any") == 0) {
|
if (strcmp(addrstr, "any") == 0) {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
}
|
}
|
||||||
else if (arg[0] == '[') {
|
else if (arg[0] == '[') {
|
||||||
addr->addr.in6.sin6_family = AF_INET6;
|
addr.in6.sin6_family = AF_INET6;
|
||||||
addr->addr.in6.sin6_port = htons(l);
|
addr.in6.sin6_port = htons(l);
|
||||||
|
|
||||||
if (inet_pton(AF_INET6, addrstr, &addr->addr.in6.sin6_addr) != 1)
|
if (inet_pton(AF_INET6, addrstr, &addr.in6.sin6_addr) != 1)
|
||||||
exit_error(ctx, "invalid bind address `%s'", addrstr);
|
exit_error(ctx, "invalid bind address `%s'", addrstr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addr->addr.in.sin_family = AF_INET;
|
addr.in.sin_family = AF_INET;
|
||||||
addr->addr.in.sin_port = htons(l);
|
addr.in.sin_port = htons(l);
|
||||||
|
|
||||||
if (inet_pton(AF_INET, addrstr, &addr->addr.in.sin_addr) != 1)
|
if (inet_pton(AF_INET, addrstr, &addr.in.sin_addr) != 1)
|
||||||
exit_error(ctx, "invalid bind address `%s'", addrstr);
|
exit_error(ctx, "invalid bind address `%s'", addrstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conf->bind_addr_default_v4 && addr->addr.sa.sa_family != AF_INET6)
|
|
||||||
conf->bind_addr_default_v4 = addr;
|
|
||||||
|
|
||||||
if (!conf->bind_addr_default_v6 && addr->addr.sa.sa_family != AF_INET)
|
|
||||||
conf->bind_addr_default_v6 = addr;
|
|
||||||
|
|
||||||
free(addrstr);
|
free(addrstr);
|
||||||
|
|
||||||
|
fastd_config_bind_address(ctx, conf, &addr, NULL, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void option_protocol(fastd_context *ctx, fastd_config *conf, const char *arg) {
|
static void option_protocol(fastd_context *ctx, fastd_config *conf, const char *arg) {
|
||||||
|
|
|
@ -104,12 +104,12 @@ default { TOKEN(TOK_DEFAULT); }
|
||||||
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
|
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
|
||||||
UPDATE_LOCATION;
|
UPDATE_LOCATION;
|
||||||
|
|
||||||
if (!inet_pton(AF_INET, yytext, &yylval->addr)) {
|
if (!inet_pton(AF_INET, yytext, &yylval->addr4)) {
|
||||||
yylval->error = "invalid address";
|
yylval->error = "invalid address";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TOK_ADDR;
|
return TOK_ADDR4;
|
||||||
}
|
}
|
||||||
|
|
||||||
[;:\{\}] { UPDATE_LOCATION; return yytext[0]; }
|
[;:\{\}] { UPDATE_LOCATION; return yytext[0]; }
|
||||||
|
|
77
src/config.y
77
src/config.y
|
@ -45,8 +45,9 @@
|
||||||
fastd_string_stack *str;
|
fastd_string_stack *str;
|
||||||
char *error;
|
char *error;
|
||||||
bool boolean;
|
bool boolean;
|
||||||
struct in_addr addr;
|
struct in_addr addr4;
|
||||||
struct in6_addr addr6;
|
struct in6_addr addr6;
|
||||||
|
fastd_peer_address addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token START_CONFIG
|
%token START_CONFIG
|
||||||
|
@ -99,7 +100,7 @@
|
||||||
%token TOK_USE
|
%token TOK_USE
|
||||||
%token TOK_DEFAULT
|
%token TOK_DEFAULT
|
||||||
|
|
||||||
%token <addr> TOK_ADDR
|
%token <addr4> TOK_ADDR4
|
||||||
%token <addr6> TOK_ADDR6
|
%token <addr6> TOK_ADDR6
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,6 +122,10 @@
|
||||||
%type <str> maybe_as
|
%type <str> maybe_as
|
||||||
%type <num> maybe_af
|
%type <num> maybe_af
|
||||||
%type <boolean> maybe_float
|
%type <boolean> maybe_float
|
||||||
|
%type <addr> bind_address
|
||||||
|
%type <str> maybe_bind_interface
|
||||||
|
%type <num> maybe_bind_default
|
||||||
|
%type <num> bind_default
|
||||||
|
|
||||||
%%
|
%%
|
||||||
start: START_CONFIG config
|
start: START_CONFIG config
|
||||||
|
@ -188,70 +193,50 @@ log_level: TOK_FATAL { $$ = LOG_CRIT; }
|
||||||
interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1->str); }
|
interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1->str); }
|
||||||
;
|
;
|
||||||
|
|
||||||
bind_new: {
|
bind: bind_address maybe_bind_interface maybe_bind_default {
|
||||||
fastd_bind_address *addr = calloc(1, sizeof(fastd_bind_address));
|
fastd_config_bind_address(ctx, conf, &$1, $2 ? $2->str : NULL, $3 == AF_UNSPEC || $3 == AF_INET, $3 == AF_UNSPEC || $3 == AF_INET6);
|
||||||
addr->next = conf->bind_addrs;
|
|
||||||
conf->bind_addrs = addr;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
bind: bind_new TOK_ADDR maybe_port maybe_bind_to_device maybe_bind_default {
|
bind_address:
|
||||||
conf->bind_addrs->addr.in.sin_family = AF_INET;
|
TOK_ADDR4 maybe_port {
|
||||||
conf->bind_addrs->addr.in.sin_addr = $2;
|
$$ = (fastd_peer_address){ .in = { .sin_family = AF_INET, .sin_addr = $1, .sin_port = htons($2) } };
|
||||||
conf->bind_addrs->addr.in.sin_port = htons($3);
|
|
||||||
if (!conf->bind_addr_default_v4)
|
|
||||||
conf->bind_addr_default_v4 = conf->bind_addrs;
|
|
||||||
}
|
}
|
||||||
| bind_new TOK_ADDR6 maybe_port maybe_bind_to_device maybe_bind_default {
|
| TOK_ADDR6 maybe_port {
|
||||||
conf->bind_addrs->addr.in6.sin6_family = AF_INET6;
|
$$ = (fastd_peer_address){ .in6 = { .sin6_family = AF_INET6, .sin6_addr = $1, .sin6_port = htons($2) } };
|
||||||
conf->bind_addrs->addr.in6.sin6_addr = $2;
|
|
||||||
conf->bind_addrs->addr.in6.sin6_port = htons($3);
|
|
||||||
if (!conf->bind_addr_default_v6)
|
|
||||||
conf->bind_addr_default_v6 = conf->bind_addrs;
|
|
||||||
}
|
}
|
||||||
| bind_new TOK_ANY maybe_port maybe_bind_to_device maybe_bind_default {
|
| TOK_ANY maybe_port {
|
||||||
conf->bind_addrs->addr.in.sin_port = htons($3);
|
$$ = (fastd_peer_address){ .in = { .sin_family = AF_UNSPEC, .sin_port = htons($2) } };
|
||||||
if (!conf->bind_addr_default_v4)
|
|
||||||
conf->bind_addr_default_v4 = conf->bind_addrs;
|
|
||||||
if (!conf->bind_addr_default_v6)
|
|
||||||
conf->bind_addr_default_v6 = conf->bind_addrs;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
maybe_bind_to_device:
|
maybe_bind_interface:
|
||||||
TOK_INTERFACE TOK_STRING {
|
TOK_INTERFACE TOK_STRING {
|
||||||
conf->bind_addrs->bindtodev = strdup($2->str);
|
$$ = $2;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
;
|
;
|
||||||
|
|
||||||
maybe_bind_default:
|
maybe_bind_default:
|
||||||
TOK_DEFAULT bind_default
|
TOK_DEFAULT bind_default {
|
||||||
|
|
$$ = $2;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
$$ = -1;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
bind_default:
|
bind_default:
|
||||||
TOK_IPV4 {
|
TOK_IPV4 {
|
||||||
if (conf->bind_addrs->addr.sa.sa_family == AF_INET6) {
|
$$ = AF_INET;
|
||||||
fastd_config_error(&@$, ctx, conf, filename, depth, "tried to set IPv6 bind as IPv4 default");
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
conf->bind_addr_default_v4 = conf->bind_addrs;
|
|
||||||
}
|
}
|
||||||
| TOK_IPV6 {
|
| TOK_IPV6 {
|
||||||
if (conf->bind_addrs->addr.sa.sa_family == AF_INET) {
|
$$ = AF_INET6;
|
||||||
fastd_config_error(&@$, ctx, conf, filename, depth, "tried to set IPv4 bind as IPv6 default");
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
conf->bind_addr_default_v6 = conf->bind_addrs;
|
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
if (conf->bind_addrs->addr.sa.sa_family != AF_INET6)
|
$$ = AF_UNSPEC;
|
||||||
conf->bind_addr_default_v4 = conf->bind_addrs;
|
|
||||||
if (conf->bind_addrs->addr.sa.sa_family != AF_INET)
|
|
||||||
conf->bind_addr_default_v6 = conf->bind_addrs;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -340,7 +325,7 @@ peer_statement: TOK_REMOTE peer_remote ';'
|
||||||
| TOK_INCLUDE peer_include ';'
|
| TOK_INCLUDE peer_include ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
peer_remote: TOK_ADDR port {
|
peer_remote: TOK_ADDR4 port {
|
||||||
free(conf->peers->hostname);
|
free(conf->peers->hostname);
|
||||||
conf->peers->hostname = NULL;
|
conf->peers->hostname = NULL;
|
||||||
|
|
||||||
|
|
233
src/fastd.c
233
src/fastd.c
|
@ -147,140 +147,114 @@ static void crypto_free(fastd_context *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned max_sockets(const fastd_config *conf) {
|
|
||||||
unsigned n = 0;
|
|
||||||
fastd_bind_address *addr;
|
|
||||||
|
|
||||||
for (addr = conf->bind_addrs; addr; addr = addr->next)
|
|
||||||
n++;
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_sockets(fastd_context *ctx) {
|
static void init_sockets(fastd_context *ctx) {
|
||||||
static const fastd_bind_address bind_any = {};
|
ctx->socks = malloc(ctx->conf->n_bind_addrs * sizeof(fastd_socket));
|
||||||
|
|
||||||
const fastd_bind_address *addr = ctx->conf->bind_addrs;
|
unsigned i;
|
||||||
const fastd_bind_address *default_v4 = ctx->conf->bind_addr_default_v4;
|
fastd_bind_address *addr = ctx->conf->bind_addrs;
|
||||||
const fastd_bind_address *default_v6 = ctx->conf->bind_addr_default_v6;
|
for (i = 0; i < ctx->conf->n_bind_addrs; i++) {
|
||||||
|
ctx->socks[i] = (fastd_socket){-2, addr};
|
||||||
|
|
||||||
if (!addr)
|
if (addr == ctx->conf->bind_addr_default_v4)
|
||||||
addr = default_v4 = default_v6 = &bind_any;
|
ctx->sock_default_v4 = &ctx->socks[i];
|
||||||
|
|
||||||
unsigned n_v4 = 0, n_v6 = 0;
|
if (addr == ctx->conf->bind_addr_default_v6)
|
||||||
bool info_ipv6 = true;
|
ctx->sock_default_v6 = &ctx->socks[i];
|
||||||
|
|
||||||
ctx->socks = calloc(max_sockets(ctx->conf), sizeof(fastd_socket));
|
|
||||||
|
|
||||||
while (addr) {
|
|
||||||
int fd = -1;
|
|
||||||
int af = AF_UNSPEC;
|
|
||||||
|
|
||||||
if (addr->addr.sa.sa_family != AF_INET) {
|
|
||||||
fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (fd < 0) {
|
|
||||||
if (info_ipv6) {
|
|
||||||
pr_warn(ctx, "there seems to be no IPv6 support; explicitely bind to an IPv4 address (or 0.0.0.0) to disable this warning");
|
|
||||||
info_ipv6 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
af = AF_INET6;
|
|
||||||
|
|
||||||
int val = (addr->addr.sa.sa_family == AF_INET6);
|
|
||||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) {
|
|
||||||
pr_warn_errno(ctx, "setsockopt");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fd < 0 && addr->addr.sa.sa_family != AF_INET6) {
|
|
||||||
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (fd < 0)
|
|
||||||
exit_errno(ctx, "unable to create socket");
|
|
||||||
else
|
|
||||||
af = AF_INET;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (addr->bindtodev) {
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, addr->bindtodev, strlen(addr->bindtodev))) {
|
|
||||||
pr_warn_errno(ctx, "setsockopt: unable to bind to device");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fastd_peer_address bind_address = addr->addr;
|
|
||||||
|
|
||||||
if (bind_address.sa.sa_family == AF_UNSPEC) {
|
|
||||||
memset(&bind_address, 0, sizeof(bind_address));
|
|
||||||
bind_address.sa.sa_family = af;
|
|
||||||
|
|
||||||
if (af == AF_INET6)
|
|
||||||
bind_address.in6.sin6_port = addr->addr.in.sin_port;
|
|
||||||
else
|
|
||||||
bind_address.in.sin_port = addr->addr.in.sin_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr*)&bind_address, af == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) {
|
|
||||||
pr_warn(ctx, "bind");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->socks[ctx->n_socks] = (fastd_socket){fd, addr};
|
|
||||||
|
|
||||||
if (af == AF_INET6) {
|
|
||||||
if (addr == default_v6)
|
|
||||||
ctx->sock_default_v6 = &ctx->socks[ctx->n_socks];
|
|
||||||
|
|
||||||
n_v6++;
|
|
||||||
|
|
||||||
if (addr->addr.sa.sa_family == AF_UNSPEC) {
|
|
||||||
if (addr == default_v4)
|
|
||||||
ctx->sock_default_v4 = &ctx->socks[ctx->n_socks];
|
|
||||||
|
|
||||||
n_v4++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (addr == default_v4)
|
|
||||||
ctx->sock_default_v4 = &ctx->socks[ctx->n_socks];
|
|
||||||
|
|
||||||
n_v4++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->n_socks++;
|
|
||||||
|
|
||||||
addr = addr->next;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
error:
|
|
||||||
if (fd >= 0) {
|
|
||||||
if (close(fd))
|
|
||||||
pr_error_errno(ctx, "close");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr->bindtodev)
|
|
||||||
pr_warn(ctx, "unable to bind to %I on `%s'", &addr->addr, addr->bindtodev);
|
|
||||||
else
|
|
||||||
pr_warn(ctx, "unable to bind to %I", &addr->addr);
|
|
||||||
|
|
||||||
if (addr == default_v4 || addr == default_v6)
|
|
||||||
exit_error(ctx, "unable to bind to default address");
|
|
||||||
|
|
||||||
addr = addr->next;
|
addr = addr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx->n_socks)
|
ctx->n_socks = ctx->conf->n_bind_addrs;
|
||||||
exit_error(ctx, "all bind attempts failed");
|
}
|
||||||
|
|
||||||
if (!n_v4 && ctx->conf->n_v4)
|
static int bind_socket(fastd_context *ctx, const fastd_bind_address *addr, bool warn) {
|
||||||
pr_warn(ctx, "there are IPv4 peers defined, but there was no successful IPv4 bind");
|
int fd = -1;
|
||||||
|
int af = AF_UNSPEC;
|
||||||
|
|
||||||
if (!n_v6 && ctx->conf->n_v6)
|
if (addr->addr.sa.sa_family != AF_INET) {
|
||||||
pr_warn(ctx, "there are IPv6 peers defined, but there was no successful IPv4 bind");
|
fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (fd >= 0) {
|
||||||
|
af = AF_INET6;
|
||||||
|
|
||||||
|
int val = (addr->addr.sa.sa_family == AF_INET6);
|
||||||
|
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) {
|
||||||
|
if (warn)
|
||||||
|
pr_warn_errno(ctx, "setsockopt");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fd < 0 && addr->addr.sa.sa_family != AF_INET6) {
|
||||||
|
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (fd < 0)
|
||||||
|
exit_errno(ctx, "unable to create socket");
|
||||||
|
else
|
||||||
|
af = AF_INET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (addr->bindtodev) {
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, addr->bindtodev, strlen(addr->bindtodev))) {
|
||||||
|
if (warn)
|
||||||
|
pr_warn_errno(ctx, "setsockopt: unable to bind to device");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fastd_peer_address bind_address = addr->addr;
|
||||||
|
|
||||||
|
if (bind_address.sa.sa_family == AF_UNSPEC) {
|
||||||
|
memset(&bind_address, 0, sizeof(bind_address));
|
||||||
|
bind_address.sa.sa_family = af;
|
||||||
|
|
||||||
|
if (af == AF_INET6)
|
||||||
|
bind_address.in6.sin6_port = addr->addr.in.sin_port;
|
||||||
|
else
|
||||||
|
bind_address.in.sin_port = addr->addr.in.sin_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr*)&bind_address, af == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) {
|
||||||
|
if (warn)
|
||||||
|
pr_warn(ctx, "bind");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fd >= 0) {
|
||||||
|
if (close(fd))
|
||||||
|
pr_error_errno(ctx, "close");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warn) {
|
||||||
|
if (addr->bindtodev)
|
||||||
|
pr_warn(ctx, "unable to bind to %I on `%s'", &addr->addr, addr->bindtodev);
|
||||||
|
else
|
||||||
|
pr_warn(ctx, "unable to bind to %I", &addr->addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bind_sockets(fastd_context *ctx) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->n_socks; i++) {
|
||||||
|
if (ctx->socks[i].fd >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ctx->socks[i].fd = bind_socket(ctx, ctx->socks[i].addr, ctx->socks[i].fd < -1);
|
||||||
|
|
||||||
|
if (ctx->socks[i].fd >= 0) {
|
||||||
|
if (ctx->socks[i].addr->bindtodev)
|
||||||
|
pr_info(ctx, "successfully bound to %I on `%s'", &ctx->socks[i].addr->addr, ctx->socks[i].addr->bindtodev);
|
||||||
|
else
|
||||||
|
pr_info(ctx, "successfully bound to %I", &ctx->socks[i].addr->addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_tuntap(fastd_context *ctx) {
|
static void init_tuntap(fastd_context *ctx) {
|
||||||
|
@ -315,12 +289,17 @@ static void init_tuntap(fastd_context *ctx) {
|
||||||
|
|
||||||
ctx->ifname = strndup(ifr.ifr_name, IFNAMSIZ);
|
ctx->ifname = strndup(ifr.ifr_name, IFNAMSIZ);
|
||||||
|
|
||||||
int ctl_sock = ctx->socks[0].fd;
|
int ctl_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (ctl_sock < 0)
|
||||||
|
exit_errno(ctx, "socket");
|
||||||
|
|
||||||
ifr.ifr_mtu = ctx->conf->mtu;
|
ifr.ifr_mtu = ctx->conf->mtu;
|
||||||
if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0)
|
if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0)
|
||||||
exit_errno(ctx, "SIOCSIFMTU ioctl failed");
|
exit_errno(ctx, "SIOCSIFMTU ioctl failed");
|
||||||
|
|
||||||
|
if (close(ctl_sock))
|
||||||
|
pr_error_errno(ctx, "close");
|
||||||
|
|
||||||
pr_debug(ctx, "tun/tap device initialized.");
|
pr_debug(ctx, "tun/tap device initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,6 +903,8 @@ int main(int argc, char *argv[]) {
|
||||||
pr_info(&ctx, "fastd " FASTD_VERSION " starting");
|
pr_info(&ctx, "fastd " FASTD_VERSION " starting");
|
||||||
|
|
||||||
init_sockets(&ctx);
|
init_sockets(&ctx);
|
||||||
|
bind_sockets(&ctx);
|
||||||
|
|
||||||
init_tuntap(&ctx);
|
init_tuntap(&ctx);
|
||||||
|
|
||||||
init_peers(&ctx);
|
init_peers(&ctx);
|
||||||
|
@ -949,6 +930,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
while (!terminate) {
|
while (!terminate) {
|
||||||
handle_tasks(&ctx);
|
handle_tasks(&ctx);
|
||||||
|
|
||||||
|
bind_sockets(&ctx);
|
||||||
handle_input(&ctx);
|
handle_input(&ctx);
|
||||||
|
|
||||||
maintenance(&ctx);
|
maintenance(&ctx);
|
||||||
|
|
|
@ -160,6 +160,7 @@ struct _fastd_config {
|
||||||
|
|
||||||
char *ifname;
|
char *ifname;
|
||||||
|
|
||||||
|
unsigned n_bind_addrs;
|
||||||
fastd_bind_address *bind_addrs;
|
fastd_bind_address *bind_addrs;
|
||||||
|
|
||||||
fastd_bind_address *bind_addr_default_v4;
|
fastd_bind_address *bind_addr_default_v4;
|
||||||
|
@ -187,6 +188,7 @@ struct _fastd_config {
|
||||||
fastd_string_stack *peer_dirs;
|
fastd_string_stack *peer_dirs;
|
||||||
fastd_peer_config *peers;
|
fastd_peer_config *peers;
|
||||||
|
|
||||||
|
unsigned n_peers;
|
||||||
unsigned n_floating;
|
unsigned n_floating;
|
||||||
unsigned n_v4;
|
unsigned n_v4;
|
||||||
unsigned n_v6;
|
unsigned n_v6;
|
||||||
|
@ -277,6 +279,7 @@ bool fastd_config_protocol(fastd_context *ctx, fastd_config *conf, const char *n
|
||||||
bool fastd_config_method(fastd_context *ctx, fastd_config *conf, const char *name);
|
bool fastd_config_method(fastd_context *ctx, fastd_config *conf, const char *name);
|
||||||
bool fastd_config_crypto(fastd_context *ctx, fastd_config *conf, const char *alg, const char *impl);
|
bool fastd_config_crypto(fastd_context *ctx, fastd_config *conf, const char *alg, const char *impl);
|
||||||
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level);
|
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level);
|
||||||
|
void fastd_config_bind_address(fastd_context *ctx, fastd_config *conf, const fastd_peer_address *address, const char *bindtodev, bool default_v4, bool default_v6);
|
||||||
void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]);
|
void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]);
|
||||||
void fastd_reconfigure(fastd_context *ctx, fastd_config *conf);
|
void fastd_reconfigure(fastd_context *ctx, fastd_config *conf);
|
||||||
void fastd_config_release(fastd_context *ctx, fastd_config *conf);
|
void fastd_config_release(fastd_context *ctx, fastd_config *conf);
|
||||||
|
|
Loading…
Add table
Reference in a new issue