help-bash
[Top][All Lists]
Advanced

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

Re: How to know /dev/tcp/host/port is closed?


From: Peng Yu
Subject: Re: How to know /dev/tcp/host/port is closed?
Date: Thu, 1 Apr 2021 10:02:42 -0500

On 3/31/21, Leonid Isaev (ifax) <leonid.isaev@ifax.com> wrote:
> On Wed, Mar 31, 2021 at 04:17:01PM -0500, Peng Yu wrote:
>> See the following code. When the first printf is finished, the
>> connection should have been closed. But it seems that bash does not
>> know it (see the exit status code of { true >&"$fd"; } 2>/dev/null).
>> Is it a bug?
>
> No, it's not a bug, but a feature, called "half-closed" TCP sockets.
>
> Let's pick the client-server conversation off-wire with tshark(1) (starting
> from the end of your {...}:
>
>> } {fd}<>/dev/tcp/httpbin.org/80
>
> Here we have a TCP handshake:
> -----8<-----
>  25          2 192.168.122.43 -> 54.166.163.67 TCP 74 59392 > http [SYN]
> Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=1043835330 TSecr=0 WS=64
>  26          2 54.166.163.67 -> 192.168.122.43 TCP 74 http > 59392 [SYN,
> ACK] Seq=0 Ack=1 Win=26847 Len=0 MSS=1460 SACK_PERM=1 TSval=781007956
> TSecr=1043835330 WS=256
>  27          2 192.168.122.43 -> 54.166.163.67 TCP 66 59392 > http [ACK]
> Seq=1 Ack=1 Win=29248 Len=0 TSval=1043835340 TSecr=781007956
> ----->8-----
> (54.166.163.67 is one of IPs httpbin.org resolves to, and 192.168.122.43 is
> my test VM)
>
>> $ {
>>     header=(
>>         'GET /get HTTP/1.1'
>>         'Host: httpbin.org'
>>         'Connection: close'
>>     )
>>     builtin printf '%s\r\n' "${header[@]}" '' >&"$fd"
>
> Now, we send data, and the server replies (frame 38):
> -----8<-----
>  30          2 192.168.122.43 -> 54.166.163.67 TCP 85 [TCP segment of a
> reassembled PDU]
>  35          2 54.166.163.67 -> 192.168.122.43 TCP 66 http > 59392 [ACK]
> Seq=1 Ack=20 Win=26880 Len=0 TSval=781007960 TSecr=1043835346
>  36          2 192.168.122.43 -> 54.166.163.67 HTTP 106 GET /get HTTP/1.1
>  37          2 54.166.163.67 -> 192.168.122.43 TCP 66 http > 59392 [ACK]
> Seq=1 Ack=60 Win=26880 Len=0 TSval=781007961 TSecr=1043835353
>  38          2 54.166.163.67 -> 192.168.122.43 HTTP 490 HTTP/1.1 200 OK
> (application/json)
> ----->8-----
>
> But since we sent "Connection: close", the server closes it's part of TCP

https://youtu.be/bKQfbkE1Nac?t=40

I see an explanation on how to close a TCP connection above. There two
steps. So in this slide, there are two packets sent (the first one
with ACK set, the second one with FIN set)?

- 2 Send ACK
- 3 Send FIN

The slide is different from what is actually happening in this bash
example as FIN+ACK are sent in one packet?

> connection with a FIN+ACK:

So once bash sees FIN (whether it is a combination of both FIN and ACK
or just a FIN), bash will return an EOF when reading from the socket
(after reading all the stream before the end)?

Thanks.

> -----8<-----
>  39          2 54.166.163.67 -> 192.168.122.43 TCP 66 http > 59392 [FIN,
> ACK] Seq=425 Ack=60 Win=26880 Len=0 TSval=781007962 TSecr=1043835353
>  40          2 192.168.122.43 -> 54.166.163.67 TCP 66 59392 > http [ACK]
> Seq=60 Ack=425 Win=30272 Len=0 TSval=1043835362 TSecr=781007962

-- 
Regards,
Peng



reply via email to

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