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; }
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); } }
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; }