O Protocolo

O modelo do Constrained Application Protocol (CoAP) permite que a interação Machine-to-Machine seja de uma forma semelhante ao modelo cliente/servidor, porém onde ambas as máquinas atuem nas duas funções diferente do modelo HTTP. Para definir se a mensagem enviada é uma solicitação ou resposta o protocolo insere alguns Códigos de Método e de Resposta nas próprias mensagens. Apesar de o CoAP ser uma camada de aplicação, pode-se pensar em uma abstração de duas camadas, onde a mais baixa lida com o UDP e as mensagens a outra parte está no nível da aplicação lidando com as solicitações e respostas.


Figura 1: Camadas abstratas do CoAP.



O CoAP realiza troca de mensagens (solicitações e respostas) por meio do UDP entre nós (pontos) finais, utilizando uma estrutura de cabeçalho com comprimento fixo curto de 4 bytes, podendo conter ainda opções binárias compactas e um payload (carga de conteúdo útil). Um ID de 16 bits identifica cada mensagem, usado para detectar duplicatas e para confiabilidade.
A confiabilidade é conseguida marcando-se uma mensagem como Confirmable (CON), e partir disso, há a retransmissão de uma mensagem de confirmação, respeitando-se um tempo limite padrão até que o destinatário envie uma mensagem de Acknowledgement (ACK) com o mesmo ID da mensagem do nó correspondente. Uma mensagem de Reset (RST) é retornada pelo destinatário se ele não estiver habilitado a fornecer uma resposta adequada, em vez do ACK.


Figura 2: Transmissão de mensagem confiável com ID = 0x7d34.


No caso de uma mensagem que não necessita de transmissão confiável (medições em um sensor, por exemplo), uma mensagem Non-Confirmable (NON) é enviada, que não é replicada pelo destinatário, mas ainda contém um ID que detecta duplicatas. Novamente, se o destinatário não for capaz de processar a mensagem, ele responde com uma mensagem RST.


Figura 3: Transmissão de mensagem não confiável com ID = 0x01a0.



As solicitações e respostas são transportadas em mensagens CoAP, incluindo um código de método ou código de resposta, além de opções que podem conter informações padrões ou opcionais (como URI e tipos de payload). Um token é incluído para realizar a correspondência entre solicitações e respostas, independente de mensagens subjacentes. A solicitação é realizada por meio de mensagens CON ou NON, que é respondida com um ACK de confirmação se estiver imediatamente disponível. Esse formato é denominado resposta em Piggybacked.


Figura 4: Duas solicitações GET com resposta em Piggybacked, uma bem sucedida e a outra não.


Caso o servidor não possa responder imediatamente a uma requisição com mensagem confirmável, ele simplesmente responde com uma mensagem vazia para o cliente pare de realizar pedidos. Quando ele estiver disponível, uma nova mensagem confirmável é retransmitida, sendo assim chamada de Resposta Separada.


Figura 5: Uma solicitação GET com Resposta Separada.


Embora o servidor possa enviar uma mensagem de confirmação, se uma requisição for realizada com uma mensagem NON, uma nova mensagem NON é repassada como resposta.


Figura 6: Solicitação e Resposta em mensagens Não-Confirmáveis.


Vale ressaltar que o CoAP, de maneira similar ao HTTP, faz uso de métodos GET, PUT, POST e DELET. Isso pode ser estendido para além dos quatro, não necessariamente utilizados em pares, como em casos onde uma única solicitação pode obter múltiplas respostas (por exemplo, em um Multicast).


O CoAP suporta armazenamento em cache (que pode estar presente num nó final ou intermediário), carregando informações de validez e recência nas respostas, atendendo de forma mais eficiente às solicitações. O proxying permite melhorar o desempenho, principalmente em redes restritas, onde pode ser necessário lidar com segurança ou limitações de tráfego. O protocolo permite que pedidos sejam feitos a partir de outro ponto de extremidade, onde o URI (Identificador Uniforme de Recurso) está definido na requisição, ao passo que o IP está definido para o endereço de proxy.


2.2) Comunicação



2.2.1) Formato da Mensagem

O UDP lida com a troca de mensagens compactas, onde cada mensagem CoAP ocupa uma seção de dados de um datagrama UDP, sendo codificada por um formato binário simples. O formato começa a partir de um cabeçalho de 4 bytes fixos seguido por um token de tamanho variável, compreendido entre 0 e 8 bytes. Uma sequência de zeros ou opções sucede o token, podendo ainda conter um payload no resto do datagrama.


Figura 7: Formato da Mensagem.


No cabeçalho, os campos são definidos como:
- Ver: indica o número da versão do CoAP em binário.
- T: indica se a mensagem é CON (0), NON (1), ACK (2) ou RST (3).
- TKL: indica o tamanho variável do token (0 a 8 bytes).
- Code: 3 bits mais significativos indicam se é uma solicitação (0), uma resposta bem sucedida (2), erro de resposta do cliente (4), ou um erro do servidor (5). O resto é reservado.
- Message ID: usada para detectar duplicatas ou correspondências entre mensagens ACK/RST e CON/NON.


A troca de mensagens no CoAP é feita de forma assíncrona entre os nós finais que podem ser de origem e destino. Essa definição de um ponto final vai depender de como ele é identificado, seja ele sem segurança (através de um endereço IP e um número de porta UDP), ou com segurança, conforme for definido esse modo.
Pelo fato de o CoAP poder realizar transportes não confiáveis, ele implementa um mecanismo leve de confiabilidade para tratar mensagens que cheguem fora de ordem, duplicadas ou que desapareçam sem aviso prévio. Uma mensagem pode conter uma solicitação, uma resposta ou pode estar vazia, sinalizada pelo campo de código no cabeçalho.

a) Transmissão de forma Confiável

A origem retransmite uma mensagem CON em intervalos de tempos crescentes, até que receba uma confirmação ACK (ou RST) ou até que acabe o número de tentativas. Uma rejeição pode ser tratada usando um código reservado no datagrama. Todo este processo é controlado por um tempo limite e um contador de retransmissão:


Figura 8: Esquema de transmissão confiável entre pontos finais.


b) Transmissão de forma Não Confiável

Como as mensagens não-confirmáveis dispensam reconhecimento, o nó de destino não é capaz de confirmar se houve ou não recepção. Desta forma, um nó de origem pode enviar múltiplas cópias da mesma mensagem, ou a própria rede pode duplicar uma mensagem durante a transmissão. Isto pode ser especificado através do ID da mensagem.


Figura 9: Esquema de transmissão não confiável entre pontos finais.

Figura 9: Uso dos tipos de mensagem. O (*) representa um ping CoAP.



O ID de uma mensagem, conjuntamente com informações de endereços correspondentes a nós finais, é responsável por correlacionar ACK’s e RST’s a mensagens CON e NON. Ele é um inteiro de 16 bits, gerado pela emissor no cabeçalho CoAP, que precisa ser replicado pelo receptor, ou seja, os IDs de mensagens precisam ser correspondentes entre a origem e o destino. Vale ressaltar que um mesmo ID não pode ser reutilizado durante uma mesma troca.
Contudo, um destinatário pode receber várias vezes uma mesma mensagem CON, desde que as reconheça pelos ACK’s ou RST’s, processando apenas uma única vez a solicitação ou resposta contida na cópia. Esta situação é útil para quando um reconhecimento se perde ou a mensagem não atinge o seu destino antes do tempo limite. O mesmo vale para mensagens NON, mas como não há reconhecimento neste caso, o receptor deve ignorar silenciosamente as mensagens duplicadas.


O CoAP fornece um limite superior para o tamanho de uma mensagem, de tal forma que, se ela exceder o tamanho de um pacote na camada de enlace, haverá desfragmentação. Desta forma, a mensagem deve ser devidamente encapsulada para caber num pacote único IP, e necessariamente, dentro um datagrama IP.
Diversas aplicações necessitam de um buffer para alocar mensagens recebidas, principalmente em nós restritos, sendo capazes de determinar e recuperar a porção perdida de um datagrama. O buffer deve conter ao menos o cabeçalho CoAP e as opções, senão toda carga útil, por isso a importância do tamanho da mensagem.


Para não haver congestionamento, os clientes devem limitar o número de interações pendentes simultaneamente que eles tem com um servidor através de NSTART (que tem como valor padrão igual a 1). Essas interações são definidas como interações onde um pedido que ainda não recebeu uma resposta ou uma mensagem de reconhecimento, ou um CON que não recebeu ACK.


O CoAP opera sob um modelo similar ao HTTP no que diz respeito à comunicação, sendo capaz de atuar como cliente, enviando diversas requisições à um servidor e atendendo às solicitações a partir do mesmo. A única particularidade reside na troca de mensagens que é feita de forma assíncrona.

a) Solicitações

Uma solicitação pode ser iniciada configurando-se o campo de código no cabeçalho (que define a mensagem como CON ou NON) para um código de método que vai ser aplicado a algum recurso. Como visto anteriormente, o CoAP suporta os métodos GET (que possui propriedades de recuperação), PUT e DELET (que podem ser invocados diversas vezes e POST (relacionado a criação ou atualização de um recurso no destino).

b) Respostas

Um servidor responde a uma requisição através de um token correspondente gerado pelo cliente, sendo a resposta identificada pelo código no cabeçalho, que indica a tentativa de entender e satisfazer o pedido. Dos 8 bits de código, os 3 mais significativos definem a classe da resposta, enquanto o restante serve para detalhes adicionais. As classes podem ser:

- Sucesso: pedido entendido e aceito.
- Erro do cliente: pedido com sintaxe incorreta ou não que pode ser realizado.
- Erro do servidor: falha no servidor ao atender um pedido.


Figura 10: Estrutura do código de resposta.


Como visto antes, o token é representado por uma sequência de 0 a 8 bytes e é usado para diferenciar solicitações do cliente, sendo cada um exclusivo para um determinado par de nós finais (origem e destino). Um token pode ter comprimento 0 (vazio) quando outros não estão em uso, ou quando solicitações são feitas em sequência e recebem resposta em Piggybacked. Por fim, se um token não gerado for recebido no destino, este deve simplesmente ignorá-lo.


Escola Politécnica
UFRJ

Acesso ao site da Escola Politécnica da Universidade Federal do Rio de Janeiro.

Ir ao site

Grupo de Teleinformática e Automação

Site do Grupo de Teleinformática e Automação da Universidade Federal do Rio de Janeiro.

Ir ao site

Redes de Computadores I
2018.1

Primeira versão dos trabalhos feitos pela turma de Redes de Computadores I do período de 2018.1

Ir ao site

Contato

Fernanda Cassinelli: nandacassinelli@poli.ufrj.br
Lucas Miranda:
lucasmiranda@poli.ufrj.br
Lucas do Vale:
lukasvale22@poli.ufrj.br