windows: support for getting multiple addresses for a network interface

This commit is contained in:
Igor Zinkovsky 2011-12-14 22:56:53 -08:00
parent 3d189de699
commit 7aacfad447

View File

@ -475,9 +475,11 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
unsigned long size = 0;
IP_ADAPTER_ADDRESSES* adapter_addresses;
IP_ADAPTER_ADDRESSES* adapter_address;
IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
uv_interface_address_t* address;
struct sockaddr* sock_addr;
int length;
char* name;
if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size)
!= ERROR_BUFFER_OVERFLOW) {
@ -500,7 +502,11 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
for (adapter_address = adapter_addresses;
adapter_address != NULL;
adapter_address = adapter_address->Next) {
(*count)++;
unicast_address = adapter_address->FirstUnicastAddress;
while (unicast_address) {
(*count)++;
unicast_address = unicast_address->Next;
}
}
*addresses = (uv_interface_address_t*)
@ -513,41 +519,44 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
for (adapter_address = adapter_addresses;
adapter_address != NULL;
adapter_address = adapter_address->Next,
address++) {
adapter_address = adapter_address->Next) {
name = NULL;
unicast_address = adapter_address->FirstUnicastAddress;
/* Convert FriendlyName to utf8 */
length = uv_utf16_to_utf8(adapter_address->FriendlyName, -1, NULL, 0);
if (!length) {
address->name = NULL;
address->address.address4 = uv_addr_ip4_any_;
continue;
}
address->name = (char*)malloc(length);
if (!address->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (!uv_utf16_to_utf8(adapter_address->FriendlyName, -1, address->name,
length)) {
free(address->name);
address->name = NULL;
address->address.address4 = uv_addr_ip4_any_;
continue;
}
if (adapter_address->FirstUnicastAddress) {
sock_addr = adapter_address->FirstUnicastAddress->Address.lpSockaddr;
while (unicast_address) {
sock_addr = unicast_address->Address.lpSockaddr;
if (sock_addr->sa_family == AF_INET6) {
address->address.address6 = *((struct sockaddr_in6 *)sock_addr);
} else {
address->address.address4 = *((struct sockaddr_in *)sock_addr);
}
}
address->is_internal =
adapter_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? 1 : 0;
address->is_internal =
adapter_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? 1 : 0;
if (!name) {
/* Convert FriendlyName to utf8 */
length = uv_utf16_to_utf8(adapter_address->FriendlyName, -1, NULL, 0);
if (length) {
name = (char*)malloc(length);
if (!name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (!uv_utf16_to_utf8(adapter_address->FriendlyName, -1, name,
length)) {
free(name);
name = NULL;
}
}
}
assert(name);
address->name = name;
unicast_address = unicast_address->Next;
address++;
}
}
free(adapter_addresses);
@ -559,9 +568,13 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
int i;
char* freed_name = NULL;
for (i = 0; i < count; i++) {
free(addresses[i].name);
if (freed_name != addresses[i].name) {
freed_name = addresses[i].name;
free(freed_name);
}
}
free(addresses);