From owner-freebsd-arch Wed Feb 7 17:47:35 2001 Delivered-To: freebsd-arch@freebsd.org Received: from molly.straylight.com (molly.straylight.com [209.68.199.242]) by hub.freebsd.org (Postfix) with ESMTP id D0B2A37B491; Wed, 7 Feb 2001 17:47:15 -0800 (PST) Received: from dickie (case.straylight.com [209.68.199.244]) by molly.straylight.com (8.11.0/8.10.0) with SMTP id f181l5X04054; Wed, 7 Feb 2001 17:47:09 -0800 From: "Jonathan Graehl" To: Cc: "Jonathan Lemon" Subject: empirical results of waiting for nonblocking connect with kqueue/EVFILT_WRITE (EV_EOF is not set for timed out connections, bug?) Date: Wed, 7 Feb 2001 17:47:54 -0800 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 Importance: Normal Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG cases for the kevent returned from EVFILT_WRITE for socket whose connect returned error EWOULDBLOCK: connection failed, refused: flags=0x8001 (= EV_EOF & EV_ADD); data=0x4000 connection failed, timed out (+ any icmp response, host unreachable, host admin prohibited, etc): flags=0x1 (= EV_ADD); data=0x4000 connection succesful: flags=0x1 = EV_ADD; data=0x43e0 ( = socket buffer bytes available to write) if you want to see the particular error code (host or net unreachable, or just plain timed out) for a timed out connection, you can use getsockopt(SO_ERROR...). also getpeername can determine if the socket is connected (is there a more direct socket call to do so?) question: clearly, the event for a pending connection has these reproducible (aside from changing the socket send buffer size), undocumented values in the flags/data fields. what can be counted on (and documented) in the future? for now, i would use the test e.data != 0x4000, and make sure i don't set my socket send buffer small enough for any confusion to arise. i would think that EV_EOF should be set for timed out connections as well as refused ones, and this should be the documented criteria my suggestion would be to create a flag EV_SOERR, and change filt_soread and filt_sowrite (in sys/kern/uipc_socket.c) from: if (so->so_error) /* temporary udp error */ return (1); to: if (so->so_error) { kn->kn_flags |= EV_SOERR; kn->kn_data = so->so_error; return (1); } or, to maintain compatibility (if it is necessary to return with no indication for udp errors?), to: if (so->so_error) { if ((so->so_proto->pr_flags & PR_CONNREQUIRED)) kn->kn_flags |= EV_EOF; return (1); } (EV_EOF and/or EV_SOERR would be fine in either case, as long as there is some indication, although it would be nice to not have to getsockopt(SO_ERR,...)) larger context: static int filt_sowrite(struct knote *kn, long hint) { struct socket *so = (struct socket *)kn->kn_fp->f_data; kn->kn_data = sbspace(&so->so_snd); if (so->so_state & SS_CANTSENDMORE) { kn->kn_flags |= EV_EOF; return (1); } if (so->so_error) /* temporary udp error */ return (1); if (((so->so_state & SS_ISCONNECTED) == 0) && (so->so_proto->pr_flags & PR_CONNREQUIRED)) return (0); return (kn->kn_data >= so->so_snd.sb_lowat); } disclaimer: i only vaguely understand what's going on ;) -- Jonathan Graehl email: jonathan@graehl.org web: http://jonathan.graehl.org/ phone: 858-642-7562 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message