Commit e3c156d2 authored by Jaewook Jung's avatar Jaewook Jung Committed by Dan Mihai

added filter to handle an IP loopback message in CA directly

If IoTivity stack sends a message to itself, which means the loopback,
it is unnecessary to let them go through the socket layer.
Especially it is a waste when the large payload will be sent by block-wise transfer.
So I made CA layer to handle the loopback message directly.

Change-Id: I2b8e5217575df391dd4ab66d924a3a24c2584915
Signed-off-by: default avatarJaewook Jung <jw0213.jung@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/12887Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: default avatarPhil Coval <philippe.coval@osg.samsung.com>
Reviewed-by: default avatarHyuna Jo <hyuna0213.jo@samsung.com>
Reviewed-by: default avatarJaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: default avatarDan Mihai <Daniel.Mihai@microsoft.com>
parent 89781fc8
......@@ -160,6 +160,12 @@ CAResult_t CAStopListeningServerAdapters();
*/
CAResult_t CAStartDiscoveryServerAdapters();
/**
* Check whether the endpoint is my own or not.
* @return true or false.
*/
bool CAIsLocalEndpoint(const CAEndpoint_t *ep);
/**
* Terminates the adapters which are initialized during the initialization.
*/
......
......@@ -133,6 +133,12 @@ CAResult_t CAReadIPData();
*/
CAResult_t CAStopIP();
/**
* Check whether the endpoint is my own or not.
* @return true or false.
*/
bool CAIPIsLocalEndpoint(const CAEndpoint_t *ep);
/**
* Terminate the IP connectivity adapter.
* Configuration information will be deleted from further use.
......
......@@ -752,6 +752,19 @@ CAResult_t CAStartDiscoveryServerAdapters()
return result;
}
bool CAIsLocalEndpoint(const CAEndpoint_t *ep)
{
#ifdef IP_ADAPTER
if (ep->adapter & CA_ADAPTER_IP)
{
return CAIPIsLocalEndpoint(ep);
}
#endif /* IP_ADAPTER */
//TODO: implement for the other adapters(EDR/LE/NFC)
return false;
}
void CATerminateAdapters()
{
for (uint32_t index = 0; index < g_numberOfAdapters; index++)
......
......@@ -999,6 +999,13 @@ CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg
OICFree(data);
#else
if (SEND_TYPE_UNICAST == data->type && CAIsLocalEndpoint(data->remoteEndpoint))
{
OIC_LOG(DEBUG, TAG,
"This is a loopback message. Transfer it to the receive queue directly");
CAQueueingThreadAddData(&g_receiveThread, data, sizeof(CAData_t));
return CA_STATUS_OK;
}
#ifdef WITH_BWT
if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
{
......
......@@ -61,6 +61,11 @@ typedef struct
static CAQueueingThread_t *g_sendQueueHandle = NULL;
#endif
/**
* List of the endpoint that has a stack-owned IP address.
*/
static u_arraylist_t *g_ownIpEndpointList = NULL;
/**
* Network Packet Received Callback to CA.
*/
......@@ -83,6 +88,8 @@ static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint,
const void *data, size_t dataLength);
#endif
static void CAUpdateStoredIPAddressInfo(CANetworkStatus_t status);
#ifndef SINGLE_THREAD
static CAResult_t CAIPInitializeQueueHandles();
......@@ -108,11 +115,20 @@ CAResult_t CAIPInitializeQueueHandles()
return CA_STATUS_OK;
}
g_ownIpEndpointList = u_arraylist_create();
if (!g_ownIpEndpointList)
{
OIC_LOG(ERROR, TAG, "Memory allocation failed! (g_ownIpEndpointList)");
return CA_MEMORY_ALLOC_FAILED;
}
// Create send message queue
g_sendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
if (!g_sendQueueHandle)
{
OIC_LOG(ERROR, TAG, "Memory allocation failed!");
OIC_LOG(ERROR, TAG, "Memory allocation failed! (g_sendQueueHandle)");
u_arraylist_free(&g_ownIpEndpointList);
g_ownIpEndpointList = NULL;
return CA_MEMORY_ALLOC_FAILED;
}
......@@ -123,6 +139,8 @@ CAResult_t CAIPInitializeQueueHandles()
OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
OICFree(g_sendQueueHandle);
g_sendQueueHandle = NULL;
u_arraylist_free(&g_ownIpEndpointList);
g_ownIpEndpointList = NULL;
return CA_STATUS_FAILED;
}
......@@ -134,12 +152,16 @@ void CAIPDeinitializeQueueHandles()
CAQueueingThreadDestroy(g_sendQueueHandle);
OICFree(g_sendQueueHandle);
g_sendQueueHandle = NULL;
u_arraylist_free(&g_ownIpEndpointList);
g_ownIpEndpointList = NULL;
}
#endif // SINGLE_THREAD
void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
{
CAUpdateStoredIPAddressInfo(status);
if (g_networkChangeCallback)
{
g_networkChangeCallback(adapter, status);
......@@ -150,6 +172,40 @@ void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
}
}
static void CAUpdateStoredIPAddressInfo(CANetworkStatus_t status)
{
if (CA_INTERFACE_UP == status)
{
OIC_LOG(DEBUG, TAG, "IP adapter status is on. Store the own IP address info");
CAEndpoint_t *eps = NULL;
uint32_t numOfEps = 0;
CAResult_t res = CAGetIPInterfaceInformation(&eps, &numOfEps);
if (CA_STATUS_OK != res)
{
OIC_LOG(ERROR, TAG, "CAGetIPInterfaceInformation failed");
return;
}
for (size_t i = 0; i < numOfEps; i++)
{
u_arraylist_add(g_ownIpEndpointList, (void *)&eps[i]);
}
}
else // CA_INTERFACE_DOWN
{
OIC_LOG(DEBUG, TAG, "IP adapter status is off. Remove the own IP address info");
uint32_t len = u_arraylist_length(g_ownIpEndpointList);
for (uint32_t i = len; i > 0; i--)
{
CAEndpoint_t *ep = u_arraylist_remove(g_ownIpEndpointList, i - 1);
OICFree(ep);
}
}
}
#ifdef __WITH_DTLS__
static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, size_t dataLength)
{
......@@ -161,7 +217,6 @@ static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, size_t
}
#endif
void CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
size_t dataLength)
{
......@@ -176,6 +231,31 @@ void CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
}
}
bool CAIPIsLocalEndpoint(const CAEndpoint_t *ep)
{
char addr[MAX_ADDR_STR_SIZE_CA];
OICStrcpy(addr, MAX_ADDR_STR_SIZE_CA, ep->addr);
// drop the zone ID if the address of endpoint is IPv6. ifindex will be checked instead.
if ((ep->flags & CA_IPV6) && strchr(addr, '%'))
{
strtok(addr, "%");
}
size_t len = u_arraylist_length(g_ownIpEndpointList);
for (size_t i = 0; i < len; i++)
{
CAEndpoint_t *ownIpEp = u_arraylist_get(g_ownIpEndpointList, i);
if (!strcmp(addr, ownIpEp->addr) && ep->port == ownIpEp->port
&& ep->ifindex == ownIpEp->ifindex)
{
return true;
}
}
return false;
}
void CAIPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
uint32_t dataLength, CAResult_t result)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment