Re: ECONNRESET not returned when calling send() on a socket

2019-12-23 Thread Germain Le Chapelain
On Mon, 23 Dec 2019 09:58:58 +
Sad Clouds  wrote:

> I'm curious, if you use two threads on a blocking socket, how do you
> implement I/O timeout in order to prevent a rouge client from running
> DoS attacks (read/write a few bytes of data, then go to sleep for a few
> minutes) 

I make a round-robin of connections that I may accept,
Say, of 1 or 5 thousands connections 

once one is valid I forget about the rest , since I only expect one


I guess I am realizing now that for me I have one singular point ,where the 
certificates are exchanged and verified, when I know the connection is valid.

Maybe your problem is different

I kindof pulled of nowhere the # of 1 to 5 thousand listening threads, as I 
actually haven't implemented that part on my project yet :p
(and I should, because now I have to wait until the rogue server tires for my 
thing to kick-in :))

But looking at my system, it says that:

>sysctl -a
...
kern.posix_threads = 200112

so it seems honnest.  You will only use all of the threads against a pack of 
rogue servers ;)

-- 
Germain Le Chapelain 
Software Engineer
Lanvaux



Re: ECONNRESET not returned when calling send() on a socket

2019-12-23 Thread Sad Clouds
On Mon, 23 Dec 2019 14:31:19 +0300
Valery Ushakov  wrote:

> On Mon, Dec 23, 2019 at 11:22:41 +, Sad Clouds wrote:
> 
> > I handle SIGPIPE now, but don't see the value of having both SIGPIPE
> > and ECONNRESET for a socket. The behaviour is rather inconsistent,
> > i.e. you call send() and sometimes you get a SIGPIPE signal and
> > sometimes you don't. Maybe it's just a Linux issue and NetBSD always
> > sends SIGPIPE.
> 
> Why do you keep inflicting this on yourself?  Just disable SIGPIPE
> delivery for your sockets.  That's the way it's meant to be used.  
> 
> -uwe

Because there is no portable way of disabling SIGPIPE, but looks like
there is no way around it, so that is what I've been doing with #ifdef
macros. 


Re: ECONNRESET not returned when calling send() on a socket

2019-12-23 Thread Valery Ushakov
On Mon, Dec 23, 2019 at 11:22:41 +, Sad Clouds wrote:

> I handle SIGPIPE now, but don't see the value of having both SIGPIPE
> and ECONNRESET for a socket. The behaviour is rather inconsistent,
> i.e. you call send() and sometimes you get a SIGPIPE signal and
> sometimes you don't. Maybe it's just a Linux issue and NetBSD always
> sends SIGPIPE.

Why do you keep inflicting this on yourself?  Just disable SIGPIPE
delivery for your sockets.  That's the way it's meant to be used.  

-uwe


Re: ECONNRESET not returned when calling send() on a socket

2019-12-23 Thread Valery Ushakov
On Sun, Dec 22, 2019 at 21:20:41 +, Sad Clouds wrote:

> On Sun, 22 Dec 2019 23:44:33 +0300
> Valery Ushakov  wrote:
> 
> > LOL.  Sorry :) I mean, you are already using poll(2).  It literally
> > cannot get *any* worse.  Literally.  The margins of this email are
> > just too narrow...  Sorry again, traumatic memories...
> > 
> > E.g. NetBSD and Solaris never report POLLHUP for sockets.  Windows and
> > OSX report POLLHUP when remote half-closes.  Linux reports it on full
> > close.  NetBSD and Solaris don't report POLLERR on failed connect(2),
> > just POLLOUT.  And I don't even want to think about scenarios like
> > reset after half-close...
> 
> Well, I don't have problems with poll(). For a small number of file
> descriptors it works quite well. Yes it does get expensive when you
> start using 1000s of file descriptors, but then you just use epoll(),
> kqueue(), etc.

This is not what I mean.

-uwe


Re: ECONNRESET not returned when calling send() on a socket

2019-12-23 Thread Sad Clouds
On Sun, 22 Dec 2019 21:20:41 +
Sad Clouds  wrote:

> > On NetBSD you always get SIGPIPE (whn not turned off), right?
> If I remember correctly, on NetBSD sometimes I got ECONNRESET,
> sometimes I got SIGPIPE, depending on at what time the other TCP
> application was killed. On Linux I think I always got ECONNRESET.

This is what I get on Solaris with 4 TCP sockets, when I kill the
client while it is running on Linux host. Three threads get SIGPIPE
signals when calling send() and one thread gets ECONNRESET errno when
calling recv():

Error XXX.c:2040: XXX_send_buf() failed, Broken pipe
Error XXX.c:2112: XXX_recv_buf() failed, Connection reset by peer
Error XXX.c:2040: XXX_send_buf() failed, Broken pipe
Error XXX.c:2040: XXX_send_buf() failed, Broken pipe


But swapping them round and running server process on Linux and client
process on Solaris, I get this when killing the client:

Error XXX.c:2146: Client unexpectedly closed connection
Error XXX.c:2040: XXX_send_buf() failed, Connection reset by peer
Error XXX.c:2040: XXX_send_buf() failed, Broken pipe
Error XXX.c:2040: XXX_send_buf() failed, Connection reset by peer

So on Linux I get a mixture of various conditions, EOF when calling
recv(), ECONNRESET and SIGPIPE when calling send().

Not sure if NetBSD behaves the same, most of the time I get SIGPIPE,
but can't remember if I've ever seen ECONNRESET for send().

I handle SIGPIPE now, but don't see the value of having both SIGPIPE
and ECONNRESET for a socket. The behaviour is rather inconsistent,
i.e. you call send() and sometimes you get a SIGPIPE signal and
sometimes you don't. Maybe it's just a Linux issue and NetBSD always
sends SIGPIPE.


Re: ECONNRESET not returned when calling send() on a socket

2019-12-23 Thread Sad Clouds
On Sun, 22 Dec 2019 23:01:23 -0800
Germain Le Chapelain  wrote:

> I'm not saying poll() is wrong but it's more that from the other bits
> (different errors checking, sigpipe) , it felt to me like you are
> re-implementing TCP.

Not at all. I/O multiplexing with select()/poll()/epoll()/kqueue(),
etc. is a pretty standard way of handling multiple file descriptors.

Regardless of what you do, it will not change the behaviour of send()
syscall.

I'm curious, if you use two threads on a blocking socket, how do you
implement I/O timeout in order to prevent a rouge client from running
DoS attacks (read/write a few bytes of data, then go to sleep for a few
minutes) on platforms like Solaris, which may not support SO_RCVTIMEO
and SO_SNDTIMEO socket options?