# Aplicações da Internet

DNS, HTTP, FTP, correio, sockets e distribuição cliente-servidor e P2P.

Página: https://resumos.rgo.pt/cadeiras/rc/aplicacoes/

Ao pedir `http://exemplo.test/dados`, o navegador pode precisar de resolver `exemplo.test`, abrir uma ligação e pedir `/dados`, embora uma resposta válida em cache possa dispensar tudo isso. O resto desta página segue esse pedido em HTTP/1.1, separando-o de DNS e TCP.

## DNS: nomes e registos

DNS é uma base distribuída e hierárquica. O recursor do cliente pode consultar raiz, domínio de topo e autoritativos, guardando em cache até ao TTL.

Uma pergunta **recursiva** pede a resposta final ao servidor consultado, enquanto numa interação **iterativa** esse servidor pode indicar outro a consultar. No percurso habitual, o cliente pede recursão ao seu resolver e o resolver segue referências na hierarquia; uma resposta em cache pode evitar as consultas seguintes. São normalmente os servidores locais que aceitam pedidos recursivos; raiz, TLD e autoritativos respondem com referências para o resolver seguir.

| Registo | Informação |
| --- | --- |
| A | Endereço IPv4 |
| AAAA | Endereço IPv6 |
| CNAME | Nome canónico de um alias |
| MX | Servidor de correio e preferência |
| NS | Servidor de nomes autoritativo |
| PTR | Nome associado a um endereço no espaço inverso |

DNS clássico usa a porta 53, com UDP para muitas perguntas e TCP quando necessário, incluindo transferências de zona e respostas que exigem esse transporte. «DNS é sempre UDP» é falso. Novos transportes cifrados não mudam a função dos registos.

## HTTP: pedido e resposta

HTTP define métodos, recursos, cabeçalhos, estados e conteúdo. Em HTTP/1.1, a mensagem usa linha inicial e cabeçalhos terminados por CRLF, seguidos de uma linha vazia, e o comprimento do corpo precisa de ser determinado corretamente, por exemplo por `Content-Length` ou por uma codificação definida.

```
GET /dados HTTP/1.1
Host: exemplo.test
Connection: close
```

Uma resposta pode ser `200 OK`, `301 Moved Permanently`, `404 Not Found` ou `500 Internal Server Error`, e `Content-Type` descreve o formato do corpo. GET pede uma representação; POST submete dados para processamento; PUT substitui uma representação; DELETE pede remoção. O significado exato depende do recurso e das regras HTTP.

A ligação **persistente** reutiliza TCP para vários pedidos. Numa conta simplificada com RTT constante, sem DNS ou TLS e objetos pequenos, um TCP novo custa cerca de um RTT a abrir e outro para pedido/resposta, por isso reutilizar evita repetir a abertura.

Cookies permitem associar pedidos a estado da aplicação, pois HTTP não mantém automaticamente uma sessão de utilizador. Uma cache pode reutilizar conteúdo e validar uma versão com pedidos condicionais, por exemplo `If-Modified-Since` ou `If-None-Match`, recebendo `304 Not Modified` se aplicável.

HTTPS acrescenta proteção através de TLS. HTTP/2 usa enquadramento binário e multiplexagem sobre uma ligação TCP; HTTP/3 usa QUIC. Não descrevas todo o HTTP como texto transmitido sobre TCP: essa descrição é de HTTP/1.x.

Uma resposta ao pedido anterior pode ter este conteúdo. Lê cada fim de linha dos cabeçalhos como CRLF e a linha vazia como separador do corpo, porque é essa delimitação que permite ao recetor saber onde começa o corpo:

```
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 2

42
```

`Content-Length: 2` conta os dois bytes do corpo `42`, não as linhas de cabeçalhos. Uma ligação TCP pode entregar a resposta em várias leituras, incluindo uma leitura que termine a meio de um cabeçalho, por isso o recetor precisa de acumular dados e aplicar a delimitação HTTP.

## FTP e sockets

FTP clássico mantém controlo em TCP 21 e abre ligações separadas para dados. No ativo, o servidor inicia dados para o cliente; no passivo, o cliente liga-se à porta anunciada. FTP não cifra credenciais; SFTP é outro protocolo sobre SSH.

Um cliente TCP usa socket, connect, send e recv. O servidor usa socket, bind, listen e accept; `accept` cria um socket para a conversa, mantendo o socket de escuta para outras. Em UDP, usam-se datagramas e endereços, por exemplo `sendto` e `recvfrom`, sem exigir um handshake TCP.

`recv(4096)` pode devolver menos bytes do que os pedidos e não corresponde necessariamente a uma mensagem inteira. Para dados com comprimento conhecido, lê num ciclo até completar ou detetar fecho. Para envio em Python, `sendall` tenta enviar todos os bytes, mas não garante que a aplicação remota já os processou.

## Correio eletrónico

SMTP transporta correio entre servidores e suporta a submissão por clientes segundo a configuração do serviço. O servidor remetente procura MX do domínio destinatário para saber onde entregar. POP3 e IMAP permitem ao utilizador aceder à sua caixa; IMAP mantém um modelo de pastas e estado no servidor.

MIME descreve tipos de conteúdo, anexos e codificações no corpo. Um endereço de correio não é um endereço IP, e resolver o domínio do destinatário não significa procurar apenas o seu registo A. Portas dependem do serviço e da proteção: SMTP clássico 25, submissão 587, POP3 110 e IMAP 143, com outras portas para TLS implícito.

### Delimitar os dados em SMTP

Na transferência SMTP com `DATA`, o servidor autoriza o conteúdo com a resposta 354. O emissor termina-o com uma linha que contém apenas um ponto, usando CRLF nos fins de linha. Não fecha TCP para assinalar o fim da mensagem; a ligação pode continuar.

Para enviar texto que já começa por um ponto, acrescenta outro no início dessa linha, **dot-stuffing**. A linha de conteúdo `.` viaja como `..`; `.nota` viaja como `..nota`. O recetor reconhece a linha `.` como terminador e, nas restantes linhas iniciadas por ponto, remove o primeiro. Este mecanismo distingue dados de controlo, como o stuffing de ligação, mas aplica-se às linhas da mensagem SMTP.

Depois de aceitar a mensagem, o servidor responde 250. Isso confirma a aceitação para entrega pelo servidor, não que o destinatário já a leu. A delimitação descrita é a do comando `DATA`; extensões podem definir outro mecanismo.

## Cliente-servidor e P2P

No cliente-servidor, um servidor fornece conteúdo. Em P2P, participantes também fornecem a outros. Um P2P pode usar servidores auxiliares como trackers.

Para distribuir um ficheiro de $F$ bits a N clientes, servidor com upload $u_s$ e clientes de download mínimo $d_{min}$, um limite inferior cliente-servidor é:

$$
D_{CS}\ge\max(NF/u_s,F/d_{min}).
$$

Em P2P, contando uploads $u_i$ dos peers, um limite inferior ideal é:

$$
D_{P2P}\ge\max(F/u_s,F/d_{min},NF/(u_s+\sum u_i)).
$$

**Exemplo.** F=100 Mbit, N=10, servidor 10 Mbit/s, cada peer upload 1 Mbit/s e download 5 Mbit/s. Cliente-servidor: máximo de 100 s e 20 s, logo pelo menos 100 s; P2P: máximo de 10 s, 20 s e 50 s, logo pelo menos 50 s. São limites inferiores, não tempos garantidos, pois fragmentos disponíveis, protocolo e topologia podem acrescentar espera.

## DNS, TCP e HTTP no mesmo pedido

Se nada estiver em cache, a sequência é: 1) resolver o nome com o resolver, que segue raiz, TLD e autoritativo; 2) abrir TCP ao endereço obtido; 3) enviar o pedido HTTP e ler a resposta. Com HTTP/1.1 persistente, o passo 2 serve vários pedidos, e com objeto válido em cache os passos seguintes podem não existir. ARP resolve o MAC local, não o IP do servidor, e o router encaminha sem interpretar HTML.

Uma cache válida pode eliminar a comunicação seguinte ou a sequência inteira: se o resolver tem o nome, não consulta a hierarquia; se o objeto está válido em cache, não abre ligação nem envia pedido. No destino, a porta entrega o pedido ao processo servidor.

Escreve o percurso sem consultar e identifica o que pode desaparecer quando há cache ou uma ligação persistente.

## Exercícios

Aceitar recursão DNS

Que servidores DNS aceitam normalmente pedidos recursivos?

Pista

Quem faz o trabalho de seguir a hierarquia?

Solução

Os servidores de nomes locais.

*   **Servidores de nomes locais..** O resolver local recebe o pedido recursivo do cliente e segue as referências.
*   **Servidores de raiz..** A raiz responde com referências, não com a resposta final.
*   **Servidores autoritativos..** Respondem pelos seus dados; não resolvem por outros.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#dns-nomes-e-registos)

Distinguir conteúdo e terminador SMTP

Depois de `DATA` e da resposta 354, uma mensagem SMTP tem estas quatro linhas consecutivas no corpo:

```
Bom dia
.
.nota
fim.
```

Os cabeçalhos e a linha vazia que os separa do corpo já foram enviados. Escreve as linhas que viajam para estas quatro linhas de conteúdo e acrescenta o terminador de `DATA`. Cada fim de linha usa CRLF. Explica como o recetor recupera o texto e se precisa de fechar TCP para saber que a mensagem terminou. Usa a transferência por `DATA`, sem extensões de chunking.

Pista

A regra olha para o primeiro carácter de cada linha de conteúdo.

Solução

```
Bom dia
..
..nota
fim.
.
```

As duas linhas que começavam por ponto recebem outro no início. O ponto no fim de `fim.` não muda. O recetor identifica a última linha, que só contém `.`, como terminador; remove um ponto do início das linhas `..` e `..nota`, recuperando o conteúdo original. A mensagem acaba sem fechar TCP, permitindo outra transação na mesma ligação. Uma resposta 250 posterior confirma a aceitação pelo servidor para entrega.

Confere a tua resposta:

*   Acrescento um ponto apenas às linhas que já começam por ponto.
*   Termino DATA com uma linha contendo só um ponto.
*   Recupero as linhas originais e mantenho a ligação TCP.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#delimitar-os-dados-em-smtp)

Reutilizar uma ligação HTTP

Uma ligação HTTP/1.1 persistente começa com TCP novo, RTT de 50 ms. Pede dois objetos pequenos, um de cada vez, sem pipelining. Ignora DNS, TLS, transmissão e processamento. Quanto demora desde a abertura até receber o segundo objeto, em ms?

Pista

Conta a abertura de TCP e cada pedido/resposta.

Solução

50+50+50=150 ms. Com uma ligação nova para cada objeto seriam 200 ms. A persistência poupa a segunda abertura; não elimina o segundo pedido/resposta.

Erros frequentes

Aplicar 2 RTT a qualquer versão e situação de HTTP sem verificar hipóteses.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#http-pedido-e-resposta)

Distribuição ideal entre peers

F=100 Mbit, N=10, us=10 Mbit/s; cada peer upload 1 Mbit/s, download 5 Mbit/s. Qual o limite inferior ideal P2P em segundos?

Pista

Calcula os três limites e escolhe o máximo.

Solução

Pelo menos 50 s. Não é garantia de execução: nem toda a capacidade pode ser utilizável instantaneamente.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#cliente-servidor-e-p2p)

Ler dados de uma aplicação

Uma aplicação envia uma mensagem de 1000 bytes por TCP. Uma única chamada `recv(1000)` garante receber exatamente essa mensagem?

Pista

Distingue fluxo de bytes e mensagens.

Solução

Não. Pode retornar menos bytes ou combinar dados de envios; usa a regra de comprimento ou delimitação da aplicação.

*   **Não; TCP preserva bytes e ordem, sem fronteiras das chamadas..** A aplicação deve delimitar e completar as suas leituras.
*   **Sim, se a ligação for fiável..** Fiabilidade não implica uma leitura por envio.
*   **Sim, se os 1000 bytes couberem numa trama..** Segmentação física não define as fronteiras da aplicação.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#ftp-e-sockets)

Seguir DNS e cache antes de pedir HTTP

O navegador pede [http://exemplo.test/dados](http://exemplo.test/dados) em HTTP/1.1. Compara três casos: objeto fresco na cache do navegador; objeto expirado, registo A válido no resolver e nenhuma ligação TCP aberta; sem objeto, sem registo no resolver e nenhuma ligação TCP aberta. Descreve as mensagens necessárias, incluindo o significado de uma resposta 304. Para o último caso, assume que o resolver segue referências da raiz até ao servidor autoritativo.

Pista

Localiza primeiro o dado em cache e verifica se está válido.

Solução

Com objeto fresco, o navegador pode servi-lo diretamente sem DNS, TCP ou HTTP na rede. Com objeto expirado, usa o endereço em cache no resolver, evitando consultas à hierarquia. Se possuir um validador, abre TCP e envia um pedido condicional. Uma resposta 304 permite reutilizar o corpo guardado; não contém de novo o objeto. Sem validador, pode ser necessário um pedido normal e uma resposta com corpo.

No terceiro caso, o cliente pergunta ao resolver. Este consulta raiz, TLD e autoritativo conforme as referências, obtém A e devolve o endereço ao cliente. Depois o navegador abre TCP e envia o pedido HTTP. DNS resolve nomes; não fornece o MAC remoto nem os bytes de /dados. A cache em cada etapa elimina operações diferentes.

Confere a tua resposta:

*   No objeto fresco dispenso mensagens.
*   Distingo cache DNS de cache HTTP.
*   Explico pedido condicional e 304.
*   Ordeno resolução, abertura TCP e pedido HTTP.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#dns-tcp-e-http-no-mesmo-pedido)

Diagnosticar a ligação de dados FTP

Um cliente abre TCP 21 e autentica-se num servidor FTP clássico. A firewall do cliente permite ligações iniciadas por ele, mas bloqueia novas ligações iniciadas pelo servidor. O download em modo ativo falha. Explica por que a autenticação pode funcionar e os dados falhar, e como o modo passivo muda o sentido da ligação de dados. Assume que a porta anunciada pelo servidor é permitida para ligações de saída do cliente.

Pista

FTP usa ligações distintas para controlo e dados.

Solução

A ligação de controlo foi iniciada pelo cliente e é permitida. No ativo, o servidor tenta abrir outra ligação para o cliente, que a firewall bloqueia. No passivo, o servidor anuncia uma porta e o cliente inicia a ligação de dados para ela. Pelas regras dadas, essa ligação é permitida. Isto não cifra credenciais nem garante sucesso com qualquer configuração de firewall.

Confere a tua resposta:

*   Distingo controlo de dados.
*   Localizo a ligação bloqueada no modo ativo.
*   Justifico o modo passivo sem prometer contornar toda a firewall.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/rc/aplicacoes/#ftp-e-sockets)
