Re: ECONNRESET not returned when calling send() on a socket
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
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
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
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
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
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?