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) { int uriHostLength = getUriHostLength(uri, uriLength); if (uriHostLength > 0) result = getCachedAddressByUri(uri, uriHostLength); 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++; while (index < uriLength) { if (uri[index] == ']') { break; } index++; } } else if ((uri[index] == ':') || (uri[index] == '/') ) { hostnameLength = index - startIndex; memcpy(&hostname, &uri[startIndex], hostnameLength); hostname[hostnameLength] = 0; if (uri[index] == '/') break; state = UriParseState_Port; port = 0; startIndex = index + 1; } 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) { hostnameLength = uriLength - startIndex; memcpy(hostname, &uri[startIndex], hostnameLength); hostname[hostnameLength] = 0; } if (hostnameLength > 0 && port > 0) { uip_ipaddr_t * resolvedAddress = getHostByName(hostname); if (resolvedAddress) { NetworkAddress * networkAddress = addCachedAddress(uri, uriHostLength); if (networkAddress) { memcpy(&networkAddress->Address, resolvedAddress, sizeof(uip_ipaddr_t)); networkAddress->Secure = secure; networkAddress->useCount = 1; networkAddress->Port = UIP_HTONS(port); result = networkAddress; } } } } } return result; }