From 9073f78abbe9eb9a40c1082fd616af3c5f8ebde6 Mon Sep 17 00:00:00 2001 From: Kush Date: Mon, 14 Oct 2019 21:02:34 +0530 Subject: [PATCH] TCP Socket Bind API https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/593 https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/588/commits/1f7cb27e719bfd876fd0ff900747eeb3d7210d46 (cherry-picked from 1f7cb27e719bfd876fd0ff900747eeb3d7210d46) Change-Id: I48954a2caa59d95464a29a257c67b38325b64d12 Signed-off-by: Kush Signed-off-by: Sudipto --- resource/csdk/connectivity/api/cacommon.h | 6 ++ resource/csdk/connectivity/api/cautilinterface.h | 12 +++ .../connectivity/src/tcp_adapter/catcpadapter.c | 1 + .../connectivity/src/tcp_adapter/catcpserver.c | 105 +++++++++++++++++++++ 4 files changed, 124 insertions(+) mode change 100644 => 100755 resource/csdk/connectivity/api/cautilinterface.h mode change 100644 => 100755 resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c mode change 100644 => 100755 resource/csdk/connectivity/src/tcp_adapter/catcpserver.c diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index c0593e0..002794c 100755 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -98,6 +98,11 @@ extern "C" #define CA_MAX_TOKEN_LEN (8) /** +* Max interface name length. +*/ +#define CA_MAX_INTERFACE_NAME_LEN (16) + +/** * Max URI length. */ #ifdef ARDUINO @@ -651,6 +656,7 @@ typedef struct int connectionFds[2]; /**< connection pipe */ bool started; /**< the TCP adapter has started */ bool terminate; /**< the TCP adapter needs to stop */ + bool bindenabled; /**< binding of TCP socket enabled */ bool ipv4tcpenabled; /**< IPv4 TCP enabled by OCInit flags */ bool ipv6tcpenabled; /**< IPv6 TCP enabled by OCInit flags */ } tcp; diff --git a/resource/csdk/connectivity/api/cautilinterface.h b/resource/csdk/connectivity/api/cautilinterface.h old mode 100644 new mode 100755 index af1f3b0..59e0315 --- a/resource/csdk/connectivity/api/cautilinterface.h +++ b/resource/csdk/connectivity/api/cautilinterface.h @@ -482,6 +482,18 @@ CAResult_t CAUnSetTCPKeepAlive(const CAEndpoint_t *endpoint); * @return - Direct 'errno' value from kernel */ int CAGetTCPLastErrorCode(); + +/** + * Set the interface to be used for outgoing TCP packets. + * Tcp client sockets (before establishing connection) will be bound to the IP address of the given WiFi interface. + * Internally, Iotivity reads the IP address assigned to the given interace + * and binds it with the TCP client socket before connect(). + * + * @param[in] ifname WiFi interface name. + * + * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h). + */ +CAResult_t CASetTCPServerSocketBindIP(const char* ifname); #endif #ifdef __cplusplus diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c b/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c old mode 100644 new mode 100755 index 4c5b995..83493d3 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c @@ -360,6 +360,7 @@ static void CAInitializeTCPGlobals() caglobals.tcp.selectTimeout = CA_TCP_SELECT_TIMEOUT; caglobals.tcp.listenBacklog = CA_TCP_LISTEN_BACKLOG; caglobals.tcp.svrlist = NULL; + caglobals.tcp.bindenabled = false; CATransportFlags_t flags = 0; if (caglobals.client) diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c old mode 100644 new mode 100755 index 6a2e24c..ad7f8fb --- a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c @@ -21,6 +21,9 @@ #include #include #include +#if defined(__TIZEN__) +#include +#endif #ifdef __TIZENRT__ #include #include @@ -144,6 +147,8 @@ static CATCPSessionInfo_t *CAGetSessionInfoFromFDAsOwner(int fd, size_t *index); #if defined(__TIZEN__) static char g_cloudproxyUri[CA_MAX_URI_LENGTH]; +static char g_interfaceName[CA_MAX_INTERFACE_NAME_LEN]; + CAResult_t CASetCloudAddressForProxy(const char *uri) { if (uri == NULL) @@ -159,6 +164,22 @@ const char *CAGetCloudAddressForProxy() return NULL; return g_cloudproxyUri; } + +CAResult_t CASetTCPServerSocketBindIP(const char* ifname) +{ + CAResult_t res = CA_STATUS_OK; +#ifdef TCP_ADAPTER + VERIFY_NON_NULL_RET(ifname, TAG, "Interface name is NULL", CA_STATUS_INVALID_PARAM); + + OIC_LOG(DEBUG, TAG, "Setting Socket Bind"); + caglobals.tcp.bindenabled = true; + OICStrcpy(g_interfaceName, sizeof (g_interfaceName), ifname); +#else + OIC_LOG(DEBUG, TAG, "Not supported!"); + res = CA_NOT_SUPPORTED; +#endif + return res; +} #endif #define MAX_TCP_SOCK_COUNT 4 @@ -889,6 +910,54 @@ static CAResult_t CATCPConvertNameToAddr(int family, const char *host, uint16_t } #if defined(__TIZEN__) +static char * CATCPGetInterfaceAddr() +{ + struct ifaddrs *ifaddr, *ifa; + int family, s, n; + char *host = (uint8_t *)OICMalloc(NI_MAXHOST); + + if (getifaddrs(&ifaddr) == -1) + { + OIC_LOG_V(ERROR, TAG, "getifaddrs failed: errno %s", strerror(errno)); + OICFree(host); + return NULL; + } + + for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) + { + if (ifa->ifa_addr == NULL) + continue; + + family = ifa->ifa_addr->sa_family; + OIC_LOG_V(DEBUG, TAG,"Interface name: %s",ifa->ifa_name); + + if ((strncmp(g_interfaceName,ifa->ifa_name,strlen(ifa->ifa_name))==0) + && (family == AF_INET || family == AF_INET6)) + { + s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), + host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + if (s != 0) + { + OIC_LOG_V(ERROR, TAG, "getnameinfo failed: errno %s", strerror(errno)); + freeifaddrs(ifaddr); + OICFree(host); + return NULL; + } + + OIC_LOG_V(DEBUG, TAG, "Interface address: %s", host); + freeifaddrs(ifaddr); + return host; + } + } + + freeifaddrs(ifaddr); + OICFree(host); + OIC_LOG(ERROR, TAG, "Interface address not found"); + return NULL; +} +#endif + +#if defined(__TIZEN__) static int CAGetHTTPStatusCode(char * response) { char *resp, *code_plus, *ptrSave; int ret = -1; @@ -945,6 +1014,42 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem) socklen = sizeof(struct sockaddr_in); } +#if defined(__TIZEN__) + if (caglobals.tcp.bindenabled) + { + char *host_address = CATCPGetInterfaceAddr(); + if (host_address) + { + if (sa.ss_family == AF_INET) + { + struct sockaddr_in client; + memset(&client, 0x00, sizeof(client)); + inet_pton(AF_INET, host_address, &(client.sin_addr.s_addr)); + if (-1 == bind(fd, (struct sockaddr *)&client, socklen)) + { + OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", strerror(errno)); + OICFree(host_address); + return CA_SOCKET_OPERATION_FAILED; + } + } + else + { + struct sockaddr_in6 client6; + memset(&client6, 0x00, sizeof(client6)); + client6.sin6_family = AF_INET6; + inet_pton(AF_INET6, host_address, &client6.sin6_addr.s6_addr); + if (-1 == bind(fd, (struct sockaddr *)&client6, socklen)) + { + OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", strerror(errno)); + OICFree(host_address); + return CA_SOCKET_OPERATION_FAILED; + } + } + OICFree(host_address); + } + } +#endif + // #4. connect to remote server device. if (connect(fd, (struct sockaddr *)&sa, socklen) < 0) { -- 2.7.4