Rejecting connection attempts on socket

  • Follow


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
0
Reply kenbrody (1860) 5/22/2012 4:02:07 PM

Kenneth Brody <kenbrody@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.
>
> 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"?

'close the listening socket' would seem like the obvious answer.

-- 
http://www.greenend.org.uk/rjk/
0
Reply rjk (492) 5/22/2012 4:11:06 PM


On 5/22/2012 12:11 PM, Richard Kettlewell wrote:
> Kenneth Brody<kenbrody@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
0
Reply kenbrody (1860) 5/22/2012 4:37:30 PM

Kenneth Brody <kenbrody@spamcop.net> writes:

> On 5/22/2012 12:11 PM, Richard Kettlewell wrote:
>> Kenneth Brody<kenbrody@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.

Why not?  You can create it again when you want to start accepting
connections again.

-- 
http://www.greenend.org.uk/rjk/
0
Reply rjk (492) 5/22/2012 4:42:11 PM

On 5/22/2012 12:42 PM, Richard Kettlewell wrote:
> Kenneth Brody<kenbrody@spamcop.net>  writes:
>> On 5/22/2012 12:11 PM, Richard Kettlewell wrote:
>>> Kenneth Brody<kenbrody@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
0
Reply kenbrody (1860) 5/22/2012 5:03:02 PM

On 5/22/2012 1:03 PM, Kenneth Brody wrote:
> On 5/22/2012 12:42 PM, Richard Kettlewell wrote:
>> Kenneth Brody<kenbrody@spamcop.net> writes:
>>> On 5/22/2012 12:11 PM, Richard Kettlewell wrote:
>>>> Kenneth Brody<kenbrody@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.

     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
esosman@ieee-dot-org.invalid
0
Reply esosman2 (2945) 5/22/2012 5:18:33 PM

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
0
Reply lacos2 (200) 5/22/2012 6:02:21 PM

Kenneth Brody <kenbrody@spamcop.net> writes:
> Richard Kettlewell wrote:
>> Kenneth Brody<kenbrody@spamcop.net>  writes:
>>> Richard Kettlewell wrote:
>>>> Kenneth Brody<kenbrody@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.

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/
0
Reply rjk (492) 5/22/2012 6:44:51 PM

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.

0
Reply nobody (4805) 5/23/2012 9:46:06 AM

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.
0
Reply xroche (185) 5/23/2012 11:04:19 AM

Xavier Roche <xroche@free.fr.NOSPAM.invalid> writes:
>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.

Not if you set the listen backlog parameter to zero.

scott
0
Reply scott1 (356) 5/23/2012 3:23:29 PM

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.
0
Reply xroche (185) 5/23/2012 3:32:38 PM

Scott Lurndal <scott@slp53.sl.home> wrote:
> Xavier Roche <xroche@free.fr.NOSPAM.invalid> writes:
> >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.

> Not if you set the listen backlog parameter to zero.

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.
0
Reply William 5/23/2012 8:30:08 PM

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

0
Reply doomster121 (274) 5/24/2012 5:16:11 AM

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.

0
Reply nobody (4805) 5/24/2012 2:36:03 PM

On Tue, 22 May 2012 20:02:21 +0200, "Ersek, Laszlo"
<lacos@caesar.elte.hu> wrote:

>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.

This is what I do.
-- 
(\__/)  M.
(='.'=) If a man stands in a forest and no woman is around
(")_(") is he still wrong?

0
Reply i1658 (113) 5/28/2012 2:25:14 PM

15 Replies
111 Views

(page loaded in 0.137 seconds)

Similiar Articles:


















7/24/2012 10:47:55 PM


Reply: