// TCPDialer contains options to control a group of Dial calls. type TCPDialer struct { // Concurrency controls the maximum number of concurrent Dials // that can be performed using this object. // Setting this to 0 means unlimited. // // WARNING: This can only be changed before the first Dial. // Changes made after the first Dial will not affect anything. Concurrency int
// LocalAddr is the local address to use when dialing an // address. // If nil, a local address is automatically chosen. LocalAddr *net.TCPAddr
// This may be used to override DNS resolving policy, like this: // var dialer = &fasthttp.TCPDialer{ // Resolver: &net.Resolver{ // PreferGo: true, // StrictErrors: false, // Dial: func (ctx context.Context, network, address string) (net.Conn, error) { // d := net.Dialer{} // return d.DialContext(ctx, "udp", "8.8.8.8:53") // }, // }, // } Resolver Resolver
// DisableDNSResolution may be used to disable DNS resolution DisableDNSResolution bool // DNSCacheDuration may be used to override the default DNS cache duration (DefaultDNSCacheDuration) DNSCacheDuration time.Duration
staticint setipaddr(constchar *name, struct sockaddr*addr_ret, size_t addr_ret_size, int af) { structaddrinfo hints, *res; int error;
memset((void *) addr_ret, '\0', sizeof(*addr_ret)); if (name[0] == '\0') { int siz; memset(&hints, 0, sizeof(hints)); hints.ai_family = af; hints.ai_socktype = SOCK_DGRAM; /*dummy*/ hints.ai_flags = AI_PASSIVE; Py_BEGIN_ALLOW_THREADS ACQUIRE_GETADDRINFO_LOCK error = getaddrinfo(NULL, "0", &hints, &res); Py_END_ALLOW_THREADS /* We assume that those thread-unsafe getaddrinfo() versions *are* safe regarding their return value, ie. that a subsequent call to getaddrinfo() does not destroy the outcome of the first call. */ RELEASE_GETADDRINFO_LOCK if(error){ set_gaierror(error); return-1; } switch (res->ai_family) { case AF_INET: siz = 4; break;
# ifdef ENABLE_IPV6
case AF_INET6: siz = 16; break;
# endif
default: freeaddrinfo(res); PyErr_SetString(PyExc_OSError, "unsupported address family"); return-1; } if (res->ai_next) { freeaddrinfo(res); PyErr_SetString(PyExc_OSError, "wildcard resolved to multiple address"); return-1; } if (res->ai_addrlen < addr_ret_size) addr_ret_size = res->ai_addrlen; memcpy(addr_ret, res->ai_addr, addr_ret_size); freeaddrinfo(res); return siz; } /*special-case broadcast - inet_addr() below can return INADDR_NONE for * this */ if (strcmp(name, "255.255.255.255") == 0 || strcmp(name, "<broadcast>") == 0) { structsockaddr_in*sin; if (af != AF_INET && af != AF_UNSPEC) { PyErr_SetString(PyExc_OSError, "address family mismatched"); return-1; } sin = (struct sockaddr_in *)addr_ret; memset((void*) sin, '\0', sizeof(*sin)); sin->sin_family = AF_INET;
/* avoid a name resolution in case of numeric address */
# ifdef HAVE_INET_PTON
/*check for an IPv4 address*/ if (af == AF_UNSPEC || af == AF_INET) { structsockaddr_in *sin = (struct sockaddr_in*)addr_ret; memset(sin, 0, sizeof(*sin)); if (inet_pton(AF_INET, name, &sin->sin_addr) > 0) { sin->sin_family = AF_INET;
# ifdef HAVE_SOCKADDR_SA_LEN
sin->sin_len = sizeof(*sin);
# endif
return4; } }
# ifdef ENABLE_IPV6
/* check for an IPv6 address - if the address contains a scope ID, we * fallback to getaddrinfo(), which can handle translation from interface *name to interface index*/ if ((af == AF_UNSPEC || af == AF_INET6) && !strchr(name, '%')) { structsockaddr_in6 *sin = (struct sockaddr_in6*)addr_ret; memset(sin, 0, sizeof(*sin)); if (inet_pton(AF_INET6, name, &sin->sin6_addr) > 0) { sin->sin6_family = AF_INET6;
# ifdef HAVE_SOCKADDR_SA_LEN
sin->sin6_len = sizeof(*sin);
# endif
return16; } }
# endif/*ENABLE_IPV6*/
# else/*HAVE_INET_PTON*/
/* check for an IPv4 address*/ if (af == AF_INET || af == AF_UNSPEC) { structsockaddr_in *sin = (struct sockaddr_in*)addr_ret; memset(sin, 0, sizeof(*sin)); if ((sin->sin_addr.s_addr = inet_addr(name)) != INADDR_NONE) { sin->sin_family = AF_INET;
# ifdef HAVE_SOCKADDR_SA_LEN
sin->sin_len = sizeof(*sin);
# endif
return4; } }
# endif/*HAVE_INET_PTON*/
/* perform a name resolution */ memset(&hints, 0, sizeof(hints)); hints.ai_family = af; Py_BEGIN_ALLOW_THREADS ACQUIRE_GETADDRINFO_LOCK error = getaddrinfo(name, NULL, &hints, &res);
# if defined(__digital__) && defined(__unix__)
if (error == EAI_NONAME && af == AF_UNSPEC) { /*On Tru64 V5.1, numeric-to-addr conversion fails if no address family is given. Assume IPv4 for now.*/ hints.ai_family = AF_INET; error = getaddrinfo(name, NULL, &hints, &res); }
# endif
Py_END_ALLOW_THREADS RELEASE_GETADDRINFO_LOCK /* see comment in setipaddr()*/ if (error) { set_gaierror(error); return-1; } if (res->ai_addrlen < addr_ret_size) addr_ret_size = res->ai_addrlen; memcpy((char *) addr_ret, res->ai_addr, addr_ret_size); freeaddrinfo(res); switch (addr_ret->sa_family) { case AF_INET: return4;
// ~/.cache/typescript/5.3/node_modules/@types/node/dns.d.ts /** * Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or * AAAA (IPv6) record. All `option` properties are optional. If `options` is an * integer, then it must be `4` or `6` – if `options` is `0` or not provided, then * IPv4 and IPv6 addresses are both returned if found. * * With the `all` option set to `true`, the arguments for `callback` change to`(err, addresses)`, with `addresses` being an array of objects with the * properties `address` and `family`. * * On error, `err` is an `Error` object, where `err.code` is the error code. * Keep in mind that `err.code` will be set to `'ENOTFOUND'` not only when * the host name does not exist but also when the lookup fails in other ways * such as no available file descriptors. * * `dns.lookup()` does not necessarily have anything to do with the DNS protocol. * The implementation uses an operating system facility that can associate names * with addresses and vice versa. This implementation can have subtle but * important consequences on the behavior of any Node.js program. Please take some * time to consult the `Implementation considerations section` before using`dns.lookup()`. ...
// // IPv6 Changes: Add getaddrinfo and getnameinfo methods. // privateunsafestatic SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo) { // gets the resolved name return TryGetAddrInfo(name, AddressInfoHints.AI_CANONNAME, out hostinfo); }
privateunsafestatic SocketError TryGetAddrInfo(string name, AddressInfoHints flags, out IPHostEntry hostinfo) { // // Use SocketException here to show operation not supported // if, by some nefarious means, this method is called on an // unsupported platform. // #if FEATURE_PAL thrownew SocketException(SocketError.OperationNotSupported); #else SafeFreeAddrInfo root = null; ArrayList addresses = new ArrayList(); string canonicalname = null;
AddressInfo hints = new AddressInfo(); hints.ai_flags = flags; hints.ai_family = AddressFamily.Unspecified; // gets all address families // // Use try / finally so we always get a shot at freeaddrinfo // try { SocketError errorCode = (SocketError)SafeFreeAddrInfo.GetAddrInfo(name, null, ref hints, out root); if (errorCode != SocketError.Success) { // Should not throw, return mostly blank hostentry hostinfo = new IPHostEntry(); hostinfo.HostName = name; hostinfo.Aliases = newstring[0]; hostinfo.AddressList = new IPAddress[0]; return errorCode; }
AddressInfo* pAddressInfo = (AddressInfo*)root.DangerousGetHandle(); // // Process the results // while (pAddressInfo!=null) { SocketAddress sockaddr; // // Retrieve the canonical name for the host - only appears in the first AddressInfo // entry in the returned array. // if (canonicalname==null && pAddressInfo->ai_canonname!=null) { canonicalname = Marshal.PtrToStringUni((IntPtr)pAddressInfo->ai_canonname); } // // Only process IPv4 or IPv6 Addresses. Note that it's unlikely that we'll // ever get any other address families, but better to be safe than sorry. // We also filter based on whether IPv6 is supported on the current // platform / machine. // if ( ( pAddressInfo->ai_family == AddressFamily.InterNetwork ) || // Never filter v4 (pAddressInfo->ai_family == AddressFamily.InterNetworkV6 && Socket.OSSupportsIPv6))
{ sockaddr = new SocketAddress(pAddressInfo->ai_family, pAddressInfo->ai_addrlen); // // Push address data into the socket address buffer // for (int d = 0; d < pAddressInfo->ai_addrlen; d++) { sockaddr.m_Buffer[d] = *(pAddressInfo->ai_addr + d); } // // NOTE: We need an IPAddress now, the only way to create it from a // SocketAddress is via IPEndPoint. This ought to be simpler. // if ( pAddressInfo->ai_family == AddressFamily.InterNetwork ) { addresses.Add( ((IPEndPoint)IPEndPoint.Any.Create(sockaddr)).Address ); } else { addresses.Add( ((IPEndPoint)IPEndPoint.IPv6Any.Create(sockaddr)).Address ); } } // // Next addressinfo entry // pAddressInfo = pAddressInfo->ai_next; } } finally { if (root != null) { root.Close(); } }
// // Finally, put together the IPHostEntry // hostinfo = new IPHostEntry();