Re: in_pcbbind() and in_broadcast/in_iawithaddr

2014-06-04 Thread Mike Belopuhov
On 3 June 2014 09:18, Martin Pieuchot mpieuc...@nolizard.org wrote:
 On 02/06/14(Mon) 15:45, Martin Pieuchot wrote:
 This diff is similar to the one that has been committed to handle the
 SOCK_RAW binding.  I'd like to stop using in_iawithaddr() *and*
 in_broadcast().  Since these functions are just doing an iteration on
 all the addresses present in the RB-tree (or equivalent), let's use
 ifa_ifwithaddr() instead.

 This diff should not introduce any behavior change concerning SOCK_DGRAM
 and binding to multicast addresses.

 As pointed out by jca@ this diff breaks on loopback.  This is because
 the loopback IPv4 addresses are abusing the dstaddr field to be able to
 create a route to their address.  Hopefully this hack can be removed
 once the local route diff is in, but in the meantime let's use the less
 intuitive but equivalent idiom:

 sin-sin_addr.s_addr != ia-ia_addr.s_addr

 Update diff below, is this one ok?


OK



Re: in_pcbbind() and in_broadcast/in_iawithaddr

2014-06-03 Thread Martin Pieuchot
On 02/06/14(Mon) 15:45, Martin Pieuchot wrote:
 This diff is similar to the one that has been committed to handle the
 SOCK_RAW binding.  I'd like to stop using in_iawithaddr() *and*
 in_broadcast().  Since these functions are just doing an iteration on
 all the addresses present in the RB-tree (or equivalent), let's use
 ifa_ifwithaddr() instead.
 
 This diff should not introduce any behavior change concerning SOCK_DGRAM
 and binding to multicast addresses.

As pointed out by jca@ this diff breaks on loopback.  This is because
the loopback IPv4 addresses are abusing the dstaddr field to be able to
create a route to their address.  Hopefully this hack can be removed
once the local route diff is in, but in the meantime let's use the less
intuitive but equivalent idiom:

sin-sin_addr.s_addr != ia-ia_addr.s_addr

Update diff below, is this one ok?

Index: netinet/in_pcb.c
===
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.155
diff -u -p -r1.155 in_pcb.c
--- netinet/in_pcb.c7 May 2014 08:26:38 -   1.155
+++ netinet/in_pcb.c3 Jun 2014 07:12:53 -
@@ -261,14 +261,22 @@ in_pcbbind(struct inpcb *inp, struct mbu
reuseport = SO_REUSEADDR|SO_REUSEPORT;
} else if (sin-sin_addr.s_addr != INADDR_ANY) {
sin-sin_port = 0;  /* yech... */
-   if (!(so-so_options  SO_BINDANY) 
-   in_iawithaddr(sin-sin_addr,
-   inp-inp_rtableid) == NULL)
+   if (!((so-so_options  SO_BINDANY) ||
+   (sin-sin_addr.s_addr == INADDR_BROADCAST 
+so-so_type == SOCK_DGRAM))) {
+   struct in_ifaddr *ia;
+
+   ia = ifatoia(ifa_ifwithaddr(sintosa(sin),
+   inp-inp_rtableid));
+   if (ia == NULL)
+return (EADDRNOTAVAIL);
+
/* SOCK_RAW does not use in_pcbbind() */
-   if (!(so-so_type == SOCK_DGRAM 
-   in_broadcast(sin-sin_addr, NULL,
-   inp-inp_rtableid)))
-   return (EADDRNOTAVAIL);
+   if (so-so_type != SOCK_DGRAM 
+   sin-sin_addr.s_addr !=
+   ia-ia_addr.sin_addr.s_addr)
+return (EADDRNOTAVAIL);
+   }
}
if (lport) {
struct inpcb *t;



Re: in_pcbbind() and in_broadcast/in_iawithaddr

2014-06-03 Thread Jérémie Courrèges-Anglas
Martin Pieuchot mpieuc...@nolizard.org writes:

[...]

 Update diff below, is this one ok?

Looks correct; ok.

[...]

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



in_pcbbind() and in_broadcast/in_iawithaddr

2014-06-02 Thread Martin Pieuchot
This diff is similar to the one that has been committed to handle the
SOCK_RAW binding.  I'd like to stop using in_iawithaddr() *and*
in_broadcast().  Since these functions are just doing an iteration on
all the addresses present in the RB-tree (or equivalent), let's use
ifa_ifwithaddr() instead.

This diff should not introduce any behavior change concerning SOCK_DGRAM
and binding to multicast addresses.

Ok?

Index: netinet/in_pcb.c
===
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.155
diff -u -p -r1.155 in_pcb.c
--- netinet/in_pcb.c7 May 2014 08:26:38 -   1.155
+++ netinet/in_pcb.c2 Jun 2014 13:37:59 -
@@ -261,14 +261,19 @@ in_pcbbind(struct inpcb *inp, struct mbu
reuseport = SO_REUSEADDR|SO_REUSEPORT;
} else if (sin-sin_addr.s_addr != INADDR_ANY) {
sin-sin_port = 0;  /* yech... */
-   if (!(so-so_options  SO_BINDANY) 
-   in_iawithaddr(sin-sin_addr,
-   inp-inp_rtableid) == NULL)
+   if (!((so-so_options  SO_BINDANY) ||
+   (sin-sin_addr.s_addr == INADDR_BROADCAST 
+so-so_type == SOCK_DGRAM))) {
+   struct in_ifaddr *ia;
+
+   ia = ifatoia(ifa_ifwithaddr(sintosa(sin),
+   inp-inp_rtableid));
/* SOCK_RAW does not use in_pcbbind() */
-   if (!(so-so_type == SOCK_DGRAM 
-   in_broadcast(sin-sin_addr, NULL,
-   inp-inp_rtableid)))
-   return (EADDRNOTAVAIL);
+   if (ia == NULL || (sin-sin_addr.s_addr ==
+   ia-ia_broadaddr.sin_addr.s_addr 
+   so-so_type != SOCK_DGRAM))
+return (EADDRNOTAVAIL);
+   }
}
if (lport) {
struct inpcb *t;