lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Issues with netconn callbacks


From: address@hidden
Subject: Re: [lwip-users] Issues with netconn callbacks
Date: Tue, 3 Dec 2019 20:21:53 +0100
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1

Am 03.12.2019 um 01:05 schrieb Davide Bettio:
Hello,

Il giorno lun 2 dic 2019 alle ore 21:26 address@hidden
<mailto:address@hidden> <address@hidden <mailto:address@hidden>>
ha scritto:

    Am 02.12.2019 um 20:39 schrieb Davide Bettio:
    So you're running the stock lwIP that comes with ESP32? If so, I don't
    know how "vanilla" this is and how they keep their copy of lwIP up to
    date...


Yes, I'm using the ESP32 version.

     >
     > We decided to use netconn API since it provides us asynchronous
    callbacks.
     > However I'm experiencing an unexpected behavior with it (when
    using it
     > as a TCP server):
     > I get my callback called also for netconns which I didn't accept yet.

    I'm not sure I understand that. Just for you to know: netconn is the
    basis of the standard socket implementation in lwIP but otherwise not
    may not too be widely used.


Do you suggest me to avoid using netconn?

No, not at all! I merely wanted to say that it's not as widely used:
people seeking portability use sockets, most people seeking performance
use the raw callback API. The netconn API *is* in use by everyone using
the socket API.

Anyway I would appreciate an
API which allows me to:

- Receive asynchronous events (callbacks are ok)
- 0 copy to improve efficiency
- No need for a BSD socket API, I'm writing a virtual machine, so
everything is wrapped

netconn looked like the right choice for this kind of needs.
Should I use some kind of hybrid approach? like using sockets and
somehow callbacks?

No, don't try that, it won't work without modifying the sources.


    Being like that, you *may* get problems when using netconn in a
    different way than the socket API uses it internally. Maybe you can
    cross-check your code against sockets.c and see if you do anything
    different?


I'm using it in this way:

struct netconn *conn = netconn_new_with_proto_and_callback(NETCONN_TCP,
0, socket_callback);


err_t status = netconn_bind(conn, IP_ADDR_ANY, port);

if (UNLIKELY(status != ERR_OK)) {

//TODO

fprintf(stderr, "bind error: %i\n", status);

return;

}


ip_addr_t naddr;

u16_t nport;

status = netconn_getaddr(conn, &naddr, &nport, 1);

if (UNLIKELY(status != ERR_OK)) {

//TODO

fprintf(stderr, "getaddr error: %i\n", status);

return;

}

Anyway I keep getting my callback called for netconns I didn't yet accept.

Oh, OK, I think I understand. Have a look at sockets.c:

- in event_callback(), we check if the netconn is already connected to a
socket (conn->callback_arg.socket in current git master). If that is <
0, it's not yet connected. To keep track of "receive events", which we
count only for the socket layer, not for the netconn layer, we use this
socket member to count into the negative. conn->callback_arg.socket is
-1 by default unless initialized to a socket (which is >= 0), so if it
is -2, we had one RCVPLUS event (SENDPLUS cannot happen at that stage).

All this can happen because the stack internally accepted the connection
(SYN-ACK, ACK), so the remote side is free to send data. Internally, the
new netconn is then put on the listener's netconn->acceptmbox, and what
I described above is the situation before an application thread takes
this new netconn out of that acceptmbox (via netconn_accept()).

- lwip_accept() takes a netconn out of the listener's
netconn->acceptmbox and allocates a socket for it. To prevent missing
RCVPLUS events that have already happened, we check for
newconn->callback_arg.socket begin < -1.

And here you see what I mean: all this could well be hidden inside
netconn and the socket API could be a thinner wrapper around netconn,
mainly just wrapping structs and memcpy code. But being like it is, you
might miss some things you know from sockets when using the netconn API.


     >
     > So I get this output from my code:
     >
     > handler not found for: 0x3ffc3bf4
     > processed all events
     > found handler for: 0x3ffcd464
     > tcp_server_handler
     > going to send a ready message
     > accepted conn: 0x3ffc3bf4
     > accepted_socket
     >
     > Is this an intended behavior?

    That's no debug output from lwIP


Yes, right, it's just a trace of my application.

     > - Is it possible to check if any byte is already in the buffer
    ready to
     > be received?

    Yes, you can use nonblocking receive. Again, see sockets.c if you need
    an example.

     > - Is it possible to check if a netconn is still open or it has
    been closed?

    Well, you get informed it is closed and you'll get an error trying to
    use it...


Yes right, I was trying to understand to if it was possible to get this
kind of information by inspecting netconn struct.

No, not really. You have to keep track.

Regards,
Simon


Thank you for your help so far.


Regards,
Davide Bettio.

_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users





reply via email to

[Prev in Thread] Current Thread [Next in Thread]