-
Notifications
You must be signed in to change notification settings - Fork 738
Network data usage of Azure IoT SDK over MQTT on idle connection.
Last edited on May 8th, 2020.
Run ont a Ubuntu 18.04 environment.
- Install Wireshark.
user@ubuntu:/$ sudo apt-get update
user@ubuntu:/$ sudo apt-get install wireshark
user@ubuntu:/$ sudo usermod -aG wireshark $(whoami)
user@ubuntu:/$ sudo reboot
- Clone, update samples and build the C SDK
user@ubuntu:/$ git clone --recursive https://github.com/azure/azure-iot-sdk-c.git
user@ubuntu:/$ cd azure-iot-sdk-c
Update the sample 'iothub_ll_telemetry_sample.c' with your connection string (example below):
user@ubuntu:/azure-iot-sdk-c$ git diff
diff --git a/iothub_client/samples/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.c b/iothub_client/samples/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.c
index eb008853f..f62f2bdaf 100644
--- a/iothub_client/samples/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.c
+++ b/iothub_client/samples/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.c
@@ -50,7 +50,7 @@ and removing calls to _DoWork will yield the same results. */
/* Paste in the your iothub connection string */
-static const char* connectionString = "[device connection string]";
+static const char* connectionString = "HostName=REDACTED.azure-devices.net;DeviceId=deviceid;SharedAccessKey=READACTED";
#define MESSAGE_COUNT 5
static bool g_continueRunning = true;
static size_t g_message_count_send_confirmations = 0;
@@ -170,7 +170,7 @@ int main(void)
else if (g_message_count_send_confirmations >= MESSAGE_COUNT)
{
// After all messages are all received stop running
- g_continueRunning = false;
+ // g_continueRunning = false;
}
IoTHubDeviceClient_LL_DoWork(device_ll_handle);
user@ubuntu:/azure-iot-sdk-c$
Continue with building:
user@ubuntu:/azure-iot-sdk-c$ mkdir cmake
user@ubuntu:/azure-iot-sdk-c$ cd cmake
user@ubuntu:/azure-iot-sdk-c/cmake$ cmake -DCMAKE_BUILD_TYPE=Debug ..
user@ubuntu:/azure-iot-sdk-c/cmake$ make -j
- Find your IoT Hub ip address
user@ubuntu:~$ nslookup REDACTED.azure-devices.net
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
REDACTED.azure-devices.net canonical name = ihsu-prod-xyz-000.cloudapp.net.
Name: ihsu-prod-xyz-000.cloudapp.net
Address: 111.222.333.444
user@ubuntu:~$
-
Open Wireshark on desktop UI.
-
Select the interface to capture on.
-
Apply a filter to show only traffic to/from the Azure IoT Hub
ip.addr == 111.222.333.444
-
Click to start capturing.
-
Run the sample
user@ubuntu:/azure-iot-sdk-c/cmake$ cd iothub_client/samples/iothub_ll_telemetry_sample/
user@ubuntu:/azure-iot-sdk-c/cmake/iothub_client/samples/iothub_ll_telemetry_sample/$ ./iothub_ll_telemetry_sample
Creating IoTHub Device handle
Sending message 1 to IoTHub
Sending message 2 to IoTHub
Sending message 3 to IoTHub
Sending message 4 to IoTHub
Sending message 5 to IoTHub
-> 14:48:15 CONNECT | VER: 4 | KEEPALIVE: 240 | FLAGS: 192 | USERNAME: REDACTED.azure-devices.net/deviceid/?api-version=2017-11-08-preview&DeviceClientType=iothubclient%2f1.3.8%20(native%3b%20Linux%3b%20x86_64) | PWD: XXXX | CLEAN: 0
<- 14:48:15 CONNACK | SESSION_PRESENT: true | RETURN_CODE: 0x0
The device client is connected to iothub
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 2 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 3 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 4 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 5 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 6 | PAYLOAD_LEN: 12
<- 14:48:15 PUBACK | PACKET_ID: 2
Confirmation callback received for message 1 with result IOTHUB_CLIENT_CONFIRMATION_OK
<- 14:48:15 PUBACK | PACKET_ID: 3
Confirmation callback received for message 2 with result IOTHUB_CLIENT_CONFIRMATION_OK
<- 14:48:15 PUBACK | PACKET_ID: 4
Confirmation callback received for message 3 with result IOTHUB_CLIENT_CONFIRMATION_OK
<- 14:48:15 PUBACK | PACKET_ID: 5
Confirmation callback received for message 4 with result IOTHUB_CLIENT_CONFIRMATION_OK
<- 14:48:15 PUBACK | PACKET_ID: 6
Confirmation callback received for message 5 with result IOTHUB_CLIENT_CONFIRMATION_OK
-> 14:52:15 PINGREQ
<- 14:52:15 PINGRESP
- Collect the traces from Wireshark
"No.","Time","Source","Destination","Protocol","Length","Info"
"5","2.180387533","192.168.1.186","111.222.333.444","TCP","74","38328 > 8883 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=202858383 TSecr=0 WS=128"
"6","2.225055787","111.222.333.444","192.168.1.186","TCP","74","8883 > 38328 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1440 WS=256 SACK_PERM=1 TSval=433712819 TSecr=202858383"
"7","2.225144862","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=202858428 TSecr=433712819"
"8","2.225557512","192.168.1.186","111.222.333.444","TLSv1.2","359","Client Hello"
"9","2.277717873","111.222.333.444","192.168.1.186","TLSv1.2","4083","Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done"
"10","2.277766831","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=294 Ack=4018 Win=62720 Len=0 TSval=202858481 TSecr=433712866"
"11","2.288469964","192.168.1.186","111.222.333.444","TLSv1.2","276","Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message"
"12","2.335115283","111.222.333.444","192.168.1.186","TLSv1.2","157","Change Cipher Spec, Encrypted Handshake Message"
"13","2.335169316","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=504 Ack=4109 Win=64128 Len=0 TSval=202858538 TSecr=433712928"
"14","2.335660797","192.168.1.186","111.222.333.444","TLSv1.2","487","Application Data"
"15","2.387524386","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"16","2.387602485","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=925 Ack=4178 Win=64128 Len=0 TSval=202858591 TSecr=433712981"
"17","2.390251353","192.168.1.186","111.222.333.444","TLSv1.2","215","Application Data"
"18","2.465242544","111.222.333.444","192.168.1.186","TCP","66","8883 > 38328 [ACK] Seq=4178 Ack=1074 Win=262656 Len=0 TSval=433713059 TSecr=202858593"
"19","2.465305781","192.168.1.186","111.222.333.444","TLSv1.2","662","Application Data, Application Data, Application Data, Application Data"
"20","2.514491256","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"21","2.529349441","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"22","2.529551485","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1670 Ack=4316 Win=64128 Len=0 TSval=202858733 TSecr=433713106"
"23","2.547088383","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"24","2.572525823","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"25","2.572676666","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1670 Ack=4454 Win=64128 Len=0 TSval=202858776 TSecr=433713138"
"26","2.588395105","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"27","2.630312977","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1670 Ack=4523 Win=64128 Len=0 TSval=202858833 TSecr=433713174"
"169","242.390700741","192.168.1.186","111.222.333.444","TLSv1.2","135","Application Data"
"170","242.436047043","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
"171","242.436115051","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1739 Ack=4592 Win=64128 Len=0 TSval=203098639 TSecr=433953094"
- Traffic analysis:
"No.","Time","Source","Destination","Protocol","Length","Info"
"5","2.180387533","192.168.1.186","111.222.333.444","TCP","74","38328 > 8883 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=202858383 TSecr=0 WS=128"
"6","2.225055787","111.222.333.444","192.168.1.186","TCP","74","8883 > 38328 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1440 WS=256 SACK_PERM=1 TSval=433712819 TSecr=202858383"
"7","2.225144862","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=202858428 TSecr=433712819"
"8","2.225557512","192.168.1.186","111.222.333.444","TLSv1.2","359","Client Hello"
"9","2.277717873","111.222.333.444","192.168.1.186","TLSv1.2","4083","Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done"
"10","2.277766831","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=294 Ack=4018 Win=62720 Len=0 TSval=202858481 TSecr=433712866"
"11","2.288469964","192.168.1.186","111.222.333.444","TLSv1.2","276","Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message"
"12","2.335115283","111.222.333.444","192.168.1.186","TLSv1.2","157","Change Cipher Spec, Encrypted Handshake Message"
"13","2.335169316","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=504 Ack=4109 Win=64128 Len=0 TSval=202858538 TSecr=433712928"
"14","2.335660797","192.168.1.186","111.222.333.444","TLSv1.2","487","Application Data"
-> 14:48:15 CONNECT | VER: 4 | KEEPALIVE: 240 | FLAGS: 192 | USERNAME: REDACTED.azure-devices.net/deviceid/?api-version=2017-11-08-preview&DeviceClientType=iothubclient%2f1.3.8%20(native%3b%20Linux%3b%20x86_64) | PWD: XXXX | CLEAN: 0
"15","2.387524386","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:48:15 CONNACK | SESSION_PRESENT: true | RETURN_CODE: 0x0
"16","2.387602485","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=925 Ack=4178 Win=64128 Len=0 TSval=202858591 TSecr=433712981"
"17","2.390251353","192.168.1.186","111.222.333.444","TLSv1.2","215","Application Data"
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 2 | PAYLOAD_LEN: 12
"18","2.465242544","111.222.333.444","192.168.1.186","TCP","66","8883 > 38328 [ACK] Seq=4178 Ack=1074 Win=262656 Len=0 TSval=433713059 TSecr=202858593"
"19","2.465305781","192.168.1.186","111.222.333.444","TLSv1.2","662","Application Data, Application Data, Application Data, Application Data"
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 3 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 4 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 5 | PAYLOAD_LEN: 12
-> 14:48:15 PUBLISH | IS_DUP: false | RETAIN: 0 | QOS: DELIVER_AT_LEAST_ONCE | TOPIC_NAME: devices/deviceid/messages/events/property_key=property_value | PACKET_ID: 6 | PAYLOAD_LEN: 12
"20","2.514491256","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:48:15 PUBACK | PACKET_ID: 2
"21","2.529349441","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:48:15 PUBACK | PACKET_ID: 3
"22","2.529551485","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1670 Ack=4316 Win=64128 Len=0 TSval=202858733 TSecr=433713106"
"23","2.547088383","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:48:15 PUBACK | PACKET_ID: 4
"24","2.572525823","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:48:15 PUBACK | PACKET_ID: 5
"25","2.572676666","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1670 Ack=4454 Win=64128 Len=0 TSval=202858776 TSecr=433713138"
"26","2.588395105","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:48:15 PUBACK | PACKET_ID: 6
"27","2.630312977","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1670 Ack=4523 Win=64128 Len=0 TSval=202858833 TSecr=433713174"
"169","242.390700741","192.168.1.186","111.222.333.444","TLSv1.2","135","Application Data"
-> 14:52:15 PINGREQ
"170","242.436047043","111.222.333.444","192.168.1.186","TLSv1.2","135","Application Data"
<- 14:52:15 PINGRESP
"171","242.436115051","192.168.1.186","111.222.333.444","TCP","66","38328 > 8883 [ACK] Seq=1739 Ack=4592 Win=64128 Len=0 TSval=203098639 TSecr=433953094"
Traffic on wire:
Message | Size (bytes) |
---|---|
CONNECT | 487 |
CONNACK | 135 |
PUBLISH (1 telemetry) | 215 |
PUBLISH (4 telemetry) | 662 |
PUBACK (telemetry) | 135 |
PINGREQ | 135 |
PINGRESP | 135 |
DISCONNECT | 135 |
Plus 66-byte TCP ACKs.
If no messages are actively sent or received by the user, the IoT Hub client uses data traffic to account for (MQTT) keep-alives and SAS token refreshes.
For simplification, the calculations below will ignore TCP ACK sizes.
Keep Alives
Keep-alives are exchanged every 4 minutes by default, what results in 4050 bytes/hour, or 97.2 Kbytes/day.
According to the offical documentation, the maximum keep alive frequency is one every 1767 seconds:
So if the MQTT timeout is changed in the IoT client to every 1760 seconds (for safety to avoid disconnection), the data usage for keep-alives would be 552.3 bytes/hour (a reduction of 86% of keep-alive data usage).
To change the MQTT keep-alive frequency, do:
uint16_t keepAlivePeriodInSecs = 1760;
IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_KEEP_ALIVE, &keepAlivePeriodInSecs);
SAS Token refresh
The second optimization that can be done is in the frequency of re-connections for SAS token refreshes.
By default the IoT client generates SAS tokens that are valid for 60 minutes, and "refreshes" them every 80% of that valid period (48 minutes).
Since with MQTT 3.1.1 there is no way to update credentials over the same connection, the IoT client disconnects and reconnects with a new SAS token.
A CONNECT packet is 487 bytes long, while a DISCONNECT is 135 bytes.
So every re-connection uses 622 bytes, and since there is one reconnect every 48 minutes, by default the IoT client uses on average 778 bytes/hour for SAS token refreshes.
Reducing the frequency of SAS token refreshes to once every 12 hours results in a traffic usage for re-connections of 65 bytes/hour, on average (a reduction of 91.7% of SAS token refresh data usage).
The SAS token expiration time can be changed using the following:
size_t sasTokenExpiryTimeInInSecs = 30;
IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_SAS_TOKEN_LIFETIME, &sasTokenExpiryTimeInInSecs);
- Summary
The default data usage of the IoT Hub client over MQTT protocol for SAS token refreshes and keep-alives is of about 4602.3 bytes/hour.
If optimizations are applied to reduce the keep-alives to once every 1760 seconds and SAS token refreshes to once every 12 hours, the data traffic is decreases to 617.3 bytes/hour (a reduction of 86.6%).
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.