mirror of
https://github.com/neocturne/fastd.git
synced 2025-05-14 20:25:08 +02:00
Add support for defining the MTU per peer
This commit is contained in:
parent
14a991a1ce
commit
9ef4d441ad
10 changed files with 104 additions and 63 deletions
|
@ -609,6 +609,7 @@ static void peer_dirs_read_peer_group(fastd_peer_group_t *group) {
|
||||||
/** Initializes the configured peers */
|
/** Initializes the configured peers */
|
||||||
static void configure_peers(bool dirs_only) {
|
static void configure_peers(bool dirs_only) {
|
||||||
ctx.has_floating = false;
|
ctx.has_floating = false;
|
||||||
|
ctx.max_mtu = conf.mtu;
|
||||||
|
|
||||||
ssize_t i;
|
ssize_t i;
|
||||||
for (i = VECTOR_LEN(ctx.peers)-1; i >= 0; i--) {
|
for (i = VECTOR_LEN(ctx.peers)-1; i >= 0; i--) {
|
||||||
|
@ -634,6 +635,9 @@ static void configure_peers(bool dirs_only) {
|
||||||
if (fastd_peer_is_floating(peer))
|
if (fastd_peer_is_floating(peer))
|
||||||
ctx.has_floating = true;
|
ctx.has_floating = true;
|
||||||
|
|
||||||
|
if (conf.mode != MODE_TAP && peer->mtu > ctx.max_mtu)
|
||||||
|
ctx.max_mtu = peer->mtu;
|
||||||
|
|
||||||
peer->config_state = CONFIG_STATIC;
|
peer->config_state = CONFIG_STATIC;
|
||||||
|
|
||||||
if (!fastd_peer_is_established(peer)) {
|
if (!fastd_peer_is_established(peer)) {
|
||||||
|
|
10
src/config.y
10
src/config.y
|
@ -478,6 +478,7 @@ peer_statement: TOK_REMOTE peer_remote ';'
|
||||||
| TOK_FLOAT peer_float ';'
|
| TOK_FLOAT peer_float ';'
|
||||||
| TOK_KEY peer_key ';'
|
| TOK_KEY peer_key ';'
|
||||||
| TOK_INTERFACE peer_interface ';'
|
| TOK_INTERFACE peer_interface ';'
|
||||||
|
| TOK_MTU peer_mtu ';'
|
||||||
| TOK_INCLUDE peer_include ';'
|
| TOK_INCLUDE peer_include ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -550,6 +551,15 @@ peer_interface: TOK_STRING {
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
peer_mtu: TOK_UINT {
|
||||||
|
if ($1 < 576 || $1 > 65535) {
|
||||||
|
fastd_config_error(&@$, state, "invalid MTU");
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->peer->mtu = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
peer_include: TOK_STRING {
|
peer_include: TOK_STRING {
|
||||||
if (!fastd_config_read($1->str, state->peer_group, state->peer, state->depth))
|
if (!fastd_config_read($1->str, state->peer_group, state->peer, state->depth))
|
||||||
YYERROR;
|
YYERROR;
|
||||||
|
|
|
@ -159,6 +159,7 @@ struct fastd_iface {
|
||||||
fastd_poll_fd_t fd; /**< The file descriptor of the tunnel interface */
|
fastd_poll_fd_t fd; /**< The file descriptor of the tunnel interface */
|
||||||
char *name; /**< The interface name */
|
char *name; /**< The interface name */
|
||||||
fastd_peer_t *peer; /**< The peer associated with the interface (if any) */
|
fastd_peer_t *peer; /**< The peer associated with the interface (if any) */
|
||||||
|
uint16_t mtu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -301,6 +302,7 @@ struct fastd_context {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool has_floating; /**< Specifies if any of the configured peers have floating remotes */
|
bool has_floating; /**< Specifies if any of the configured peers have floating remotes */
|
||||||
|
uint16_t max_mtu; /**< The maximum MTU of all peer-specific interfaces */
|
||||||
|
|
||||||
uint32_t peer_addr_ht_seed; /**< The hash seed used for peer_addr_ht */
|
uint32_t peer_addr_ht_seed; /**< The hash seed used for peer_addr_ht */
|
||||||
size_t peer_addr_ht_size; /**< The number of hash buckets in the peer address hashtable */
|
size_t peer_addr_ht_size; /**< The number of hash buckets in the peer address hashtable */
|
||||||
|
@ -416,13 +418,13 @@ static inline void fastd_setnonblock(int fd) {
|
||||||
|
|
||||||
|
|
||||||
/** Returns the maximum payload size \em fastd is configured to transport */
|
/** Returns the maximum payload size \em fastd is configured to transport */
|
||||||
static inline size_t fastd_max_payload(void) {
|
static inline size_t fastd_max_payload(uint16_t mtu) {
|
||||||
switch (conf.mode) {
|
switch (conf.mode) {
|
||||||
case MODE_TAP:
|
case MODE_TAP:
|
||||||
case MODE_MULTITAP:
|
case MODE_MULTITAP:
|
||||||
return conf.mtu+ETH_HLEN;
|
return mtu+ETH_HLEN;
|
||||||
case MODE_TUN:
|
case MODE_TUN:
|
||||||
return conf.mtu;
|
return mtu;
|
||||||
default:
|
default:
|
||||||
exit_bug("invalid mode");
|
exit_bug("invalid mode");
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ static fastd_string_stack_t * parse_string_list(const uint8_t *data, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Allocates and initializes a new handshake packet */
|
/** Allocates and initializes a new handshake packet */
|
||||||
static fastd_handshake_buffer_t new_handshake(uint8_t type, bool little_endian, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space) {
|
static fastd_handshake_buffer_t new_handshake(uint8_t type, bool little_endian, uint16_t mtu, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space) {
|
||||||
size_t version_len = strlen(FASTD_VERSION);
|
size_t version_len = strlen(FASTD_VERSION);
|
||||||
size_t protocol_len = strlen(conf.protocol->name);
|
size_t protocol_len = strlen(conf.protocol->name);
|
||||||
size_t method_len = method ? strlen(method->name) : 0;
|
size_t method_len = method ? strlen(method->name) : 0;
|
||||||
|
@ -190,7 +190,7 @@ static fastd_handshake_buffer_t new_handshake(uint8_t type, bool little_endian,
|
||||||
fastd_handshake_buffer_t buffer = {
|
fastd_handshake_buffer_t buffer = {
|
||||||
.buffer = fastd_buffer_alloc(sizeof(fastd_handshake_packet_t), 1,
|
.buffer = fastd_buffer_alloc(sizeof(fastd_handshake_packet_t), 1,
|
||||||
3*5 + /* handshake type, mode, reply code */
|
3*5 + /* handshake type, mode, reply code */
|
||||||
6 + /* MTU */
|
(mtu ? 6 : 0) + /* MTU */
|
||||||
4+version_len + /* version name */
|
4+version_len + /* version name */
|
||||||
4+protocol_len + /* protocol name */
|
4+protocol_len + /* protocol name */
|
||||||
4+method_len + /* method name */
|
4+method_len + /* method name */
|
||||||
|
@ -204,7 +204,9 @@ static fastd_handshake_buffer_t new_handshake(uint8_t type, bool little_endian,
|
||||||
|
|
||||||
fastd_handshake_add_uint8(&buffer, RECORD_HANDSHAKE_TYPE, type);
|
fastd_handshake_add_uint8(&buffer, RECORD_HANDSHAKE_TYPE, type);
|
||||||
fastd_handshake_add_uint8(&buffer, RECORD_MODE, get_mode_id());
|
fastd_handshake_add_uint8(&buffer, RECORD_MODE, get_mode_id());
|
||||||
fastd_handshake_add_uint16_endian(&buffer, RECORD_MTU, conf.mtu);
|
|
||||||
|
if (mtu)
|
||||||
|
fastd_handshake_add_uint16_endian(&buffer, RECORD_MTU, mtu);
|
||||||
|
|
||||||
fastd_handshake_add(&buffer, RECORD_VERSION_NAME, version_len, FASTD_VERSION);
|
fastd_handshake_add(&buffer, RECORD_VERSION_NAME, version_len, FASTD_VERSION);
|
||||||
fastd_handshake_add(&buffer, RECORD_PROTOCOL_NAME, protocol_len, conf.protocol->name);
|
fastd_handshake_add(&buffer, RECORD_PROTOCOL_NAME, protocol_len, conf.protocol->name);
|
||||||
|
@ -222,18 +224,18 @@ static fastd_handshake_buffer_t new_handshake(uint8_t type, bool little_endian,
|
||||||
|
|
||||||
/** Allocates and initializes a new initial handshake packet */
|
/** Allocates and initializes a new initial handshake packet */
|
||||||
fastd_handshake_buffer_t fastd_handshake_new_init(size_t tail_space) {
|
fastd_handshake_buffer_t fastd_handshake_new_init(size_t tail_space) {
|
||||||
return new_handshake(1, true, NULL, conf.secure_handshakes ? NULL : conf.peer_group->methods, tail_space);
|
return new_handshake(1, true, 0, NULL, conf.secure_handshakes ? NULL : conf.peer_group->methods, tail_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Allocates and initializes a new reply handshake packet */
|
/** Allocates and initializes a new reply handshake packet */
|
||||||
fastd_handshake_buffer_t fastd_handshake_new_reply(uint8_t type, bool little_endian, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space) {
|
fastd_handshake_buffer_t fastd_handshake_new_reply(uint8_t type, bool little_endian, uint16_t mtu, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space) {
|
||||||
fastd_handshake_buffer_t buffer = new_handshake(type, little_endian, method, methods, tail_space);
|
fastd_handshake_buffer_t buffer = new_handshake(type, little_endian, mtu, method, methods, tail_space);
|
||||||
fastd_handshake_add_uint8(&buffer, RECORD_REPLY_CODE, 0);
|
fastd_handshake_add_uint8(&buffer, RECORD_REPLY_CODE, 0);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prints the error corresponding to the given reply code and error detail */
|
/** Prints the error corresponding to the given reply code and error detail */
|
||||||
static void print_error(const char *prefix, const fastd_peer_address_t *remote_addr, uint8_t reply_code, uint16_t error_detail) {
|
static void print_error(const char *prefix, const fastd_peer_t *peer, const fastd_peer_address_t *remote_addr, uint8_t reply_code, uint16_t error_detail) {
|
||||||
const char *error_field_str;
|
const char *error_field_str;
|
||||||
|
|
||||||
if (error_detail >= RECORD_MAX)
|
if (error_detail >= RECORD_MAX)
|
||||||
|
@ -260,7 +262,7 @@ static void print_error(const char *prefix, const fastd_peer_address_t *remote_a
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RECORD_MTU:
|
case RECORD_MTU:
|
||||||
pr_warn("Handshake with %I failed: %s error: MTU configuration differs with peer (local MTU is %u)", remote_addr, prefix, conf.mtu);
|
pr_warn("Handshake with %I failed: %s error: MTU configuration differs with peer (local MTU is %u)", remote_addr, prefix, fastd_peer_get_mtu(peer));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RECORD_METHOD_NAME:
|
case RECORD_METHOD_NAME:
|
||||||
|
@ -281,7 +283,7 @@ static void print_error(const char *prefix, const fastd_peer_address_t *remote_a
|
||||||
|
|
||||||
/** Sends an error reply to a peer */
|
/** Sends an error reply to a peer */
|
||||||
void fastd_handshake_send_error(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, uint8_t reply_code, uint16_t error_detail) {
|
void fastd_handshake_send_error(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, uint8_t reply_code, uint16_t error_detail) {
|
||||||
print_error("sending", remote_addr, reply_code, error_detail);
|
print_error("sending", peer, remote_addr, reply_code, error_detail);
|
||||||
|
|
||||||
fastd_handshake_buffer_t buffer = {
|
fastd_handshake_buffer_t buffer = {
|
||||||
.buffer = fastd_buffer_alloc(sizeof(fastd_handshake_packet_t), 0, 3*5 /* enough space for handshake type, reply code and error detail */),
|
.buffer = fastd_buffer_alloc(sizeof(fastd_handshake_packet_t), 0, 3*5 /* enough space for handshake type, reply code and error detail */),
|
||||||
|
@ -355,14 +357,14 @@ static inline fastd_handshake_t parse_tlvs(const fastd_buffer_t *buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prints the error found in a received handshake */
|
/** Prints the error found in a received handshake */
|
||||||
static inline void print_error_reply(const fastd_peer_address_t *remote_addr, const fastd_handshake_t *handshake) {
|
static inline void print_error_reply(const fastd_peer_t *peer, const fastd_peer_address_t *remote_addr, const fastd_handshake_t *handshake) {
|
||||||
uint8_t reply_code = as_uint8(&handshake->records[RECORD_REPLY_CODE]);
|
uint8_t reply_code = as_uint8(&handshake->records[RECORD_REPLY_CODE]);
|
||||||
uint16_t error_detail = RECORD_MAX;
|
uint16_t error_detail = RECORD_MAX;
|
||||||
|
|
||||||
if (handshake->records[RECORD_ERROR_DETAIL].length == 1 || handshake->records[RECORD_ERROR_DETAIL].length == 2)
|
if (handshake->records[RECORD_ERROR_DETAIL].length == 1 || handshake->records[RECORD_ERROR_DETAIL].length == 2)
|
||||||
error_detail = as_uint(&handshake->records[RECORD_ERROR_DETAIL]);
|
error_detail = as_uint(&handshake->records[RECORD_ERROR_DETAIL]);
|
||||||
|
|
||||||
print_error("received", remote_addr, reply_code, error_detail);
|
print_error("received", peer, remote_addr, reply_code, error_detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Does some basic validity checks on a received handshake */
|
/** Does some basic validity checks on a received handshake */
|
||||||
|
@ -381,15 +383,6 @@ static inline bool check_records(fastd_socket_t *sock, const fastd_peer_address_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conf.secure_handshakes || handshake->type > 1) {
|
|
||||||
if (handshake->records[RECORD_MTU].length == 2) {
|
|
||||||
if (as_uint16_endian(&handshake->records[RECORD_MTU], handshake->little_endian) != conf.mtu) {
|
|
||||||
fastd_handshake_send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_MTU);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handshake->type > 1) {
|
if (handshake->type > 1) {
|
||||||
if (handshake->records[RECORD_REPLY_CODE].length != 1) {
|
if (handshake->records[RECORD_REPLY_CODE].length != 1) {
|
||||||
pr_warn("received handshake reply without reply code from %I", remote_addr);
|
pr_warn("received handshake reply without reply code from %I", remote_addr);
|
||||||
|
@ -397,7 +390,18 @@ static inline bool check_records(fastd_socket_t *sock, const fastd_peer_address_
|
||||||
}
|
}
|
||||||
|
|
||||||
if (as_uint8(&handshake->records[RECORD_REPLY_CODE]) != REPLY_SUCCESS) {
|
if (as_uint8(&handshake->records[RECORD_REPLY_CODE]) != REPLY_SUCCESS) {
|
||||||
print_error_reply(remote_addr, handshake);
|
print_error_reply(peer, remote_addr, handshake);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fastd_handshake_check_mtu(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake) {
|
||||||
|
if (handshake->records[RECORD_MTU].length == 2) {
|
||||||
|
if (as_uint16_endian(&handshake->records[RECORD_MTU], handshake->little_endian) != fastd_peer_get_mtu(peer)) {
|
||||||
|
fastd_handshake_send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_MTU);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,9 +100,10 @@ struct fastd_handshake_buffer {
|
||||||
|
|
||||||
|
|
||||||
fastd_handshake_buffer_t fastd_handshake_new_init(size_t tail_space);
|
fastd_handshake_buffer_t fastd_handshake_new_init(size_t tail_space);
|
||||||
fastd_handshake_buffer_t fastd_handshake_new_reply(uint8_t type, bool little_endian, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space);
|
fastd_handshake_buffer_t fastd_handshake_new_reply(uint8_t type, bool little_endian, uint16_t mtu, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space);
|
||||||
|
|
||||||
void fastd_handshake_send_error(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, uint8_t reply_code, uint16_t error_detail);
|
void fastd_handshake_send_error(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, uint8_t reply_code, uint16_t error_detail);
|
||||||
|
bool fastd_handshake_check_mtu(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake);
|
||||||
const fastd_method_info_t * fastd_handshake_get_method(const fastd_peer_t *peer, const fastd_handshake_t *handshake);
|
const fastd_method_info_t * fastd_handshake_get_method(const fastd_peer_t *peer, const fastd_handshake_t *handshake);
|
||||||
void fastd_handshake_handle(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer);
|
void fastd_handshake_handle(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer);
|
||||||
|
|
||||||
|
|
61
src/iface.c
61
src/iface.c
|
@ -87,13 +87,13 @@ static inline fastd_iface_type_t get_iface_type(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void open_iface(fastd_iface_t *iface, const char *ifname);
|
static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
/** Opens the TUN/TAP device helper shared by Android and Linux targets */
|
/** Opens the TUN/TAP device helper shared by Android and Linux targets */
|
||||||
static void open_iface_linux(fastd_iface_t *iface, const char *ifname, const char *dev_name) {
|
static void open_iface_linux(fastd_iface_t *iface, const char *ifname, uint16_t mtu, const char *dev_name) {
|
||||||
int ctl_sock = -1;
|
int ctl_sock = -1;
|
||||||
struct ifreq ifr = {};
|
struct ifreq ifr = {};
|
||||||
|
|
||||||
|
@ -132,8 +132,8 @@ static void open_iface_linux(fastd_iface_t *iface, const char *ifname, const cha
|
||||||
if (ioctl(ctl_sock, SIOCGIFMTU, &ifr) < 0)
|
if (ioctl(ctl_sock, SIOCGIFMTU, &ifr) < 0)
|
||||||
exit_errno("SIOCGIFMTU ioctl failed");
|
exit_errno("SIOCGIFMTU ioctl failed");
|
||||||
|
|
||||||
if (ifr.ifr_mtu != conf.mtu) {
|
if (ifr.ifr_mtu != mtu) {
|
||||||
ifr.ifr_mtu = conf.mtu;
|
ifr.ifr_mtu = mtu;
|
||||||
if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0) {
|
if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0) {
|
||||||
pr_error_errno("unable to set TUN/TAP interface MTU: SIOCSIFMTU ioctl failed");
|
pr_error_errno("unable to set TUN/TAP interface MTU: SIOCSIFMTU ioctl failed");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -160,7 +160,7 @@ static void open_iface_linux(fastd_iface_t *iface, const char *ifname, const cha
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
|
||||||
/** Opens the TUN/TAP device */
|
/** Opens the TUN/TAP device */
|
||||||
static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu) {
|
||||||
if (conf.android_integration) {
|
if (conf.android_integration) {
|
||||||
if (get_iface_type() != IFACE_TYPE_TUN)
|
if (get_iface_type() != IFACE_TYPE_TUN)
|
||||||
exit_bug("Non-TUN iface type with Android integration");
|
exit_bug("Non-TUN iface type with Android integration");
|
||||||
|
@ -172,27 +172,27 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
||||||
fastd_android_send_pid();
|
fastd_android_send_pid();
|
||||||
} else {
|
} else {
|
||||||
/* this requires root on Android */
|
/* this requires root on Android */
|
||||||
open_iface_linux(iface, ifname, "/dev/tun");
|
open_iface_linux(iface, ifname, mtu, "/dev/tun");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
|
|
||||||
/** Opens the TUN/TAP device */
|
/** Opens the TUN/TAP device */
|
||||||
static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu) {
|
||||||
open_iface_linux(iface, ifname, "/dev/net/tun");
|
open_iface_linux(iface, ifname, mtu, "/dev/net/tun");
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
|
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
|
|
||||||
/** Sets the MTU of the TUN/TAP device */
|
/** Sets the MTU of the TUN/TAP device */
|
||||||
static void set_tun_mtu(fastd_iface_t *iface) {
|
static void set_tun_mtu(fastd_iface_t *iface, uint16_t mtu) {
|
||||||
struct tuninfo tuninfo;
|
struct tuninfo tuninfo;
|
||||||
|
|
||||||
if (ioctl(iface->fd.fd, TUNGIFINFO, &tuninfo) < 0)
|
if (ioctl(iface->fd.fd, TUNGIFINFO, &tuninfo) < 0)
|
||||||
exit_errno("TUNGIFINFO ioctl failed");
|
exit_errno("TUNGIFINFO ioctl failed");
|
||||||
|
|
||||||
tuninfo.mtu = conf.mtu;
|
tuninfo.mtu = mtu;
|
||||||
|
|
||||||
if (ioctl(iface->fd.fd, TUNSIFINFO, &tuninfo) < 0)
|
if (ioctl(iface->fd.fd, TUNSIFINFO, &tuninfo) < 0)
|
||||||
exit_errno("TUNSIFINFO ioctl failed");
|
exit_errno("TUNSIFINFO ioctl failed");
|
||||||
|
@ -202,29 +202,29 @@ static void set_tun_mtu(fastd_iface_t *iface) {
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
/** Sets the MTU of the TAP device */
|
/** Sets the MTU of the TAP device */
|
||||||
static void set_tap_mtu(fastd_iface_t *iface) {
|
static void set_tap_mtu(fastd_iface_t *iface, uint16_t mtu) {
|
||||||
struct tapinfo tapinfo;
|
struct tapinfo tapinfo;
|
||||||
|
|
||||||
if (ioctl(iface->fd.fd, TAPGIFINFO, &tapinfo) < 0)
|
if (ioctl(iface->fd.fd, TAPGIFINFO, &tapinfo) < 0)
|
||||||
exit_errno("TAPGIFINFO ioctl failed");
|
exit_errno("TAPGIFINFO ioctl failed");
|
||||||
|
|
||||||
tapinfo.mtu = conf.mtu;
|
tapinfo.mtu = mtu;
|
||||||
|
|
||||||
if (ioctl(iface->fd.fd, TAPSIFINFO, &tapinfo) < 0)
|
if (ioctl(iface->fd.fd, TAPSIFINFO, &tapinfo) < 0)
|
||||||
exit_errno("TAPSIFINFO ioctl failed");
|
exit_errno("TAPSIFINFO ioctl failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets up the TUN device */
|
/** Sets up the TUN device */
|
||||||
static void setup_tun(fastd_iface_t *iface) {
|
static void setup_tun(fastd_iface_t *iface, uint16_t mtu) {
|
||||||
int one = 1;
|
int one = 1;
|
||||||
if (ioctl(iface->fd.fd, TUNSIFHEAD, &one) < 0)
|
if (ioctl(iface->fd.fd, TUNSIFHEAD, &one) < 0)
|
||||||
exit_errno("TUNSIFHEAD ioctl failed");
|
exit_errno("TUNSIFHEAD ioctl failed");
|
||||||
|
|
||||||
set_tun_mtu(iface);
|
set_tun_mtu(iface, mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets up the TAP device */
|
/** Sets up the TAP device */
|
||||||
static void setup_tap(fastd_iface_t *iface) {
|
static void setup_tap(fastd_iface_t *iface, uint16_t mtu) {
|
||||||
struct ifreq ifr = {};
|
struct ifreq ifr = {};
|
||||||
|
|
||||||
if (ioctl(iface->fd.fd, TAPGIFNAME, &ifr) < 0)
|
if (ioctl(iface->fd.fd, TAPGIFNAME, &ifr) < 0)
|
||||||
|
@ -233,11 +233,11 @@ static void setup_tap(fastd_iface_t *iface) {
|
||||||
free(iface->name);
|
free(iface->name);
|
||||||
iface->name = fastd_strndup(ifr.ifr_name, IFNAMSIZ-1);
|
iface->name = fastd_strndup(ifr.ifr_name, IFNAMSIZ-1);
|
||||||
|
|
||||||
set_tap_mtu(iface);
|
set_tap_mtu(iface, mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Opens the TUN/TAP device */
|
/** Opens the TUN/TAP device */
|
||||||
static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu) {
|
||||||
char dev_name[5+IFNAMSIZ] = "/dev/";
|
char dev_name[5+IFNAMSIZ] = "/dev/";
|
||||||
const char *type;
|
const char *type;
|
||||||
|
|
||||||
|
@ -273,11 +273,11 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
||||||
|
|
||||||
switch (get_iface_type()) {
|
switch (get_iface_type()) {
|
||||||
case IFACE_TYPE_TAP:
|
case IFACE_TYPE_TAP:
|
||||||
setup_tap(iface);
|
setup_tap(iface, mtu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFACE_TYPE_TUN:
|
case IFACE_TYPE_TUN:
|
||||||
setup_tun(iface);
|
setup_tun(iface, mtu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -311,19 +311,19 @@ static void set_link0(fastd_iface_t *iface, bool set) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets up the TUN device */
|
/** Sets up the TUN device */
|
||||||
static void setup_tun(fastd_iface_t *iface) {
|
static void setup_tun(fastd_iface_t *iface, uint16_t mtu) {
|
||||||
set_link0(iface, false);
|
set_link0(iface, false);
|
||||||
set_tun_mtu(iface);
|
set_tun_mtu(iface, mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets up the TAP device */
|
/** Sets up the TAP device */
|
||||||
static void setup_tap(fastd_iface_t *iface) {
|
static void setup_tap(fastd_iface_t *iface, uint16_t mtu) {
|
||||||
set_link0(iface, true);
|
set_link0(iface, true);
|
||||||
set_tun_mtu(iface);
|
set_tun_mtu(iface, mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Opens the TUN/TAP device */
|
/** Opens the TUN/TAP device */
|
||||||
static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu) {
|
||||||
char dev_name[5+IFNAMSIZ] = "/dev/";
|
char dev_name[5+IFNAMSIZ] = "/dev/";
|
||||||
if (!ifname)
|
if (!ifname)
|
||||||
exit_error("config error: no interface name given.");
|
exit_error("config error: no interface name given.");
|
||||||
|
@ -340,11 +340,11 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
||||||
|
|
||||||
switch (get_iface_type()) {
|
switch (get_iface_type()) {
|
||||||
case IFACE_TYPE_TAP:
|
case IFACE_TYPE_TAP:
|
||||||
setup_tap(iface);
|
setup_tap(iface, mtu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFACE_TYPE_TUN:
|
case IFACE_TYPE_TUN:
|
||||||
setup_tun(iface);
|
setup_tun(iface, mtu);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -357,7 +357,7 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
|
|
||||||
/** Opens the TUN/TAP device */
|
/** Opens the TUN/TAP device */
|
||||||
static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu) {
|
||||||
const char *devtype;
|
const char *devtype;
|
||||||
switch (get_iface_type()) {
|
switch (get_iface_type()) {
|
||||||
case IFACE_TYPE_TAP:
|
case IFACE_TYPE_TAP:
|
||||||
|
@ -392,7 +392,7 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
||||||
|
|
||||||
struct ifreq ifr = {};
|
struct ifreq ifr = {};
|
||||||
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
|
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
|
||||||
ifr.ifr_mtu = conf.mtu;
|
ifr.ifr_mtu = mtu;
|
||||||
if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0)
|
if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0)
|
||||||
exit_errno("SIOCSIFMTU ioctl failed");
|
exit_errno("SIOCSIFMTU ioctl failed");
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) {
|
||||||
|
|
||||||
/** Reads a packet from the TUN/TAP device */
|
/** Reads a packet from the TUN/TAP device */
|
||||||
void fastd_iface_handle(fastd_iface_t *iface) {
|
void fastd_iface_handle(fastd_iface_t *iface) {
|
||||||
size_t max_len = fastd_max_payload();
|
size_t max_len = fastd_max_payload(iface->mtu);
|
||||||
|
|
||||||
fastd_buffer_t buffer;
|
fastd_buffer_t buffer;
|
||||||
if (multiaf_tun && get_iface_type() == IFACE_TYPE_TUN)
|
if (multiaf_tun && get_iface_type() == IFACE_TYPE_TUN)
|
||||||
|
@ -514,9 +514,10 @@ fastd_iface_t * fastd_iface_open(fastd_peer_t *peer) {
|
||||||
|
|
||||||
fastd_iface_t *iface = fastd_new(fastd_iface_t);
|
fastd_iface_t *iface = fastd_new(fastd_iface_t);
|
||||||
iface->peer = peer;
|
iface->peer = peer;
|
||||||
|
iface->mtu = fastd_peer_get_mtu(peer);
|
||||||
|
|
||||||
pr_debug("initializing TUN/TAP device...");
|
pr_debug("initializing TUN/TAP device...");
|
||||||
open_iface(iface, ifname);
|
open_iface(iface, ifname, iface->mtu);
|
||||||
|
|
||||||
if (iface->fd.fd < 0) {
|
if (iface->fd.fd < 0) {
|
||||||
free(iface);
|
free(iface);
|
||||||
|
|
11
src/peer.h
11
src/peer.h
|
@ -73,6 +73,7 @@ struct fastd_peer {
|
||||||
fastd_protocol_peer_state_t *protocol_state; /**< Protocol-specific peer state */
|
fastd_protocol_peer_state_t *protocol_state; /**< Protocol-specific peer state */
|
||||||
|
|
||||||
char *ifname; /**< Peer-specific interface name */
|
char *ifname; /**< Peer-specific interface name */
|
||||||
|
uint16_t mtu; /**< Peer-specific interface MTU */
|
||||||
|
|
||||||
/* Starting here, more dynamic fields follow: */
|
/* Starting here, more dynamic fields follow: */
|
||||||
|
|
||||||
|
@ -283,6 +284,16 @@ static inline const fastd_string_stack_t * fastd_peer_get_methods(const fastd_pe
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint16_t fastd_peer_get_mtu(const fastd_peer_t *peer) {
|
||||||
|
if (conf.mode == MODE_TAP)
|
||||||
|
return conf.mtu;
|
||||||
|
|
||||||
|
if (peer && peer->mtu)
|
||||||
|
return peer->mtu;
|
||||||
|
|
||||||
|
return conf.mtu;
|
||||||
|
}
|
||||||
|
|
||||||
/** Checks if a MAC address is a normal unicast address */
|
/** Checks if a MAC address is a normal unicast address */
|
||||||
static inline bool fastd_eth_addr_is_unicast(fastd_eth_addr_t addr) {
|
static inline bool fastd_eth_addr_is_unicast(fastd_eth_addr_t addr) {
|
||||||
return ((addr.data[0] & 1) == 0);
|
return ((addr.data[0] & 1) == 0);
|
||||||
|
|
|
@ -314,7 +314,7 @@ static void respond_handshake(const fastd_socket_t *sock, const fastd_peer_addre
|
||||||
if (!update_shared_handshake_key(peer, handshake_key, peer_handshake_key))
|
if (!update_shared_handshake_key(peer, handshake_key, peer_handshake_key))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fastd_handshake_buffer_t buffer = fastd_handshake_new_reply(2, little_endian, method, fastd_peer_get_methods(peer), 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES));
|
fastd_handshake_buffer_t buffer = fastd_handshake_new_reply(2, little_endian, fastd_peer_get_mtu(peer), method, fastd_peer_get_methods(peer), 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES));
|
||||||
|
|
||||||
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
|
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
|
||||||
fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
|
fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
|
||||||
|
@ -373,7 +373,7 @@ static void finish_handshake(fastd_socket_t *sock, const fastd_peer_address_t *l
|
||||||
&peer->key->key, &sigma, compat ? NULL : shared_handshake_key.w, handshake_key->serial))
|
&peer->key->key, &sigma, compat ? NULL : shared_handshake_key.w, handshake_key->serial))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fastd_handshake_buffer_t buffer = fastd_handshake_new_reply(3, handshake->little_endian, method, NULL, 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES));
|
fastd_handshake_buffer_t buffer = fastd_handshake_new_reply(3, handshake->little_endian, fastd_peer_get_mtu(peer), method, NULL, 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES));
|
||||||
|
|
||||||
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
|
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
|
||||||
fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
|
fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
|
||||||
|
@ -661,6 +661,9 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_socket_t *sock, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fastd_handshake_check_mtu(sock, local_addr, remote_addr, peer, handshake))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!has_field(handshake, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES)) {
|
if (!has_field(handshake, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES)) {
|
||||||
pr_debug("received handshake without sender handshake key from %P[%I]", peer, remote_addr);
|
pr_debug("received handshake without sender handshake key from %P[%I]", peer, remote_addr);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -244,7 +244,7 @@ static inline void handle_socket_receive(fastd_socket_t *sock, const fastd_peer_
|
||||||
|
|
||||||
/** Reads a packet from a socket */
|
/** Reads a packet from a socket */
|
||||||
void fastd_receive(fastd_socket_t *sock) {
|
void fastd_receive(fastd_socket_t *sock) {
|
||||||
size_t max_len = 1 + fastd_max_payload() + conf.max_overhead;
|
size_t max_len = 1 + fastd_max_payload(ctx.max_mtu) + conf.max_overhead;
|
||||||
fastd_buffer_t buffer = fastd_buffer_alloc(max_len, conf.min_decrypt_head_space, conf.min_decrypt_tail_space);
|
fastd_buffer_t buffer = fastd_buffer_alloc(max_len, conf.min_decrypt_head_space, conf.min_decrypt_tail_space);
|
||||||
fastd_peer_address_t local_addr;
|
fastd_peer_address_t local_addr;
|
||||||
fastd_peer_address_t recvaddr;
|
fastd_peer_address_t recvaddr;
|
||||||
|
|
15
src/shell.c
15
src/shell.c
|
@ -77,10 +77,18 @@ void fastd_shell_env_free(fastd_shell_env_t *env) {
|
||||||
|
|
||||||
/** Adds an interface name to a shell environment */
|
/** Adds an interface name to a shell environment */
|
||||||
void fastd_shell_env_set_iface(fastd_shell_env_t *env, const fastd_iface_t *iface) {
|
void fastd_shell_env_set_iface(fastd_shell_env_t *env, const fastd_iface_t *iface) {
|
||||||
if (iface)
|
if (iface) {
|
||||||
|
char buf[6];
|
||||||
|
|
||||||
fastd_shell_env_set(env, "INTERFACE", iface->name);
|
fastd_shell_env_set(env, "INTERFACE", iface->name);
|
||||||
else
|
|
||||||
|
snprintf(buf, sizeof(buf), "%u", iface->mtu);
|
||||||
|
fastd_shell_env_set(env, "INTERFACE_MTU", buf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
fastd_shell_env_set(env, "INTERFACE", NULL);
|
fastd_shell_env_set(env, "INTERFACE", NULL);
|
||||||
|
fastd_shell_env_set(env, "INTERFACE_MTU", NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Applies a shell environment to the current process */
|
/** Applies a shell environment to the current process */
|
||||||
|
@ -92,9 +100,6 @@ static void shell_command_setenv(pid_t pid, const fastd_shell_env_t *env) {
|
||||||
snprintf(buf, sizeof(buf), "%u", (unsigned)pid);
|
snprintf(buf, sizeof(buf), "%u", (unsigned)pid);
|
||||||
setenv("FASTD_PID", buf, 1);
|
setenv("FASTD_PID", buf, 1);
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%u", conf.mtu);
|
|
||||||
setenv("INTERFACE_MTU", buf, 1);
|
|
||||||
|
|
||||||
if (!env)
|
if (!env)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue