Author: bz
Date: Sat Apr  9 01:29:46 2011
New Revision: 220462
URL: http://svn.freebsd.org/changeset/base/220462

Log:
  After r219579 and r219779 unbreak v4-mapped v6 sockets for UDP
  some more.  Similar to what we do for TCP check for v4-mapped
  addresses and then handle them or the normal v6 address case.
  For either set inp_vflags before calling into the pcb connect
  function so that we have an unambiguous view in case we need to
  set the local address or port.
  
  Looked at:    tuexen (as part of more)
  MFC after:    3 days

Modified:
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c     Fri Apr  8 21:27:31 2011        
(r220461)
+++ head/sys/netinet6/udp6_usrreq.c     Sat Apr  9 01:29:46 2011        
(r220462)
@@ -909,43 +909,41 @@ udp6_connect(struct socket *so, struct s
 
        INP_INFO_WLOCK(&V_udbinfo);
        INP_WLOCK(inp);
-       if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
-           IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+       if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
                struct sockaddr_in sin;
 
+               if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
+                       error = EINVAL;
+                       goto out;
+               }
                if (inp->inp_faddr.s_addr != INADDR_ANY) {
                        error = EISCONN;
                        goto out;
                }
                in6_sin6_2_sin(&sin, sin6);
+               inp->inp_vflag |= INP_IPV4;
+               inp->inp_vflag &= ~INP_IPV6;
                error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
                if (error != 0)
                        goto out;
                error = in_pcbconnect(inp, (struct sockaddr *)&sin,
                    td->td_ucred);
-               if (error == 0) {
-                       inp->inp_vflag |= INP_IPV4;
-                       inp->inp_vflag &= ~INP_IPV6;
+               if (error == 0)
                        soisconnected(so);
-               }
                goto out;
        }
        if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
                error = EISCONN;
                goto out;
        }
+       inp->inp_vflag &= ~INP_IPV4;
+       inp->inp_vflag |= INP_IPV6;
        error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
        if (error != 0)
                goto out;
        error = in6_pcbconnect(inp, nam, td->td_ucred);
-       if (error == 0) {
-               if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
-                       /* should be non mapped addr */
-                       inp->inp_vflag &= ~INP_IPV4;
-                       inp->inp_vflag |= INP_IPV6;
-               }
+       if (error == 0)
                soisconnected(so);
-       }
 out:
        INP_WUNLOCK(inp);
        INP_INFO_WUNLOCK(&V_udbinfo);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to