Redes de Computadores
Trabalho Prático III
DCC Deep Web
1
Introdução
Neste trabalho iremos desenvolver uma plataforma de roteamento cebola.1
Estas plataformas permitem que clientes se conectem a servidores sem revelar
sua identidade para os servidores e para os outros clientes na rede. Para isso,
clientes criam uma tuneis de forma que vários clientes se interpõem entre a
origem e o destino de cada pacote.
Nossa plataforma irá permitir que vários clientes se conheçam, estabeleçam túneis para roteamento cebola, e comuniquem dados com um servidor remoto de forma (pseudo-)anônima.2
2
Protocolo e funcionamento
As mensagens do DCC Deep Web possuem o seguinte formato de cabeçalho:
0
1
2
3
4
+-------+-------+-------+-------+
| CODE | TID
| TTL
| RSRVD |
+-------+-------+-------+-------+
| DESTINATION IP
|
+-------------------------------+
| DEST PORT
| LENGTH
|
+---------------+---------------+
| PAYLOAD
|
| ...
|
O protocolo do DCC Deep Web possui mensagens de quatro tipos distintos: (i) mensagens de entrada na rede e disseminação de dispositivos, (ii)
mensagem para teste de presença na rede, (iii) mensagens para criação e
fechamento de túneis, e (iv) mensagens para transmissão de dados em um
túnel.
1
2
Um exemplo deste tipo de aplicação é o Tor.
A comunicação não será totalmente segura pois não iremos criptografar os dados.
2.1
Entrada e disseminação de clientes
Existem três mensagens para disseminação de informações sobre clientes que
compõem a rede:
peer-announce (1): Essa mensagem é a primeira enviada por um novo
cliente quando ele entra no sistema. Ela é enviada a um cliente qualquer
préviamente conhecido que já está no sistema. Os campos TID e TTL não
são utilizados e devem ter o valor zero. O campo length deve ter o valor
zero pois mensagens peer-announce não têm corpo, apenas cabeçalho.
Os campos IP e port devem conter o IP e porta onde o novo cliente irá
receber conexões do DCC Deep Web. Quando um cliente recebe uma
mensagem peer-announce ele armazena o IP e porta recebidos na sua
lista de clientes conhecidos.
peer-request (2): Esta mensagem requisita a lista de clientes conhecidos.
Os campos TID, TTL, IP e port não são utilizados e devem ter o valor
zero. (O cliente realizando a requisição é identificado pelo soquete de
rede onde a requisição foi recebida.) O campo length deve ter o valor
zero pois mensagens peer-request não têm corpo, apenas cabeçalho.
Um cliente que recebe uma mensagem peer-request deve responder
ao requisitante enviando uma mensagem peer-list.
peer-list (3): Esta mensagem é a resposta para mensagens peer-request.
Os campos TID, TTL, IP e port não são utilizados e devem ter o valor zero. O campo length terá um valor igual a 6n bytes, onde n é
o número de clientes conhecidos. Para cada cliente conhecido serão
enviados 6 bytes contendo o endereço IP e a porta onde aquele cliente
recebe conexões do DCC Deep Web; o mesmo IP e porta passados pelo
cliente na mensagem peer-announce quando ele entrou na rede. Um
cliente que recebe uma mensagem peer-list deve colocar todos IPs e
portas recebidos na sua lista de clientes conhecidos.
Quando um novo cliente entra na rede, ele primeiro envia uma requisição
peer-announce a outro cliente que já entrou no sistema para anunciar sua
presença. O novo cliente deve também pedir uma lista de outros clientes que
estão na rede enviando uma requisição peer-request. O novo cliente pode
enviar mensagens peer-announce e peer-request para todos os clientes em
sua lista de clientes conhecidos.
Durante sua permanência na rede, clientes devem enviar requisições peerannounce e peer-request periodicamente para anunciar sua presença na
rede e descobrir a presença de outros clientes na rede. Quando novos clientes
são descobertos na rede, conexões do DCC Deep Web devem ser estabelecidas
com estes clientes. Cada cliente conhecido deve estar associado a um soquete
de rede utilizado para fazer comunicação com aquele cliente.
2.2
Mensagens de teste de presença e comunicação
O DCC Deep Web suporta duas mensagens de teste que funcionam de forma
similar a mensagens de ping (echo request) e pong (echo reply) na Internet:
peer-ping (4): Esta mensagem testa se um membro ainda está ativo. O
teste pode ser realizado periodicamente ou sob demanda (e.g., antes
de encaminhando uma mensagem tunnel-create), a cargo da implementação. O campo TID é utilizado para identificar a requisição e
pode ter qualquer valor. Os campos TTL, IP e port não são utilizados
e devem ter valor zero. O campo length deve ter o valor zero pois mensagens peer-ping não têm corpo, apenas cabeçalho. Um cliente que
recebe uma mensagem peer-ping deve responder com uma mensagem
peer-pong.
peer-pong (5): Esta mensagem é enviada como resposta às mensagens peerping. A mensagem peer-pong é enviada apenas ao remetente da mensagem peer-ping. O campo TID da mensagem peer-pong deve ter o
mesmo valor da mensagem peer-ping que responde. Os campos TTL,
IP e port não são utilizados e devem ter valor zero. O campo length
deve ter o valor zero pois mensagens peer-pong não têm corpo, apenas
cabeçalho.
2.3
Mensagens para criação e fechamento de túneis
Considere que os clientes participantes do DCC Deep Web sejam enumerados
por C1 , C2 , . . . , Cn . A comunicação anônima é estabelecida através de túneis
criados através dos seguintes passos:
1. Um cliente Ci envia uma requisição para um outro cliente Cj escolhido
aleatoriamente para estabelecer um túnel. Esta requisição estabelece a
comunicação entre Ci e Cj para o túnel.
2. Se Cj não for o último cliente no túnel, voltamos à etapa anterior
fazendo i ← j para construir o resto do túnel. Se Cj for o último
cliente no túnel, passamos para a etapa seguinte.
3. Cj , o último cliente no túnel, deve abrir uma conexão com o servidor
indicado na requisição de criação do túnel e confirmar a criação do
túnel para o nó anterior a ele no túnel.
4. Um cliente Ci , ao receber a confirmação de criação do túnel, repassa
a confirmação para o nó anterior a ele no túnel. A confirmação irá
percorrer todo o túnel até chegar ao cliente que originou a requisição
de criação do túnel.
5. Após o recebimento da confirmação de criação do túnel, o cliente pode
utilizar o túnel normalmente.
6. Quando o túnel não for mais necessário, o cliente que requisitou a
criação do túnel irá enviar uma mensagem de fechamento do túnel, que
irá percorrer todo o túnel até o último dispositivo no túnel.
Durante o estabelecimento de um túnel (etapas 1–4), cada cliente deve
preencher uma tabela de roteamento utilizada para rotear pacotes recebidos
nos túneis. A tabela de roteamento dos túneis deve mapear (Cin, TIDin ) →
(Cout , TIDout ). Cin e TIDin são o cliente e o TID de onde a requisição foi
recebida. Cout e TIDout são o identificador do próximo cliente no túnel e o
TID combinado com o próximo cliente. O cliente que requisitou a criação de
um túnel usa valores especiais de Cin e TIDin para identificar que é o inı́cio
do túnel. De forma similar, o último cliente no túnel usa valores especiais
de Cout e TIDout para identificar que é o último cliente no túnel. De forma
gráfica, a tabela deve conter as seguintes informações:
+---------+---------+---------+---------+
| C in
| TID in | C out
| TID out |
+---------+---------+---------+---------+
Os identificadores de túnel, TIDs, são transmitidos no campo TID no
cabeçalho dos pacotes do DCC Deep Web. Os identificadores de cliente
(Cin e Cout ) ficam a cargo da implementação; podem ser utilizados, e.g., o IP
e porta do cliente ou seu soquete de rede.
As etapas 1–4 acima são implementadas através das mensagens seguintes:
tunnel-create (6): Esta mensagem envia uma requisição para criação de
um túnel no DCC Deep Web. Quando um cliente deseja criar um novo
túnel, ele inicia o processo de criação do túnel enviando uma requisição
tunnel-create para um cliente conhecido escolhido aleatoriamente. O
campo TID deve conter o identificador que será utilizado para comunicação entre o transmissor (Ci ) e o destinatário (Cj ) no túnel sendo
criado. O campo TTL deve ser inicializado aleatoriamente com um valor entre 4 e 32. O campo IP e port devem conter o IP e a porta do
servidor ao qual o último cliente no túnel irá se conectar. O campo
length deve ter o valor zero pois mensagens tunnel-create não têm
corpo, apenas cabeçalho.
Quando um cliente recebe uma mensagem tunnel-create, ele verifica
se o TTL tem valor zero. Se o TTL tiver valor zero, o cliente é o último
cliente no túnel. O cliente deve estabelecer uma conexão com um servidor externo no IP e porta indicados nos campos IP e port da mensagem
tunnel-create. Se a conexão com o servidor externo for estabelecida
com sucesso, o cliente deve atualizar sua tabela de roteamento para
redirecionar dados recebidos no túnel para o servidor e dados recebidos
do servidor para o túnel. O cliente deve também confirmar a criação
do túnel enviando uma mensagem tunnel-ok ao cliente anterior (i.e.,
o cliente do qual recebeu a mensagem tunnel-create).
Quando um cliente recebe uma mensagem tunnel-create e o valor do
campo TTL é maior do que zero, ele é um nó intermediário no túnel.
O cliente deve decrementar o valor do campo TTL e escolher um conhecido aleatório para continuar a requisição de criação de túnel. A
mensagem tunnel-create repassada deve: conter os mesmos valores
para os campos IP, port e length da mensagem tunnel-create original; ter o valor do campo TTL decrementado; utilizar qualquer TID que
o cliente tiver livre (o TID é local, não é global). Ao repassar pedidos de
criação de túneis, clientes devem atualizar suas tabelas de roteamento.
tunnel-ok (7): Esta mensagem é enviada na direção contrária das mensagens tunnel-create para confirmar que um túnel foi estabelecido
com sucesso. Esta mensagem deve conter os mesmos valores nos campos TID, IP e port que a mensagem tunnel-create recebida. Estes
campos são utilizados para identificar qual túnel foi estabelecido com
sucesso. O campo TTL não é utilizado e deve ter o valor zero. O campo
length deve ter o valor zero pois mensagens tunnel-create não têm
corpo, apenas cabeçalho.
Um cliente que recebe uma mensagem tunnel-ok, deve repassar a
mensagem ao cliente anterior no túnel. Após receber a mensagem
tunnel-ok, o cliente que originou a criação do túnel pode começar
a utilizá-lo usando as mensagens descritas na seção 2.4. Se um túnel
não for confirmado com mensagens tunnel-ok dentro de 60 segundos,
sua criação deve ser abortada; os recursos reservados ao túnel devem
ser liberados, mas não é preciso enviar nenhuma mensagem.
Quando um túnel não é mais necessário, o cliente deve terminá-lo enviando a seguinte mensagem:
tunnel-destroy (8): Esta mensagem fecha um túnel. O campo TID deve
conter o identificador do túnel; os campos IP e port devem conter o
IP e porta do servidor externo utilizados quando da criação do túnel
(nas mensagens tunnel-create). O campo TTL não é utilizado e deve
ter valor zero. O campo length deve ter o valor zero pois mensagens
tunnel-create não têm corpo, apenas cabeçalho.
Ao receber uma mensagem tunnel-destroy, o cliente deve liberar todos os recursos associados ao túnel (entradas na tabela de roteamento,
TIDs, soquetes com servidores externos). Caso o cliente não seja o
último cliente no túnel, ele deve atualizar o valor do campo TID e repassar a mensagem tunnel-destroy ao próximo cliente no túnel.
2.4
Transmissão de dados
A transmissão de dados em túneis é realizada pelas seguintes mensagens:
tunnel-data (9): Esta mensagem carrega dados que devem ser encaminhados em um túnel. O campos TID deve conter o identificador de
um túnel préviamente criado através das mensagens tunnel-create e
tunnel-ok. Os campos TTL, IP e port não são utilizados e devem ter
valor zero. O campo length deve conter o tamanho do payload (em
bytes). Ao receber uma mensagem tunnel-data um dispositivo deve
repassar a mensagem à outra ponta do túnel. O cliente que originou
o túnel repassa dados recebidos da aplicação para o túnel e os dados
recebidos do túnel para a aplicação. O último cliente no túnel, que está
conectado ao servidor externo, repassa dados recebidos do túnel para
o servidor externo e repassa os dados recebidos do servidor externo no
túnel.
3
Implementação e avaliação
Este trabalho deve ser realizado em grupo de até quatro alunos. Os grupos
deverão implementar o protocolo descrito acima e formar uma rede de roteamento cebola. Seu cliente deve interoperar com outros clientes (teste com
clientes dos colegas), inclusive com o cliente de referência a ser implementado
pelo professor. O professor irá executar um cliente do DCC Deep Web no
computador george.dcc.ufmg.br na porta 80. O cliente pode ser implementado em Python, C, C++ ou Java, mas deve interoperar com clientes
escritos em outras linguagens.
A avaliação do código será feita criando uma rede do DCC Deep Web
com clientes de cada grupo e clientes implementados pelo professor. Cada
grupo deverá entregar documentação em PDF de até 4 páginas (duas folhas),
sem capa, utilizando fonte tamanho 10, e figuras de tamanho adequado ao
tamanho da fonte. A documentação deve discutir desafios, dificuldades e
imprevistos de projeto, bem como as soluções adotadas para os problemas.
4
Extras
Verificação de clientes entrando no sistema. Um cliente que já está
no sistema pode verificar, ao receber uma mensagem peer-announce, se
a mensagem está sendo recebida num soquete de rede usando o IP e porta
contidos na mensagem peer-announce. Esta verificação evita que um cliente
envie informações falsas ou incorretas.
Download

TP3: DCC Deep Web