[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
- Re: How to know /dev/tcp/host/port is closed?,
Peng Yu <=