Update on debugging this thing (already updated
https://gitlab.com/qemu-project/qemu/-/issues/1835):
I saw that `tcp_chr_free_connection` was called after the first response
being successfully sent:
```

slirp_guestfwd_write guestfwd_write: size 80tcp_chr_write
tcp_chr_write: s->state:2tcp_chr_write tcp_chr_write:
len:80qemu_chr_write_parameter len: 80 // tracking
qemu_chr_writeqemu_chr_write_res len: 80 // same
thingtcp_chr_free_connection tcp_chr_free_connection: state: 2,
changing it to disconnecttcp_chr_change_state tcp_chr_change_state:
state: 2, next state: 0 // state 2==connected, 0==disconnected.

```
And after that, the state of `SocketChardev` remained disconnected, and
when the 2nd request came in, the `tcp_chr_write` dropped it directly.
Maybe this state machine should be reset after every connection? Not sure.

On Thu, Aug 17, 2023 at 11:58 AM Felix Wu <f...@google.com> wrote:

> Hi Samuel,
>
> Thanks for the clarification! I missed the email so didn't reply in time,
> but was able to figure it out.
>
> Hi everyone,
> IPv6 guestfwd works in my local test but it has a weird bug: if you send
> two requests, the first one gets the correct response, but the second one
> gets stuck.
> I am using a simple http server for this test, and just noticed this bug
> also exists in IPv4 guestfwd. I've documented it in
> https://gitlab.com/qemu-project/qemu/-/issues/1835.
>
> Just want to check if anyone has seen the same issue before.
>
> Thanks! Felix
>
> On Thu, Jul 20, 2023 at 7:54 AM Samuel Thibault <samuel.thiba...@gnu.org>
> wrote:
>
>> Hello,
>>
>> Felix Wu, le mar. 18 juil. 2023 18:12:16 -0700, a ecrit:
>> > 02 == SYN so it looks good. But both tcpdump and wireshark (looking
>> into packet
>> > dump provided by QEMU invocation)
>>
>> Which packet dump?
>>
>> > I added multiple prints inside slirp and confirmed the ipv6 version of
>> [1] was
>> > reached.
>> > in tcp_output function [2], I got following print:
>> > qemu-system-aarch64: info: Slirp: AF_INET6 out dst ip =
>> > fdb5:481:10ce:0:8c41:aaff:fea9:f674, port = 52190
>> > qemu-system-aarch64: info: Slirp: AF_INET6 out src ip = fec0::105, port
>> = 54322
>> > It looks like there should be something being sent back to the guest,
>>
>> That's what it is.
>>
>> > unless my understanding of tcp_output is wrong.
>>
>> It looks so.
>>
>> > To understand the datapath of guestfwd better, I have the following
>> questions:
>> > 1. What's the meaning of tcp_input and tcp_output? My guess is the
>> following
>> > graph, but I would like to confirm.
>>
>> No, tcp_input is for packets that come from the guest, and tcp_output is
>> for packets that are send to the guest. So it's like that:
>>
>> >         tcp_input    write_cb          host send()
>> > QEMU --------> slirp -----------> QEMU --------------------> host
>> >     <--------        <---------         <-----------------
>> >          tcp_output  slirp_socket_recv    host recv()
>>
>> > 2. I don't see port 6655 in the above process. How does slirp know 6655
>> is the
>> > port that needs to be visited on the host side?
>>
>> Slirp itself *doesn't* know that port. The guestfwd piece just calls the
>> SlirpWriteCb when it has data coming from the guest. See the
>> documentation:
>>
>> /* Set up port forwarding between a port in the guest network and a
>>  * callback that will receive the data coming from the port */
>> SLIRP_EXPORT
>> int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
>>                        struct in_addr *guest_addr, int guest_port);
>>
>> and
>>
>> /* This is called by the application for a guestfwd, to provide the data
>> to be
>>  * sent on the forwarded port */
>> SLIRP_EXPORT
>> void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int
>> guest_port,
>>                        const uint8_t *buf, int size);
>>
>> Samuel
>>
>

Reply via email to