Como modificar apenas o ID do cliente em uma mensagem MQTT CONNECT?

8

Estou brincando com as mensagens do MQTT CONNECT. Eu tenho um programa C simples que abre um soquete TCP / IP em direção a um broker Mosquitto em execução no meu laptop, envia uma mensagem MQTT CONNECT, (normalmente) recebe a resposta CONNACK de 4 bytes de comprimento e fecha o soquete e sai do programa.

Atualmente, não construo minha própria mensagem CONNECT, mas uso uma de uma captura do Wireshark.

Captura de tela da captura de Wireshark

Ele pode ser exportado como uma matriz C, a parte do MQTT:

char packet_bytes[] = {
  0x10, 0x20, 0x00, 0x06, 0x4d, 0x51, 0x49, 0x73,
  0x64, 0x70, 0x03, 0x02, 0x00, 0x3c, 0x00, 0x12,
  0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x31, 0x34, 0x38,
  0x35, 0x38, 0x39, 0x30, 0x38, 0x35, 0x37, 0x31,
  0x39, 0x34
};

Usando essa matriz não modificada, tudo funciona muito bem, aqui está a saída do broker:

1486237905: New connection from 192.168.1.2 on port 1883.
1486237905: New client connected from 192.168.1.2 as root.1485890857194 (c1, k60).
1486237905: Sending CONNACK to root.1485890857194 (0, 0)
1486237905: Socket error on client root.1485890857194, disconnecting.

Os problemas começam quando desejo modificar o ID do cliente na mensagem. Minha tentativa mais simples é cortar o último caractere 4do final do ID.

Eu acho que isso requer três modificações no código real.

  1. Excluindo o último byte da matriz, o 0x34.
  2. Decrementando o Remaining Lengthcampo (segundo byte na matriz) na mensagem. Então, de 32 a 31, 0x20-> 0x1F.
  3. Decrementando o número de bytes do parâmetro da sendfunção. De 34 a 33. (+2 por causa dos campos Header Flagse Remaining Length)

char packet_bytes[] = {
  0x10, 0x1F, 0x00, 0x06, 0x4d, 0x51, 0x49, 0x73,
  0x64, 0x70, 0x03, 0x02, 0x00, 0x3c, 0x00, 0x12,
  0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x31, 0x34, 0x38,
  0x35, 0x38, 0x39, 0x30, 0x38, 0x35, 0x37, 0x31,
  0x39
};


if( send(s , packet_bytes , 33, 0) < 0)
{
    puts("Send failed");
    return 1;
}

Não funciona, aqui está a saída do broker:

1486239491: New connection from 192.168.1.2 on port 1883.
1486239491: Socket error on client <unknown>, disconnecting.

Eu sei que o Remaining Lengthcampo requer uma localização especial, mas não abaixo de 128.

Tabela de comprimento restante

O que eu perdi aqui, o que devo modificar ao lado do Remaining Lengthcampo?

Bence Kaulics
fonte
O broker não registra o código de erro do soquete ou algo assim?
Aurora0001
@ Aurora0001 Na verdade, eu não verifiquei como pensava que um log detalhado de console faria. Vou verificar, tenho que encontrar arquivos de log no Windows.
Bence Kaulics
1
@ Aurora0001 Na verdade, eu estava tão ocupado em encontrar o erro no lado do cliente que não pensei em pesquisar logs mais detalhados do servidor, então obrigado por apontar. Vou atualizar se encontrar alguma coisa.
Bence Kaulics
Atualmente, não tenho logs adicionais disponíveis.
Bence Kaulics
1
@ Aurora0001 Não, os dados são enviados, apenas neste caso não recebo CONACK, a função recv retorna 0 e o programa sai. Vou tentar fazer uma captura então.
Bence Kaulics

Respostas:

5

Eu consegui encontrar o meu erro. Por engano, presumi que o ID do cliente é um campo de correção, mas é apenas parte da carga útil da mensagem, portanto, é necessário um prefixo de comprimento . Das especificações :

A carga útil do CONNECT Packet contém um ou mais campos prefixados em comprimento, cuja presença é determinada pelos sinalizadores no cabeçalho da variável. Esses campos, se presentes, DEVEM aparecer na ordem Identificador do Cliente, Tópico, Mensagem, Nome do Usuário, Senha

Portanto, mais um byte deve ser diminuído na mensagem. Os passos corretos:

  1. Excluindo o último byte da matriz, o 0x34.
  2. Decrementando o campo Comprimento Restante (2º byte na matriz) na mensagem. Então, de 32 a 31, 0x20 -> 0x1F.
  3. Decrementando o byte de prefixo de comprimento do ID do cliente na carga útil. No meu caso, é o 16º byte (contando de 1) 0x12---> 0x11.
  4. Decrementando o número de bytes do parâmetro da função de envio. De 34 a 33. (+2 devido aos campos Sinalizadores de cabeçalho e Comprimento restante)

Após esta etapa adicional, o broker retornou a mensagem CONNACK.

Bence Kaulics
fonte