1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * 3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 9e66f31c5Sopenharmony_ci * 10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 12e66f31c5Sopenharmony_ci * 13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 20e66f31c5Sopenharmony_ci */ 21e66f31c5Sopenharmony_ci 22e66f31c5Sopenharmony_ci#include <assert.h> 23e66f31c5Sopenharmony_ci 24e66f31c5Sopenharmony_ci#include "uv.h" 25e66f31c5Sopenharmony_ci#include "internal.h" 26e66f31c5Sopenharmony_ci#include "req-inl.h" 27e66f31c5Sopenharmony_ci#include "idna.h" 28e66f31c5Sopenharmony_ci 29e66f31c5Sopenharmony_ci/* EAI_* constants. */ 30e66f31c5Sopenharmony_ci#include <winsock2.h> 31e66f31c5Sopenharmony_ci 32e66f31c5Sopenharmony_ci/* Needed for ConvertInterfaceIndexToLuid and ConvertInterfaceLuidToNameA */ 33e66f31c5Sopenharmony_ci#include <iphlpapi.h> 34e66f31c5Sopenharmony_ci 35e66f31c5Sopenharmony_ciint uv__getaddrinfo_translate_error(int sys_err) { 36e66f31c5Sopenharmony_ci switch (sys_err) { 37e66f31c5Sopenharmony_ci case 0: return 0; 38e66f31c5Sopenharmony_ci case WSATRY_AGAIN: return UV_EAI_AGAIN; 39e66f31c5Sopenharmony_ci case WSAEINVAL: return UV_EAI_BADFLAGS; 40e66f31c5Sopenharmony_ci case WSANO_RECOVERY: return UV_EAI_FAIL; 41e66f31c5Sopenharmony_ci case WSAEAFNOSUPPORT: return UV_EAI_FAMILY; 42e66f31c5Sopenharmony_ci case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY; 43e66f31c5Sopenharmony_ci case WSAHOST_NOT_FOUND: return UV_EAI_NONAME; 44e66f31c5Sopenharmony_ci case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE; 45e66f31c5Sopenharmony_ci case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE; 46e66f31c5Sopenharmony_ci default: return uv_translate_sys_error(sys_err); 47e66f31c5Sopenharmony_ci } 48e66f31c5Sopenharmony_ci} 49e66f31c5Sopenharmony_ci 50e66f31c5Sopenharmony_ci 51e66f31c5Sopenharmony_ci/* 52e66f31c5Sopenharmony_ci * MinGW is missing this 53e66f31c5Sopenharmony_ci */ 54e66f31c5Sopenharmony_ci#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR) 55e66f31c5Sopenharmony_ci typedef struct addrinfoW { 56e66f31c5Sopenharmony_ci int ai_flags; 57e66f31c5Sopenharmony_ci int ai_family; 58e66f31c5Sopenharmony_ci int ai_socktype; 59e66f31c5Sopenharmony_ci int ai_protocol; 60e66f31c5Sopenharmony_ci size_t ai_addrlen; 61e66f31c5Sopenharmony_ci WCHAR* ai_canonname; 62e66f31c5Sopenharmony_ci struct sockaddr* ai_addr; 63e66f31c5Sopenharmony_ci struct addrinfoW* ai_next; 64e66f31c5Sopenharmony_ci } ADDRINFOW, *PADDRINFOW; 65e66f31c5Sopenharmony_ci 66e66f31c5Sopenharmony_ci DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node, 67e66f31c5Sopenharmony_ci const WCHAR* service, 68e66f31c5Sopenharmony_ci const ADDRINFOW* hints, 69e66f31c5Sopenharmony_ci PADDRINFOW* result); 70e66f31c5Sopenharmony_ci 71e66f31c5Sopenharmony_ci DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo); 72e66f31c5Sopenharmony_ci#endif 73e66f31c5Sopenharmony_ci 74e66f31c5Sopenharmony_ci 75e66f31c5Sopenharmony_ci/* Adjust size value to be multiple of 4. Use to keep pointer aligned. 76e66f31c5Sopenharmony_ci * Do we need different versions of this for different architectures? */ 77e66f31c5Sopenharmony_ci#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) 78e66f31c5Sopenharmony_ci 79e66f31c5Sopenharmony_ci#ifndef NDIS_IF_MAX_STRING_SIZE 80e66f31c5Sopenharmony_ci#define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE 81e66f31c5Sopenharmony_ci#endif 82e66f31c5Sopenharmony_ci 83e66f31c5Sopenharmony_cistatic void uv__getaddrinfo_work(struct uv__work* w) { 84e66f31c5Sopenharmony_ci uv_getaddrinfo_t* req; 85e66f31c5Sopenharmony_ci struct addrinfoW* hints; 86e66f31c5Sopenharmony_ci int err; 87e66f31c5Sopenharmony_ci 88e66f31c5Sopenharmony_ci req = container_of(w, uv_getaddrinfo_t, work_req); 89e66f31c5Sopenharmony_ci hints = req->addrinfow; 90e66f31c5Sopenharmony_ci req->addrinfow = NULL; 91e66f31c5Sopenharmony_ci err = GetAddrInfoW(req->node, req->service, hints, &req->addrinfow); 92e66f31c5Sopenharmony_ci req->retcode = uv__getaddrinfo_translate_error(err); 93e66f31c5Sopenharmony_ci} 94e66f31c5Sopenharmony_ci 95e66f31c5Sopenharmony_ci 96e66f31c5Sopenharmony_ci/* 97e66f31c5Sopenharmony_ci * Called from uv_run when complete. Call user specified callback 98e66f31c5Sopenharmony_ci * then free returned addrinfo 99e66f31c5Sopenharmony_ci * Returned addrinfo strings are converted from UTF-16 to UTF-8. 100e66f31c5Sopenharmony_ci * 101e66f31c5Sopenharmony_ci * To minimize allocation we calculate total size required, 102e66f31c5Sopenharmony_ci * and copy all structs and referenced strings into the one block. 103e66f31c5Sopenharmony_ci * Each size calculation is adjusted to avoid unaligned pointers. 104e66f31c5Sopenharmony_ci */ 105e66f31c5Sopenharmony_cistatic void uv__getaddrinfo_done(struct uv__work* w, int status) { 106e66f31c5Sopenharmony_ci uv_getaddrinfo_t* req; 107e66f31c5Sopenharmony_ci size_t addrinfo_len = 0; 108e66f31c5Sopenharmony_ci ssize_t name_len = 0; 109e66f31c5Sopenharmony_ci size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); 110e66f31c5Sopenharmony_ci struct addrinfoW* addrinfow_ptr; 111e66f31c5Sopenharmony_ci struct addrinfo* addrinfo_ptr; 112e66f31c5Sopenharmony_ci char* alloc_ptr = NULL; 113e66f31c5Sopenharmony_ci char* cur_ptr = NULL; 114e66f31c5Sopenharmony_ci int r; 115e66f31c5Sopenharmony_ci 116e66f31c5Sopenharmony_ci req = container_of(w, uv_getaddrinfo_t, work_req); 117e66f31c5Sopenharmony_ci 118e66f31c5Sopenharmony_ci /* release input parameter memory */ 119e66f31c5Sopenharmony_ci uv__free(req->alloc); 120e66f31c5Sopenharmony_ci req->alloc = NULL; 121e66f31c5Sopenharmony_ci 122e66f31c5Sopenharmony_ci if (status == UV_ECANCELED) { 123e66f31c5Sopenharmony_ci assert(req->retcode == 0); 124e66f31c5Sopenharmony_ci req->retcode = UV_EAI_CANCELED; 125e66f31c5Sopenharmony_ci goto complete; 126e66f31c5Sopenharmony_ci } 127e66f31c5Sopenharmony_ci 128e66f31c5Sopenharmony_ci if (req->retcode == 0) { 129e66f31c5Sopenharmony_ci /* Convert addrinfoW to addrinfo. First calculate required length. */ 130e66f31c5Sopenharmony_ci addrinfow_ptr = req->addrinfow; 131e66f31c5Sopenharmony_ci while (addrinfow_ptr != NULL) { 132e66f31c5Sopenharmony_ci addrinfo_len += addrinfo_struct_len + 133e66f31c5Sopenharmony_ci ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); 134e66f31c5Sopenharmony_ci if (addrinfow_ptr->ai_canonname != NULL) { 135e66f31c5Sopenharmony_ci name_len = uv_utf16_length_as_wtf8(addrinfow_ptr->ai_canonname, -1); 136e66f31c5Sopenharmony_ci if (name_len < 0) { 137e66f31c5Sopenharmony_ci req->retcode = name_len; 138e66f31c5Sopenharmony_ci goto complete; 139e66f31c5Sopenharmony_ci } 140e66f31c5Sopenharmony_ci addrinfo_len += ALIGNED_SIZE(name_len + 1); 141e66f31c5Sopenharmony_ci } 142e66f31c5Sopenharmony_ci addrinfow_ptr = addrinfow_ptr->ai_next; 143e66f31c5Sopenharmony_ci } 144e66f31c5Sopenharmony_ci 145e66f31c5Sopenharmony_ci /* allocate memory for addrinfo results */ 146e66f31c5Sopenharmony_ci alloc_ptr = (char*)uv__malloc(addrinfo_len); 147e66f31c5Sopenharmony_ci 148e66f31c5Sopenharmony_ci /* do conversions */ 149e66f31c5Sopenharmony_ci if (alloc_ptr != NULL) { 150e66f31c5Sopenharmony_ci cur_ptr = alloc_ptr; 151e66f31c5Sopenharmony_ci addrinfow_ptr = req->addrinfow; 152e66f31c5Sopenharmony_ci 153e66f31c5Sopenharmony_ci while (addrinfow_ptr != NULL) { 154e66f31c5Sopenharmony_ci /* copy addrinfo struct data */ 155e66f31c5Sopenharmony_ci assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); 156e66f31c5Sopenharmony_ci addrinfo_ptr = (struct addrinfo*)cur_ptr; 157e66f31c5Sopenharmony_ci addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; 158e66f31c5Sopenharmony_ci addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; 159e66f31c5Sopenharmony_ci addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; 160e66f31c5Sopenharmony_ci addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; 161e66f31c5Sopenharmony_ci addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; 162e66f31c5Sopenharmony_ci addrinfo_ptr->ai_canonname = NULL; 163e66f31c5Sopenharmony_ci addrinfo_ptr->ai_addr = NULL; 164e66f31c5Sopenharmony_ci addrinfo_ptr->ai_next = NULL; 165e66f31c5Sopenharmony_ci 166e66f31c5Sopenharmony_ci cur_ptr += addrinfo_struct_len; 167e66f31c5Sopenharmony_ci 168e66f31c5Sopenharmony_ci /* copy sockaddr */ 169e66f31c5Sopenharmony_ci if (addrinfo_ptr->ai_addrlen > 0) { 170e66f31c5Sopenharmony_ci assert(cur_ptr + addrinfo_ptr->ai_addrlen <= 171e66f31c5Sopenharmony_ci alloc_ptr + addrinfo_len); 172e66f31c5Sopenharmony_ci memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); 173e66f31c5Sopenharmony_ci addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; 174e66f31c5Sopenharmony_ci cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); 175e66f31c5Sopenharmony_ci } 176e66f31c5Sopenharmony_ci 177e66f31c5Sopenharmony_ci /* convert canonical name to UTF-8 */ 178e66f31c5Sopenharmony_ci if (addrinfow_ptr->ai_canonname != NULL) { 179e66f31c5Sopenharmony_ci name_len = alloc_ptr + addrinfo_len - cur_ptr; 180e66f31c5Sopenharmony_ci r = uv__copy_utf16_to_utf8(addrinfow_ptr->ai_canonname, 181e66f31c5Sopenharmony_ci -1, 182e66f31c5Sopenharmony_ci cur_ptr, 183e66f31c5Sopenharmony_ci (size_t*)&name_len); 184e66f31c5Sopenharmony_ci assert(r == 0); 185e66f31c5Sopenharmony_ci addrinfo_ptr->ai_canonname = cur_ptr; 186e66f31c5Sopenharmony_ci cur_ptr += ALIGNED_SIZE(name_len + 1); 187e66f31c5Sopenharmony_ci } 188e66f31c5Sopenharmony_ci assert(cur_ptr <= alloc_ptr + addrinfo_len); 189e66f31c5Sopenharmony_ci 190e66f31c5Sopenharmony_ci /* set next ptr */ 191e66f31c5Sopenharmony_ci addrinfow_ptr = addrinfow_ptr->ai_next; 192e66f31c5Sopenharmony_ci if (addrinfow_ptr != NULL) { 193e66f31c5Sopenharmony_ci addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; 194e66f31c5Sopenharmony_ci } 195e66f31c5Sopenharmony_ci } 196e66f31c5Sopenharmony_ci req->addrinfo = (struct addrinfo*)alloc_ptr; 197e66f31c5Sopenharmony_ci } else { 198e66f31c5Sopenharmony_ci req->retcode = UV_EAI_MEMORY; 199e66f31c5Sopenharmony_ci } 200e66f31c5Sopenharmony_ci } 201e66f31c5Sopenharmony_ci 202e66f31c5Sopenharmony_ci /* return memory to system */ 203e66f31c5Sopenharmony_ci if (req->addrinfow != NULL) { 204e66f31c5Sopenharmony_ci FreeAddrInfoW(req->addrinfow); 205e66f31c5Sopenharmony_ci req->addrinfow = NULL; 206e66f31c5Sopenharmony_ci } 207e66f31c5Sopenharmony_ci 208e66f31c5Sopenharmony_cicomplete: 209e66f31c5Sopenharmony_ci uv__req_unregister(req->loop, req); 210e66f31c5Sopenharmony_ci 211e66f31c5Sopenharmony_ci /* finally do callback with converted result */ 212e66f31c5Sopenharmony_ci if (req->getaddrinfo_cb) 213e66f31c5Sopenharmony_ci req->getaddrinfo_cb(req, req->retcode, req->addrinfo); 214e66f31c5Sopenharmony_ci} 215e66f31c5Sopenharmony_ci 216e66f31c5Sopenharmony_ci 217e66f31c5Sopenharmony_civoid uv_freeaddrinfo(struct addrinfo* ai) { 218e66f31c5Sopenharmony_ci char* alloc_ptr = (char*)ai; 219e66f31c5Sopenharmony_ci 220e66f31c5Sopenharmony_ci /* release copied result memory */ 221e66f31c5Sopenharmony_ci uv__free(alloc_ptr); 222e66f31c5Sopenharmony_ci} 223e66f31c5Sopenharmony_ci 224e66f31c5Sopenharmony_ci 225e66f31c5Sopenharmony_ci/* 226e66f31c5Sopenharmony_ci * Entry point for getaddrinfo 227e66f31c5Sopenharmony_ci * we convert the UTF-8 strings to UNICODE 228e66f31c5Sopenharmony_ci * and save the UNICODE string pointers in the req 229e66f31c5Sopenharmony_ci * We also copy hints so that caller does not need to keep memory until the 230e66f31c5Sopenharmony_ci * callback. 231e66f31c5Sopenharmony_ci * return 0 if a callback will be made 232e66f31c5Sopenharmony_ci * return error code if validation fails 233e66f31c5Sopenharmony_ci * 234e66f31c5Sopenharmony_ci * To minimize allocation we calculate total size required, 235e66f31c5Sopenharmony_ci * and copy all structs and referenced strings into the one block. 236e66f31c5Sopenharmony_ci * Each size calculation is adjusted to avoid unaligned pointers. 237e66f31c5Sopenharmony_ci */ 238e66f31c5Sopenharmony_ciint uv_getaddrinfo(uv_loop_t* loop, 239e66f31c5Sopenharmony_ci uv_getaddrinfo_t* req, 240e66f31c5Sopenharmony_ci uv_getaddrinfo_cb getaddrinfo_cb, 241e66f31c5Sopenharmony_ci const char* node, 242e66f31c5Sopenharmony_ci const char* service, 243e66f31c5Sopenharmony_ci const struct addrinfo* hints) { 244e66f31c5Sopenharmony_ci char hostname_ascii[256]; 245e66f31c5Sopenharmony_ci size_t nodesize = 0; 246e66f31c5Sopenharmony_ci size_t servicesize = 0; 247e66f31c5Sopenharmony_ci size_t hintssize = 0; 248e66f31c5Sopenharmony_ci char* alloc_ptr = NULL; 249e66f31c5Sopenharmony_ci ssize_t rc; 250e66f31c5Sopenharmony_ci 251e66f31c5Sopenharmony_ci if (req == NULL || (node == NULL && service == NULL)) { 252e66f31c5Sopenharmony_ci return UV_EINVAL; 253e66f31c5Sopenharmony_ci } 254e66f31c5Sopenharmony_ci 255e66f31c5Sopenharmony_ci UV_REQ_INIT(req, UV_GETADDRINFO); 256e66f31c5Sopenharmony_ci req->getaddrinfo_cb = getaddrinfo_cb; 257e66f31c5Sopenharmony_ci req->addrinfo = NULL; 258e66f31c5Sopenharmony_ci req->loop = loop; 259e66f31c5Sopenharmony_ci req->retcode = 0; 260e66f31c5Sopenharmony_ci 261e66f31c5Sopenharmony_ci /* calculate required memory size for all input values */ 262e66f31c5Sopenharmony_ci if (node != NULL) { 263e66f31c5Sopenharmony_ci rc = uv__idna_toascii(node, 264e66f31c5Sopenharmony_ci node + strlen(node), 265e66f31c5Sopenharmony_ci hostname_ascii, 266e66f31c5Sopenharmony_ci hostname_ascii + sizeof(hostname_ascii)); 267e66f31c5Sopenharmony_ci if (rc < 0) 268e66f31c5Sopenharmony_ci return rc; 269e66f31c5Sopenharmony_ci nodesize = strlen(hostname_ascii) + 1; 270e66f31c5Sopenharmony_ci node = hostname_ascii; 271e66f31c5Sopenharmony_ci } 272e66f31c5Sopenharmony_ci 273e66f31c5Sopenharmony_ci if (service != NULL) { 274e66f31c5Sopenharmony_ci rc = uv_wtf8_length_as_utf16(service); 275e66f31c5Sopenharmony_ci if (rc < 0) 276e66f31c5Sopenharmony_ci return rc; 277e66f31c5Sopenharmony_ci servicesize = rc; 278e66f31c5Sopenharmony_ci } 279e66f31c5Sopenharmony_ci if (hints != NULL) { 280e66f31c5Sopenharmony_ci hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); 281e66f31c5Sopenharmony_ci } 282e66f31c5Sopenharmony_ci 283e66f31c5Sopenharmony_ci /* allocate memory for inputs, and partition it as needed */ 284e66f31c5Sopenharmony_ci alloc_ptr = uv__malloc(ALIGNED_SIZE(nodesize * sizeof(WCHAR)) + 285e66f31c5Sopenharmony_ci ALIGNED_SIZE(servicesize * sizeof(WCHAR)) + 286e66f31c5Sopenharmony_ci hintssize); 287e66f31c5Sopenharmony_ci if (!alloc_ptr) 288e66f31c5Sopenharmony_ci return UV_ENOMEM; 289e66f31c5Sopenharmony_ci 290e66f31c5Sopenharmony_ci /* save alloc_ptr now so we can free if error */ 291e66f31c5Sopenharmony_ci req->alloc = (void*) alloc_ptr; 292e66f31c5Sopenharmony_ci 293e66f31c5Sopenharmony_ci /* Convert node string to UTF16 into allocated memory and save pointer in the 294e66f31c5Sopenharmony_ci * request. The node here has been converted to ascii. */ 295e66f31c5Sopenharmony_ci if (node != NULL) { 296e66f31c5Sopenharmony_ci req->node = (WCHAR*) alloc_ptr; 297e66f31c5Sopenharmony_ci uv_wtf8_to_utf16(node, (WCHAR*) alloc_ptr, nodesize); 298e66f31c5Sopenharmony_ci alloc_ptr += ALIGNED_SIZE(nodesize * sizeof(WCHAR)); 299e66f31c5Sopenharmony_ci } else { 300e66f31c5Sopenharmony_ci req->node = NULL; 301e66f31c5Sopenharmony_ci } 302e66f31c5Sopenharmony_ci 303e66f31c5Sopenharmony_ci /* Convert service string to UTF16 into allocated memory and save pointer in 304e66f31c5Sopenharmony_ci * the req. */ 305e66f31c5Sopenharmony_ci if (service != NULL) { 306e66f31c5Sopenharmony_ci req->service = (WCHAR*) alloc_ptr; 307e66f31c5Sopenharmony_ci uv_wtf8_to_utf16(service, (WCHAR*) alloc_ptr, servicesize); 308e66f31c5Sopenharmony_ci alloc_ptr += ALIGNED_SIZE(servicesize * sizeof(WCHAR)); 309e66f31c5Sopenharmony_ci } else { 310e66f31c5Sopenharmony_ci req->service = NULL; 311e66f31c5Sopenharmony_ci } 312e66f31c5Sopenharmony_ci 313e66f31c5Sopenharmony_ci /* copy hints to allocated memory and save pointer in req */ 314e66f31c5Sopenharmony_ci if (hints != NULL) { 315e66f31c5Sopenharmony_ci req->addrinfow = (struct addrinfoW*) alloc_ptr; 316e66f31c5Sopenharmony_ci req->addrinfow->ai_family = hints->ai_family; 317e66f31c5Sopenharmony_ci req->addrinfow->ai_socktype = hints->ai_socktype; 318e66f31c5Sopenharmony_ci req->addrinfow->ai_protocol = hints->ai_protocol; 319e66f31c5Sopenharmony_ci req->addrinfow->ai_flags = hints->ai_flags; 320e66f31c5Sopenharmony_ci req->addrinfow->ai_addrlen = 0; 321e66f31c5Sopenharmony_ci req->addrinfow->ai_canonname = NULL; 322e66f31c5Sopenharmony_ci req->addrinfow->ai_addr = NULL; 323e66f31c5Sopenharmony_ci req->addrinfow->ai_next = NULL; 324e66f31c5Sopenharmony_ci } else { 325e66f31c5Sopenharmony_ci req->addrinfow = NULL; 326e66f31c5Sopenharmony_ci } 327e66f31c5Sopenharmony_ci 328e66f31c5Sopenharmony_ci uv__req_register(loop, req); 329e66f31c5Sopenharmony_ci 330e66f31c5Sopenharmony_ci if (getaddrinfo_cb) { 331e66f31c5Sopenharmony_ci uv__work_submit(loop, 332e66f31c5Sopenharmony_ci &req->work_req, 333e66f31c5Sopenharmony_ci UV__WORK_SLOW_IO, 334e66f31c5Sopenharmony_ci uv__getaddrinfo_work, 335e66f31c5Sopenharmony_ci uv__getaddrinfo_done); 336e66f31c5Sopenharmony_ci return 0; 337e66f31c5Sopenharmony_ci } else { 338e66f31c5Sopenharmony_ci uv__getaddrinfo_work(&req->work_req); 339e66f31c5Sopenharmony_ci uv__getaddrinfo_done(&req->work_req, 0); 340e66f31c5Sopenharmony_ci return req->retcode; 341e66f31c5Sopenharmony_ci } 342e66f31c5Sopenharmony_ci} 343e66f31c5Sopenharmony_ci 344e66f31c5Sopenharmony_ciint uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) { 345e66f31c5Sopenharmony_ci NET_LUID luid; 346e66f31c5Sopenharmony_ci wchar_t wname[NDIS_IF_MAX_STRING_SIZE + 1]; /* Add one for the NUL. */ 347e66f31c5Sopenharmony_ci int r; 348e66f31c5Sopenharmony_ci 349e66f31c5Sopenharmony_ci if (buffer == NULL || size == NULL || *size == 0) 350e66f31c5Sopenharmony_ci return UV_EINVAL; 351e66f31c5Sopenharmony_ci 352e66f31c5Sopenharmony_ci r = ConvertInterfaceIndexToLuid(ifindex, &luid); 353e66f31c5Sopenharmony_ci 354e66f31c5Sopenharmony_ci if (r != 0) 355e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 356e66f31c5Sopenharmony_ci 357e66f31c5Sopenharmony_ci r = ConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname)); 358e66f31c5Sopenharmony_ci 359e66f31c5Sopenharmony_ci if (r != 0) 360e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 361e66f31c5Sopenharmony_ci 362e66f31c5Sopenharmony_ci return uv__copy_utf16_to_utf8(wname, -1, buffer, size); 363e66f31c5Sopenharmony_ci} 364e66f31c5Sopenharmony_ci 365e66f31c5Sopenharmony_ciint uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) { 366e66f31c5Sopenharmony_ci int r; 367e66f31c5Sopenharmony_ci 368e66f31c5Sopenharmony_ci if (buffer == NULL || size == NULL || *size == 0) 369e66f31c5Sopenharmony_ci return UV_EINVAL; 370e66f31c5Sopenharmony_ci 371e66f31c5Sopenharmony_ci r = snprintf(buffer, *size, "%d", ifindex); 372e66f31c5Sopenharmony_ci 373e66f31c5Sopenharmony_ci if (r < 0) 374e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 375e66f31c5Sopenharmony_ci 376e66f31c5Sopenharmony_ci if (r >= (int) *size) { 377e66f31c5Sopenharmony_ci *size = r + 1; 378e66f31c5Sopenharmony_ci return UV_ENOBUFS; 379e66f31c5Sopenharmony_ci } 380e66f31c5Sopenharmony_ci 381e66f31c5Sopenharmony_ci *size = r; 382e66f31c5Sopenharmony_ci return 0; 383e66f31c5Sopenharmony_ci} 384