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
This commit is contained in:
parent
2140d9c83b
commit
9537bb47b7
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user