Re: svn commit: r313043 - head/sys/kern

2017-02-03 Thread Gleb Smirnoff
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

2017-02-02 Thread Hartmut.Brandt
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

2017-02-02 Thread Gleb Smirnoff
  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

2017-02-02 Thread Hartmut.Brandt
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

2017-02-02 Thread Hartmut.Brandt
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

2017-02-01 Thread Gleb Smirnoff
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

2017-02-01 Thread hiren panchasara
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

2017-02-01 Thread Hartmut Brandt
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"