Пример #1
0
CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress,
                                          uint16_t multicastPort)
{
    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");

    // Input validation
    VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
    VERIFY_NON_NULL(multicastAddress, IP_SERVER_TAG, "port");

    uint16_t port = multicastPort;
    if (0 >= port)
    {
        OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: Multicast port is invalid!");
        return CA_STATUS_INVALID_PARAM;
    }

    ca_mutex_lock(g_mutexServerInfoList);
    bool isMulticastServerStarted = CAIsMulticastServerStarted(g_serverInfoList, localAddress,
                                                               multicastAddress, port);
    if (!isMulticastServerStarted)
    {
        int mulicastServerFd = -1;
        CAResult_t ret = CACreateSocket(&mulicastServerFd, multicastAddress, &port, false);
        if (ret != CA_STATUS_OK)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to create multicast socket");
            ca_mutex_unlock(g_mutexServerInfoList);
            return ret;
        }

        struct ip_mreq multicastMemberReq = {.imr_interface.s_addr = inet_addr(localAddress)};
        inet_aton(multicastAddress, &multicastMemberReq.imr_multiaddr);

        if (-1 == setsockopt(mulicastServerFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                             (char *) &multicastMemberReq, sizeof(struct ip_mreq)))
        {
            OIC_LOG_V(ERROR, IP_SERVER_TAG,
                      "Failed to add to multicast group, Error code: %s\n", strerror(errno));
            close(mulicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return CA_STATUS_FAILED;
        }

        CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
        if (!info)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
            close(mulicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return CA_MEMORY_ALLOC_FAILED;
        }

        char *netMask = NULL;
        if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
        }
        if (netMask)
        {
            OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
            OICFree(netMask);
        }

        OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), multicastAddress);
        info->endpoint.port = multicastPort;
        info->endpoint.flags = 0;
        info->socketFd = mulicastServerFd;
        info->isServerStarted = true;
        info->isMulticastServer = true;
        OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);

        ret = CAAddServerInfo(g_serverInfoList, info);

        if (CA_STATUS_OK != ret)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
            close(mulicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return ret;
        }
        ca_mutex_unlock(g_mutexServerInfoList);

        ret = CAIPStartPacketReceiverHandler();
        if (CA_STATUS_OK != ret)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
            close(mulicastServerFd);
            return ret;
        }
    }
Пример #2
0
static void CAReceiveHandler(void *data)
{
    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");

    fd_set readFds;
    int maxSd = 0;
    struct timeval timeout;
    char recvBuffer[COAP_MAX_PDU_SIZE] = { 0 };

    while (true != g_packetHandlerStopFlag)
    {
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        FD_ZERO(&readFds);

        ca_mutex_lock(g_mutexServerInfoList);
        uint32_t listIndex = 0;
        uint32_t listLength = u_arraylist_length(g_serverInfoList);

        u_arraylist_t *tempServerInfoList = u_arraylist_create();
        if (!tempServerInfoList)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_create failed");
            ca_mutex_unlock(g_mutexServerInfoList);
            return;
        }

        for (listIndex = 0; listIndex < listLength; listIndex++)
        {
            CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(g_serverInfoList, listIndex);
            if (!info)
            {
                listIndex++;
                continue;
            }

            int sd = info->socketFd;
            //if valid socket descriptor then add to read list
            if (sd > 0)
            {
                FD_SET(sd, &readFds);
            }

            //highest file descriptor number, need it for the select function
            if (sd > maxSd)
            {
                maxSd = sd;
            }

            CAServerInfo_t *newInfo = (CAServerInfo_t *) OICMalloc(sizeof(CAServerInfo_t));
            if (!newInfo)
            {
                OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
                CAClearServerInfoList(tempServerInfoList);
                ca_mutex_unlock(g_mutexServerInfoList);
                return;
            }

            *newInfo = *info;

            CAResult_t result = u_arraylist_add(tempServerInfoList, (void *) newInfo);
            if (CA_STATUS_OK != result)
            {
                OIC_LOG(ERROR, IP_SERVER_TAG, "u_arraylist_add failed!Thread exit");
                CAClearServerInfoList(tempServerInfoList);
                ca_mutex_unlock(g_mutexServerInfoList);
                return;
            }
        }

        ca_mutex_unlock(g_mutexServerInfoList);

        int ret = select(maxSd + 1, &readFds, NULL, NULL, &timeout);
        if (g_packetHandlerStopFlag)
        {
            OIC_LOG_V(DEBUG, IP_SERVER_TAG,
                      "Packet receiver handler Stop request received. Thread exited");
            CAClearServerInfoList(tempServerInfoList);
            break;
        }
        if (ret < 0)
        {
            OIC_LOG_V(FATAL, IP_SERVER_TAG, "select returned error %s", strerror(errno));
            CAClearServerInfoList(tempServerInfoList);
            continue;
        }

        listLength = u_arraylist_length(tempServerInfoList);
        for (listIndex = 0; listIndex < listLength; listIndex++)
        {
            CAServerInfo_t *info = (CAServerInfo_t *) u_arraylist_get(tempServerInfoList,
                                                                      listIndex);
            if (!info)
            {
                continue;
            }

            int sd = info->socketFd;
            if (FD_ISSET(sd , &readFds))
            {
                OIC_LOG_V(ERROR, IP_SERVER_TAG,
                          "data Received server information ip %s, port %d socket %d",
                          info->endpoint.addr, info->endpoint.port, sd);
                memset(recvBuffer, 0, sizeof(recvBuffer));

                struct sockaddr_in srcSockAddress = { 0 };
                socklen_t srcAddressLen = sizeof(srcSockAddress);

                //Reading from socket
                ssize_t recvLen = recvfrom(sd, recvBuffer, sizeof(recvBuffer), 0,
                                           (struct sockaddr *) &srcSockAddress, &srcAddressLen);
                if (-1 == recvLen)
                {
                    OIC_LOG_V(ERROR, IP_SERVER_TAG, "Recvfrom failed %s", strerror(errno));
                    continue;
                }
                else if (0 == recvLen)
                {
                    OIC_LOG_V(ERROR, IP_SERVER_TAG, "Server socket shutdown sock fd[%d]", sd);
                    ca_mutex_lock(g_mutexAdapterServerContext);
                    // Notify upper layer this exception
                    if (g_adapterIPServerContext->exceptionCallback)
                    {
                        // need to make proper exception callback.
                        //g_adapterIPServerContext->exceptionCallback(ctx->type);
                    }
                    ca_mutex_unlock(g_mutexAdapterServerContext);
                }

                char srcIPAddress[CA_IPADDR_SIZE] = { 0 };
                if (!inet_ntop(AF_INET, &srcSockAddress.sin_addr.s_addr, srcIPAddress,
                               sizeof(srcIPAddress)))
                {

                    OIC_LOG(ERROR, IP_SERVER_TAG, "inet_ntop is failed!");
                    continue;
                }

                uint16_t srcPort = ntohs(srcSockAddress.sin_port);

                OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Received packet from %s:%d len %d",
                          srcIPAddress, srcPort, recvLen);

                char *netMask = NULL;
                if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(info->ifAddr, &netMask))
                {
                    OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
                    continue;
                }

                if (!CAAdapterIsSameSubnet(info->ifAddr, srcIPAddress, netMask))
                {
                    OIC_LOG(DEBUG, IP_SERVER_TAG,
                            "Packet received from different subnet, Ignore!");
                    OICFree(netMask);
                    continue;
                }
                OICFree(netMask);

                CAEndpoint_t ep;
                strncpy(ep.addr, srcIPAddress, MAX_ADDR_STR_SIZE_CA);
                ep.port = srcPort;
                ep.flags = (CATransportFlags_t)CA_IPV4 | CA_IPV6;
                ep.adapter = CA_ADAPTER_IP;

                if (info->endpoint.flags & CA_SECURE)
                {
#ifdef __WITH_DTLS__
                    ep.flags |= CA_SECURE;
                    (void)CAAdapterNetDtlsDecrypt(&ep, (uint8_t *)recvBuffer, recvLen);
                    OIC_LOG_V(DEBUG, IP_SERVER_TAG,
                              "CAAdapterNetDtlsDecrypt returns [%d]", ret);
#endif
                }
                else //both multicast and unicast
                {
                    ca_mutex_lock(g_mutexAdapterServerContext);

                    if (g_adapterIPServerContext->packetReceivedCallback)
                    {
                        g_adapterIPServerContext->packetReceivedCallback(&ep,
                                                          recvBuffer, recvLen);
                    }

                    ca_mutex_unlock(g_mutexAdapterServerContext);
                }
            }
        }
        CAClearServerInfoList(tempServerInfoList);
    }
    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
}
Пример #3
0
CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool isSecured)
{
    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");

    // Input validation
    VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
    VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");

    ca_mutex_lock(g_mutexServerInfoList);
    bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
    if (!isUnicastServerStarted)
    {
        int unicastServerFd = -1;
        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, isSecured,
                                                 &unicastServerFd))
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
            ca_mutex_unlock(g_mutexServerInfoList);
            return CA_STATUS_FAILED;
        }

        CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
        if (!info)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
            close(unicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return CA_MEMORY_ALLOC_FAILED;
        }

        char *netMask = NULL;
        if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
        }
        if (netMask)
        {
            OICStrcpy(info->subNetMask, sizeof(info->subNetMask), netMask);
            OICFree(netMask);
        }
        OICStrcpy(info->endpoint.addr, sizeof(info->endpoint.addr), localAddress);
        info->endpoint.port = *port;
        info->endpoint.flags = isSecured ? CA_SECURE : 0;
        info->endpoint.adapter = CA_ADAPTER_IP;
        info->socketFd = unicastServerFd;
        info->isServerStarted = true;
        info->isMulticastServer = false;
        OICStrcpy(info->ifAddr, sizeof(info->ifAddr), localAddress);

        CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
            close(unicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return res;
        }
        ca_mutex_unlock(g_mutexServerInfoList);

        res = CAIPStartPacketReceiverHandler();
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
            close(unicastServerFd);
            return res;
        }
    }
    else
    {
        OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
                  localAddress, *port);
        ca_mutex_unlock(g_mutexServerInfoList);
    }

    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
    return CA_STATUS_OK;
}
Пример #4
0
CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port,
                                        bool forceBindStart, bool isSecured)
{
    OIC_LOG(DEBUG, IP_SERVER_TAG, "IN");

    // Input validation
    VERIFY_NON_NULL(localAddress, IP_SERVER_TAG, "localAddress");
    VERIFY_NON_NULL(port, IP_SERVER_TAG, "port");

    if (0 >= *port)
    {
        OIC_LOG(ERROR, IP_SERVER_TAG, "Invalid input: port is invalid!");
        return CA_STATUS_INVALID_PARAM;
    }

    ca_mutex_lock(g_mutexServerInfoList);
    bool isUnicastServerStarted = CAIsUnicastServerStarted(g_serverInfoList, localAddress, *port);
    if (!isUnicastServerStarted)
    {
        int unicastServerFd = -1;
        if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceBindStart, isSecured,
                                                 &unicastServerFd))
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to start unicast server!");
            ca_mutex_unlock(g_mutexServerInfoList);
            return CA_STATUS_FAILED;
        }

        CAServerInfo_t *info = (CAServerInfo_t *) OICCalloc(1, sizeof(CAServerInfo_t));
        if (!info)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Malloc failed");
            close(unicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return CA_MEMORY_ALLOC_FAILED;
        }

        char *netMask = NULL;
        if (CA_STATUS_OK != CAIPGetInterfaceSubnetMask(localAddress, &netMask))
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "Failed to get IP subnet");
        }
        if (netMask)
        {
            strncpy(info->subNetMask, netMask, sizeof(info->subNetMask) - 1);
            info->subNetMask[sizeof(info->subNetMask)-1] = '\0';
            OICFree(netMask);
        }
        strncpy(info->ipAddress, localAddress, sizeof(info->ipAddress) - 1);
        info->ipAddress[sizeof(info->ipAddress) - 1] = '\0';
        info->port = *port;
        info->socketFd = unicastServerFd;
        info->isSecured = isSecured;
        info->isServerStarted = true;
        info->isMulticastServer = false;
        strncpy(info->ifAddr, localAddress, sizeof(info->ifAddr) - 1);
        info->ifAddr[sizeof(info->ifAddr) - 1] = '\0';

        CAResult_t res = CAAddServerInfo(g_serverInfoList, info);
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "CAAddServerInfo failed!");
            close(unicastServerFd);
            ca_mutex_unlock(g_mutexServerInfoList);
            return res;
        }
        ca_mutex_unlock(g_mutexServerInfoList);

        res = CAIPStartPacketReceiverHandler();
        if (CA_STATUS_OK != res)
        {
            OIC_LOG(ERROR, IP_SERVER_TAG, "CAIPStartPacketReceiverHandler failed!");
            close(unicastServerFd);
            return res;
        }
    }
    else
    {
        OIC_LOG_V(DEBUG, IP_SERVER_TAG, "Already Unicast Server Started ip [%s] port [%d]",
                  localAddress, *port);
        ca_mutex_unlock(g_mutexServerInfoList);
    }

    OIC_LOG(DEBUG, IP_SERVER_TAG, "OUT");
    return CA_STATUS_OK;
}