Comment modifier uniquement l'ID client dans un message MQTT CONNECT?

8

Je joue avec les messages MQTT CONNECT. J'ai un programme C simple qui ouvre un socket TCP / IP vers un courtier Mosquitto fonctionnant sur mon ordinateur portable, envoie un message MQTT CONNECT, (normalement) reçoit la réponse CONNACK de 4 octets, puis ferme le socket et quitte le programme.

Actuellement, je ne crée pas mon propre message CONNECT mais j'en utilise un à partir d'une capture Wireshark.

Capture d'écran de Wireshark Capture

Il peut être exporté sous forme de tableau C, la partie 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
};

En utilisant ce tableau non modifié, tout fonctionne très bien, voici la sortie du courtier:

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.

Les problèmes commencent lorsque je souhaite modifier l'ID client dans le message. Ma tentative la plus simple consiste à couper le dernier caractère 4de la fin de l'ID.

Je pense que cela nécessite trois modifications dans le code réel.

  1. Suppression du dernier octet du tableau, le 0x34.
  2. Décrémenter le Remaining Lengthchamp (2ème octet du tableau) dans le message. Donc du 32 au 31, 0x20-> 0x1F.
  3. Décrémenter le paramètre nombre d'octets de la sendfonction. De 34 à 33. (+2 à cause des champs Header Flagset 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;
}

Cela ne fonctionne pas, voici la sortie du courtier:

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

Je sais que le Remaining Lengthdomaine nécessite une liaison spéciale mais pas inférieure à 128.

Tableau des longueurs restantes

Qu'est-ce que j'ai raté ici, que dois-je modifier à côté du Remaining Lengthterrain?

Bence Kaulics
la source
Le courtier n'enregistre-t-il pas le code d'erreur de socket ou quelque chose comme ça?
Aurora0001
@ Aurora0001 En fait, je n'ai pas vérifié car je pensais qu'une journalisation détaillée de la console ferait l'affaire. Je vais le vérifier, je dois trouver des fichiers journaux sous Windows.
Bence Kaulics
1
@ Aurora0001 En fait, j'étais tellement occupé à trouver l'erreur côté client, je n'ai pas pensé à rechercher des journaux de serveur plus détaillés, donc merci de le signaler. Je mettrai à jour si je trouve quelque chose.
Bence Kaulics
Actuellement, je n'ai pas de journaux supplémentaires disponibles.
Bence Kaulics
1
@ Aurora0001 Non, les données sont envoyées, seulement dans ce cas je ne reçois pas CONACK, la fonction recv retourne 0 et le programme se termine. J'essaierai alors de faire une capture.
Bence Kaulics

Réponses:

5

J'ai réussi à trouver mon erreur. Par erreur, j'ai supposé que l'ID client est un champ fixe, mais ce n'est qu'une partie de la charge utile du message, donc un préfixe de longueur est nécessaire. D'après les spécifications :

La charge utile du paquet CONNECT contient un ou plusieurs champs préfixés par la longueur, dont la présence est déterminée par les indicateurs dans l'en-tête de variable. Ces champs, s'ils sont présents, DOIVENT apparaître dans l'ordre Identifiant client, Sujet, Message, Nom d'utilisateur, Mot de passe

Un octet de plus doit donc être décrémenté dans le message. Les étapes correctes:

  1. Suppression du dernier octet du tableau, le 0x34.
  2. Décrémenter le champ Longueur restante (2e octet du tableau) dans le message. Donc du 32 au 31, 0x20 -> 0x1F.
  3. Décrémenter l'octet de préfixe de longueur de l'ID client dans la charge utile. Dans mon cas, c'est le 16e octet (à partir de 1) 0x12---> 0x11.
  4. Décrémenter le nombre d'octets paramètre de la fonction d'envoi. De 34 à 33. (+2 en raison des champs Indicateurs d'en-tête et Longueur restante)

Après cette étape supplémentaire, le courtier a renvoyé le message CONNACK.

Bence Kaulics
la source