bool readUDP(NetworkSocket * networkSocket, int socketHandle, uint8_t * buffer, int bufferLength, NetworkAddress ** sourceAddress, int *readLength) { bool result = false; struct sockaddr_storage sourceSocket; socklen_t sourceSocketLength = sizeof(struct sockaddr_storage); errno = 0; *readLength = recvfrom(socketHandle, buffer, bufferLength, MSG_DONTWAIT, (struct sockaddr *)&sourceSocket, &sourceSocketLength); int lastError = errno; if (*readLength == SOCKET_ERROR) { *readLength = 0; if ((lastError == EWOULDBLOCK) || (lastError == EAGAIN)) { result = true; } else { networkSocket->LastError = NetworkSocketError_ReadError; } } else { NetworkAddress * networkAddress = NULL; NetworkAddress matchAddress; size_t size = sizeof(struct _NetworkAddress); memset(&matchAddress, 0, size); memcpy(&matchAddress.Address.Sa, &sourceSocket, sourceSocketLength); matchAddress.Secure = (networkSocket->SocketType & NetworkSocketType_Secure) == NetworkSocketType_Secure; networkAddress = getCachedAddress(&matchAddress, NULL, 0); if (networkAddress == NULL) { networkAddress = (NetworkAddress *)malloc(size); if (networkAddress) { // Add new address to cache (note: uri and secure is unknown) memcpy(networkAddress, &matchAddress, size); addCachedAddress(networkAddress, NULL, 0); networkAddress->useCount++; // TODO - ensure addresses are freed? (after t/o or transaction or DTLS session closed) } } if (networkAddress) { *sourceAddress = networkAddress; result = true; } } return result; }
bool readUDP(NetworkSocket * networkSocket, uint8_t * buffer, int bufferLength, NetworkAddress ** sourceAddress, int *readLength) { bool result = true; *readLength = 0; //if (uip_newdata() && (UIP_IP_BUF->destport == networkSocket->Port) ) if (uip_newdata()) { Lwm2m_Debug("Packet from: %d %d\n", UIP_IP_BUF->destport, networkSocket->Port); if (uip_datalen() > bufferLength) *readLength = bufferLength; else *readLength = uip_datalen(); } if (*readLength > 0) { memcpy(buffer, uip_appdata, *readLength); NetworkAddress * networkAddress = NULL; NetworkAddress matchAddress; size_t size = sizeof(struct _NetworkAddress); memset(&matchAddress, 0, size); memcpy(&matchAddress.Address, &UIP_IP_BUF->srcipaddr, sizeof(uip_ipaddr_t)); matchAddress.Port = UIP_IP_BUF->srcport; //uip_ntohs(UIP_UDP_BUF->srcport); matchAddress.Secure = (networkSocket->SocketType & NetworkSocketType_Secure) == NetworkSocketType_Secure; networkAddress = getCachedAddress(&matchAddress, NULL, 0); if (networkAddress == NULL) { networkAddress = addCachedAddress(NULL, 0); if (networkAddress) { // Add new address to cache (note: uri and secure is unknown) memcpy(networkAddress, &matchAddress, size); networkAddress->useCount++; // TODO - ensure addresses are freed? (after t/o or transaction or DTLS session closed) } } if (networkAddress) { *sourceAddress = networkAddress; } } return result; }
bool readUDP(NetworkSocket * networkSocket, uint8_t * buffer, int bufferLength, NetworkAddress ** sourceAddress, int *readLength) { bool result = true; *readLength = 0; //if (uip_newdata() && (UIP_IP_BUF->destport == networkSocket->Port) ) if (uip_newdata()) { Lwm2m_Debug("Packet from: %d %d\n", uip_htons(UIP_IP_BUF->destport), networkSocket->Port); if (uip_datalen() > bufferLength) *readLength = bufferLength; else *readLength = uip_datalen(); } if (*readLength > 0) { uip_ipaddr_t * address = &UIP_IP_BUF->srcipaddr; uint16_t port = uip_htons(UIP_IP_BUF->srcport); bool secure = (networkSocket->SocketType & NetworkSocketType_Secure) == NetworkSocketType_Secure; memcpy(buffer, uip_appdata, *readLength); NetworkAddress * networkAddress = getCachedAddress(address, port); if (networkAddress == NULL) { networkAddress = addCachedAddress(address, port, secure); if (networkAddress) { networkAddress->useCount++; // TODO - ensure addresses are freed? (after t/o or transaction or DTLS session closed) } } if (networkAddress) { *sourceAddress = networkAddress; } } return result; }
NetworkAddress * NetworkAddress_New(const char * uri, int uriLength) { NetworkAddress * result = NULL; if (uri && uriLength > 0) { int uriHostLength = getUriHostLength(uri, uriLength); if (uriHostLength > 0) result = getCachedAddressByUri(uri, uriHostLength); if (!result) { bool ip6Address = false; bool secure = false; int index = 0; int startIndex = 0; int port = 5683; char hostname[MAX_URI_LENGTH]; int hostnameLength = 0; UriParseState state = UriParseState_Scheme; while (index < uriLength) { if (state == UriParseState_Scheme) { if ((uri[index] == ':') && ((index + 2) < uriLength) && (uri[index+1] == '/') && (uri[index+2] == '/')) { int length = index - startIndex; if ((length == 4) && (strncmp(&uri[startIndex],"coap", length) == 0)) { } else if ((length == 5) && (strncmp(&uri[startIndex],"coaps", length) == 0)) { port = 5684; secure = true; } else { break; } state = UriParseState_Hostname; index += 2; startIndex = index + 1; } index++; } else if (state == UriParseState_Hostname) { if ((uri[index] == '[') ) { index++; startIndex = index; while (index < uriLength) { if (uri[index] == ']') { ip6Address = true; break; } hostname[hostnameLength] = uri[index]; hostnameLength++; index++; } } else if ((uri[index] == ':') || (uri[index] == '/') ) { hostname[hostnameLength] = 0; if (uri[index] == '/') break; state = UriParseState_Port; port = 0; startIndex = index + 1; } else { hostname[hostnameLength] = uri[index]; hostnameLength++; } index++; } else if (state == UriParseState_Port) { if (uri[index] == '/') { break; } else if (isdigit(uri[index])) { port = (port * 10) + (uri[index] - '0'); } index++; } } if (state == UriParseState_Hostname) { hostname[hostnameLength] = 0; } if (hostnameLength > 0 && port > 0) { NetworkAddress * networkAddress = NULL; if (ip6Address) { networkAddress = NetworkAddress_FromIPAddress(hostname, port); } else { struct hostent *resolvedAddress = gethostbyname(hostname); if (resolvedAddress) { size_t size = sizeof(struct _NetworkAddress); networkAddress = (NetworkAddress *) malloc(size); if (networkAddress) { memset(networkAddress, 0, size); if (resolvedAddress->h_addrtype == AF_INET) { networkAddress->Address.Sin.sin_family = AF_INET; memcpy(&networkAddress->Address.Sin.sin_addr, *(resolvedAddress->h_addr_list), sizeof(struct in_addr)); networkAddress->Address.Sin.sin_port = htons(port); } else if (resolvedAddress->h_addrtype == AF_INET6) { networkAddress->Address.Sin6.sin6_family = AF_INET6; memcpy(&networkAddress->Address.Sin6.sin6_addr, *(resolvedAddress->h_addr_list), sizeof(struct in6_addr)); networkAddress->Address.Sin6.sin6_port = htons(port); } else { free(networkAddress); networkAddress = NULL; } } } } if (networkAddress) { networkAddress->Secure = secure; result = getCachedAddress(networkAddress, uri, uriHostLength); if (result) { // Matched existing address free(networkAddress); } else { result = networkAddress; } } } } if (result) { if (result->useCount == 0) { addCachedAddress(result, uri, uriHostLength); } result->useCount++; } } return result; }
NetworkAddress * NetworkAddress_New(const char * uri, int uriLength) { NetworkAddress * result = NULL; if (uri && uriLength > 0) { if (!result) { bool secure = false; int index = 0; int startIndex = 0; int port = 5683; char hostname[MAX_URI_LENGTH]; int hostnameLength = 0; UriParseState state = UriParseState_Scheme; while (index < uriLength) { if (state == UriParseState_Scheme) { if ((uri[index] == ':') && ((index + 2) < uriLength) && (uri[index+1] == '/') && (uri[index+2] == '/')) { int length = index - startIndex; if ((length == 4) && (strncmp(&uri[startIndex],"coap", length) == 0)) { } else if ((length == 5) && (strncmp(&uri[startIndex],"coaps", length) == 0)) { port = 5684; secure = true; } else { break; } state = UriParseState_Hostname; index += 2; startIndex = index + 1; } index++; } else if (state == UriParseState_Hostname) { if ((uri[index] == '[') ) { index++; startIndex = index; while (index < uriLength) { if (uri[index] == ']') { break; } hostname[hostnameLength] = uri[index]; hostnameLength++; index++; } } else if ((uri[index] == ':') || (uri[index] == '/') ) { hostname[hostnameLength] = 0; if (uri[index] == '/') break; state = UriParseState_Port; port = 0; startIndex = index + 1; } else { hostname[hostnameLength] = uri[index]; hostnameLength++; } index++; } else if (state == UriParseState_Port) { if (uri[index] == '/') { break; } else if (isdigit(uri[index])) { port = (port * 10) + (uri[index] - '0'); } index++; } } if (state == UriParseState_Hostname) { hostname[hostnameLength] = 0; } if (hostnameLength > 0 && port > 0) { uip_ipaddr_t * resolvedAddress = getHostByName(hostname); if (resolvedAddress) { NetworkAddress * networkAddress = getCachedAddress(resolvedAddress, port); if(!networkAddress) { networkAddress = addCachedAddress(resolvedAddress, port, secure); } if (networkAddress) { result = networkAddress; } } } } if(result) { result->useCount++; } } return result; }