Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rejecting connection attempts on socket

670 views
Skip to first unread message

Kenneth Brody

unread,
May 22, 2012, 12:02:07 PM5/22/12
to
I've searched and searched, and I have a feeling the answer is "you can't",
but I figured I'd ask here just in case I missed something.

I have a socket, I've bound it to a port, and entered a listening state. I
have accepted several connections, and do not want to talk to any more
clients until I am done with one of them.

Now, I want further connection attempts to receive ECONNREFUSED.

I do not want to accept the connection and immediately close it. I do not
want to simply not call accept, and have the client hang around, waiting for
the eventual ETIMEDOUT. I just want a simple "I'm too busy to talk to you,
go away, ECONNREFUSED" error. (Actually, I'd settle for any error on the
client side, as long as it was immediate.)

And, once I've finished with one of the clients I'm talking to, I want to be
able to go back to accepting connections.

Windows' WSAAccept() API call has a callback function which allows me to say
"reject this connection", but I don't see anything in POSIX to allow this.

Have I missed something, or is this really "sorry, you can't do that"?

Thank you.

--
Kenneth Brody

Richard Kettlewell

unread,
May 22, 2012, 12:11:06 PM5/22/12
to
'close the listening socket' would seem like the obvious answer.

--
http://www.greenend.org.uk/rjk/

Kenneth Brody

unread,
May 22, 2012, 12:37:30 PM5/22/12
to
On 5/22/2012 12:11 PM, Richard Kettlewell wrote:
> Kenneth Brody<kenb...@spamcop.net> writes:
>> I've searched and searched, and I have a feeling the answer is "you
>> can't", but I figured I'd ask here just in case I missed something.
>>
>> I have a socket, I've bound it to a port, and entered a listening
>> state. I have accepted several connections, and do not want to talk
>> to any more clients until I am done with one of them.
>>
>> Now, I want further connection attempts to receive ECONNREFUSED.
>>
>> I do not want to accept the connection and immediately close it. I do
>> not want to simply not call accept, and have the client hang around,
>> waiting for the eventual ETIMEDOUT. I just want a simple "I'm too
>> busy to talk to you, go away, ECONNREFUSED" error. (Actually, I'd
>> settle for any error on the client side, as long as it was immediate.)
>>
>> And, once I've finished with one of the clients I'm talking to, I want
>> to be able to go back to accepting connections.
[...]
> 'close the listening socket' would seem like the obvious answer.

While that would be fine if I never wanted to accept more connections,
closing the listening socket is not a viable solution here.

--
Kenneth Brody

Richard Kettlewell

unread,
May 22, 2012, 12:42:11 PM5/22/12
to
Why not? You can create it again when you want to start accepting
connections again.

--
http://www.greenend.org.uk/rjk/

Kenneth Brody

unread,
May 22, 2012, 1:03:02 PM5/22/12
to
On 5/22/2012 12:42 PM, Richard Kettlewell wrote:
> Kenneth Brody<kenb...@spamcop.net> writes:
>> On 5/22/2012 12:11 PM, Richard Kettlewell wrote:
>>> Kenneth Brody<kenb...@spamcop.net> writes:
[...]
>>>> And, once I've finished with one of the clients I'm talking to, I want
>>>> to be able to go back to accepting connections.
>> [...]
>>> 'close the listening socket' would seem like the obvious answer.
>>
>> While that would be fine if I never wanted to accept more connections,
>> closing the listening socket is not a viable solution here.
>
> Why not? You can create it again when you want to start accepting
> connections again.

Assuming that that port is still available, and some other program hasn't
grabbed it.

--
Kenneth Brody

Eric Sosman

unread,
May 22, 2012, 1:18:33 PM5/22/12
to
Um, er, how do the clients know what port to connect to? I've
run into two approaches:

1) The clients and the listener agree on a pre-chosen port
number, and the listener makes its own arrangements with
the host O/S to get exclusive use of that port. If this
fits your case, then the arrangements should still be in
effect and the O/S will give you the same number and won't
let anyone else use it.

2) The listener uses whatever port the O/S chooses to give
it, and then publishes the number through some kind of
naming service. If you're doing this, just re-publish
the new number when you resume accepting connections.
(You could even go so far as to publish "Out To Lunch"
when you're not accepting new work.)

If you're using some other scheme, please describe it.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Ersek, Laszlo

unread,
May 22, 2012, 2:02:21 PM5/22/12
to
On Tue, 22 May 2012, Kenneth Brody wrote:

> I have a socket, I've bound it to a port, and entered a listening state.
> I have accepted several connections, and do not want to talk to any more
> clients until I am done with one of them.
>
> Now, I want further connection attempts to receive ECONNREFUSED.
>
> I do not want to accept the connection and immediately close it. I do
> not want to simply not call accept, and have the client hang around,
> waiting for the eventual ETIMEDOUT. I just want a simple "I'm too busy
> to talk to you, go away, ECONNREFUSED" error. (Actually, I'd settle for
> any error on the client side, as long as it was immediate.)
>
> And, once I've finished with one of the clients I'm talking to, I want
> to be able to go back to accepting connections.

I recall a similar discussion:

http://groups.google.com/group/comp.unix.programmer/msg/8fdc56db4b06312f
http://groups.google.com/group/comp.unix.programmer/msg/faaa28babafbea19

Focusing on the current question, I took away that accepting and closing
immediately was the portable way.

Laszlo

Richard Kettlewell

unread,
May 22, 2012, 2:44:51 PM5/22/12
to
That's true. But you make much the same assumption when you bind in the
first place, too. If you want a reliable overall system then you need
to find some way of preventing your programs from dueling with one
another.

--
http://www.greenend.org.uk/rjk/

Nobody

unread,
May 23, 2012, 5:46:06 AM5/23/12
to
On Tue, 22 May 2012 12:02:07 -0400, Kenneth Brody wrote:

> I have a socket, I've bound it to a port, and entered a listening state.
> I have accepted several connections, and do not want to talk to any more
> clients until I am done with one of them.
>
> Now, I want further connection attempts to receive ECONNREFUSED.

1. close() the socket and re-create it when you're ready.

2. Add an iptables rule to respond with RST to SYN packets on that port
(requires root privilege).

> Windows' WSAAccept() API call has a callback function which allows me to
> say "reject this connection", but I don't see anything in POSIX to allow
> this.
>
> Have I missed something, or is this really "sorry, you can't do that"?

Userspace doesn't get notified of a connection until the three-way
handshake has completed, but ECONNREFUSED is only reported if the
handshake fails.

Sending an RST after the SYN+ACK will result in connect() succeeding then
a subsequent read/write/etc failing.

Xavier Roche

unread,
May 23, 2012, 7:04:19 AM5/23/12
to
On 05/22/2012 06:02 PM, Kenneth Brody wrote:
> I have a socket, I've bound it to a port, and entered a listening state.
> I have accepted several connections, and do not want to talk to any more
> clients until I am done with one of them.
> Now, I want further connection attempts to receive ECONNREFUSED.

Note that at this point, you may have several other clients *already*
connected, in the connection queue.

Scott Lurndal

unread,
May 23, 2012, 11:23:29 AM5/23/12
to
Not if you set the listen backlog parameter to zero.

scott

Xavier Roche

unread,
May 23, 2012, 11:32:38 AM5/23/12
to
On 05/23/2012 05:23 PM, Scott Lurndal wrote:
>> Note that at this point, you may have several other clients *already*
>> connected, in the connection queue.
> Not if you set the listen backlog parameter to zero.

You can't AFAIK ("A backlog argument of 0 may allow the socket to accept
connections, in which case the length of the listen queue may be set to
an implementation-defined minimum value.")

Note that this "implementation-defined minimum value" can be something
different than 1.

William Ahern

unread,
May 23, 2012, 4:30:08 PM5/23/12
to
I tried that. It doesn't work by default, at least on OS X Lion, Linux
3.2, and OpenBSD 5.2.

Scanning through the OpenBSD source code (sys/kern/uipc_socket.c), it looks
like it has a default minimum backlog of 80. If I lower the minimum to 0 and
then set the backlog on a socket to 0, my connection attempt just hangs.

I don't see anything analogous to sominconn on OS X or Linux (no sysctl mib or
/proc entry). I'm too lazy to wade through the Linux networking code to
understand why neither listen(0) nor even listen(1) works, or how to coax it
to work in an intuitive way. (Actually, I did try wading through it, and I
must admit defeat. :(

I suspect the only way to get the behavior the OP wants is to close the
socket. (I don't know of any way to unset the listen mode of a socket.) The
best I've been able to do is to lower the backlog on OpenBSD, which appears
to just not answer the SYN, leaving the connection hanging. I wouldn't be
surprised if the only way to signal ECONNREFUSED is via an ICMP message,
which is probably only sent when a socket isn't bound and listening to a
port.

Ulrich Eckhardt

unread,
May 24, 2012, 1:16:11 AM5/24/12
to
Kenneth Brody wrote:
[closing and reopening]
> Assuming that that port is still available, and some other program
> hasn't grabbed it.

There is an option (SOREUSECONN or something like that) that allows you to
bind multiple sockets to that port. Bind a new one to the port and close
the first that is listening. The only problem I see is that this doesn't
prevent any other program from grabbing that port either, unless this is
only for the current process.

Uli

Nobody

unread,
May 24, 2012, 10:36:03 AM5/24/12
to
On Wed, 23 May 2012 13:30:08 -0700, William Ahern wrote:

> I wouldn't be
> surprised if the only way to signal ECONNREFUSED is via an ICMP message,
> which is probably only sent when a socket isn't bound and listening to a
> port.

If nothing is bound to the port, the SYN will elicit a RST. ECONNREFUSED
may result from either a RST or an ICMP "port unreachable" error (type 3
code 3). Most other ICMP errors result in ENETUNREACH or EHOSTUNREACH.

Mark

unread,
May 28, 2012, 10:25:14 AM5/28/12
to
This is what I do.
--
(\__/) M.
(='.'=) If a man stands in a forest and no woman is around
(")_(") is he still wrong?

0 new messages