RIOT-OS / RIOT

RIOT - The friendly OS for IoT
https://riot-os.org
GNU Lesser General Public License v2.1
4.94k stars 1.99k forks source link

GCOAP Error from gnrc_sock_udp #8287

Closed Josar closed 6 years ago

Josar commented 6 years ago

Hello I got an strange behavior when compiling the gcoap example. Maye someone has an idea.

I run Riot on an atxmega256a3u with an at86rf233.

When I compile with ENABLE_DEBUG (1) tin gcoap.c then everything works as expected and I am able to get .well-known/core information from the node. But when I disable debug I always get the error -EPROTO from gnrc_sock_udp.
Which checks

if ( (sock->remote.family != AF_UNSPEC) &&  /* check remote end-point if set */
     (  (sock->remote.port != byteorder_ntohs(hdr->src_port)) ||
         /* We only have IPv6 for now, so just comparing the whole end point
         * should suffice */
        ( (memcmp(&sock->remote.addr, &ipv6_addr_unspecified, sizeof(ipv6_addr_t)) != 0) &&
          (memcmp(&sock->remote.addr, &tmp.addr, sizeof(ipv6_addr_t)) != 0)
        )
      )
   ) {

With debug:

_recv_ieee802154: received packet from 18:c0:ff:ee:1a:c0:ff:ee of length 65
00000000  6F  00  08  E0  8B  21  A5  00  00  00  00  00  00  00  00  00
00000010  00  00  00  00  01  21  A5  00  00  00  00  00  00  20  28  3C
00000020  DC  25  BB  61  3E  F0  81  3D  16  33  F2  6F  50  01  73  6A
00000030  BB  2E  77  65  6C  6C  2D  6B  6E  6F  77  6E  04  63  6F  72
00000040  65
_recv_ieee802154: reallocating.
Address Format specified unspecified 0, Format 0
Port 0 != 33085
IP good ipv6_addr_unspecified: 0
IP good tmp.addr: 1

Without Debug:

_recv_ieee802154: received packet from 18:c0:ff:ee:1a:c0:ff:ee of length 65
00000000  6F  00  05  01  10  21  A5  00  00  00  00  00  00  00  00  00
00000010  00  00  00  00  01  21  A5  00  00  00  00  00  00  20  28  3C
00000020  DC  25  BB  61  3E  F0  83  5E  16  33  F0  4E  50  01  73  6A
00000030  BB  2E  77  65  6C  6C  2D  6B  6E  6F  77  6E  04  63  6F  72
00000040  65
_recv_ieee802154: reallocating.
Address Format specified unspecified 1, Format -29115
Port 41 != 33630
IP good ipv6_addr_unspecified: 1
IP good tmp.addr: 1

So the question is where are these values assigned to the sock, so I can investigate this further. And what could cause this strange behavior.

Thanks in advance Josua Arndt

Answer from the mailing list:

This looks like some memory is used without proper initialisation. When compiled with debug symbols and output, memory is likely zeroed but w/o debug it's not. Hence, you get arbitrary ports and IPv6 addresses and formats, e.g., port 41 or format -29115, here. Cheers, Sebastian

Description

Steps to reproduce the issue

Run gcoap example without debug.

Expected results

With debug enabled and debug dsiabled answering coap request should work.

Actual results

Does not.

Versions

Riot on atxmega256a3u with an at86rf233. RPI with openlabs transceiver and libcoap.

kb2ma commented 6 years ago

I have not seen this issue, so let me ask a few questions to be sure I understand. I assume the issue is with gcoap acting as a server, where the request is a GET for /.well-known/core.

Do you have the CLI installed? If so, send a GET for /cli/stats to gcoap. You should receive a payload with an integer encoded as a string in response.

At what point do you see the -EPROTO UDP response -- when gcoap attempts to send its response?

Have you defined any CoAP resources for the server?

Do you see the same results when the gcoap server runs on Linux native?

Josar commented 6 years ago

My setup is as follows.

RasperryPi with openlabs radio. Jiminy Xmega board, atXmega256a3u with atmel at86rf233.

When i run the gcoap example a can receive the values with the rpi. So yes gcoap as server.

As soon as i compile gcoap.c for the xmega without debug there seems some variables which are not properly initialized but where zeroed when used with debug.

The packet is send from the rpi and received from xmeega but it does not pass sock_udp_recv.

https://github.com/RIOT-OS/RIOT/blob/7b9b383d5299756e12aa50f9698ebf12b1576277/sys/net/gnrc/sock/udp/gnrc_sock_udp.c#L197

with debug enabled the values which are checked are as follows

Address Format specified unspecified 0, Format 0
Port 0 != 33085
IP good ipv6_addr_unspecified: 0
IP good tmp.addr: 1

without

Address Format specified unspecified 1, Format -29115
Port 41 != 33630
IP good ipv6_addr_unspecified: 1
IP good tmp.addr: 1

Running gcoap as client is not working out of the box but there was no time and need to test this, yet. But it most probably has something todo with the upper layer not receivign the answer, as well. As the receiver again gets the answer from the rpi.

kb2ma commented 6 years ago

Thanks for the additional information. The immediate problem is that the values in sock->remote are not zeroed out. sock->remote is always zeroed at gcoap startup. Specifically, gcoap_init() starts the gcoap thread, which runs _event_loop(). This function calls sock_udp_create(), which zeroes sock->remote.

So, it looks like the problem is a matter of overwriting rather than initialization. I wonder if the stack size on this board is an issue. GCOAP_STACK_SIZE is defined in gcoap.h, and includes extra space if debug is enabled. Does increasing GCOAP_STACK_SIZE work around the problem?

kYc0o commented 6 years ago

@Josar did you try @kb2ma suggestions?

Josar commented 6 years ago

I think GCOAP_STACK_SIZE was the problem.