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 --- |