Re: svn commit: r313043 - head/sys/kern
On Fri, Feb 03, 2017 at 07:51:24AM +, hartmut.bra...@dlr.de wrote: H> It was attached to my mail, but maybe got removed somewhere. Here it is. It does not use asio, but reproduces the same sequence of system calls. You start it and the try to connect with telnet to port 1. I was blind, sorry :( And thanks for all replies. -- Totus tuus, Glebius. ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
RE: svn commit: r313043 - head/sys/kern
It was attached to my mail, but maybe got removed somewhere. Here it is. It does not use asio, but reproduces the same sequence of system calls. You start it and the try to connect with telnet to port 1. harti #include #include #include #include #include #include #include #include #include static void wait_loop(int kq, int sock) { struct kevent ev[32]; struct sockaddr_in addr; socklen_t socklen; for (;;) { int nev = kevent(kq, NULL, 0, ev, 32, NULL); if (nev < 1) err(1, "kevent"); for (int i = 0; i < nev; ++i) { if (ev[i].ident == sock) { printf("accept\n"); int fd = accept(ev[i].ident, (struct sockaddr *), ); if (fd == -1) err(1, "accept"); } } } } int main() { struct sockaddr_in addr; /* open a TCP socket */ int kq = kqueue(); int sock = socket(PF_INET, SOCK_STREAM, 0); struct kevent ev[2]; EV_SET([0], sock, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL); EV_SET([1], sock, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, NULL); int opt = 1; setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, , sizeof(opt)); if (kevent(kq, ev, 2, NULL, 0, NULL) == -1) err(1, "kevent"); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, , sizeof(opt)); memset(, 0, sizeof(addr)); addr.sin_port = htons(1); bind(sock, (struct sockaddr *), sizeof(addr)); listen(sock, 0x80); ioctl(sock, FIONBIO, ); if (kevent(kq, ev, 2, NULL, 0, NULL) == -1) err(1, "kevent"); wait_loop(kq, sock); } -Original Message- From: Gleb Smirnoff [mailto:gleb...@freebsd.org] Sent: Thursday, February 02, 2017 8:24 PM To: Brandt, Hartmut Cc: src-committ...@freebsd.org; svn-src-all@freebsd.org; svn-src-h...@freebsd.org Subject: Re: svn commit: r313043 - head/sys/kern Hartmut, Thanks for explanation! Is there a test program available to reproduce the problem? I want to try the sequence on my branch. On Thu, Feb 02, 2017 at 08:29:20AM +, hartmut.bra...@dlr.de wrote: H> To be honest - I feared that when I saw your messages regarding this. Here is my original message from july. Attached is also a small test program. H> H> Hi, H> H> I'm trying to use asio (that's boost::asio without boost) to handle listening sockets asynchronuosly. This appears not to work. There are also some reports on the net about this problem. I was able to reproduce the problem with a small C-programm that does the same steps as asio. The relevant sequence of system calls is: H> H> kqueue() = 3 (0x3) H> socket(PF_INET,SOCK_STREAM,6) = 4 (0x4) H> setsockopt(0x4,0x,0x800,0x7fffea2c,0x4) = 0 (0x0) H> kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0) H> setsockopt(0x4,0x,0x4,0x7fffea2c,0x4) = 0 (0x0) H> bind(4,{ AF_INET 0.0.0.0:8080 },16) = 0 (0x0) H> listen(0x4,0x80) = 0 (0x0) H> ioctl(4,FIONBIO,0xea2c) = 0 (0x0) H> kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0) H> kevent(3,0x0,0,0x7fffe5a0,32,0x0) ERR#4 'Interrupted system call' H> H> The problem here is that asio registers each file descriptor with EVFILT_READ and EVFILT_WRITE as soon as it is opened (first kevent call). H> After bringing the socket into the listening state and when async_accept() is called it registers the socket a second time. According to the man page this is perfectly legal and can be used to modify the registration. H> H> With this sequence of calls kevent() does not return when a connection is established successfully. H> H> I tracked down the problem and the reason is in soo_kqfilter(). This is called for the first EVFILT_READ registration and decides based on the SO_ACCEPTCONN flag which filter operations to use solisten_filtops or soread_filtops. In this case it chooses soread_filtops. H> H> The second EVFILT_READ registration does not call soo_kqfilter() again, but just updates the filter from the data and fflags field so the listening socket ends up with the wrong filter operations. H> H> H> H> -Original Message- H> From: Gleb Smirnoff [mailto:gleb...@freebsd.org] H> Sent: Wednesday, February 01, 2017 7:08 PM H> To: Hartmut Brandt H> Cc: src-committ...@freebsd.org; svn-src
Re: svn commit: r313043 - head/sys/kern
Hartmut, Thanks for explanation! Is there a test program available to reproduce the problem? I want to try the sequence on my branch. On Thu, Feb 02, 2017 at 08:29:20AM +, hartmut.bra...@dlr.de wrote: H> To be honest - I feared that when I saw your messages regarding this. Here is my original message from july. Attached is also a small test program. H> H> Hi, H> H> I'm trying to use asio (that's boost::asio without boost) to handle listening sockets asynchronuosly. This appears not to work. There are also some reports on the net about this problem. I was able to reproduce the problem with a small C-programm that does the same steps as asio. The relevant sequence of system calls is: H> H> kqueue() = 3 (0x3) H> socket(PF_INET,SOCK_STREAM,6) = 4 (0x4) H> setsockopt(0x4,0x,0x800,0x7fffea2c,0x4) = 0 (0x0) H> kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0) H> setsockopt(0x4,0x,0x4,0x7fffea2c,0x4) = 0 (0x0) H> bind(4,{ AF_INET 0.0.0.0:8080 },16) = 0 (0x0) H> listen(0x4,0x80) = 0 (0x0) H> ioctl(4,FIONBIO,0xea2c) = 0 (0x0) H> kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0) H> kevent(3,0x0,0,0x7fffe5a0,32,0x0) ERR#4 'Interrupted system call' H> H> The problem here is that asio registers each file descriptor with EVFILT_READ and EVFILT_WRITE as soon as it is opened (first kevent call). H> After bringing the socket into the listening state and when async_accept() is called it registers the socket a second time. According to the man page this is perfectly legal and can be used to modify the registration. H> H> With this sequence of calls kevent() does not return when a connection is established successfully. H> H> I tracked down the problem and the reason is in soo_kqfilter(). This is called for the first EVFILT_READ registration and decides based on the SO_ACCEPTCONN flag which filter operations to use solisten_filtops or soread_filtops. In this case it chooses soread_filtops. H> H> The second EVFILT_READ registration does not call soo_kqfilter() again, but just updates the filter from the data and fflags field so the listening socket ends up with the wrong filter operations. H> H> H> H> -Original Message- H> From: Gleb Smirnoff [mailto:gleb...@freebsd.org] H> Sent: Wednesday, February 01, 2017 7:08 PM H> To: Hartmut Brandt H> Cc: src-committ...@freebsd.org; svn-src-all@freebsd.org; svn-src-h...@freebsd.org H> Subject: Re: svn commit: r313043 - head/sys/kern H> H> On Wed, Feb 01, 2017 at 01:12:07PM +, Hartmut Brandt wrote: H> H> Author: harti H> H> Date: Wed Feb 1 13:12:07 2017 H> H> New Revision: 313043 H> H> URL: https://svnweb.freebsd.org/changeset/base/313043 H> H> H> H> Log: H> H> Merge filt_soread and filt_solisten and decide what to do when checking H> H> for EVFILT_READ at the point of the check not when the event is registers. H> H> This fixes a problem with asio when accepting a connection. H> H> H> H> Reviewed by:kib@, Scott Mitchell H> H> This goes into opposite direction with what I am doing: H> H> https://reviews.freebsd.org/D9356 H> H> Can you please explain the problem with asio when accepting a connection? H> H> -- H> Totus tuus, Glebius. H> H> #include H> #include H> #include H> #include H> H> #include H> #include H> #include H> #include H> #include H> H> static void H> wait_loop(int kq, int sock) H> { H> struct kevent ev[32]; H> struct sockaddr_in addr; H> socklen_t socklen; H> H> for (;;) { H> int nev = kevent(kq, NULL, 0, ev, 32, NULL); H> if (nev < 1) H> err(1, "kevent"); H> for (int i = 0; i < nev; ++i) { H> if (ev[i].ident == sock) { H> printf("accept\n"); H> int fd = accept(ev[i].ident, H> (struct sockaddr *), ); H> if (fd == -1) H> err(1, "accept"); H> } H> } H> } H> } H> H> int H> main() H> { H> struct sockaddr_in addr; H> H> /* open a TCP socket */ H> int kq = kqueue(); H> H> int sock = socket(PF_INET, SOCK_STREAM, 0); H> H> struct kevent ev[2]; H> EV_SET([0], sock, EVFILT_READ, EV_ADD | E
RE: svn commit: r313043 - head/sys/kern
Sure. Let's settle this a couple of days. harti -Original Message- From: hiren panchasara [mailto:hi...@strugglingcoder.info] Sent: Wednesday, February 01, 2017 6:33 PM To: Hartmut Brandt Cc: src-committ...@freebsd.org; svn-src-all@freebsd.org; svn-src-h...@freebsd.org Subject: Re: svn commit: r313043 - head/sys/kern On 02/01/17 at 01:12P, Hartmut Brandt wrote: > Author: harti > Date: Wed Feb 1 13:12:07 2017 > New Revision: 313043 > URL: https://svnweb.freebsd.org/changeset/base/313043 > > Log: > Merge filt_soread and filt_solisten and decide what to do when checking > for EVFILT_READ at the point of the check not when the event is registers. > This fixes a problem with asio when accepting a connection. > > Reviewed by:kib@, Scott Mitchell > > Modified: > head/sys/kern/uipc_socket.c Is it possible to MFC this back to 11? Cheers, Hiren ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
RE: svn commit: r313043 - head/sys/kern
To be honest - I feared that when I saw your messages regarding this. Here is my original message from july. Attached is also a small test program. Hi, I'm trying to use asio (that's boost::asio without boost) to handle listening sockets asynchronuosly. This appears not to work. There are also some reports on the net about this problem. I was able to reproduce the problem with a small C-programm that does the same steps as asio. The relevant sequence of system calls is: kqueue() = 3 (0x3) socket(PF_INET,SOCK_STREAM,6)= 4 (0x4) setsockopt(0x4,0x,0x800,0x7fffea2c,0x4) = 0 (0x0) kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0) setsockopt(0x4,0x,0x4,0x7fffea2c,0x4)= 0 (0x0) bind(4,{ AF_INET 0.0.0.0:8080 },16) = 0 (0x0) listen(0x4,0x80) = 0 (0x0) ioctl(4,FIONBIO,0xea2c) = 0 (0x0) kevent(3,{ 4,EVFILT_READ,EV_ADD|EV_CLEAR,0x0,0x0,0x0 4,EVFILT_WRITE,EV_ADD|EV_CLEAR,0x0,0x0,0x0 },2,0x0,0,0x0) = 0 (0x0) kevent(3,0x0,0,0x7fffe5a0,32,0x0)ERR#4 'Interrupted system call' The problem here is that asio registers each file descriptor with EVFILT_READ and EVFILT_WRITE as soon as it is opened (first kevent call). After bringing the socket into the listening state and when async_accept() is called it registers the socket a second time. According to the man page this is perfectly legal and can be used to modify the registration. With this sequence of calls kevent() does not return when a connection is established successfully. I tracked down the problem and the reason is in soo_kqfilter(). This is called for the first EVFILT_READ registration and decides based on the SO_ACCEPTCONN flag which filter operations to use solisten_filtops or soread_filtops. In this case it chooses soread_filtops. The second EVFILT_READ registration does not call soo_kqfilter() again, but just updates the filter from the data and fflags field so the listening socket ends up with the wrong filter operations. -Original Message- From: Gleb Smirnoff [mailto:gleb...@freebsd.org] Sent: Wednesday, February 01, 2017 7:08 PM To: Hartmut Brandt Cc: src-committ...@freebsd.org; svn-src-all@freebsd.org; svn-src-h...@freebsd.org Subject: Re: svn commit: r313043 - head/sys/kern On Wed, Feb 01, 2017 at 01:12:07PM +, Hartmut Brandt wrote: H> Author: harti H> Date: Wed Feb 1 13:12:07 2017 H> New Revision: 313043 H> URL: https://svnweb.freebsd.org/changeset/base/313043 H> H> Log: H> Merge filt_soread and filt_solisten and decide what to do when checking H> for EVFILT_READ at the point of the check not when the event is registers. H> This fixes a problem with asio when accepting a connection. H> H> Reviewed by: kib@, Scott Mitchell This goes into opposite direction with what I am doing: https://reviews.freebsd.org/D9356 Can you please explain the problem with asio when accepting a connection? -- Totus tuus, Glebius. #include #include #include #include #include #include #include #include #include static void wait_loop(int kq, int sock) { struct kevent ev[32]; struct sockaddr_in addr; socklen_t socklen; for (;;) { int nev = kevent(kq, NULL, 0, ev, 32, NULL); if (nev < 1) err(1, "kevent"); for (int i = 0; i < nev; ++i) { if (ev[i].ident == sock) { printf("accept\n"); int fd = accept(ev[i].ident, (struct sockaddr *), ); if (fd == -1) err(1, "accept"); } } } } int main() { struct sockaddr_in addr; /* open a TCP socket */ int kq = kqueue(); int sock = socket(PF_INET, SOCK_STREAM, 0); struct kevent ev[2]; EV_SET([0], sock, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL); EV_SET([1], sock, EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, NULL); int opt = 1; setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, , sizeof(opt)); if (kevent(kq, ev, 2, NULL, 0, NULL) == -1) err(1, "kevent"); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, , sizeof(opt)); memset(, 0, sizeof(addr)); addr.sin_port = htons(1); bind(sock, (struct sockaddr *), sizeof(addr)); listen(sock, 0x80); ioctl(sock, FIONBIO, ); if (kevent(kq, ev, 2, NULL, 0, NULL) == -1) err(1, "kevent"); wait_loop(kq, sock); } ___ svn-src-all@freebsd.org mailing list https://lists.freebs
Re: svn commit: r313043 - head/sys/kern
On Wed, Feb 01, 2017 at 01:12:07PM +, Hartmut Brandt wrote: H> Author: harti H> Date: Wed Feb 1 13:12:07 2017 H> New Revision: 313043 H> URL: https://svnweb.freebsd.org/changeset/base/313043 H> H> Log: H> Merge filt_soread and filt_solisten and decide what to do when checking H> for EVFILT_READ at the point of the check not when the event is registers. H> This fixes a problem with asio when accepting a connection. H> H> Reviewed by: kib@, Scott Mitchell This goes into opposite direction with what I am doing: https://reviews.freebsd.org/D9356 Can you please explain the problem with asio when accepting a connection? -- Totus tuus, Glebius. ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
Re: svn commit: r313043 - head/sys/kern
On 02/01/17 at 01:12P, Hartmut Brandt wrote: > Author: harti > Date: Wed Feb 1 13:12:07 2017 > New Revision: 313043 > URL: https://svnweb.freebsd.org/changeset/base/313043 > > Log: > Merge filt_soread and filt_solisten and decide what to do when checking > for EVFILT_READ at the point of the check not when the event is registers. > This fixes a problem with asio when accepting a connection. > > Reviewed by:kib@, Scott Mitchell > > Modified: > head/sys/kern/uipc_socket.c Is it possible to MFC this back to 11? Cheers, Hiren pgpj_Qej66LQO.pgp Description: PGP signature
svn commit: r313043 - head/sys/kern
Author: harti Date: Wed Feb 1 13:12:07 2017 New Revision: 313043 URL: https://svnweb.freebsd.org/changeset/base/313043 Log: Merge filt_soread and filt_solisten and decide what to do when checking for EVFILT_READ at the point of the check not when the event is registers. This fixes a problem with asio when accepting a connection. Reviewed by: kib@, Scott Mitchell Modified: head/sys/kern/uipc_socket.c Modified: head/sys/kern/uipc_socket.c == --- head/sys/kern/uipc_socket.c Wed Feb 1 08:46:59 2017(r313042) +++ head/sys/kern/uipc_socket.c Wed Feb 1 13:12:07 2017(r313043) @@ -159,16 +159,10 @@ static void filt_sordetach(struct knote static int filt_soread(struct knote *kn, long hint); static voidfilt_sowdetach(struct knote *kn); static int filt_sowrite(struct knote *kn, long hint); -static int filt_solisten(struct knote *kn, long hint); static int inline hhook_run_socket(struct socket *so, void *hctx, int32_t h_id); static int filt_soempty(struct knote *kn, long hint); fo_kqfilter_t soo_kqfilter; -static struct filterops solisten_filtops = { - .f_isfd = 1, - .f_detach = filt_sordetach, - .f_event = filt_solisten, -}; static struct filterops soread_filtops = { .f_isfd = 1, .f_detach = filt_sordetach, @@ -3107,10 +3101,7 @@ soo_kqfilter(struct file *fp, struct kno switch (kn->kn_filter) { case EVFILT_READ: - if (so->so_options & SO_ACCEPTCONN) - kn->kn_fop = _filtops; - else - kn->kn_fop = _filtops; + kn->kn_fop = _filtops; sb = >so_rcv; break; case EVFILT_WRITE: @@ -3321,6 +3312,11 @@ filt_soread(struct knote *kn, long hint) struct socket *so; so = kn->kn_fp->f_data; + if (so->so_options & SO_ACCEPTCONN) { + kn->kn_data = so->so_qlen; + return (!TAILQ_EMPTY(>so_comp)); + + } SOCKBUF_LOCK_ASSERT(>so_rcv); kn->kn_data = sbavail(>so_rcv) - so->so_rcv.sb_ctl; @@ -,11 +3329,9 @@ filt_soread(struct knote *kn, long hint) if (kn->kn_sfflags & NOTE_LOWAT) { if (kn->kn_data >= kn->kn_sdata) - return 1; - } else { - if (sbavail(>so_rcv) >= so->so_rcv.sb_lowat) - return 1; - } + return (1); + } else if (sbavail(>so_rcv) >= so->so_rcv.sb_lowat) + return (1); /* This hook returning non-zero indicates an event, not error */ return (hhook_run_socket(so, NULL, HHOOK_FILT_SOREAD)); @@ -3397,16 +3391,6 @@ filt_soempty(struct knote *kn, long hint return (0); } -/*ARGSUSED*/ -static int -filt_solisten(struct knote *kn, long hint) -{ - struct socket *so = kn->kn_fp->f_data; - - kn->kn_data = so->so_qlen; - return (!TAILQ_EMPTY(>so_comp)); -} - int socheckuid(struct socket *so, uid_t uid) { ___ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"