udp6_usrreq.c (a63915c2d7ff177ce364488f86eff99949402051) udp6_usrreq.c (4a91aa8fc9b626834dec65629decf48d1e3d5036)
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Copyright (c) 2010-2011 Juniper Networks, Inc.
6 * Copyright (c) 2014 Kevin Lo
7 * All rights reserved.
8 *

--- 1129 unchanged lines hidden (view full) ---

1138}
1139
1140static int
1141udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
1142{
1143 struct inpcb *inp;
1144 struct inpcbinfo *pcbinfo;
1145 int error;
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Copyright (c) 2010-2011 Juniper Networks, Inc.
6 * Copyright (c) 2014 Kevin Lo
7 * All rights reserved.
8 *

--- 1129 unchanged lines hidden (view full) ---

1138}
1139
1140static int
1141udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
1142{
1143 struct inpcb *inp;
1144 struct inpcbinfo *pcbinfo;
1145 int error;
1146 u_char vflagsav;
1146
1147 pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1148 inp = sotoinpcb(so);
1149 KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
1150
1151 INP_WLOCK(inp);
1152 INP_HASH_WLOCK(pcbinfo);
1147
1148 pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1149 inp = sotoinpcb(so);
1150 KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
1151
1152 INP_WLOCK(inp);
1153 INP_HASH_WLOCK(pcbinfo);
1154 vflagsav = inp->inp_vflag;
1153 inp->inp_vflag &= ~INP_IPV4;
1154 inp->inp_vflag |= INP_IPV6;
1155 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
1156 struct sockaddr_in6 *sin6_p;
1157
1158 sin6_p = (struct sockaddr_in6 *)nam;
1159
1160 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))

--- 11 unchanged lines hidden (view full) ---

1172 }
1173#endif
1174 }
1175
1176 error = in6_pcbbind(inp, nam, td->td_ucred);
1177#ifdef INET
1178out:
1179#endif
1155 inp->inp_vflag &= ~INP_IPV4;
1156 inp->inp_vflag |= INP_IPV6;
1157 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
1158 struct sockaddr_in6 *sin6_p;
1159
1160 sin6_p = (struct sockaddr_in6 *)nam;
1161
1162 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))

--- 11 unchanged lines hidden (view full) ---

1174 }
1175#endif
1176 }
1177
1178 error = in6_pcbbind(inp, nam, td->td_ucred);
1179#ifdef INET
1180out:
1181#endif
1182 if (error != 0)
1183 inp->inp_vflag = vflagsav;
1180 INP_HASH_WUNLOCK(pcbinfo);
1181 INP_WUNLOCK(inp);
1182 return (error);
1183}
1184
1185static void
1186udp6_close(struct socket *so)
1187{

--- 30 unchanged lines hidden (view full) ---

1218
1219static int
1220udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
1221{
1222 struct inpcb *inp;
1223 struct inpcbinfo *pcbinfo;
1224 struct sockaddr_in6 *sin6;
1225 int error;
1184 INP_HASH_WUNLOCK(pcbinfo);
1185 INP_WUNLOCK(inp);
1186 return (error);
1187}
1188
1189static void
1190udp6_close(struct socket *so)
1191{

--- 30 unchanged lines hidden (view full) ---

1222
1223static int
1224udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
1225{
1226 struct inpcb *inp;
1227 struct inpcbinfo *pcbinfo;
1228 struct sockaddr_in6 *sin6;
1229 int error;
1230 u_char vflagsav;
1226
1227 pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1228 inp = sotoinpcb(so);
1229 sin6 = (struct sockaddr_in6 *)nam;
1230 KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
1231
1232 /*
1233 * XXXRW: Need to clarify locking of v4/v6 flags.

--- 11 unchanged lines hidden (view full) ---

1245 error = EAFNOSUPPORT;
1246 goto out;
1247 }
1248 if (inp->inp_faddr.s_addr != INADDR_ANY) {
1249 error = EISCONN;
1250 goto out;
1251 }
1252 in6_sin6_2_sin(&sin, sin6);
1231
1232 pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1233 inp = sotoinpcb(so);
1234 sin6 = (struct sockaddr_in6 *)nam;
1235 KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
1236
1237 /*
1238 * XXXRW: Need to clarify locking of v4/v6 flags.

--- 11 unchanged lines hidden (view full) ---

1250 error = EAFNOSUPPORT;
1251 goto out;
1252 }
1253 if (inp->inp_faddr.s_addr != INADDR_ANY) {
1254 error = EISCONN;
1255 goto out;
1256 }
1257 in6_sin6_2_sin(&sin, sin6);
1253 inp->inp_vflag |= INP_IPV4;
1254 inp->inp_vflag &= ~INP_IPV6;
1255 error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
1256 if (error != 0)
1257 goto out;
1258 error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
1259 if (error != 0)
1260 goto out;
1261 vflagsav = inp->inp_vflag;
1262 inp->inp_vflag |= INP_IPV4;
1263 inp->inp_vflag &= ~INP_IPV6;
1258 INP_HASH_WLOCK(pcbinfo);
1259 error = in_pcbconnect(inp, (struct sockaddr *)&sin,
1260 td->td_ucred);
1261 INP_HASH_WUNLOCK(pcbinfo);
1264 INP_HASH_WLOCK(pcbinfo);
1265 error = in_pcbconnect(inp, (struct sockaddr *)&sin,
1266 td->td_ucred);
1267 INP_HASH_WUNLOCK(pcbinfo);
1268 /*
1269 * If connect succeeds, mark socket as connected. If
1270 * connect fails and socket is unbound, reset inp_vflag
1271 * field.
1272 */
1262 if (error == 0)
1263 soisconnected(so);
1273 if (error == 0)
1274 soisconnected(so);
1275 else if (inp->inp_laddr.s_addr == INADDR_ANY &&
1276 inp->inp_lport == 0)
1277 inp->inp_vflag = vflagsav;
1264 goto out;
1265 } else {
1266 if ((inp->inp_vflag & INP_IPV6) == 0) {
1267 error = EAFNOSUPPORT;
1268 goto out;
1269 }
1270 }
1271#endif
1272 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1273 error = EISCONN;
1274 goto out;
1275 }
1278 goto out;
1279 } else {
1280 if ((inp->inp_vflag & INP_IPV6) == 0) {
1281 error = EAFNOSUPPORT;
1282 goto out;
1283 }
1284 }
1285#endif
1286 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1287 error = EISCONN;
1288 goto out;
1289 }
1276 inp->inp_vflag &= ~INP_IPV4;
1277 inp->inp_vflag |= INP_IPV6;
1278 error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
1279 if (error != 0)
1280 goto out;
1290 error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
1291 if (error != 0)
1292 goto out;
1293 vflagsav = inp->inp_vflag;
1294 inp->inp_vflag &= ~INP_IPV4;
1295 inp->inp_vflag |= INP_IPV6;
1281 INP_HASH_WLOCK(pcbinfo);
1282 error = in6_pcbconnect(inp, nam, td->td_ucred);
1283 INP_HASH_WUNLOCK(pcbinfo);
1296 INP_HASH_WLOCK(pcbinfo);
1297 error = in6_pcbconnect(inp, nam, td->td_ucred);
1298 INP_HASH_WUNLOCK(pcbinfo);
1299 /*
1300 * If connect succeeds, mark socket as connected. If
1301 * connect fails and socket is unbound, reset inp_vflag
1302 * field.
1303 */
1284 if (error == 0)
1285 soisconnected(so);
1304 if (error == 0)
1305 soisconnected(so);
1306 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
1307 inp->inp_lport == 0)
1308 inp->inp_vflag = vflagsav;
1286out:
1287 INP_WUNLOCK(inp);
1288 return (error);
1289}
1290
1291static void
1292udp6_detach(struct socket *so)
1293{

--- 102 unchanged lines hidden ---
1309out:
1310 INP_WUNLOCK(inp);
1311 return (error);
1312}
1313
1314static void
1315udp6_detach(struct socket *so)
1316{

--- 102 unchanged lines hidden ---