summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2011-04-09 01:29:46 +0000
committerbz <bz@FreeBSD.org>2011-04-09 01:29:46 +0000
commit1710f285d41e00787d848603ddb97004fb6483dd (patch)
treef8764234490db15208c57726518cdea9113ea30a
parent65e270c51b99c45f0f2244d08ae299c1922c9815 (diff)
downloadFreeBSD-src-1710f285d41e00787d848603ddb97004fb6483dd.zip
FreeBSD-src-1710f285d41e00787d848603ddb97004fb6483dd.tar.gz
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
-rw-r--r--sys/netinet6/udp6_usrreq.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 422a9c9..b048665 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -909,43 +909,41 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
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);
OpenPOWER on IntegriCloud