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

LWIP TCP Communication Error #19676

Open
pavarott opened this issue May 29, 2023 · 0 comments
Open

LWIP TCP Communication Error #19676

pavarott opened this issue May 29, 2023 · 0 comments
Assignees
Labels
Area: network Area: Networking Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Comments

@pavarott
Copy link

Description

I want to implement a communication with a website in which the frontend communicates with the microcontroller.
This would be over RPC JSON calls.
I used the code from the testing lwip as example and tested it, sometimes the system worked for the first messages but sometimes it blocks the message until the frontend cancels the request and then the response gets proceed.

Steps to reproduce the issue

I used a nucleo-f429zi for this project.
The frontend sends two request sequentially to the response.
One time a call with the HTTP request OPTIONS and for the the procedure RPC JSON calling, the HTTP request POST.
The code is the adapted testing file, in the fucntion _tcp_recv under tests/lwip/tcp.c :

#define HTTP_MESSAGE_BUFF_SIZE (10*SOCK_INBUF_SIZE)

static int emptyCstring(char *dest, size_t element_count){
    int answer = EXIT_SUCCESS;
    memset(dest,0,element_count);
    if(strlen(dest)>0){
        answer = EXIT_FAILURE;
    }
    return answer;
}
static int getHttpMethod(char *src, char *http_method_str){
    return sscanf(src, "%7s", http_method_str);
}
static int getHttpOrigin(char *src, char *http_origin_str){
    char * origin_place = strstr(src, "Origin");
    return sscanf(origin_place+strlen("Origin:"), "%256s", http_origin_str);
}
static int getHttpMethodAndOrigin(char *src, char *http_method_str, char *http_origin_str){
        /* Parse the HTTP request */
    int status = EXIT_SUCCESS;
    int n = getHttpMethod(src, http_method_str);
    n +=  getHttpOrigin(src, http_origin_str);
    if (n != 2) {
        status = EXIT_FAILURE;
    }
    return status;
}

static void _tcp_recv(sock_tcp_t *sock, sock_async_flags_t flags, void *arg)
{
    sock_tcp_ep_t client;
    uint16_t port;
    printf("\n\n************** the flag is 0x%04x **************\n\n",flags);
    expect(strcmp(arg, "test") == 0);
    if (sock_tcp_get_remote(sock, &client) < 0) {
        /* socket was disconnected between event firing and this handler */
        return;
    }
    sock_tcp_ep_fmt(&client, _addr_str, &port);
    if (flags & SOCK_ASYNC_MSG_RECV) {
        static char http_message[HTTP_MESSAGE_BUFF_SIZE];
        char method[8];
        char origin[256];
        int res;
        emptyCstring(method,8);
        emptyCstring(origin,256);
        emptyCstring(http_message,HTTP_MESSAGE_BUFF_SIZE);
        emptyCstring(sock_inbuf,SOCK_INBUF_SIZE);
        /* we don't use timeouts so all errors should be related to a lost
         * connection */
        puts(http_message);
        while (((res = sock_tcp_read(sock, sock_inbuf, sizeof(sock_inbuf),
                                    50)) >= 0)) {
            printf("Received TCP data from client [%s]:%u\n", _addr_str, port);
            if (res > 0) {
                printf("\nNumber of bytes arrived: %d\n\n",res);
                strncat(http_message,sock_inbuf,SOCK_INBUF_SIZE);
                emptyCstring(sock_inbuf,SOCK_INBUF_SIZE);
                 if(res<SOCK_INBUF_SIZE){
                    break;
                }
            }
            else {
                puts("(nul)");
            }
        }
        printf("\nthe flag is 0x%04x\n\n",flags);
        printf("\nthe number of res is %d\n\n",ruues);
        getHttpMethodAndOrigin(http_message,method,origin);
        puts(http_message);
        puts(method);
        if(strncmp(method,"OPTIONS",strlen("OPTIONS"))==0){
            puts("enterd options");
            char *message="HTTP/1.0 200 OK\r\nAccess-Control-Allow-Headers: authorization, content-type, timeout\r\nAccess-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT\r\nAccess-Control-Allow-Origin: http://localhost:8081\r\nAllow: OPTIONS, POST\r\nContent-Length: 0\r\nContent-Type: text/html; charset=utf-8\r\nVary: Origin\r\n\r\n";
            sock_tcp_write(sock,message,strlen(message));
        }else if(strncmp(method,"POST",strlen("POST"))==0){
            puts("enterd POST");
            char *message2="HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: http://localhost:8081\r\nContent-Length: 58\r\nContent-Type: application/json\r\nVary: Origin\r\n\r\n{\"id\":\"1\",\"jsonrpc\":\"2.0\",\"result\": \"{\\\"status\\\":\\\"OK\\\"}\"}";
            sock_tcp_write(sock,message2,strlen(message2));
            puts("message sent");
        }       
    }
    if (flags & SOCK_ASYNC_CONN_FIN) {
        printf("TCP connection to [%s]:%u reset\n", _addr_str, port);
        sock_tcp_disconnect(sock);
    }
}

I also adapted the stack size for the lwip to 4096, the Makefile looks like that:

include ../Makefile.tests_common

LWIP_IPV4 ?= 1
LWIP_IPV6 ?= 0

ifneq (0, $(LWIP_IPV4))
  USEMODULE += ipv4_addr
  USEMODULE += lwip_arp
  USEMODULE += lwip_ipv4
  USEMODULE += lwip_dhcp_auto
  CFLAGS += -DETHARP_SUPPORT_STATIC_ENTRIES=1
endif

ifneq (0, $(LWIP_IPV6))
  USEMODULE += ipv6_addr
  USEMODULE += lwip_ipv6
  USEMODULE += lwip_ipv6_autoconfig
endif

# including lwip_ipv6_mld would currently break this test on at86rf2xx radios
USEMODULE += lwip lwip_netdev
USEMODULE += lwip_udp
USEMODULE += lwip_tcp
USEMODULE += sock_async_event
USEMODULE += sock_ip
USEMODULE += sock_tcp
USEMODULE += sock_udp
USEMODULE += sock_util
USEMODULE += shell
USEMODULE += shell_cmds_default
USEMODULE += ps
USEMODULE += od
USEMODULE += netdev_default
USEMODULE += ztimer_usec

ifeq ($(BOARD),native)
  USEMODULE += lwip_ethernet
endif

# Test only implemented for native
ifneq ($(BOARD),native)
  TESTS=
endif

DISABLE_MODULE += test_utils_interactive_sync
CFLAGS += -DTHREAD_STACKSIZE_DEFAULT="4096"
CFLAGs += -DMEM_DEBUG=LWIP_DBG_ON
CFLAGS += -DTCP_MSL=500
# test fails on murdock and on my machine due to the process exiting directly
TEST_ON_CI_BLACKLIST += all

include $(RIOTBASE)/Makefile.include

I use the system under IPV4 because our network here is still under IPV4.

Expected results

The application should respond to the HTTP requests.

Actual results

The behaviour is unpredictable, sometimes it answer all the request and a second later the request is not further proceed until the frontend cancels the request.
If the request is cancelled the request gets proceed from the microcontroller application.
Furthermore sometimes the systems runs into a RIOT Kernel panic:

2023-05-15 11:30:50,551 # *** RIOT kernel panic:
2023-05-15 11:30:50,553 # MEM MANAGE HANDLER
2023-05-15 11:30:50,553 # 
2023-05-15 11:30:50,562 # 	pid | name                 | state    Q | pri | stack  ( used) ( free) | base addr  | current     
2023-05-15 11:30:50,570 # 	  - | isr_stack            | -        - |   - |    512 (  448) (   64) | 0x20000000 | 0x20000160
2023-05-15 11:30:50,579 # 	  1 | main                 | bl mutex _ |   7 |   1536 (  592) (  944) | 0x2000143c | 0x200018ec 
2023-05-15 11:30:50,588 # 	  2 | lwip_netdev_mux      | bl rx    _ |   3 |   1024 (  504) (  520) | 0x200039a8 | 0x20003cfc 
2023-05-15 11:30:50,596 # 	  3 | tcpip_thread         | bl mbox  _ |   1 |   1024 (  604) (  420) | 0x20001c10 | 0x20001f24 
2023-05-15 11:30:50,605 # 	  4 | TCP server           | running  Q |   6 |   1024 (  616) (  408) | 0x200009d0 | 0x20000c7c 
2023-05-15 11:30:50,611 # 	    | SUM                  |            |     |   5120 ( 2764) ( 2356)
2023-05-15 11:30:50,611 # 
2023-05-15 11:30:50,613 # *** halted.
2023-05-15 11:30:50,613 # 
2023-05-15 11:30:50,614 # Inside isr -12

Versions

I'm using the branch 2023.01-branch.

perating System Environment
----------------------------
         Operating System: "Debian GNU/Linux" "11 (bullseye)"
                   Kernel: Linux 6.1.21-v8+ aarch64 unknown
             System shell: /usr/bin/dash (probably dash)
             make's shell: /usr/bin/dash (probably dash)

Installed compiler toolchains
-----------------------------
               native gcc: gcc (Debian 10.2.1-6) 10.2.1 20210110
        arm-none-eabi-gcc: arm-none-eabi-gcc (15:8-2019-q3-1+b1) 8.3.1 20190703 (release) [gcc-8-branch revision 273027]
                  avr-gcc: missing
           msp430-elf-gcc: missing
       riscv-none-elf-gcc: missing
  riscv64-unknown-elf-gcc: missing
     riscv-none-embed-gcc: missing
     xtensa-esp32-elf-gcc: missing
   xtensa-esp8266-elf-gcc: missing
                    clang: missing

Installed compiler libs
-----------------------
     arm-none-eabi-newlib: "3.3.0"
        msp430-elf-newlib: missing
    riscv-none-elf-newlib: missing
riscv64-unknown-elf-newlib: missing
  riscv-none-embed-newlib: missing
  xtensa-esp32-elf-newlib: missing
xtensa-esp8266-elf-newlib: missing
                 avr-libc: missing (missing)

Installed development tools
---------------------------
                   ccache: missing
                    cmake: missing
                 cppcheck: missing
                  doxygen: 1.9.1
                      git: git version 2.30.2
                     make: GNU Make 4.3
                  openocd: Open On-Chip Debugger 0.12.0
                   python: Python 3.9.2
                  python2: missing
                  python3: Python 3.9.2
                   flake8: error: /usr/bin/python3: No module named flake8
               coccinelle: missing
@pavarott pavarott changed the title LWIP IPV4 Error LWIP TCP Communication Error May 29, 2023
@maribu maribu added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Area: network Area: Networking labels May 29, 2023
@maribu maribu self-assigned this May 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: network Area: Networking Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

No branches or pull requests

2 participants