1

In a torrent client I've written, I don't accept connections unless I actually want or need more connections. This leads to netstat showing a lot of SYN_RECV, which seems plausible as I haven't yet completed the connection. Do these consume available file descriptors on the server? Is it bad practise to let the backlog fill up until I actually want to accept? Is there a better practice?

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526

2 Answers2

3

No. The connection is completed by the TCP stack, possibly long before you call accept(), and placed on the backlog queue. All that accept() does is block while the backlog queue is empty, and then remove and return the head element as a socket FD. It doesn't have anything to do with the connect handshake.

Connections in the backlog queue don't consume file descriptors. The FD is allocated by accept().

In general you should process the backlog queue as fast as possible. If you never accept a connection in the backlog queue, it will eventually get reset when you close the listening socket, which will confuse the peer. And in the meantime it has been consuming a socket and possibly a thread at the peer, wasting resources there. If you don't want the connection, accept it it and close it.

YMMV on specific platforms.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 1
    I'm a long way from my references until tomorrow, but I believe the sockets in SYN_RECV state are in another, prior queue for connections that can't be completed because the backlog queue is full, and I believe this queue should time itself out reasonably quickly. But it's all due to not accepting connections. – user207421 Jan 31 '16 at 00:35
  • Can having them in the backlog degrade system performance in any way, assuming normal configuration parameters? If the system completes the handshake before accept is even called, is this really still the SYN_RECV state? – Matt Joiner Jan 31 '16 at 07:32
  • @MattJoiner By not accepting you are consuming backlog queue resources, and degrading and misleading clients. A completed connection in the backlog queue is in ESTABLISHED state, of course. SYN_RECV is a prior state. I've already said that. – user207421 Jan 31 '16 at 20:46
  • These connections are definitely still in SYN_RECV. I assume now that they may have legitimately not completed the handshake, and wouldn't be returned from an accept(). – Matt Joiner Feb 03 '16 at 02:22
  • So they're still in the prior-to-backlog queue. We've been over that. – user207421 Feb 03 '16 at 02:26
1

Is there a better practice?

accept and immediately close them if you temporarily don't want to accept handle additional connections.

But in the context of bittorrent you may want to implement BEP 40 instead and at least perform a bittorrent handshake to see which swarm a connection belongs to and whether you should drop an existing one in favor of the new one and only close the connection if you determine it has a lower priority than the existing ones.

the8472
  • 40,999
  • 5
  • 70
  • 122
  • Thanks. I actually accept it if there is any possibility I may want to use it. If for example, all torrents on the client are completed, and not to be seeded, I have no reason to accept anything. So how about that case? – Matt Joiner Jan 31 '16 at 07:30
  • Thanks for the link to BEP40!! I had no idea this existed. – Matt Joiner Jan 31 '16 at 07:32
  • accept&close is the usual method. in principle you could also close the server socket, but i think few people bother to do that. – the8472 Jan 31 '16 at 13:07