Wie ändere ich nur die Client-ID in einer MQTT CONNECT-Nachricht?

8

Ich spiele mit MQTT CONNECT-Nachrichten herum. Ich habe ein einfaches C-Programm, das einen TCP / IP-Socket für einen auf meinem Laptop laufenden Mosquitto-Broker öffnet, eine MQTT CONNECT-Nachricht sendet, (normalerweise) die 4 Byte lange CONNACK-Antwort empfängt, dann den Socket schließt und das Programm beendet.

Derzeit erstelle ich keine eigene CONNECT-Nachricht, sondern verwende eine aus einem Wireshark-Capture.

Wireshark Capture Screenshot

Es kann als C-Array exportiert werden, der MQTT-Teil:

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
};

Mit diesem unveränderten Array funktioniert alles einwandfrei. Hier ist die Ausgabe des Brokers:

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.

Die Probleme beginnen, wenn ich die Client-ID in der Nachricht ändern möchte. Mein einfachster Versuch ist es, das letzte Zeichen 4vom Ende der ID zu entfernen.

Ich denke, dies erfordert drei Änderungen im eigentlichen Code.

  1. Löschen des letzten Bytes aus dem Array, der 0x34.
  2. Dekrementieren des Remaining LengthFeldes (2. Byte im Array) in der Nachricht. Also von 32 bis 31, 0x20-> 0x1F.
  3. Dekrementieren der Anzahl der Bytes Parameter der sendFunktion. Von 34 bis 33. (+2 wegen der Header Flagsund Remaining LengthFelder)

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;
}

Es funktioniert nicht, hier ist die Ausgabe des Brokers:

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

Ich weiß, dass das Remaining LengthFeld eine spezielle Eingabe erfordert, aber nicht unter 128.

Restlängentabelle

Was habe ich hier vermisst, was sollte ich neben dem Remaining LengthFeld ändern ?

Bence Kaulics
quelle
Protokolliert der Broker nicht den Socket-Fehlercode oder ähnliches?
Aurora0001
@ Aurora0001 Eigentlich habe ich nicht nachgesehen, da ich dachte, eine ausführliche Konsolenprotokollierung würde funktionieren. Ich werde es überprüfen, ich muss Protokolldateien unter Windows finden.
Bence Kaulics
1
@ Aurora0001 Eigentlich war ich so beschäftigt, den Fehler auf der Clientseite zu finden, dass ich nicht daran gedacht habe, detailliertere Serverprotokolle zu durchsuchen. Vielen Dank für den Hinweis. Ich werde aktualisieren, wenn ich etwas finde.
Bence Kaulics
Derzeit sind keine zusätzlichen Protokolle verfügbar.
Bence Kaulics
1
@ Aurora0001 Nein, die Daten werden gesendet, nur in diesem Fall erhalte ich kein CONACK, die Recv-Funktion gibt 0 zurück und das Programm wird beendet. Ich werde dann versuchen, eine Aufnahme zu machen.
Bence Kaulics

Antworten:

5

Ich habe meinen Fehler gefunden. Ich habe fälschlicherweise angenommen, dass die Client-ID ein Fixfeld ist, aber nur ein Teil der Nutzlast der Nachricht ist, sodass ein Längenpräfix benötigt wird. Aus den Spezifikationen :

Die Nutzdaten des CONNECT-Pakets enthalten ein oder mehrere Felder mit Längenpräfix, deren Vorhandensein durch die Flags im Variablenheader bestimmt wird. Diese Felder MÜSSEN, falls vorhanden, in der Reihenfolge Client-ID, Willenthema, Willensnachricht, Benutzername, Passwort angezeigt werden

Daher sollte ein weiteres Byte in der Nachricht dekrementiert werden. Die richtigen Schritte:

  1. Löschen des letzten Bytes aus dem Array, dem 0x34.
  2. Dekrementieren des Felds Restlänge (2. Byte im Array) in der Nachricht. Also von 32 bis 31, 0x20 -> 0x1F.
  3. Dekrementieren des Längenpräfixbytes der Client-ID in der Nutzlast. In meinem Fall ist es das 16. Byte (ab 1) 0x12---> 0x11.
  4. Dekrementieren des Parameters für die Anzahl der Bytes der Sendefunktion. Von 34 bis 33. (+2 wegen der Felder Header Flags und Restlänge)

Nach diesem zusätzlichen Schritt hat der Broker die CONNACK-Nachricht zurückgesendet.

Bence Kaulics
quelle