CURL does this for ipv4 and ipv6:

  1. Resolving the requested domain name usually results in a list of IP addresses, both ipv4 and ipv6.
  2. CURL first initiates a connection to the ipv6 address. If the connection is successful within 200ms, the ipv6 address is used directly.
  3. If an ipv6 address fails to be connected for 200ms, cURL will simultaneously initiate a connection to the address in the list.
  4. Finally, the first successful connection will be used as the subsequent cURL transport address.

Here’s cURL’s description. Look at this.

From the above process, we can see the following: ipv6 priority mechanism, Happy Eyeballs mechanism (also known as Fast Fallback mechanism), round-robin DNS mechanism.

Round-robin DNSWhat is?

This is the round-robin algorithm for DNS servers. The word comes from the French ruban rond (round ribbon), which means a circular ribbon

Polling is often used for load balancing, for example, configuring multiple IP addresses for a domain name:

Server IN A 192.168.0.1 Server IN A 10.0.0.1 Server IN A 127.0.0.1Copy the code

When concurrent requests for domain names come in, the server returns IP addresses in turn. The advantage of this algorithm is simplicity and equality of opportunity. The disadvantages are obvious, that is, requests at different times may obtain different addresses, which affects the connection sharing and caching based on IP addresses of clients. If a server IP node goes down, its IP address may be returned.

Happy EyeballsWhat is?

“Happy Eyeball” is an algorithm on the client side, so named to indicate that the algorithm is used on the client side of the Internet, not the server side.

The implementation of cURL is not simple: getaddrInfo () -> iterate over each IP address and initiate Connect () simultaneously. It splits all addresses into a two-thread queue dedicated to ipv4 and one dedicated to ipv6, and then initiates connections concurrently, with the first one to receive a reply as the final connection.

This algorithm was proposed on World IPv6 Day 2011 in order to avoid the unsatisfactory network environment in the initial stage of IPv6.

In addition to cURL, Happy Eyeballs is currently supported by Chrome, Opera, Firefox 13+, And Apple’S OS X.

GETADDRINFO WITH ROUND ROBIN DNS AND HAPPY EYEBALLS

CURL specifies ipv4, ipv6

Enforce ipv4 using the command line argument –ipv4 or -4:

% curl --ipv4 https://example.org/
Copy the code

Enforce ipv6 using the command line argument –ipv6 or -6:

% curl --ipv6 https://example.org/
Copy the code

Add the -v parameter to see the connection process:

%curl -v http://example.org/ ~
*   Trying 192.168.199.217...
* TCP_NODELAY set
* Connection failed
* connect to 192.168.199.217 port 80 failed: Connection refused
*   Trying 2001::1...
* TCP_NODELAY set
* Connected to example.org (2001::1) port 80 (#0)
> GET / HTTP/1.1
> Host: example.org
>The user-agent: curl / 7.64.1
> Accept: */*
> 
 html body
Copy the code

Small tools

Nslookup does DNS resolution

# typeThis parameter is used to set the querytype, which is the same as query and queryType. The default value is A
% nslookup -type=A example.test
Server:		192.168.199.1
Address:	192.168.199.1#53

Name:	example.test
Address: 192.168.199.169

% nslookup -type=AAAA example.test
Server:		192.168.199.1
Address:	192.168.199.1#53

example.test	has AAAA address 2001::2

Copy the code

getaddrinfo()Resolve ipv4 and ipv6 simultaneously

#include <cstring> //memset
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
 
#include <iostream>
#include <string>
#include <vector>
 
using std::vector;
using std::string;
using std::cout;
using std::endl;
 
vector<string> dns_lookup(const string &host_name, int ipv=4);
 
int main(int argc, char* argv[])
{
    int ipv;
    vector<string> domains;
    cout << "dns both ipv4 and ipv6: example.test" << endl;
    domains = dns_lookup("example.test", ipv=0);
    for(int i=0,ix=domains.size(a); i<ix; i++) cout <<"" << domains[i] << endl;
 
    return 0;
}
 
vector<string> dns_lookup(const string &host_name, int ipv)
{
    vector<string> output;
 
    struct addrinfo hints, *res, *p;
    int status, ai_family;
    char ip_address[INET6_ADDRSTRLEN];
 
    ai_family = ipv==6 ? AF_INET6 : AF_INET; //v4 vs v6?
    ai_family = ipv==0 ? AF_UNSPEC : ai_family; // AF_UNSPEC (any), or chosen
    memset(&hints, 0.sizeof hints);
    hints.ai_family = ai_family; 
    hints.ai_socktype = SOCK_STREAM;
 
    if ((status = getaddrinfo(host_name.c_str(), NULL, &hints, &res)) ! =0) {
        //cerr << "getaddrinfo: "<< gai_strerror(status) << endl;
        return output;
    }
 
    //cout << "DNS Lookup: " << host_name << " ipv:" << ipv << endl;
 
    for(p = res; p ! =NULL; p = p->ai_next) {
        void *addr;
        if (p->ai_family == AF_INET) { // IPv4
            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
            addr = &(ipv4->sin_addr);
        } else { // IPv6
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
            addr = &(ipv6->sin6_addr);
        }
 
        // convert the IP to a string
        inet_ntop(p->ai_family, addr, ip_address, sizeof ip_address);
        output.push_back(ip_address);
    }
 
    freeaddrinfo(res); // free the linked list
 
    return output;
}
Copy the code

Dig analytical DNS

#Resolve ipv4 and ipv6 simultaneously
% dig example.test AAAA example.test A +short2001: : 2 192.168.199.169
#The @ domain name server is preceded by the global server
%Dig @ 8.8.8.8 AAAA at tv.ipv6.edu.cn; < < > > DiG 9.10.6 < < > > @ 8.8.8.8 tv.ipv6.edu.cn AAAA; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 84 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ; tv.ipv6.edu.cn. IN AAAA ;; ANSWER SECTION: tv.ipv6.edu.cn. 3600 IN AAAA 2001:da8:217:1::234 ;; Query time: 158 msec ;; SERVER: 8.8.8.8 # 53 (8.8.8.8);; WHEN: Mon Sep 28 09:11:02 CST 2020 ;; MSG SIZE rcvd: 60

#The @ domain name server is followed by the local server
% dig wikimedia.org MX @ns0.wikimedia.org; <<>> DiG 9.6.1 <<>> wikimedia.org [email protected]; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61144 ;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ; wikimedia.org. IN MX ;; ANSWER SECTION: wikimedia.org. 3600 IN MX 10 mchenry.wikimedia.org. wikimedia.org. 3600 IN MX 50 lists.wikimedia.org. ;; ADDITIONAL SECTION: McHenry.wikimedia.org.3600 IN A 208.80.152.186 lists.wikimedia.org.3600 IN A 91.198.174.5; Query time: 73 msec ;; SERVER: 208.80.152.130 # 53 (208.80.152.130);; WHEN: Wed Aug 12 11:51:03 2009 ;; MSG SIZE rcvd: 109Copy the code

noun

  1. Ipv6: Internet Protocol Version 6
  2. A Record: Address Record is A group of 32-bit ipv4 addresses
  3. AAAA Record: ipv6 address Record is a group of 128-bit ipv6 addresses