On Tue, Oct 30, 2018 at 07:13:24AM +0000, Jason McIntyre wrote:
> On Mon, Oct 29, 2018 at 11:55:52PM +0100, Jan Klemkow wrote:
> > On Sun, Oct 28, 2018 at 10:58:34PM +0000, Jason McIntyre wrote:
> > > On Sun, Oct 28, 2018 at 09:40:33PM +0100, Jan Klemkow wrote:
> > > > Unlike the manpage saids or one might think , sendto(2) sets errno to
> > > > EHOSTUNREACH instead of EACCES in cases of blocking by pf(4) or not
> > > > enabled broadcasts.  Finally I ran into both cases and think, its time
> > > > to fix this issue.  The diff suggests a new explanation that should
> > > > cover all error cases.
> > > > 
> > > > Index: /usr/src/lib/libc/sys/send.2
> > > > ===================================================================
> > > > RCS file: /cvs/src/lib/libc/sys/send.2,v
> > > > retrieving revision 1.32
> > > > diff -u -p -r1.32 send.2
> > > > --- /usr/src/lib/libc/sys/send.2        5 Oct 2017 12:30:16 -0000       
> > > > 1.32
> > > > +++ /usr/src/lib/libc/sys/send.2        28 Oct 2018 20:16:20 -0000
> > > > @@ -161,13 +161,13 @@ The operation may succeed when buffers b
> > > >  The output queue for a network interface was full.
> > > >  This generally indicates that the interface has stopped sending,
> > > >  but may be caused by transient congestion.
> > > > -.It Bq Er EACCES
> > > > -The
> > > > -.Dv SO_BROADCAST
> > > > -option is not set on the socket, and a broadcast address
> > > > -was given as the destination.
> > > >  .It Bq Er EHOSTUNREACH
> > > > -The destination address specified an unreachable host.
> > > > +The destination address specified an host that is unreachable,
> > > 
> > > unless you're going for humour, "a host" rather than "an host".
> > > 
> > > i can;t comment on the accuracy, but the rest of the diff reads ok.
> > 
> > No humour (here in Germany), just a spelling mistakes :-)
> > Fixed version below.
> 
> morning.
> 
> to be fair, some people do still unambiguously use "an" before h* words.
> so as such it is not wrong (i think). still, our pages do not use that format.
> 
> anyway, enough of the small stuff. who wants to review this page and
> actually ok or nok it?

Hi,

I printed the code path below to make it easier to review the diff.
While I was following the code path again, I found an inconsistency
between udp_output() and upd6_output().  Just upd_output() turns EACCES
to EHOSTUNREACH, udp6_output does not.  The Diff below fixes udp6_output
and rounds up the sendto(2) manpage.

Bye,
Jan

Reviewer guide from sendto(2) to EHOSTUNREACH:

sys_sendto() -> sendit() -> sosend() ---+
                                        |
 +--------------------------------------+
 |
 +-> udp_usrreq() -> udp_output():
 |      ...
 |      error = ip_output(m, inp->inp_options, &inp->inp_route,
 |          (inp->inp_socket->so_options & SO_BROADCAST), inp->inp_moptions,
 |          inp, ipsecflowinfo);
 |      if (error == EACCES)    /* translate pf(4) error for userland */
 |              error = EHOSTUNREACH;
 |      ...
 |
 +-> udp_usrreq() -> udp6_output():
 |      ...
 |      error = ip6_output(m, optp, &in6p->inp_route6,
 |          flags, in6p->inp_moptions6, in6p);
 |      if (error == EACCES)    /* translate pf(4) error for userland */
 |              error = EHOSTUNREACH;
 |      ...
 |
 +-> tcp_usrreq() -> tcp_output():
        ...
        error = ip_output(m, tp->t_inpcb->inp_options,
                tp->t_inpcb->inp_route,
                ip_mtudisc ? IP_MTUDISC : 0), NULL, tp->t_inpcb, 0);
        ...
        error = ip6_output(m, tp->t_inpcb->inp_outputopts6,
                &tp->t_inpcb->inp_route6,
                0, NULL, tp->t_inpcb);
        ...
        if (error == EACCES)    /* translate pf(4) error for userland */
                error = EHOSTUNREACH;
        ...

Index: sys/netinet6/udp6_output.c
===================================================================
RCS file: /cvs/src/sys/netinet6/udp6_output.c,v
retrieving revision 1.56
diff -u -p -r1.56 udp6_output.c
--- sys/netinet6/udp6_output.c  13 Sep 2018 19:53:58 -0000      1.56
+++ sys/netinet6/udp6_output.c  9 Nov 2018 16:31:21 -0000
@@ -235,6 +235,8 @@ udp6_output(struct inpcb *in6p, struct m
 
        error = ip6_output(m, optp, &in6p->inp_route6,
            flags, in6p->inp_moptions6, in6p);
+       if (error == EACCES)    /* translate pf(4) error for userland */
+               error = EHOSTUNREACH;
        goto releaseopt;
 
 release:
Index: /usr/src/lib/libc/sys/send.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/send.2,v
retrieving revision 1.32
diff -u -p -r1.32 send.2
--- /usr/src/lib/libc/sys/send.2        5 Oct 2017 12:30:16 -0000       1.32
+++ /usr/src/lib/libc/sys/send.2        29 Oct 2018 22:48:24 -0000
@@ -161,13 +161,13 @@ The operation may succeed when buffers b
 The output queue for a network interface was full.
 This generally indicates that the interface has stopped sending,
 but may be caused by transient congestion.
-.It Bq Er EACCES
-The
-.Dv SO_BROADCAST
-option is not set on the socket, and a broadcast address
-was given as the destination.
 .It Bq Er EHOSTUNREACH
-The destination address specified an unreachable host.
+The destination address specified a host that is unreachable,
+blocked by
+.Xr pf 4
+or is broadcast communication which was not enabled
+via the socket option 
+.Dv SO_BROADCAST .
 .It Bq Er EINVAL
 The
 .Fa flags

Reply via email to