O IPv6 - Happy Eyeballs I

Olá! Bom, nessa postagem para ser sincera eu fiquei bastante curiosa com o que seria falado no assunto com esse título.
Ela foi definida na rfc6555 e é uma forma de tentar corrigir um "conflito" entre o IPv4 e IPv6, caso possua as duas pontas.


IPv6 nos softwares

Apesar do IPv6 tentar ser transparente visto da camada de aplicação, alguns problemas ainda não estão completamente resolvidos. O problema sobre qual conexão preferir caso o host possua tanto IPv6 quanto IPv4 é um deles.

Por padrão os sistemas operacionais costumam dar uma preferência unânime para o IPv6, o que é bom, pois incentiva o uso do novo protocolo. No entanto, por se tratar de um protocolo ainda em seus estados iniciais de implantação, existem muitos problemas de conectividade na rede IPv6.

Isso implica em um problema grave, pois nessa situação um usuário que possua uma conexão com IPv6 e IPv4 pode sofrer uma pior experiência de uso do que um usuário com apenas IPv4. 

Para resolver esse problema, foi desenvolvido uma técnica chamada Happy Eyeballs.

Happy Eyeballs

Definida na rfc6555Happy Eyeballs é uma forma de tentar corrigir o problema de decisão sobre qual conexão preferir, caso as duas pontas possuam IPv4 e IPv6. Seu funcionamento consiste em tentar se conectar às duas conexões simultaneamente e utilizar aquela que é estabelecida mais rapidamente, dando uma leve preferência para a conexões IPv6. Browsers como Google Chrome e Mozilla Firefox em suas versões atuais já implementam o Happy Eyeballs e o utilizam por padrão.

Em sua definição mais básica, na hora de acessar um domínio, são verificados seus IPv4 e IPv6 disponíveis para se conectar. O funcionamento padrão da maioria dos sistemas operacionais faz com que primeiro seja tentado a conexão via IPv6 e em caso de falha (timeout) é tentado a conexão via IPv4. Essa implementação apresenta um problema grave, pois caso a conexão IPv6 apresente problemas, o usuário com IPv6 sofrerá um grande delay para acessar o site, enquanto um usuário comum que apresente apenas IPv4 não sofrerá disso. Esse problema é uma das principais barreiras para os provedores de conteúdos, pois o simples fato de se implementar o IPv6 pode acarretar em um prejuízo para o provedor.

Uma solução proposta para isso foi a de tentar se conectar tanto via IPv6 como via IPv4 simultaneamente. Assim o primeiro a responder seria aceito e a outra conexão seria descartada. No entanto essa solução possui 2 problemas:
  1. Seriam desperdiçados muitos sockets para as tentativas de conexões, pois independente da qualidade do serviço sempre seriam feitas pelo menos 2 tentativas de conexão simultaneas. Além disso o excesso de tentativas poderia fazer com que regras mais rígidas de controle de acesso bloqueassem o usuário por excesso de conexões;
  2. Mesmo que o IPv6 possuísse uma qualidade aceitável, o simples fato dele ser um pouco mais lento que o IPv4 faria com que ele nunca fosse utilizado. A princípio isso não é um problema, porém acabaria gerando uma grande barreira para o avanço do IPv6, pois na situação atual é comum que as implementações de IPv6 não sejam tão eficientes quanto as IPv4 já existentes, o que faria com que tais conexões nunca fossem utilizadas, desestimulando assim seu uso.

Diante de tal problema, o algoritmo do Happy Eyeballs procura incentivar o uso do IPv6, porém sem prejudicar a experiência de uso do usuário. Isso é feito partindo do princípio de que a conexão IPv6 está OK, e caso a conexão não seja realizada após um intervalo de tempo (estimado suficiente para se estabelecer a conexão via IPv6) é tentando a conexão via IPv4. Assim mesmo que a conexão IPv6 falhe, o intervalo de tempo perdido para se estabelecer a conexão via IPv4 (da ordem de milisegundos) é praticamente imperceptível ao usuário, ao mesmo tempo em que se evita o excesso de conexões sofrido na solução anterior.

Além disso, o algoritmo do Happy Eyeballs deve guardar em um cache a decisão sobre qual conexão foi preferida (IPv4 ou IPv6). Isso ajuda a evitar tráfego desnecessário na rede, pois caso o IPv6 esteja com problemas, toda conexão feita seria feita primeiramente em IPv6 (que irá falhar) e depois em IPv4. Com o cache esse processo seria feito apenas uma vez e as demais conexões seriam feitas diretamente via IPv4. Arfc6555 especifica que o cache não deve ser guardado por mais de 10 minutos para evitar vícios na rede.

Outro ponto a ser notado é no caso do host possuir mais de um IPv6 ou mais de um IPv4. Neste caso continua se utilizando o procedimento recomendado pelo Happy Eyeballs: tentar se conectar primeiro a um (único) IPv6 e após um pequeno intervalo de tempo t (da ordem de 100 – 300ms) tentar se conectar a um (único) IPv4. Se passar outro intervalo de tempo t após tentar se conectar via IPv4, isso significa que provavelmente o problema não se deve ao protocolo em si, mas sim a outro problema (específico do IP em questão). Assim a rfc6555 recomenda que tente se conectar com os demais IPs, independente se for IPv6 ou IPv4, sempre esperando um intervalo de tempo t entre as tentativas.

Abaixo segue o exemplo do algoritmo básico do Happy Eyeballs (sem cache e admitindo um único IPv6 e um único IPv4):

        conectar (endereço) {
                encontra IPs do endereço
                tenta se conectar a o endereço IPv6
                enquanto nenhuma conexão se estabelece e timeout não estoura {
                        se passou tempo de vantagem dado ao IPv6 {
                                tenta se conectar a um endereço IPv4 (uma única vez)
                        }
                }
                se conseguiu conectar {
                        mantém a conexão conectada
                        fecha as demais conexões (sockets abertos)
                } caso não conseguiu conectar (timeout) {
                        fecha todas as conexões (sockets abertos)
                }
        }
 

Este é apenas o algortimo básico, portanto não deve ser utilizado, pois faltam recursos importantes como o cache e o tratamento caso existam mais IPs. Porém ele serve para mostrar alguns pontos importantes:
  1. Ao encontrar os IPs do endereço deve-se tomar certo cuidado, pois alguns métodos de se encontrar os IPs (como gethostbyname) retornan apenas IPv4;
  2. Sempre lembrar de fechar as conexões que não foram estabelecidas (e limpar a memória em linguagens sem garbage collector).

Abaixo o algoritmo completo do Happy Eyeballs:
        conectar (endereço) {
                encontra IPs do endereço
                verifica cache (endereço)
                se não existir cache {
                        tenta se conectar a um endereço IPv6
                        enquanto nenhuma conexão se estabelece e timeout não estoura {
                                se passou tempo de vantagem dado ao IPv6 {
                                        tenta se conectar a um endereço IPv4 (uma única vez)
                                }
                                se passou tempo de vantagem e não se conectou nem via IPv6 nem via IPv4 {
                                        tenta se conectar a qualquer outro endereço disponível
                                }
                        }
                } se estiver no cache {
                        tenta se conectar a um endereço com a versão definida no cache
                }
                se conseguiu conectar {
                        mantém a conexão conectada
                        fecha as demais conexões (sockets abertos)
                } caso não conseguiu conectar (timeout) {
                        fecha todas as conexões (sockets abertos)
                }
        }
        
        verifica cache (endereço) {
                verifica se existe o cache para endereço
                se cache existe {
                        se o cache está ativo há mais de 10 minutos {
                                limpa o cache
                        } caso contrario {
                                retorna o cache
        }
                }
        }
 

Implementando o Happy Eyeballs


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.

Sockets


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).

Blocking vs Non-blocking Sockets


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.

Suporte a IPv6

É importante verificar dois  requisitos com relação ao suporte a IPv6:
  1. 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);
  2. 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.

Comentários

Postagens mais visitadas deste blog

O IPv6 - Alocação de endereços

Característica do Protocolo FTP

A camada Aplicação - Modelo OSI