diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-03-24 03:36:49 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-03-24 03:36:49 +0100 |
commit | 9ef4d441ad91ebcbc68bdae309122f128ed69f56 (patch) | |
tree | a3162fd43e77ce9c83eadf8ef4cfb92918df4615 | |
parent | 14a991a1ced945db09e53a1e6dd0a7b2a052cfba (diff) | |
download | fastd-9ef4d441ad91ebcbc68bdae309122f128ed69f56.tar fastd-9ef4d441ad91ebcbc68bdae309122f128ed69f56.zip |
Add support for defining the MTU per peer
-rw-r--r-- | src/config.c | 4 | ||||
-rw-r--r-- | src/config.y | 10 | ||||
-rw-r--r-- | src/fastd.h | 8 | ||||
-rw-r--r-- | src/handshake.c | 46 | ||||
-rw-r--r-- | src/handshake.h | 3 | ||||
-rw-r--r-- | src/iface.c | 61 | ||||
-rw-r--r-- | src/peer.h | 11 | ||||
-rw-r--r-- | src/protocols/ec25519_fhmqvc/handshake.c | 7 | ||||
-rw-r--r-- | src/receive.c | 2 | ||||
-rw-r--r-- | src/shell.c | 15 |
10 files changed, 104 insertions, 63 deletions
diff --git a/src/config.c b/src/config.c index 9ab2f88..4b9aeec 100644 --- a/src/config.c +++ b/src/config.c @@ -609,6 +609,7 @@ static void peer_dirs_read_peer_group(fastd_peer_group_t *group) { /** Initializes the configured peers */ static void configure_peers(bool dirs_only) { ctx.has_floating = false; + ctx.max_mtu = conf.mtu; ssize_t 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)) ctx.has_floating = true; + if (conf.mode != MODE_TAP && peer->mtu > ctx.max_mtu) + ctx.max_mtu = peer->mtu; + peer->config_state = CONFIG_STATIC; if (!fastd_peer_is_established(peer)) { diff --git a/src/config.y b/src/config.y index e2bcb24..3cffa17 100644 --- a/src/config.y +++ b/src/config.y @@ -478,6 +478,7 @@ peer_statement: TOK_REMOTE peer_remote ';' | TOK_FLOAT peer_float ';' | TOK_KEY peer_key ';' | TOK_INTERFACE peer_interface ';' + | TOK_MTU peer_mtu ';' | 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 { if (!fastd_config_read($1->str, state->peer_group, state->peer, state->depth)) YYERROR; diff --git a/src/fastd.h b/src/fastd.h index fa29bf0..ee48a65 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -159,6 +159,7 @@ struct fastd_iface { fastd_poll_fd_t fd; /**< The file descriptor of the tunnel interface */ char *name; /**< The interface name */ fastd_peer_t *peer; /**< The peer associated with the interface (if any) */ + uint16_t mtu; }; @@ -301,6 +302,7 @@ struct fastd_context { #endif 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 */ 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 */ -static inline size_t fastd_max_payload(void) { +static inline size_t fastd_max_payload(uint16_t mtu) { switch (conf.mode) { case MODE_TAP: case MODE_MULTITAP: - return conf.mtu+ETH_HLEN; + return mtu+ETH_HLEN; case MODE_TUN: - return conf.mtu; + return mtu; default: exit_bug("invalid mode"); } diff --git a/src/handshake.c b/src/handshake.c index 726c117..000d685 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -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 */ -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 protocol_len = strlen(conf.protocol->name); 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 = { .buffer = fastd_buffer_alloc(sizeof(fastd_handshake_packet_t), 1, 3*5 + /* handshake type, mode, reply code */ - 6 + /* MTU */ + (mtu ? 6 : 0) + /* MTU */ 4+version_len + /* version name */ 4+protocol_len + /* protocol 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_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_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 */ 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 */ -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 buffer = new_handshake(type, little_endian, method, methods, 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, mtu, method, methods, tail_space); fastd_handshake_add_uint8(&buffer, RECORD_REPLY_CODE, 0); return buffer; } /** 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; if (error_detail >= RECORD_MAX) @@ -260,7 +262,7 @@ static void print_error(const char *prefix, const fastd_peer_address_t *remote_a break; 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; 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 */ 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 = { .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 */ -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]); uint16_t error_detail = RECORD_MAX; if (handshake->records[RECORD_ERROR_DETAIL].length == 1 || handshake->records[RECORD_ERROR_DETAIL].length == 2) 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 */ @@ -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->records[RECORD_REPLY_CODE].length != 1) { 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) { - 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; } } diff --git a/src/handshake.h b/src/handshake.h index ccd1da5..997f955 100644 --- a/src/handshake.h +++ b/src/handshake.h @@ -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_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); +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); 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); diff --git a/src/iface.c b/src/iface.c index e471c89..4010c16 100644 --- a/src/iface.c +++ b/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__ /** 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; 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) exit_errno("SIOCGIFMTU ioctl failed"); - if (ifr.ifr_mtu != conf.mtu) { - ifr.ifr_mtu = conf.mtu; + if (ifr.ifr_mtu != mtu) { + ifr.ifr_mtu = mtu; if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0) { pr_error_errno("unable to set TUN/TAP interface MTU: SIOCSIFMTU ioctl failed"); goto error; @@ -160,7 +160,7 @@ static void open_iface_linux(fastd_iface_t *iface, const char *ifname, const cha #if defined(__ANDROID__) /** 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 (get_iface_type() != IFACE_TYPE_TUN) 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(); } else { /* this requires root on Android */ - open_iface_linux(iface, ifname, "/dev/tun"); + open_iface_linux(iface, ifname, mtu, "/dev/tun"); } } #elif defined(__linux__) /** Opens the TUN/TAP device */ -static void open_iface(fastd_iface_t *iface, const char *ifname) { - open_iface_linux(iface, ifname, "/dev/net/tun"); +static void open_iface(fastd_iface_t *iface, const char *ifname, uint16_t mtu) { + open_iface_linux(iface, ifname, mtu, "/dev/net/tun"); } #elif defined(__FreeBSD__) || defined(__OpenBSD__) /** 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; if (ioctl(iface->fd.fd, TUNGIFINFO, &tuninfo) < 0) exit_errno("TUNGIFINFO ioctl failed"); - tuninfo.mtu = conf.mtu; + tuninfo.mtu = mtu; if (ioctl(iface->fd.fd, TUNSIFINFO, &tuninfo) < 0) exit_errno("TUNSIFINFO ioctl failed"); @@ -202,29 +202,29 @@ static void set_tun_mtu(fastd_iface_t *iface) { #ifdef __FreeBSD__ /** 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; if (ioctl(iface->fd.fd, TAPGIFINFO, &tapinfo) < 0) exit_errno("TAPGIFINFO ioctl failed"); - tapinfo.mtu = conf.mtu; + tapinfo.mtu = mtu; if (ioctl(iface->fd.fd, TAPSIFINFO, &tapinfo) < 0) exit_errno("TAPSIFINFO ioctl failed"); } /** 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; if (ioctl(iface->fd.fd, TUNSIFHEAD, &one) < 0) exit_errno("TUNSIFHEAD ioctl failed"); - set_tun_mtu(iface); + set_tun_mtu(iface, mtu); } /** 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 = {}; if (ioctl(iface->fd.fd, TAPGIFNAME, &ifr) < 0) @@ -233,11 +233,11 @@ static void setup_tap(fastd_iface_t *iface) { free(iface->name); iface->name = fastd_strndup(ifr.ifr_name, IFNAMSIZ-1); - set_tap_mtu(iface); + set_tap_mtu(iface, mtu); } /** 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/"; const char *type; @@ -273,11 +273,11 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) { switch (get_iface_type()) { case IFACE_TYPE_TAP: - setup_tap(iface); + setup_tap(iface, mtu); break; case IFACE_TYPE_TUN: - setup_tun(iface); + setup_tun(iface, mtu); break; default: @@ -311,19 +311,19 @@ static void set_link0(fastd_iface_t *iface, bool set) { } /** 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_tun_mtu(iface); + set_tun_mtu(iface, mtu); } /** 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_tun_mtu(iface); + set_tun_mtu(iface, mtu); } /** 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/"; if (!ifname) 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()) { case IFACE_TYPE_TAP: - setup_tap(iface); + setup_tap(iface, mtu); break; case IFACE_TYPE_TUN: - setup_tun(iface); + setup_tun(iface, mtu); break; default: @@ -357,7 +357,7 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) { #elif __APPLE__ /** 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; switch (get_iface_type()) { case IFACE_TYPE_TAP: @@ -392,7 +392,7 @@ static void open_iface(fastd_iface_t *iface, const char *ifname) { struct ifreq ifr = {}; strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1); - ifr.ifr_mtu = conf.mtu; + ifr.ifr_mtu = mtu; if (ioctl(ctl_sock, SIOCSIFMTU, &ifr) < 0) 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 */ 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; 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); iface->peer = peer; + iface->mtu = fastd_peer_get_mtu(peer); pr_debug("initializing TUN/TAP device..."); - open_iface(iface, ifname); + open_iface(iface, ifname, iface->mtu); if (iface->fd.fd < 0) { free(iface); @@ -73,6 +73,7 @@ struct fastd_peer { fastd_protocol_peer_state_t *protocol_state; /**< Protocol-specific peer state */ char *ifname; /**< Peer-specific interface name */ + uint16_t mtu; /**< Peer-specific interface MTU */ /* 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; } +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 */ static inline bool fastd_eth_addr_is_unicast(fastd_eth_addr_t addr) { return ((addr.data[0] & 1) == 0); diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c index bbe572d..bef4385 100644 --- a/src/protocols/ec25519_fhmqvc/handshake.c +++ b/src/protocols/ec25519_fhmqvc/handshake.c @@ -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)) 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_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)) 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_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)) { pr_debug("received handshake without sender handshake key from %P[%I]", peer, remote_addr); return; diff --git a/src/receive.c b/src/receive.c index df25364..338edea 100644 --- a/src/receive.c +++ b/src/receive.c @@ -244,7 +244,7 @@ static inline void handle_socket_receive(fastd_socket_t *sock, const fastd_peer_ /** Reads a packet from a socket */ 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_peer_address_t local_addr; fastd_peer_address_t recvaddr; diff --git a/src/shell.c b/src/shell.c index b678ba5..e8d6943 100644 --- a/src/shell.c +++ b/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 */ 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); - 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_MTU", NULL); + } } /** 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); setenv("FASTD_PID", buf, 1); - snprintf(buf, sizeof(buf), "%u", conf.mtu); - setenv("INTERFACE_MTU", buf, 1); - if (!env) return; |