diff --git a/configure.ac b/configure.ac index 65b3ea07..55520557 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ AC_INIT([mptcpd], # Interfaces changed: CURRENT++ REVISION=0 # added: CURRENT++ REVISION=0 AGE++ # removed: CURRENT++ REVISION=0 AGE=0 -LIB_CURRENT=4 +LIB_CURRENT=5 LIB_REVISION=0 LIB_AGE=1 diff --git a/include/linux/mptcp_upstream.h b/include/linux/mptcp_upstream.h index 1284fd5e..5c584174 100644 --- a/include/linux/mptcp_upstream.h +++ b/include/linux/mptcp_upstream.h @@ -31,6 +31,9 @@ #define MPTCP_INFO_FLAG_FALLBACK _BITUL(0) #define MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED _BITUL(1) +#define MPTCP_PM_EV_FLAG_DENY_JOIN_ID0 _BITUL(0) +#define MPTCP_PM_EV_FLAG_SERVER_SIDE _BITUL(1) + #define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0) #define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1) #define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2) diff --git a/include/linux/mptcp_upstream_pm.h b/include/linux/mptcp_upstream_pm.h index 6ac84b2f..bf44a5cf 100644 --- a/include/linux/mptcp_upstream_pm.h +++ b/include/linux/mptcp_upstream_pm.h @@ -16,10 +16,10 @@ * good time to allocate memory and send ADD_ADDR if needed. Depending on the * traffic-patterns it can take a long time until the MPTCP_EVENT_ESTABLISHED * is sent. Attributes: token, family, saddr4 | saddr6, daddr4 | daddr6, - * sport, dport, server-side. + * sport, dport, [server-side], [flags]. * @MPTCP_EVENT_ESTABLISHED: A MPTCP connection is established (can start new * subflows). Attributes: token, family, saddr4 | saddr6, daddr4 | daddr6, - * sport, dport, server-side. + * sport, dport, [server-side], [flags]. * @MPTCP_EVENT_CLOSED: A MPTCP connection has stopped. Attribute: token. * @MPTCP_EVENT_ANNOUNCED: A new address has been announced by the peer. * Attributes: token, rem_id, family, daddr4 | daddr6 [, dport]. diff --git a/include/mptcpd/plugin.h b/include/mptcpd/plugin.h index 9bb27a82..db6ed611 100644 --- a/include/mptcpd/plugin.h +++ b/include/mptcpd/plugin.h @@ -145,6 +145,9 @@ struct mptcpd_plugin_ops * @param[in] server_side @c true if this peer was the * listener (server), @c false if this * peer initiated the connection. + * @param[in] deny_join_id0 @c true if the other peer requested not to + * create a new subflow to the initial IP + * address and port * @param[in] pm Opaque pointer to mptcpd path * manager object. */ @@ -152,6 +155,7 @@ struct mptcpd_plugin_ops struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm); /** @@ -163,6 +167,9 @@ struct mptcpd_plugin_ops * @param[in] server_side @c true if this peer was the * listener (server), @c false if this * peer initiated the connection. + * @param[in] deny_join_id0 @c true if the other peer requested not to + * create a new subflow to the initial IP + * address and port * @param[in] pm Opaque pointer to mptcpd path * manager object. */ @@ -170,6 +177,7 @@ struct mptcpd_plugin_ops struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm); /** diff --git a/include/mptcpd/private/plugin.h b/include/mptcpd/private/plugin.h index 84af2ff1..2fea5f00 100644 --- a/include/mptcpd/private/plugin.h +++ b/include/mptcpd/private/plugin.h @@ -60,6 +60,7 @@ MPTCPD_API void mptcpd_plugin_unload(struct mptcpd_pm *pm); * @param[in] laddr Local address information. * @param[in] raddr Remote address information. * @param[in] server_side Server side connection flag. + * @param[in] deny_join_id0 No MPJ to the initial address and port. * @param[in] pm Opaque pointer to mptcpd path manager object. */ MPTCPD_API void mptcpd_plugin_new_connection( @@ -68,6 +69,7 @@ MPTCPD_API void mptcpd_plugin_new_connection( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm); /** @@ -77,6 +79,7 @@ MPTCPD_API void mptcpd_plugin_new_connection( * @param[in] laddr Local address information. * @param[in] raddr Remote address information. * @param[in] server_side Server side connection flag. + * @param[in] deny_join_id0 No MPJ to the initial address and port. * @param[in] pm Opaque pointer to mptcpd path manager object. */ MPTCPD_API void mptcpd_plugin_connection_established( @@ -84,6 +87,7 @@ MPTCPD_API void mptcpd_plugin_connection_established( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm); /** diff --git a/lib/plugin.c b/lib/plugin.c index 03e1b18e..a59b4fe8 100644 --- a/lib/plugin.c +++ b/lib/plugin.c @@ -575,6 +575,7 @@ void mptcpd_plugin_new_connection(char const *name, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { struct mptcpd_plugin_ops const *const ops = name_to_ops(name); @@ -586,13 +587,19 @@ void mptcpd_plugin_new_connection(char const *name, l_error("Unable to map connection to plugin."); if (ops && ops->new_connection) - ops->new_connection(token, laddr, raddr, server_side, pm); + ops->new_connection(token, + laddr, + raddr, + server_side, + deny_join_id0, + pm); } void mptcpd_plugin_connection_established(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { struct mptcpd_plugin_ops const *const ops = token_to_ops(token); @@ -602,6 +609,7 @@ void mptcpd_plugin_connection_established(mptcpd_token_t token, laddr, raddr, server_side, + deny_join_id0, pm); } diff --git a/plugins/path_managers/sspi.c b/plugins/path_managers/sspi.c index 59b8030e..0fa43e78 100644 --- a/plugins/path_managers/sspi.c +++ b/plugins/path_managers/sspi.c @@ -542,10 +542,12 @@ static void sspi_new_connection(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) raddr; (void) server_side; + (void) deny_join_id0; /** * @note Because we directly store connection tokens in a @@ -604,12 +606,14 @@ static void sspi_connection_established(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; /** diff --git a/src/path_manager.c b/src/path_manager.c index 5588fb70..3c87cec5 100644 --- a/src/path_manager.c +++ b/src/path_manager.c @@ -7,6 +7,7 @@ * Copyright (c) 2017-2022, Intel Corporation */ +#include "linux/mptcp_upstream_pm.h" #ifdef HAVE_CONFIG_H # include #endif @@ -133,6 +134,9 @@ struct pm_event_attrs /// Server side connection event (boolean) uint8_t const *server_side; + + /// Event flags + uint16_t const *flags; }; /** @@ -196,8 +200,10 @@ static void parse_netlink_attributes(struct l_genl_msg *msg, case MPTCP_ATTR_SERVER_SIDE: MPTCP_GET_NL_ATTR(data, len, attrs->server_side); break; - case MPTCP_ATTR_FAMILY: case MPTCP_ATTR_FLAGS: + MPTCP_GET_NL_ATTR(data, len, attrs->flags); + break; + case MPTCP_ATTR_FAMILY: case MPTCP_ATTR_TIMEOUT: case MPTCP_ATTR_RESET_REASON: case MPTCP_ATTR_RESET_FLAGS: @@ -252,13 +258,19 @@ static void handle_connection_created(struct pm_event_attrs const *attrs, static char const *const pm_name = NULL; bool const server_side = - (attrs->server_side != NULL ? *attrs->server_side : false); + (attrs->flags != NULL && + *attrs->flags & MPTCP_PM_EV_FLAG_SERVER_SIDE) || + (attrs->server_side != NULL && *attrs->server_side); + bool const deny_join_id0 = + attrs->flags != NULL && + *attrs->flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0; mptcpd_plugin_new_connection(pm_name, *attrs->token, (struct sockaddr *) &laddr, (struct sockaddr *) &raddr, server_side, + deny_join_id0, pm); } @@ -304,12 +316,18 @@ static void handle_connection_established(struct pm_event_attrs const *attrs, // Assume server_side is false if event attribute is unavailable. bool const server_side = - (attrs->server_side != NULL ? *attrs->server_side : false); + (attrs->flags != NULL && + *attrs->flags & MPTCP_PM_EV_FLAG_SERVER_SIDE) || + (attrs->server_side != NULL && *attrs->server_side); + bool const deny_join_id0 = + attrs->flags != NULL && + *attrs->flags & MPTCP_PM_EV_FLAG_DENY_JOIN_ID0; mptcpd_plugin_connection_established(*attrs->token, (struct sockaddr *) &laddr, (struct sockaddr *) &raddr, server_side, + deny_join_id0, pm); } diff --git a/tests/lib/call_plugin.c b/tests/lib/call_plugin.c index 7ea472e9..496cd75a 100644 --- a/tests/lib/call_plugin.c +++ b/tests/lib/call_plugin.c @@ -29,6 +29,7 @@ void call_plugin_ops(struct plugin_call_count const *count, args->laddr, args->raddr, args->server_side, + args->deny_join_id0, args->pm); for (int i = 0; i < count->connection_established; ++i) @@ -36,6 +37,7 @@ void call_plugin_ops(struct plugin_call_count const *count, args->laddr, args->raddr, args->server_side, + args->deny_join_id0, args->pm); for (int i = 0; i < count->new_address; ++i) diff --git a/tests/lib/test-plugin.h b/tests/lib/test-plugin.h index 284b1aca..95ef6e01 100644 --- a/tests/lib/test-plugin.h +++ b/tests/lib/test-plugin.h @@ -151,6 +151,7 @@ static mptcpd_aid_t const test_laddr_id_1 = 0x34; static mptcpd_aid_t const test_raddr_id_1 = 0x56; static bool const test_backup_1 = true; static bool const test_server_side_1 = true; +static bool const test_deny_join_id0_1 = true; static mptcpd_token_t const test_token_2 = 0x23456789; @@ -158,12 +159,14 @@ static mptcpd_aid_t const test_laddr_id_2 = 0x23; static mptcpd_aid_t const test_raddr_id_2 = 0x45; static bool const test_backup_2 = false; static bool const test_server_side_2 = true; +static bool const test_deny_join_id0_2 = true; static mptcpd_token_t const test_token_4 = 0x34567890; static mptcpd_aid_t const test_laddr_id_4 = 0x90; static mptcpd_aid_t const test_raddr_id_4 = 0x01; static bool const test_backup_4 = true; static bool const test_server_side_4 = false; +static bool const test_deny_join_id0_4 = false; // For verifying that a plugin will not be dispatched. static mptcpd_token_t const test_bad_token = 0xFFFFFFFF; @@ -306,6 +309,9 @@ struct plugin_call_args /// Server side connection flag. bool server_side; + /// Remote peer deny a MP_JOIN to the initial IP address and port + bool deny_join_id0; + /// Mptcpd path manager object. struct mptcpd_pm *const pm; }; diff --git a/tests/plugins/noop/noop.c b/tests/plugins/noop/noop.c index 637d80c3..58db19c9 100644 --- a/tests/plugins/noop/noop.c +++ b/tests/plugins/noop/noop.c @@ -20,12 +20,14 @@ static void plugin_noop_new_connection(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; } @@ -34,12 +36,14 @@ static void plugin_noop_connection_established( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; } diff --git a/tests/plugins/priority/one.c b/tests/plugins/priority/one.c index 8ac7e7a3..b50d18d7 100644 --- a/tests/plugins/priority/one.c +++ b/tests/plugins/priority/one.c @@ -37,6 +37,7 @@ static void plugin_one_new_connection(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) pm; @@ -47,6 +48,7 @@ static void plugin_one_new_connection(mptcpd_token_t token, assert(sockaddr_is_equal(laddr, local_addr)); assert(sockaddr_is_equal(raddr, remote_addr)); assert(server_side == test_server_side_1); + assert(deny_join_id0 == test_deny_join_id0_1); ++call_count.new_connection; } @@ -56,6 +58,7 @@ static void plugin_one_connection_established( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) pm; @@ -66,6 +69,7 @@ static void plugin_one_connection_established( assert(sockaddr_is_equal(laddr, local_addr)); assert(sockaddr_is_equal(raddr, remote_addr)); assert(server_side == test_server_side_1); + assert(deny_join_id0 == test_deny_join_id0_1); ++call_count.connection_established; } diff --git a/tests/plugins/priority/two.c b/tests/plugins/priority/two.c index c97b1845..284e0163 100644 --- a/tests/plugins/priority/two.c +++ b/tests/plugins/priority/two.c @@ -37,6 +37,7 @@ static void plugin_two_new_connection(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) pm; @@ -47,6 +48,7 @@ static void plugin_two_new_connection(mptcpd_token_t token, assert(sockaddr_is_equal(laddr, local_addr)); assert(sockaddr_is_equal(raddr, remote_addr)); assert(server_side == test_server_side_2); + assert(deny_join_id0 == test_deny_join_id0_2); ++call_count.new_connection; } @@ -56,6 +58,7 @@ static void plugin_two_connection_established( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) pm; @@ -66,6 +69,7 @@ static void plugin_two_connection_established( assert(sockaddr_is_equal(laddr, local_addr)); assert(sockaddr_is_equal(raddr, remote_addr)); assert(server_side == test_server_side_2); + assert(deny_join_id0 == test_deny_join_id0_2); ++call_count.connection_established; } diff --git a/tests/plugins/security/four.c b/tests/plugins/security/four.c index e10f74b2..3cf0f261 100644 --- a/tests/plugins/security/four.c +++ b/tests/plugins/security/four.c @@ -31,12 +31,14 @@ static void plugin_four_new_connection(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; ++call_count.new_connection; @@ -47,12 +49,14 @@ static void plugin_four_connection_established( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; ++call_count.connection_established; diff --git a/tests/plugins/security/three.c b/tests/plugins/security/three.c index a285dab9..61c94660 100644 --- a/tests/plugins/security/three.c +++ b/tests/plugins/security/three.c @@ -31,12 +31,14 @@ static void plugin_three_new_connection(mptcpd_token_t token, struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; ++call_count.new_connection; @@ -47,12 +49,14 @@ static void plugin_three_connection_established( struct sockaddr const *laddr, struct sockaddr const *raddr, bool server_side, + bool deny_join_id0, struct mptcpd_pm *pm) { (void) token; (void) laddr; (void) raddr; (void) server_side; + (void) deny_join_id0; (void) pm; ++call_count.connection_established; diff --git a/tests/test-plugin.c b/tests/test-plugin.c index 3e51eaae..d0595c13 100644 --- a/tests/test-plugin.c +++ b/tests/test-plugin.c @@ -51,7 +51,8 @@ static bool run_plugin_load(mode_t mode, struct l_queue const *queue) .laddr = (struct sockaddr const *) &test_laddr_4, .raddr = (struct sockaddr const *) &test_raddr_4, .backup = test_backup_4, - .server_side = test_server_side_4 + .server_side = test_server_side_4, + .deny_join_id0 = test_deny_join_id0_4 }; call_plugin_ops(&test_count_4, &args); @@ -181,6 +182,7 @@ static void test_nonexistent_plugins(void const *test_data) NULL, // laddr NULL, // raddr false, // server_side + false, // deny_join_id0 NULL); // pm assert(!loaded); @@ -213,7 +215,8 @@ static void test_plugin_dispatch(void const *test_data) .laddr = (struct sockaddr const *) &test_laddr_1, .raddr = (struct sockaddr const *) &test_raddr_1, .backup = test_backup_1, - .server_side = test_server_side_1 + .server_side = test_server_side_1, + .deny_join_id0 = test_deny_join_id0_1 }; call_plugin_ops(&test_count_1, &args1); @@ -225,7 +228,8 @@ static void test_plugin_dispatch(void const *test_data) .laddr = args1.laddr, .raddr = args1.raddr, .backup = args1.backup, - .server_side = args1.server_side + .server_side = args1.server_side, + .deny_join_id0 = args1.deny_join_id0 }; call_plugin_ops(&test_count_1, &args1_default); @@ -238,7 +242,8 @@ static void test_plugin_dispatch(void const *test_data) .laddr = (struct sockaddr const *) &test_laddr_2, .raddr = (struct sockaddr const *) &test_raddr_2, .backup = test_backup_2, - .server_side = test_server_side_2 + .server_side = test_server_side_2, + .deny_join_id0 = test_deny_join_id0_2 }; call_plugin_ops(&test_count_2, &args2); @@ -262,6 +267,7 @@ static void test_plugin_dispatch(void const *test_data) (struct sockaddr const *) &test_laddr_2, (struct sockaddr const *) &test_raddr_2, test_server_side_2, + test_deny_join_id0_2, NULL); // Test assertions will be triggered during plugin unload. @@ -299,11 +305,14 @@ static void test_null_plugin_ops(void const *test_data) static struct sockaddr const *const raddr = NULL; static bool backup = false; static bool server_side = false; + static bool deny_join_id0 = false; static struct mptcpd_interface const *const interface = NULL; // No dispatch should occur in the following calls. - mptcpd_plugin_new_connection(name, token, laddr, raddr, server_side, pm); - mptcpd_plugin_connection_established(token, laddr, raddr, server_side, pm); + mptcpd_plugin_new_connection(name, token, laddr, raddr, server_side, + deny_join_id0, pm); + mptcpd_plugin_connection_established(token, laddr, raddr, server_side, + deny_join_id0, pm); mptcpd_plugin_connection_closed(token, pm); mptcpd_plugin_new_address(token, id, raddr, pm); mptcpd_plugin_address_removed(token, id, pm);