8

From the ethreal packet capture, I see the following behaviour which appears quite strange to me:

Client --> Server  [SYN]
Server --> Client  [SYN, ACK]
Client --> Server  [ACK]
Server --> Client  [FIN, ACK]
Client --> Server  [ACK]
Client --> Server  [TCP Segment of a reassembled PDU] (I don't know what this means)
Server --> Client  [RST]

Any ideas as to why this could be happening?

Also, the Server Port is 6000. Could that cause any problem?

My other doubts:

  1. Why is there a FIN, ACK? Shouldn't it be only FIN? What is the meaning of the ACK in that message?
  2. Shouldn't there be a FIN from Client also?

EDIT: After some more analysis, I found if the number of file descriptors have exceeded the limit then a FIN is sent by the Server. But, in this case it doesn't appear that the file descriptors have exceeded the limit. For what other scenarios can this happen?

Jay
  • 24,173
  • 25
  • 93
  • 141

6 Answers6

18

Upon deep analysis, the following was found to be the reason of the problem:

When a Client tries TCP connect, even if the server is not currently calling accept, the connection will pass. This will happen if server has called 'listen' function and it will keep accepting the connections till backlog limit is reached.

But, if the application process exceeds the limit of max file descriptors it can use, then when server calls accept, then it realizes that there are no file descriptors available to be allocated for the socket and fails the accept call and the TCP connection sending a FIN to other side.

I just though of posting this finding here. I am still leaving the accepted answer as that of Habbie's.

Thanks to all those who answered this question.

Jay
  • 24,173
  • 25
  • 93
  • 141
6

FIN usually means the other side called shutdown(..) on the socket.

Habbie
  • 2,150
  • 15
  • 17
  • Do you mean to say that the call to 'accept' would have surely returned successfully in this case? – Jay Oct 06 '10 at 09:00
  • Yes. Without accept() you would just see silence and eventually timeouts. – Habbie Oct 06 '10 at 09:01
  • 1
    Ok, but, there is no way an accept will send a FIN right? I mean in case of some error conditions, is it possible? – Jay Oct 06 '10 at 09:04
  • Not that I'm aware of, certainly. – Habbie Oct 06 '10 at 09:06
  • Hmm? No, the connection is set up before `accept()` is called - the backlog parameter to `listen()` specifies how many connections can be in this state (connected, but `accept()` not yet called). – caf Oct 06 '10 at 10:53
3

I'm guessing the connection is being accepted by inetd or a similar daemon, which then attempts to fork and exec another program to handle the connection, and that either the fork is failing (due to resource exhaustion) or the exec is failing (due to nonexistent file, permissions error, etc.).

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
2

I think the FIN was sent by calling close() instead of shutdown().

The connection is in backlog queue; after accept(), the server decides to terminate it for whatever reason(e.g. TCP wrapper ACL or out of file descriptors). In this case, a close() decreases file descriptor(FD)'s link count by 1 to 0, so FD for this connection is fully destroyed. Afterwards the client sends data to a non-existing socket from server's point of view, server has to respond a RST.

If it was a shutdown(), server can still revive data sent by client and have to wait for FIN from client to close the connection gracefully. No RST is sent back.

p.s. close() vs shutdown()

  • At least it can be sent by `close()`. I'm having the same issue with OpenSSH ([SYN] / [SYN, ACK] / [ACK] / [FIN, ACK] sequence for some random connections), and `sshd` has calls to `close()` to close the connection; it does not use `shutdown()` at all. – vinc17 Jun 07 '22 at 15:28
1

Could be TCP wrappers. If the server process was built with libwrap support, it will accept the connection, check /etc/hosts.allow and /etc/hosts.deny, and then immediately close the connection if denied by policy.

It's easy to see if the server is using libwrap:

> ldd /usr/sbin/sshd | grep libwrap
libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f1562d44000)
eater
  • 2,697
  • 1
  • 21
  • 24
0

Seems like the server calls shutdown very shortly after accepting the connection.

valdo
  • 12,632
  • 2
  • 37
  • 67