Sempre lembrar de fechar as conexões que não foram estabelecidas (e limpar a memória em linguagens sem garbage collector).
                                se passou tempo de vantagem e não se conectou nem via IPv6 nem via IPv4 {
Como a própria rfc6555 sugere, o ideal é que as próprias aplicações implementem o Happy Eyeballs. Para isso alguns conceitos importantes são necessários.
Basicamente um socket é um par composto por um IP e uma porta que criam uma interface de comunicação com outro socket, estabelecendo assim uma conexão entre as duas interfaces (rfc793#page-84). Sockets podem se comportar diferentemente entre as diversas linguagens de programação, além disso é importante verificar se os sockets da linguagem utilizada possuem suporte a IPv6. É importante notar que a implementação de um socket pode variar de acordo com o sistema operacional, portanto sempre devemos conferir se o resultado realmente bate com o esperado (especialmente na hora de setar as flags de blocking do socket).
Por padrão, sockets são implementados em modo blocking. Modo blocking significa que quando tentamos conectar a um servidor através da função connect() do socket a aplicação fica em standby esperando a conexão se estabelecer. Pela definição do Happy Eyeballs a aplicação deve continuar a trabalhar mesmo após tentar se conectar, por isso alguma alternativa deve ser tomada. Uma das soluções mais simples envolve tornar o socket non-blocking. Ao se tornar non-blocking, o programa continua sua execução mesmo após um connect() ou select(), possibilitando assim a implementação do Happy Eyeballs.
Verificar se o sistema operacional utilizado possui suporte a IPv6 e se possuir verificar se ele está habilitado pelo sistema (principalmente em sistemas mais antigos, que possuem suporte a IPv6, porém este vem desabilitado por padrão);
Verificar se a linguagem utilizada possui suporte a IPv6, pois muitas vezes versões antigas não possuem suporte, ou possuem muitos bugs. Além disso pode ser necessário a instalação de pacotes adicionais para o funcionamento correto do programa.
Outro ponto importante é com relação a conectividade IPv6 com a internet, pois por se tratar de um protocolo razoavelmente novo, é muito comum realizar sua configuração de forma errada, o que pode gerar problemas, como mesmo possuindo IPv6 na máquina, ela não possua conectividade com o mundo externo.
        Porém essa função, assim como outras da biblioteca netdb.h, só possui suporte a IPv4. Para corrigir essa falha, foi criado a função gethostbyname2:
Como pode ser observado, foi adicionado um novo parâmetro na função chamado af (Address Family), que pode ser do tipo AF_INET para resultados exclusivamente IPv4, AF_INET6 para resultados exclusivamente IPv6 ou AF_UNSPEC para poder retornar qualquer tipo de endereço. No entanto essa função apresenta problemas caso o host em questão possua mais de 1 único IP anunciado em seu DNS. Mais informações sobre as funções gethostbyname e gethostbyname2 podem ser encontradas em:
Nota-se que a função é bem mais complexa que as anteriores, isso ocorre porque o getaddrinfo possui outras funcionalidades além das consultas DNS. O parâmetro node é o host ou IP no qual queremos nos conectar. O parâmetro service indica o tipo de serviço a ser conectado, o que pode ser uma porta (como “80” ou “22”) ou o nome do serviço (“http”, “ftp”, “telnet”, etc.). O parâmetro hints é uma estrutura de dados na qual só nos interessa o campo ai_famliy (que é o mesmo campo af da função gethostbyname2) e o campo ai_socktype, que em geral será preenchido com a constante SOCK_STREAM. O parâmetro res é a estrutura de dados na qual será recebida a resposta da consulta. Abaixo um exemplo de como utilizar a função getaddrinfo para realizar uma consulta dns:
Os sockets em C estão definidos na biblioteca sys/socket.h. Para se criar um socket é utilizado a seguinte função:
Apesar de parecer simples, essa função é um pouco confusa, pois todos os seus parâmetros de entrada são constantes pré-definidas. O parâmetro domain é o mesmo parâmetro af da função gethostbyname e o parâmetro ai_family da função getaddrinfo, ou seja, indica o tipo de endereço utilizado pelo socket. O parâmetro type é o mesmo parâmetro ai_socktype da função getaddrinfo, que indica o tipo de socket a ser utilizado. O parâmetro protocol indica o tipo de protocolo a ser utilizado na conexão pelo socket (como tcp, udp, etc.). Note que esse parâmetro é parecido com o parâmetro service da função getaddrinfo, no entanto service é uma string, enquanto protocol é um número do tipo int. Normalmente no parâmetro protocol é utilizado o valor IPPROTO_TCP, para indicar que a conexão deverá ser via TCP, porém se deixado seu valor como 0, a própria função ficará encarregada de decidir qual o melhor protocolo a ser utilizado para o tipo endereço e socket utilizado. É importante observar que essa função não retorna o socket em si, mas um número que representa o id do socket criado. Em quase todas as funções de socket o procedimento é o mesmo, não há contato direto com o socket, apenas são passados os ids dos sockets dentro das funções que irão realizar as operações. Para se conectar a um host utilizando o socket criado devemos utilizar a função connect:
        O parâmetro socket é o mesmo socket id que foi gerado na função socket. O parâmetro address é uma struct retornada pela função getaddrinfo, dentro da struct addrinfo->ai_addr O parâmetro address_len também é um parâmetro retornado pela função getaddrinfo, dentro da struct addrinfo->ai_addrlen. A struct sockaddr pode ser de vários  tipos:
É importante lembrar que ao iniciar a função connect o programa irá travar sua execução até que a conexão seja estabelecida. Para a execução do Happy Eyeballs é necessário que o programa continue sua execução mesmo após a chamada da função connect. A forma mais simples de se fazer isso é tornando o socket non-blocking. Dessa forma o programa continuará sua execução mesmo após um connect. Mais informações sobre sockets e suas funções podem ser encontradas em:
        Note que essa é uma função mais avançada, portanto deve ser utilizado com cuidado. O parâmetro fildes (File Descriptor) indica o id do arquivo a ser modificado (no nosso caso é o socket, portanto seu id). O parâmetro request indica o comando que deverá ser executado, no nosso caso seria a constante FIONBIO. O parâmetro arg são configurações ou informações adicionais específicos da operação e do tipo de fildes utilizado. Um exemplo de como utilizar a função ioctl:
        Note que nesse caso foi utilizado um parâmetro chamado opt de valor 1. A função ioctl, quando utilizada com o parâmetro FIONBIO, torna o socket non-blocking caso o parâmetro arg seja diferente de zero. Portanto no exemplo a função está tornando o socket criado em um socket non-blocking. Para retornar o socket em modo blocking basta retirar a flag setada anteriormente, utilizando o parâmetro arg com valor igual a zero:
Novamente, essa funçao deve ser utilizada com cuidado, pois mexe nas propriedades do arquivo que queremos modificar. O parâmetro fildes é o mesmo da função ioctl, ou seja, o identificador do arquivo alvo (socket). O parâmetro cmd é similar ao parâmetro request da função ioctl, porém com constantes diferentes, o mesmo se aplica ao parâmetro arg. Abaixo um exemplo de como utilizar a função fcntl para tornar o socket non-blocking:
Note que sua utilização é um pouco diferente da ioctl, pois é necessário executar a função duas vezes: uma para adquirir o parêmetro de flags do socket e outro para setar a flag indicando que o socket será non-blocking. Mais informações sobre a função fcntl podem ser acessadas em:
Quando o socket está em modo non-blocking, é necessário verificar de tempos em tempos se a conexão foi estabelecida. Existem várias formas de se verificar isso, porém para o Happy Eyeballs uma função interessante é a getpeername, da biblioteca socket.h:
Como é possível notar, esta função possui os mesmos parâmetros de entrada que a função connect, ou seja, podemos utilizar as mesmas entradas utilizadas na função connect na função getpeername, como no exemplo abaixo:
No java devemos tomar certo cuidado, pois o tratamento de IPs é dada pela classe InetAddress (java.net.InetAddress). Esta classe possui 2 implementações diretas: Inet4Adress para IPv4 e Inet6Address para IPv6. A documentação oficial das classes pode ser encontrada em: