awslabs / awslabs/aws-crt-python
Add a way to change the default TLS timeout
- Dominant language
- Python
- Stars
- 100
- Forks
- 58
- Avg merge
- 13h 51m
- Merged PRs (30d)
- 2
Description
Hi, I use this library together with `awsiot` to establish MQTT connection and use it for publishing messages to the IoT Core broker from devices that very often have poor network conditions (TCP packets getting lost, high latency). Recently one of the issues I spotted was that the MQTT connection fails with the following error:
```
awscrt.exceptions.AwsCrtError: AwsCrtError(name='AWS_IO_TLS_NEGOTIATION_TIMEOUT', message='Channel shutdown due to tls negotiation timeout', code=1067)
```
To reproduce the issue:
- introduce a high delay for each TCP packet, e.g. on Linux: `sudo tc qdisc replace dev wlp0s20f3 root netem delay 1500ms 200ms` (where `wlp0s20f3` is the name of the network interface)
- run any script that will initiate the MQTT connection (e.g. https://github.com/aws/aws-iot-device-sdk-python-v2/blob/master/samples/pubsub.py)
- revert the network delay with: `sudo tc qdisc del dev wlp0s20f3 root` (replace `wlp0s20f3` with a correct interface name)
Even though the [`mqtt_connection_builder`](https://github.com/awslabs/aws-crt-python/blob/master/awscrt/awsiot_mqtt_connection_builder.py) provides a number of timeout-related parameters, none of them has an impact on the TLS negotiation timeout that is the cause of the failure.
After some debugging I was able to find out that the C library `aws-c-io` (that this library has bindings to) defines an object [`aws_tls_connection_options`](https://github.com/awslabs/aws-c-io/blob/1cacfb24befb995e466fc1271e845ab594c6e392/include/aws/io/tls_channel_handler.h#L72) that contains the parameter `timeout_ms`. However, [the method](https://github.com/awslabs/aws-c-io/blob/4ef05c1d09e2f30b7171b9d84d8483735fabb3af/source/tls_channel_handler.c#L317) that `aws-crt-python` is [calling](https://github.com/awslabs/aws-crt-python/blob/72885c7c500f9ebceee1d6d464c6d8ca118b2613/source/io.c#L545) sets this parameter to a default, hard-coded value of [4000ms](https://github.com/awslabs/aws-c-io/blob/4ef05c1d09e2f30b7171b9d84d8483735fabb3af/source/tls_channel_handler.c#L11). What's more, the Python structures that provide the application-level abstraction (namely [`TlsContextOptions`](https://github.com/awslabs/aws-crt-python/blob/72885c7c500f9ebceee1d6d464c6d8ca118b2613/awscrt/io.py#L193)) do not contain the timeout property, so there's no way to change the value even after the context was initialized with the default one.
In order to establish the MQTT connection reliably from the device in a high-latency network, it's crucial that the TLS negotiation timeout can be set to a value higher than 4 seconds. Please provide a way to set the timeout to any custom value.
Contributor guide
Assessment
This issue has not been assessed yet.