bastando executar o dnstracer com o argumento -4 para usar IPv4, e -s . para usar os root servers como requisição inicial. $ dnstracer -s . -4 -o desconstruindoaweb.com.br Tracing to desconstruindoaweb.com.br[a] via A.ROOT-SERVERS.NET A.ROOT-SERVERS.NET [.] (198.41.0.4) |\_ a.dns.br [br] (2001:12ff::10) Not queried |\_ a.dns.br [br] (200.160.0.10) | |\_ c.sec.dns.br (200.189.40.11) Got authoritative answer | \_ a.sec.dns.br (200.160.0.11) Got authoritative answer \_ a.sec.dns.br (2001:12ff::11) Not queried |\_ b.dns.br [br] (200.189.41.10) | |\_ c.sec.dns.br (200.189.40.11) (cached) | \_ a.sec.dns.br (200.160.0.11) (cached) | \_ a.sec.dns.br (2001:12ff::11) Not queried (...) a.sec.dns.br (200.160.0.11) desconstruindoaweb.com.br -> 177.153.1.102 c.sec.dns.br (200.189.40.11) desconstruindoaweb.com.br -> 177.153.1.102
O resultado do comando foi alterado para melhorar a legibilidade, além da remoção de algumas linhas, que foram substituídas por (...) . Fica como exercício identificar cada um
dos passos que estudamos.
Com isso, terminamos a jornada de como conseguir o IP para se comunicar com o servidor do desconstruindoaweb.com.br . No
próximo capítulo, vamos estudar como o protocolo HTTP usa o protocolo TCP para chegar ao servidor de destino.
Uma requisição web passa pelas várias camadas do "modelo Ozzy", que é um modelo simplificado que nomeamos e usamos para ilustrar as camadas. Nesse modelo, existem 5 camadas: de aplicação, de transporte, de rede, de enlace e física. O protocolo DNS fica na
3.6 RESUMO
camada de aplicação e é gerenciado pelas aplicações do usuário, ou seja, o Chromium ou a glibc , e não pelo kernel.
Nós vamos procurar por entradas A do DNS, pois elas possuem o endereço IPv4 que esperamos para conectar no site referente ao
domínio que queremos acessar, no caso
desconstruindoaweb.com.br . As implementações de DNS usam
pacotes UDP por padrão, e no nosso caso estamos usando a implementação da glibc como base.
Para requisitar o DNS, a glibc vai criar um socket UDP
usando a syscall chamada socket . Após criar o socket, ela usa a
syscall connect para atribuir o endereço. Com isso, os pacotes
UDP já podem ser enviados. O protocolo UDP não é orientado à conexão, portanto, ao enviá-lo, não haverá certeza de entrega nem ordem de chegada dos pacotes. Estamos chamando somente de UDP, mas aqui estamos usando o UDP/IP, que é a junção dos dois protocolos. Essa junção proporciona o envio e entrega dos pacotes no destinatário, usando a camada de transporte e rede respectivamente.
Com isso, é feita a comunicação do computador local com o servidor de DNS configurado e o processo de busca do IP do domínio começa. Primeiro, o servidor de DNS pergunta aos root servers qual é o IP do domínio do desconstruindoaweb.com.br .
Eles vão passar a referência dos servidores de Top-Level Domain, que por sua vez enviarão uma lista de servidores que podem saber sobre o domínio.
Um desses servidores será o servidor autoritativo do nosso domínio e vai enviar a informação sobre o IP que foi registrado para uso. Ao receber essa informação, o nosso servidor de DNS vai encaminhá-la para nós como resposta à nossa requisição.
1. Definição do modelo OSI na ISO —
http://www.iso.org/iso/catalogue_detail.htm? csnumber=20269
2. TANENBAUM, A. S.; WETHERALL, D. Computer Networks. Singapore: Pearson Education, 2011.
3. Código de DNS do Chromium —
https://code.google.com/p/chromium/codesearch#chromium/ src/net/dns/dns_protocol
4. Código da função getaddrinfo —
https://sourceware.org/git/?
p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;hb=HEAD#l 2321
5. GitHub pages — https://pages.github.com/
6. RFC1035 e a definição do protocolo DNS —
https://tools.ietf.org/html/rfc1035
7. RFC768 e a definição do protocolo UDP —
https://tools.ietf.org/html/rfc768
8. Métricas do uso de IPv4 e IPv6 —
http://www.worldipv6launch.org/measurements/
9. Fazendo o connect na glibc — https://sourceware.org/git/? p=glibc.git;a=blob;f=sysdeps/posix/getaddrinfo.c;hb=HEAD#l 2526
3.7 REFERÊNCIAS
CAPÍTULO 4
Todo o caminho da resolução de nomes já foi percorrido, conseguimos resolver o domínio do site que queríamos e conseguir seu endereço IP. Agora vamos estudar o que o protocolo HTTP precisa fazer para requisitar a informação do site do
desconstruindoaweb.com.br e trazê-la até o nosso computador.
O protocolo HTTP também fica na camada de aplicação, como vimos no nosso modelo "Ozzy" no capítulo passado. Sabemos que o HTTP não vai ser administrado pelo kernel, portanto, o Chromium que vai cuidar da implementação do protocolo[1].
As versões do protocolo mais utilizadas atualmente são as da série 1.x, sendo que a mais nova dessa linha é a 1.1. Essa versão do protocolo HTTP é definida pela RFC2616[2], e seus vários anexos. O protocolo é composto apenas de texto, e conseguimos exemplificá- lo de uma forma sucinta utilizando o comando telnet . O que esse
comando faz é executar uma conexão direta com um determinado endereço e porta. Um exemplo seria: $ telnet desconstruindoaweb.com.br 80 Trying 177.153.1.102... Connected to desconstruindoaweb.com.br. Escape character is '^]'.
TRANSFERINDO
HYPERTEXTO
4.1 O BÁSICO DO HTTP
50 4 TRANSFERINDO HYPERTEXTONesse caso, abrimos uma conexão com o
desconstruindoaweb.com.br na porta 80, que é a padrão do
protocolo HTTP. Ele resolveu o domínio, seguindo um processo parecido com o que estudamos nos capítulos anteriores, e conseguiu o endereço IP 177.153.1.102 . Com o IP em mãos, ele iniciou
uma conexão e nos deixou com acesso para digitar o que quisermos. O que for digitado agora vai ser enviado para o servidor de destino, é como se o telnet entregasse um terminal que, em vez de estar
rodando bash — como é comum para a maioria dos sistemas
Unix-like —, está rodando HTTP. Esse exemplo não é real, mas serve como uma metáfora.
Aqui, vamos usar o protocolo HTTP para requisitar a página principal do desconstruindoaweb.com.br :
GET / HTTP/1.1
Host: desconstruindoaweb.com.br
Como o protocolo é baseado em texto, podemos utilizá-lo diretamente via telnet . É claro que é uma versão bem
simplificada, mas é funcional e vai nos retornar: HTTP/1.1 200 OK
(...)
Onde está o (...) virão várias informações sobre os
cabeçalhos utilizados pelo protocolo e, logo em seguida, o conteúdo do HTML da página web que pedimos.
Vamos analisar com calma cada um dos passos que fizemos anteriormente. Na primeira linha, nós usamos o texto GET / HTTP/1.1 . Esta diz ao servidor web que queremos fazer um GET
no caminho / , ou a raiz da aplicação, utilizando o protocolo HTTP com a versão 1.1 , que é a versão mais atual da série 1.x do
protocolo.
Para entender melhor o que faz o GET do comando, precisamos
conhecer melhor os tipos de requisição do HTTP. Ele possui vários métodos, ou verbos, e cada um tem sua função. Os mais comuns são:
GET — Deve ser utilizado apenas para receber
informações, como foi nosso caso.
POST — Deve ser usado quando for necessário enviar
informações novas para serem adicionadas ao recurso
da URL. Exemplo: POST
http://biblioteca.com/livros criaria um novo
livro com os dados enviados.
PUT — Deve ser utilizado para atualizar recursos que
estão em uma determinada URL. Exemplo: PUT http://biblioteca.com/livros/2 altera os dados do
livro com id 2 para o que foi enviado.
DELETE — Deve ser usado para pedir ao servidor que
exclua o recurso da URL em questão. Exemplo:
DELETE http://biblioteca.com/livros/2 exclui o
livro referente ao id 2.
Para vermos isso na prática, podemos acessar
http://desconstruindoaweb.com.br no Chromium e olhar as
informações do Developer Tools. Lá vai estar disponível o método do HTTP que foi usado para fazer a requisição. Nesse caso, o navegador vai fazer um GET para a raiz do site para conseguir seu
conteúdo.