Esempio n. 1
0
static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
{
    char recvBuffer[COAP_MAX_PDU_SIZE];

    struct sockaddr_storage srcAddr;
    socklen_t srcAddrLen = sizeof (srcAddr);

    ssize_t recvLen = recvfrom(fd,
                               recvBuffer,
                               sizeof (recvBuffer),
                               0,
                               (struct sockaddr *)&srcAddr,
                               &srcAddrLen);
    if (-1 == recvLen)
    {
        OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
        return CA_STATUS_FAILED;
    }

    CASecureEndpoint_t sep =
    {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = flags}};

    if (flags & CA_IPV6)
    {
        sep.endpoint.interface = ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id;
        ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id = 0;
    }
    CAConvertAddrToName(&srcAddr, sep.endpoint.addr, &sep.endpoint.port);

    if (flags & CA_SECURE)
    {
#ifdef __WITH_DTLS__
        int ret = CAAdapterNetDtlsDecrypt(&sep, (uint8_t *)recvBuffer, recvLen);
        OIC_LOG_V(DEBUG, TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
#else
        OIC_LOG(ERROR, TAG, "Encrypted message but no DTLS");
#endif
    }
    else
    {
        if (g_packetReceivedCallback)
        {
            g_packetReceivedCallback(&sep, recvBuffer, recvLen);
        }
    }

    return CA_STATUS_OK;
}
Esempio n. 2
0
static void CAAcceptConnection()
{
    struct sockaddr_storage clientaddr;
    socklen_t clientlen = sizeof (struct sockaddr_in);

    int sockfd = accept(g_acceptServerFD, (struct sockaddr *)&clientaddr,
                        &clientlen);
    if (-1 != sockfd)
    {
        CATCPSessionInfo_t *svritem =
                (CATCPSessionInfo_t *) OICCalloc(1, sizeof (*svritem));
        if (!svritem)
        {
            OIC_LOG(ERROR, TAG, "Out of memory");
            close(sockfd);
            return;
        }

        svritem->fd = sockfd;
        CAConvertAddrToName((struct sockaddr_storage *)&clientaddr, clientlen,
                            (char *) &svritem->sep.endpoint.addr, &svritem->sep.endpoint.port);

        ca_mutex_lock(g_mutexObjectList);
        bool result = u_arraylist_add(caglobals.tcp.svrlist, svritem);
        if (!result)
        {
            OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
            close(sockfd);
            OICFree(svritem);
            ca_mutex_unlock(g_mutexObjectList);
            return;
        }
        ca_mutex_unlock(g_mutexObjectList);

        CHECKFD(sockfd);
    }
}
Esempio n. 3
0
static CAResult_t CAReceiveMessage(int fd, CATransportFlags_t flags)
{
    char recvBuffer[COAP_MAX_PDU_SIZE];

    size_t len;
    int level, type, namelen;
    struct sockaddr_storage srcAddr;
    unsigned char *pktinfo = NULL;
    struct cmsghdr *cmp = NULL;
    struct iovec iov = { recvBuffer, sizeof (recvBuffer) };
    union control
    {
        struct cmsghdr cmsg;
        unsigned char data[CMSG_SPACE(sizeof (struct in6_pktinfo))];
    } cmsg;

    if (flags & CA_IPV6)
    {
        namelen = sizeof (struct sockaddr_in6);
        level = IPPROTO_IPV6;
        type = IPV6_PKTINFO;
        len = sizeof (struct in6_pktinfo);
    }
    else
    {
        namelen = sizeof (struct sockaddr_in);
        level = IPPROTO_IP;
        type = IP_PKTINFO;
        len = sizeof (struct in6_pktinfo);
    }

    struct msghdr msg = { .msg_name = &srcAddr,
                          .msg_namelen = namelen,
                          .msg_iov = &iov,
                          .msg_iovlen = 1,
                          .msg_control = &cmsg,
                          .msg_controllen = CMSG_SPACE(len) };

    ssize_t recvLen = recvmsg(fd, &msg, flags);
    if (-1 == recvLen)
    {
        OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
        return CA_STATUS_FAILED;
    }

    if (flags & CA_MULTICAST)
    {
        for (cmp = CMSG_FIRSTHDR(&msg); cmp != NULL; cmp = CMSG_NXTHDR(&msg, cmp))
        {
            if (cmp->cmsg_level == level && cmp->cmsg_type == type)
            {
                pktinfo = CMSG_DATA(cmp);
            }
        }
    }

    CASecureEndpoint_t sep = {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = flags}};

    if (flags & CA_IPV6)
    {
        sep.endpoint.interface = ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id;
        ((struct sockaddr_in6 *)&srcAddr)->sin6_scope_id = 0;

        if ((flags & CA_MULTICAST) && pktinfo)
        {
            struct in6_addr *addr = &(((struct in6_pktinfo *)pktinfo)->ipi6_addr);
            unsigned char topbits = ((unsigned char *)addr)[0];
            if (topbits != 0xff)
            {
                sep.endpoint.flags &= ~CA_MULTICAST;
            }
        }
    }
    else
    {
        if ((flags & CA_MULTICAST) && pktinfo)
        {
            struct in_addr *addr = &((struct in_pktinfo *)pktinfo)->ipi_addr;
            uint32_t host = ntohl(addr->s_addr);
            unsigned char topbits = ((unsigned char *)&host)[3];
            if (topbits < 224 || topbits > 239)
            {
                sep.endpoint.flags &= ~CA_MULTICAST;
            }
        }
    }

    CAConvertAddrToName(&srcAddr, msg.msg_namelen, sep.endpoint.addr, &sep.endpoint.port);

    if (flags & CA_SECURE)
    {
#ifdef __WITH_DTLS__
        int ret = CAAdapterNetDtlsDecrypt(&sep, (uint8_t *)recvBuffer, recvLen);
        OIC_LOG_V(DEBUG, TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
#else
        OIC_LOG(ERROR, TAG, "Encrypted message but no DTLS");
#endif
    }
    else
    {
        if (g_packetReceivedCallback)
        {
            g_packetReceivedCallback(&sep, recvBuffer, recvLen);
        }
    }

    return CA_STATUS_OK;
}