From 59d7765e2a3ddea4be053bc9c511c53f8367be19 Mon Sep 17 00:00:00 2001 From: "chleun.moon" Date: Mon, 5 Feb 2018 11:09:22 +0900 Subject: [PATCH] Add Multipath TCP Change-Id: I374ced383bc1c89d764bc264a17c4400393e346b Signed-off-by: Cheoleun Moon --- include/connection_extension.h | 32 ++++++ include/net_connection_mptcp_private.h | 22 ++++ packaging/capi-network-connection.spec | 2 +- src/connection_mptcp.c | 125 ++++++++++++++++++++ src/libnetwork_mptcp.c | 204 +++++++++++++++++++++++++++++++++ test/connection_test.c | 152 ++++++++++++++++++++++++ 6 files changed, 536 insertions(+), 1 deletion(-) create mode 100644 include/net_connection_mptcp_private.h create mode 100644 src/connection_mptcp.c create mode 100644 src/libnetwork_mptcp.c diff --git a/include/connection_extension.h b/include/connection_extension.h index 961b11d..0a8cd15 100755 --- a/include/connection_extension.h +++ b/include/connection_extension.h @@ -17,6 +17,9 @@ #ifndef __TIZEN_NETWORK_CONNECTION_EXTENSION_H__ #define __TIZEN_NETWORK_CONNECTION_EXTENSION_H__ +#include "net_connection.h" +#include "network-mptcp-intf.h" + #ifdef __cplusplus extern "C" { #endif @@ -62,6 +65,35 @@ int connection_profile_stop_tcpdump(connection_h connection); */ int connection_profile_get_tcpdump_state(connection_h connection, gboolean *tcpdump_state); + +typedef enum { + CONNECTION_MPTCP_DISABLE = 0, + CONNECTION_MPTCP_ENABLE_ALL = 1, + CONNECTION_MPTCP_ENABLE_SOCKOPT = 2, +} connection_mptcp_enable_e; + +typedef enum { + CONNECTION_MPTCP_PM_UNKNOWN, + CONNECTION_MPTCP_PM_DEFAULT, + CONNECTION_MPTCP_PM_FULLMESH, +} connection_mptcp_path_manager_e; + +typedef enum { + CONNECTION_MPTCP_SCHEDULER_UNKNOWN, + CONNECTION_MPTCP_SCHEDULER_DEFAULT, + CONNECTION_MPTCP_SCHEDULER_ROUNDROBIN, +} connection_mptcp_scheduler_e; + +int connection_mptcp_enable(connection_mptcp_enable_e enable); +int connection_mptcp_disable(void); +int connection_mptcp_get_enabled(connection_mptcp_enable_e* enable); + +int connection_mptcp_set_path_manager(connection_mptcp_path_manager_e pm); +int connection_mptcp_get_path_manager(connection_mptcp_path_manager_e* pm); + +int connection_mptcp_set_scheduler(connection_mptcp_scheduler_e scheduler); +int connection_mptcp_get_scheduler(connection_mptcp_scheduler_e* scheduler); + /** * @} */ diff --git a/include/net_connection_mptcp_private.h b/include/net_connection_mptcp_private.h new file mode 100644 index 0000000..a2b4716 --- /dev/null +++ b/include/net_connection_mptcp_private.h @@ -0,0 +1,22 @@ +#ifndef __CONNECTION_MPTCP_H__ +#define __CONNECTION_MPTCP_H__ + +#include "connection_extension.h" + +#ifdef __cplusplus +extern "C" { +#endif + +gboolean _connection_libnet_mptcp_supported(); +int _connection_libnet_mptcp_enable(connection_mptcp_enable_e enable); +int _connection_libnet_mptcp_get_enabled(connection_mptcp_enable_e* enable); +int _connection_libnet_mptcp_set_path_manager(connection_mptcp_path_manager_e pm); +int _connection_libnet_mptcp_get_path_manager(connection_mptcp_path_manager_e* pm); +int _connection_libnet_mptcp_set_scheduler(connection_mptcp_scheduler_e scheduler); +int _connection_libnet_mptcp_get_scheduler(connection_mptcp_scheduler_e* scheduler); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/capi-network-connection.spec b/packaging/capi-network-connection.spec index 0e5f691..8244508 100755 --- a/packaging/capi-network-connection.spec +++ b/packaging/capi-network-connection.spec @@ -1,6 +1,6 @@ Name: capi-network-connection Summary: Network Connection library in TIZEN C API -Version: 1.0.108 +Version: 1.0.109 Release: 1 Group: System/Network License: Apache-2.0 diff --git a/src/connection_mptcp.c b/src/connection_mptcp.c new file mode 100644 index 0000000..c0cf639 --- /dev/null +++ b/src/connection_mptcp.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License") +{ +} + + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "connection_extension.h" +#include "net_connection_private.h" +#include "net_connection_mptcp_private.h" + +EXPORT_API int connection_mptcp_enable(connection_mptcp_enable_e enable) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + if (enable == CONNECTION_MPTCP_DISABLE) { + CONNECTION_LOG(CONNECTION_ERROR, "Use connection_mptcp_disable()"); + return CONNECTION_ERROR_INVALID_PARAMETER; + } + + return _connection_libnet_mptcp_enable(enable); +} + +EXPORT_API int connection_mptcp_disable(void) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + return _connection_libnet_mptcp_enable(CONNECTION_MPTCP_DISABLE); +} + +EXPORT_API int connection_mptcp_get_enabled(connection_mptcp_enable_e* enable) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + if (enable == NULL) { + CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); + return CONNECTION_ERROR_INVALID_PARAMETER; + } + + return _connection_libnet_mptcp_get_enabled(enable); +} + + +EXPORT_API int connection_mptcp_set_path_manager(connection_mptcp_path_manager_e pm) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + return _connection_libnet_mptcp_set_path_manager(pm); +} + +EXPORT_API int connection_mptcp_get_path_manager(connection_mptcp_path_manager_e* pm) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + if (pm == NULL) { + CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); + return CONNECTION_ERROR_INVALID_PARAMETER; + } + + return _connection_libnet_mptcp_get_path_manager(pm); +} + + +EXPORT_API int connection_mptcp_set_scheduler(connection_mptcp_scheduler_e scheduler) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + return _connection_libnet_mptcp_set_scheduler(scheduler); +} + +EXPORT_API int connection_mptcp_get_scheduler(connection_mptcp_scheduler_e* scheduler) +{ + // check MPTCP support + if (_connection_libnet_mptcp_supported() == FALSE) { + CONNECTION_LOG(CONNECTION_ERROR, "MPTCP is not supported"); + return CONNECTION_ERROR_NOT_SUPPORTED; + } + + if (scheduler == NULL) { + CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); + return CONNECTION_ERROR_INVALID_PARAMETER; + } + + return _connection_libnet_mptcp_get_scheduler(scheduler); +} + + diff --git a/src/libnetwork_mptcp.c b/src/libnetwork_mptcp.c new file mode 100644 index 0000000..3b53185 --- /dev/null +++ b/src/libnetwork_mptcp.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "net_connection_private.h" +#include "connection_extension.h" +#include "net_connection_mptcp_private.h" + +static const char* __convert_mptcp_path_manager_enum_to_str(connection_mptcp_path_manager_e pm) +{ + switch (pm) { + case CONNECTION_MPTCP_PM_UNKNOWN: + return NULL; + case CONNECTION_MPTCP_PM_DEFAULT: + return "default"; + case CONNECTION_MPTCP_PM_FULLMESH: + return "fullmesh"; + } + return NULL; +} + +static connection_mptcp_path_manager_e __convert_mptcp_path_manager_str_to_enum(char* pm) +{ + if (g_strcmp0(pm, "default") == 0) + return CONNECTION_MPTCP_PM_DEFAULT; + if (g_strcmp0(pm, "fullmesh") == 0) + return CONNECTION_MPTCP_PM_FULLMESH; + return CONNECTION_MPTCP_PM_UNKNOWN; +} + +static const char* __convert_mptcp_scheduler_enum_to_str(connection_mptcp_scheduler_e scheduler) +{ + switch (scheduler) { + case CONNECTION_MPTCP_SCHEDULER_UNKNOWN: + return NULL; + case CONNECTION_MPTCP_SCHEDULER_DEFAULT: + return "default"; + case CONNECTION_MPTCP_SCHEDULER_ROUNDROBIN: + return "roundrobin"; + } + return NULL; +} + +static connection_mptcp_scheduler_e __convert_mptcp_scheduler_str_to_enum(char *scheduler) +{ + if (g_strcmp0(scheduler, "default") == 0) + return CONNECTION_MPTCP_SCHEDULER_DEFAULT; + if (g_strcmp0(scheduler, "roundrobin") == 0) + return CONNECTION_MPTCP_SCHEDULER_ROUNDROBIN; + return CONNECTION_MPTCP_SCHEDULER_UNKNOWN; +} + +gboolean _connection_libnet_mptcp_supported() +{ + int rv = 0; + gboolean support = false; + + rv = net_mptcp_supported(&support); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return false; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to enable MPTCP [%d]", rv); + return false; + } + + return support; +} + +int _connection_libnet_mptcp_enable(connection_mptcp_enable_e enable) +{ + int rv = 0; + + rv = net_mptcp_set_enable((int)enable); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return CONNECTION_ERROR_PERMISSION_DENIED; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to enable MPTCP [%d]", rv); + return CONNECTION_ERROR_OPERATION_FAILED; + } + + return CONNECTION_ERROR_NONE; +} + +int _connection_libnet_mptcp_get_enabled(connection_mptcp_enable_e* enable) +{ + int rv = 0; + int result = 0; + + rv = net_mptcp_get_enabled(&result); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return CONNECTION_ERROR_PERMISSION_DENIED; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MPTCP enabled state [%d]", rv); + return CONNECTION_ERROR_OPERATION_FAILED; + } + + *enable = (connection_mptcp_enable_e)result; + return CONNECTION_ERROR_NONE; +} + + +int _connection_libnet_mptcp_set_path_manager(connection_mptcp_path_manager_e pm) +{ + int rv = 0; + const char* str = __convert_mptcp_path_manager_enum_to_str(pm); + CONNECTION_LOG(CONNECTION_ERROR, "set path manager %s", str); + + if (str == NULL) { + CONNECTION_LOG(CONNECTION_ERROR, "Invalid Parameter"); + return CONNECTION_ERROR_INVALID_PARAMETER; + } + + rv = net_mptcp_set_path_manager(str); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return CONNECTION_ERROR_PERMISSION_DENIED; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to set MPTCP path manager [%d]", rv); + return CONNECTION_ERROR_OPERATION_FAILED; + } + + return CONNECTION_ERROR_NONE; +} + +int _connection_libnet_mptcp_get_path_manager(connection_mptcp_path_manager_e* pm) +{ + int rv = 0; + char* result = NULL; + + rv = net_mptcp_get_path_manager(&result); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return CONNECTION_ERROR_PERMISSION_DENIED; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MPTCP path manager [%d]", rv); + return CONNECTION_ERROR_OPERATION_FAILED; + } + + CONNECTION_LOG(CONNECTION_ERROR, "get path manager %s", result); + *pm = __convert_mptcp_path_manager_str_to_enum(result); + g_free(result); + return CONNECTION_ERROR_NONE; +} + + +int _connection_libnet_mptcp_set_scheduler(connection_mptcp_scheduler_e scheduler) +{ + int rv = 0; + const char *str = __convert_mptcp_scheduler_enum_to_str(scheduler); + CONNECTION_LOG(CONNECTION_ERROR, "set scheduler %s", str); + + if (str == NULL) { + CONNECTION_LOG(CONNECTION_ERROR, "Invalid Parameter"); + return CONNECTION_ERROR_INVALID_PARAMETER; + } + + rv = net_mptcp_set_scheduler(str); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return CONNECTION_ERROR_PERMISSION_DENIED; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to set MPTCP scheduler [%d]", rv); + return CONNECTION_ERROR_OPERATION_FAILED; + } + + return CONNECTION_ERROR_NONE; +} + +int _connection_libnet_mptcp_get_scheduler(connection_mptcp_scheduler_e* scheduler) +{ + int rv = 0; + char* result = NULL; + + rv = net_mptcp_get_scheduler(&result); + if (rv == NET_ERR_ACCESS_DENIED) { + CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); + return CONNECTION_ERROR_PERMISSION_DENIED; + } else if (rv != NET_ERR_NONE) { + CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MPTCP scheduler [%d]", rv); + return CONNECTION_ERROR_OPERATION_FAILED; + } + + CONNECTION_LOG(CONNECTION_ERROR, "get scheduler %s", result); + *scheduler = __convert_mptcp_scheduler_str_to_enum(result); + g_free(result); + return CONNECTION_ERROR_NONE; +} diff --git a/test/connection_test.c b/test/connection_test.c index 753cab1..2abebf0 100755 --- a/test/connection_test.c +++ b/test/connection_test.c @@ -2183,6 +2183,134 @@ int test_get_tcpdump_state(void) return 1; } +int test_mptcp_enable(void) +{ + int rv = 0; + rv = connection_mptcp_enable(CONNECTION_MPTCP_ENABLE_ALL); + + if (rv != CONNECTION_ERROR_NONE) { + printf("Failure[%s]\n", test_print_error(rv)); + return -1; + } + return 1; +} + +int test_mptcp_disable(void) +{ + int rv = 0; + rv = connection_mptcp_disable(); + + if (rv != CONNECTION_ERROR_NONE) { + printf("Failure[%s]\n", test_print_error(rv)); + return -1; + } + return 1; +} + +int test_mptcp_set_path_manager(void) +{ + int rv = 0; + int input = 0; + rv = test_get_user_int("Input Path Manager (1: default, 2: fullmesh)", &input); + + switch (input) { + case 1: + rv = connection_mptcp_set_path_manager(CONNECTION_MPTCP_PM_DEFAULT); + break; + case 2: + rv = connection_mptcp_set_path_manager(CONNECTION_MPTCP_PM_FULLMESH); + break; + default: + printf("Invalid input!!\n"); + return -1; + } + + if (rv != CONNECTION_ERROR_NONE) { + printf("Failure[%s]\n", test_print_error(rv)); + return -1; + } + + return 1; +} + +int test_mptcp_get_path_manager(void) +{ + int rv = 0; + connection_mptcp_path_manager_e pm; + + rv = connection_mptcp_get_path_manager(&pm); + if (rv != CONNECTION_ERROR_NONE) { + printf("Failure[%s]\n", test_print_error(rv)); + return -1; + } + + switch (pm) { + case CONNECTION_MPTCP_PM_DEFAULT: + printf("Path Manager: Default\n"); + break; + case CONNECTION_MPTCP_PM_FULLMESH: + printf("Path Manager: FullMesh\n"); + break; + default: + printf("Error: Invalid Path Manager\n"); + return -1; + } + + return 1; +} + +int test_mptcp_set_scheduler(void) +{ + int rv = 0; + int input = 0; + rv = test_get_user_int("Input Scheduler (1: default, 2: roundrobin)", &input); + + switch (input) { + case 1: + rv = connection_mptcp_set_scheduler(CONNECTION_MPTCP_SCHEDULER_DEFAULT); + break; + case 2: + rv = connection_mptcp_set_scheduler(CONNECTION_MPTCP_SCHEDULER_ROUNDROBIN); + break; + default: + printf("Invalid input!!\n"); + return -1; + } + + if (rv != CONNECTION_ERROR_NONE) { + printf("Failure[%s]\n", test_print_error(rv)); + return -1; + } + + return 1; +} + +int test_mptcp_get_scheduler(void) +{ + int rv = 0; + connection_mptcp_scheduler_e scheduler; + + rv = connection_mptcp_get_scheduler(&scheduler); + if (rv != CONNECTION_ERROR_NONE) { + printf("Failure[%s]\n", test_print_error(rv)); + return -1; + } + + switch (scheduler) { + case CONNECTION_MPTCP_SCHEDULER_DEFAULT: + printf("Scheduler: Default\n"); + break; + case CONNECTION_MPTCP_SCHEDULER_ROUNDROBIN: + printf("Scheduler: RountRobin\n"); + break; + default: + printf("Error: Invalid Scheduler\n"); + return -1; + } + + return 1; +} + int main(int argc, char **argv) { GMainLoop *mainloop; @@ -2264,6 +2392,12 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) printf("H - Start TCP Dump\n"); printf("I - Stop TCP Dump\n"); printf("J - Get TCP Dump State\n"); + printf("K - Enable MPTCP (internal)\n"); + printf("L - Disable MPTCP (internal)\n"); + printf("M - Set MPTCP Path Manager (internal)\n"); + printf("N - Get MPTCP Path Manager (internal)\n"); + printf("O - Set MPTCP Scheduler (internal)\n"); + printf("P - Get MPTCP Scheduler (internal)\n"); printf(LOG_RED "0 - Exit \n" LOG_END); printf("ENTER - Show options menu.......\n"); } @@ -2397,6 +2531,24 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) case 'J': rv = test_get_tcpdump_state(); break; + case 'K': + rv = test_mptcp_enable(); + break; + case 'L': + rv = test_mptcp_disable(); + break; + case 'M': + rv = test_mptcp_set_path_manager(); + break; + case 'N': + rv = test_mptcp_get_path_manager(); + break; + case 'O': + rv = test_mptcp_set_scheduler(); + break; + case 'P': + rv = test_mptcp_get_scheduler(); + break; } -- 2.7.4