Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] Azure Integration in RIOT OS #20223

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tanvirBsmrstu
Copy link

@tanvirBsmrstu tanvirBsmrstu commented Jan 3, 2024

Contribution description (3 modules, one package, one application)

  1. Zero-touch device provisioning with Device Provisioning Service using X.509 certificate.
  2. Cloud-to-Device and Device-to-Cloud messaging with Azure IoT Hub.
  3. Receiving and parsing Direct method invocation from Azure IoT Hub.
  4. Receiving and parsing Device Twins update notifications from Azure IoT Hub.
  • Azure IoT SDK for embedded C is integrated using a new RIOT package
  • "gnrc_wolfssl_tls" module uses wolfssl and gnrc to achieve TLS
  • "mqtts_riot_iface" module uses paho mqtt package and gnrc_wolfssl_tls module to achieve MQTTS
  • "az_riot_pnp_iface" module is a wrapper on top of MQTTS and azure SDK to provide a Plug-and-play flavour.
  • Scripts are provided to facilitate generating self signed certificates.
  • A demo application /examples/az_pnp_demo is provided with a reach Readme.md file.

Testing procedure

  • A demo application /examples/az_pnp_demo is provided with a reach Readme.md file.
    Please read carefully the Readme

Current Limitations

DNS is not integrated yet, please see the readme and use IP at the mentioned place for testing.
Error handling has to improve a lot.

Thanks,
Tanvir Hasan

authored-by: tanvirBsmrstu tanvir.bsmrstu@gmail.com

authored-by: tanvirBsmrstu <tanvir.bsmrstu@gmail.com.com>
@tanvirBsmrstu tanvirBsmrstu requested a review from jia200x as a code owner January 3, 2024 10:08
@github-actions github-actions bot added Area: network Area: Networking Area: doc Area: Documentation Area: pkg Area: External package ports Area: examples Area: Example Applications labels Jan 3, 2024
@benpicco benpicco requested a review from OlegHahm January 3, 2024 12:18
Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really useful, thank you!
Can you please split this into different commits for the different packages and the application and modules?

That should make this easier to review - static tests also already has some comments.

USEMODULE += sock_dns
USEMODULE += auto_init_sock_dns
# USEMODULE += gnrc_ipv6_nib_dns
CFLAGS += -DCONFIG_AUTO_INIT_SOCK_DNS_SERVER_ADDR=\"fd12:dead:beef::1\"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's wrong with the default? (I think that's Google's DNS)
fd12:dead:beef::1 is not a global address, so that won't work.

Or do we need DNS64 here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do need DNS64 for now since - according to Microsoft - Azure IoT do not support IPv6 right now.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need DNS64 here. For example, RIOT has "global.azure-devices-provisioning.net" the address of Azure DPS which supports only IPv4. Since the POC is using gnrc, we need a IPv6 version of the DPS address. I setup a nat64 on my linux machine. When I use dig global.azure-devices-provisioning.net +short AAAA @2001:4860:4860::64 it returns

id-prod-global-endpoint.trafficmanager.net.
idsu-prod-dewc-1-su-az.germanywestcentral.cloudapp.azure.com.
64:ff9b::3374:91ca

Which RIOT can not (or I don't know how to) parse using sock_dns_query function. Any help or a commit here would be much more appreciated. This you can find in gnrc_wolfssl_tls.c as a commented todo option and also as warning in the Readme.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But could you also use a public server like 2001:67c:2b0::6 so users don’t have to do the setup first?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My current setup with nat64 and nib RIOT application can only access address prefixed with 64:ff9b::/96, any other public IP is not reachable since I have created the tap interface without uplink.
The packet got lost at the tapbr0. I might have missed the routing configuration, but it did not follow the default routing for some reason.
I need some help here due to my lack of expertise in networking.
Therefore, I used google's public dns64 in my linux machine. (2001:4860:4860::64)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I use -u, for example, -u eth0, I miss the nat64 interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then you can use a public DNS64/NAT64 service and don't have to set up anything yourself.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing so, I get the following response with multiple answers, and the last one containing the IP(highlighted), but dns_msg_parse_reply can not parse the IP from it and I get -74(BadMsg) error returned. Please check the Wireshark screenshot below.
Note: in the make file I had to do the following

USEMODULE += sock_dns
USEMODULE += auto_init_sock_dns
USEMODULE += gnrc_ipv6_nib_dns 
CFLAGS += -DCONFIG_AUTO_INIT_SOCK_DNS_SERVER_ADDR=\"2001:67c:2b0::6\"
CFLAGS += -DCONFIG_DNS_MSG_LEN=256

Screenshot from 2024-01-08 20-37-05

Copy link
Contributor

@benpicco benpicco Jan 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh looks like this uncovers a bug in our DNS parsing code - it fails here.

Unfortunately I have no idea what that while loop is supposed to do - maybe @miri64 has an idea?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#20857 provides a fix

CFLAGS += -Wno-error=unused-value
CFLAGS += -Wno-error=unused-variable

CFLAGS += -Wno-strict-prototypes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be set by an application, if the warnings are in your code you should fix them.
If they are in the package, add those flags to the package.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warnings are in the package, I have added these flags in the package itself and forgot to clean the application.
Thanks, I will take care of this.


include $(RIOTBASE)/Makefile.include

ifneq (,$(filter arch_esp,$(FEATURES_USED)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set those unconditionally so users of atwinc15x0 also benefit.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have started with the paho mqtt example, I kept these as it is. I think it would be nice if I remove all the wifi related setup, since this POC can only run on Native due to some limitations (how I read the certificate from memory using dynamic memory allocation) and it does not use any wifi feature. I missed cleaning this make file.

Comment on lines +7 to +8
ifeq ($(BOARD),native)
USEMODULE += netdev_default
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only native?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will remove the checks.

// #include <net/sock/tcp.h>
#include "ztimer.h"
#include <stdio.h>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't anything GNRC specific here, so why the name?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GNRC is a dependency for this module and specified in the .dep file. Any better naming suggestion is really appreciated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sock_wolfssl_tls since it uses the sock API

If Azure portal setup is not done yet, please see the [Azure Portal README](./docs/Readme.md).

### NAT64 and DNS64 configuration
Here is a nice document by Professor Oliver Hahm [NAT64 Configuration](https://teaching.dahahm.de/riot/2023/09/29/RIOT_GNRC_ipv4.html)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having the user go through the trouble of setting this all up themselves I'd just direct them to a public DNS64/NAT64 service and give this as optional information if they really want to set up their own.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then we should also add a test that checks whether the public service is still available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we could run such a service on the community server, then we could make it the default in RIOT

@OlegHahm
Copy link
Member

OlegHahm commented Jan 4, 2024

I guess the new modules should go into different directories in sys/net.

@fabian18
Copy link
Contributor

fabian18 commented Jan 7, 2024

I think the mqtts module should exist in pkg/paho-mqtt/contrib and the tls module should exist in pkg/wolfssl/sock_tls.

WolfSSL already provides something for us in wolfio.h which seems to be something like your TLSContext.

#ifdef WOLFSSL_GNRC
    #include <sock_types.h>
    #include <net/gnrc.h>
    #include <net/af.h>
    #include <net/sock.h>
    #include <net/gnrc/tcp.h>
    #include <net/gnrc/udp.h>

    struct gnrc_wolfssl_ctx {
        union socket_connector {
        #ifdef MODULE_SOCK_TCP
            sock_tcp_t tcp;
        #endif
            sock_udp_t udp;
        } conn;
        WOLFSSL_CTX *ctx;
        WOLFSSL *ssl;

        int closing;
        struct _sock_tl_ep peer_addr;
    };

    typedef struct gnrc_wolfssl_ctx sock_tls_t;

    WOLFSSL_LOCAL int GNRC_ReceiveFrom(WOLFSSL* ssl, char* buf, int sz,
                                     void* ctx);
    WOLFSSL_LOCAL int GNRC_SendTo(WOLFSSL* ssl, char* buf, int sz, void* ctx);

#endif

@tanvirBsmrstu
Copy link
Author

Hi @fabian18,
Thank you so much for your time and comments. There are so many things to improve. I would love to have more comments and ideas on how this work can be refactored.

I have seen the structure in the library, but it, by default, includes udp. That's why I did not use that. There might be some scenario where UDP is not needed.
Secondly, the implementation of GNRC_** functions are specific to UDP again. I thought changing in the third party code would not be a good idea, that's why I wrote my custom implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: doc Area: Documentation Area: examples Area: Example Applications Area: network Area: Networking Area: pkg Area: External package ports
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants