Commit 0d676dc9b9030a7d06a57ec953c8b56ad1bd8978

Authored by Wiebe Cazemier
1 parent 243c873f

Connect handling, mostly

client.cpp
@@ -74,7 +74,10 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn) @@ -74,7 +74,10 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn)
74 while ((encodedByte & 128) != 0); 74 while ((encodedByte & 128) != 0);
75 packet_length += remaining_length_i; 75 packet_length += remaining_length_i;
76 76
77 - // TODO: unauth client can't send many bytes 77 + if (!authenticated && packet_length >= 1024*1024)
  78 + {
  79 + throw ProtocolError("An unauthenticated client sends a packet of 1 MB or bigger? Probably it's just random bytes.");
  80 + }
78 81
79 if (packet_length <= getBufBytesUsed()) 82 if (packet_length <= getBufBytesUsed())
80 { 83 {
@@ -99,6 +102,13 @@ bool Client::bufferToMqttPackets(std::vector&lt;MqttPacket&gt; &amp;packetQueueIn) @@ -99,6 +102,13 @@ bool Client::bufferToMqttPackets(std::vector&lt;MqttPacket&gt; &amp;packetQueueIn)
99 // TODO: reset buffer to normal size after a while of not needing it, or not needing the extra space. 102 // TODO: reset buffer to normal size after a while of not needing it, or not needing the extra space.
100 } 103 }
101 104
  105 +void Client::setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen)
  106 +{
  107 + this->clientid = clientId;
  108 + this->username = username;
  109 + this->connectPacketSeen = connectPacketSeen;
  110 +}
  111 +
102 112
103 113
104 114
client.h
@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 7
8 #include "threaddata.h" 8 #include "threaddata.h"
9 #include "mqttpacket.h" 9 #include "mqttpacket.h"
  10 +#include "exceptions.h"
10 11
11 #define CLIENT_BUFFER_SIZE 1024 12 #define CLIENT_BUFFER_SIZE 1024
12 #define MQTT_HEADER_LENGH 2 13 #define MQTT_HEADER_LENGH 2
@@ -26,7 +27,9 @@ class Client @@ -26,7 +27,9 @@ class Client
26 int ri = 0; 27 int ri = 0;
27 28
28 bool authenticated = false; 29 bool authenticated = false;
  30 + bool connectPacketSeen = false;
29 std::string clientid; 31 std::string clientid;
  32 + std::string username;
30 33
31 ThreadData_p threadData; 34 ThreadData_p threadData;
32 35
@@ -55,6 +58,11 @@ public: @@ -55,6 +58,11 @@ public:
55 int getFd() { return fd;} 58 int getFd() { return fd;}
56 bool readFdIntoBuffer(); 59 bool readFdIntoBuffer();
57 bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn); 60 bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn);
  61 + void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen);
  62 + void setAuthenticated(bool value) { authenticated = value;}
  63 + bool getAuthenticated() { return authenticated; }
  64 + bool hasConnectPacketSeen() { return connectPacketSeen; }
  65 +
58 66
59 }; 67 };
60 68
mqttpacket.cpp
@@ -7,24 +7,25 @@ MqttPacket::MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client @@ -7,24 +7,25 @@ MqttPacket::MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client
7 sender(sender) 7 sender(sender)
8 { 8 {
9 unsigned char _packetType = buf[0] >> 4; 9 unsigned char _packetType = buf[0] >> 4;
10 - packetType = (PacketType)_packetType; // TODO: veryify some other things and set to invalid if doesn't match 10 + packetType = (PacketType)_packetType;
  11 + pos += fixed_header_length;
11 12
12 std::memcpy(&bites[0], buf, len); 13 std::memcpy(&bites[0], buf, len);
13 } 14 }
14 15
15 void MqttPacket::handle() 16 void MqttPacket::handle()
16 { 17 {
17 - pos += fixed_header_length;  
18 -  
19 if (packetType == PacketType::CONNECT) 18 if (packetType == PacketType::CONNECT)
20 handleConnect(); 19 handleConnect();
21 } 20 }
22 21
23 void MqttPacket::handleConnect() 22 void MqttPacket::handleConnect()
24 { 23 {
  24 + if (sender->hasConnectPacketSeen())
  25 + throw ProtocolError("Client already sent a CONNECT.");
  26 +
25 // TODO: Do all packets have a variable header? 27 // TODO: Do all packets have a variable header?
26 - variable_header_length = (bites[fixed_header_length] << 8) | (bites[fixed_header_length+1]);  
27 - pos += 2; 28 + variable_header_length = readTwoBytesToUInt16();
28 29
29 if (variable_header_length == 4) 30 if (variable_header_length == 4)
30 { 31 {
@@ -36,12 +37,54 @@ void MqttPacket::handleConnect() @@ -36,12 +37,54 @@ void MqttPacket::handleConnect()
36 if (magic_marker == "MQTT" && protocol_level == 0x04) 37 if (magic_marker == "MQTT" && protocol_level == 0x04)
37 { 38 {
38 protocolVersion = ProtocolVersion::Mqtt311; 39 protocolVersion = ProtocolVersion::Mqtt311;
  40 +
  41 + char flagByte = readByte();
  42 + bool reserved = !!(flagByte & 0b00000001);
  43 +
  44 + if (reserved)
  45 + throw ProtocolError("Protocol demands reserved flag in CONNECT is 0");
  46 +
  47 +
  48 + bool user_name_flag = !!(flagByte & 0b10000000);
  49 + bool password_flag = !!(flagByte & 0b01000000);
  50 + bool will_retain = !!(flagByte & 0b00100000);
  51 + char will_qos = (flagByte & 0b00011000) >> 3;
  52 + bool will_flag = !!(flagByte & 0b00000100);
  53 + bool clean_session = !!(flagByte & 0b00000010);
  54 +
  55 + uint16_t keep_alive = readTwoBytesToUInt16();
  56 +
  57 + uint16_t client_id_length = readTwoBytesToUInt16();
  58 + std::string client_id(readBytes(client_id_length), client_id_length);
  59 +
  60 + std::string username;
  61 + std::string password;
  62 +
  63 + if (will_flag)
  64 + {
  65 +
  66 + }
  67 + if (user_name_flag)
  68 + {
  69 + uint16_t user_name_length = readTwoBytesToUInt16();
  70 + username = std::string(readBytes(user_name_length), user_name_length);
  71 + }
  72 + if (password_flag)
  73 + {
  74 + uint16_t password_length = readTwoBytesToUInt16();
  75 + password = std::string(readBytes(password_length), password_length);
  76 + }
  77 +
  78 + sender->setClientProperties(clientid, username, true);
  79 +
39 } 80 }
40 } 81 }
41 else if (variable_header_length == 6) 82 else if (variable_header_length == 6)
42 { 83 {
43 - throw new ProtocolError("Only MQTT 3.1.1 implemented."); 84 + throw ProtocolError("Only MQTT 3.1.1 implemented.");
44 } 85 }
  86 +
  87 + throw ProtocolError("Unprogrammed sequence in CONNECT.");
45 } 88 }
46 89
47 char *MqttPacket::readBytes(size_t length) 90 char *MqttPacket::readBytes(size_t length)
@@ -59,11 +102,20 @@ char MqttPacket::readByte() @@ -59,11 +102,20 @@ char MqttPacket::readByte()
59 if (pos + 1 > bites.size()) 102 if (pos + 1 > bites.size())
60 throw ProtocolError("Invalid packet: header specifies invalid length."); 103 throw ProtocolError("Invalid packet: header specifies invalid length.");
61 104
62 - char b = bites[pos];  
63 - pos++; 105 + char b = bites[pos++];
64 return b; 106 return b;
65 } 107 }
66 108
  109 +uint16_t MqttPacket::readTwoBytesToUInt16()
  110 +{
  111 + if (pos + 2 > bites.size())
  112 + throw ProtocolError("Invalid packet: header specifies invalid length.");
  113 +
  114 + uint16_t i = bites[pos] << 8 | bites[pos+1];
  115 + pos += 2;
  116 + return i;
  117 +}
  118 +
67 119
68 120
69 std::string MqttPacket::getClientId() 121 std::string MqttPacket::getClientId()
mqttpacket.h
@@ -34,6 +34,7 @@ public: @@ -34,6 +34,7 @@ public:
34 void handleConnect(); 34 void handleConnect();
35 char *readBytes(size_t length); 35 char *readBytes(size_t length);
36 char readByte(); 36 char readByte();
  37 + uint16_t readTwoBytesToUInt16();
37 }; 38 };
38 39
39 #endif // MQTTPACKET_H 40 #endif // MQTTPACKET_H