Do we have test cases or a document that can be a definitive guide to UDP port re-use on FreeBSD? Including effects of INP_REUSEADDR, INP_REUSEPORT and INP_REUSEPORT_LB socket options, socket addresses, socket credentials? I can find some descriptions on the internet, but they do not seem to be complete. The effect of addresses is under-described and I do not see any mention of credentials (UIDs).

Is there a way to tell if some behavior is correct or not?
Is it all in heads of people and in the change history?

On 04/10/2022 14:46, Andriy Gapon wrote:
On 04/10/2022 14:37, Sean Bruno wrote:


On 10/3/22 04:14, Andriy Gapon wrote:

I must admit that the condition in question is fairly long and non-trivial and I cannot decipher it, but these two lines look wrong to me:

                                      (t->inp_flags2 & INP_REUSEPORT) ||
                                      (t->inp_flags2 & INP_REUSEPORT_LB) == 0) &&

I'd expect that the check would be symmetric with respect to INP_REUSEPORT and INP_REUSEPORT_LB.
The problem seems to come from 1a43cff92a20d / r334719 / D11003.


I think you are pointing at this absurd conditional?

https://cgit.freebsd.org/src/tree/sys/netinet/in_pcb.c#n1049

Besides the twisted logic, what problem are you trying to solve?

Yes, that conditional.
I pointed out the part of it that does not make sense to me.

Also, in my tests SO_REUSEPORT does not actually allow to share a port.
Test scenario:
- create a UDP socket
- setsockopt(SO_REUSEPORT)
- bind the socket to a port and wild card address
- success
- now repeat the previous steps with the same port *under a different user id*
- bind fails

I wonder if the following would be a correct change.

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index d9247f50d32b..f5e6e3932a96 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1003,6 +1003,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
      /*
       * XXX
       * This entire block sorely needs a rewrite.
+     * And a good comment describing the rationale behind the conditions.
       */
                  if (t &&
                      ((inp->inp_flags2 & INP_BINDMULTI) == 0) &&
@@ -1011,8 +1012,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp,
                       ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
                      (ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
                       ntohl(t->inp_laddr.s_addr) != INADDR_ANY ||
-                     (t->inp_flags2 & INP_REUSEPORT) ||
-                     (t->inp_flags2 & INP_REUSEPORT_LB) == 0) &&
+                     (t->inp_flags2 & (INP_REUSEPORT | INP_REUSEPORT_LB)) == 0) 
&&
                      (inp->inp_cred->cr_uid !=
                       t->inp_cred->cr_uid))
                      return (EADDRINUSE);


--
Andriy Gapon


Reply via email to