udp6_usrreq.c (96972) | udp6_usrreq.c (97658) |
---|---|
1/* $FreeBSD: head/sys/netinet6/udp6_usrreq.c 96972 2002-05-20 05:41:09Z tanimura $ */ | 1/* $FreeBSD: head/sys/netinet6/udp6_usrreq.c 97658 2002-05-31 11:52:35Z tanimura $ */ |
2/* $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 254 unchanged lines hidden (view full) --- 264 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 265 /* 266 * KAME NOTE: do not 267 * m_copy(m, offset, ...) above. 268 * sbappendaddr() expects M_PKTHDR, 269 * and m_copy() will copy M_PKTHDR 270 * only if offset is 0. 271 */ | 2/* $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 254 unchanged lines hidden (view full) --- 264 if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { 265 /* 266 * KAME NOTE: do not 267 * m_copy(m, offset, ...) above. 268 * sbappendaddr() expects M_PKTHDR, 269 * and m_copy() will copy M_PKTHDR 270 * only if offset is 0. 271 */ |
272 if (last->in6p_flags & IN6P_CONTROLOPTS) | 272 if (last->in6p_flags & IN6P_CONTROLOPTS 273 || last->in6p_socket->so_options & SO_TIMESTAMP) |
273 ip6_savecontrol(last, &opts, 274 ip6, n); | 274 ip6_savecontrol(last, &opts, 275 ip6, n); |
275 else { 276 SOCK_LOCK(last->in6p_socket); 277 if (last->in6p_socket->so_options & SO_TIMESTAMP) { 278 SOCK_UNLOCK(last->in6p_socket); 279 ip6_savecontrol(last, &opts, 280 ip6, n); 281 } else 282 SOCK_UNLOCK(last->in6p_socket); 283 } | |
284 285 m_adj(n, off + sizeof(struct udphdr)); 286 if (sbappendaddr(&last->in6p_socket->so_rcv, 287 (struct sockaddr *)&udp_in6, 288 n, opts) == 0) { 289 m_freem(n); 290 if (opts) 291 m_freem(opts); 292 udpstat.udps_fullsock++; | 276 277 m_adj(n, off + sizeof(struct udphdr)); 278 if (sbappendaddr(&last->in6p_socket->so_rcv, 279 (struct sockaddr *)&udp_in6, 280 n, opts) == 0) { 281 m_freem(n); 282 if (opts) 283 m_freem(opts); 284 udpstat.udps_fullsock++; |
293 } else { 294 SOCK_LOCK(last->in6p_socket); | 285 } else |
295 sorwakeup(last->in6p_socket); | 286 sorwakeup(last->in6p_socket); |
296 SOCK_UNLOCK(last->in6p_socket); 297 } | |
298 opts = NULL; 299 } 300 } 301 last = in6p; 302 /* 303 * Don't look for additional matches if this one does 304 * not have either the SO_REUSEPORT or SO_REUSEADDR 305 * socket options set. This heuristic avoids searching 306 * through all pcbs in the common case of a non-shared 307 * port. It assumes that an application will never 308 * clear these options after setting them. 309 */ | 287 opts = NULL; 288 } 289 } 290 last = in6p; 291 /* 292 * Don't look for additional matches if this one does 293 * not have either the SO_REUSEPORT or SO_REUSEADDR 294 * socket options set. This heuristic avoids searching 295 * through all pcbs in the common case of a non-shared 296 * port. It assumes that an application will never 297 * clear these options after setting them. 298 */ |
310 SOCK_LOCK(last->in6p_socket); | |
311 if ((last->in6p_socket->so_options & | 299 if ((last->in6p_socket->so_options & |
312 (SO_REUSEPORT|SO_REUSEADDR)) == 0) { 313 SOCK_UNLOCK(last->in6p_socket); | 300 (SO_REUSEPORT|SO_REUSEADDR)) == 0) |
314 break; | 301 break; |
315 } else 316 SOCK_UNLOCK(last->in6p_socket); | |
317 } 318 319 if (last == NULL) { 320 /* 321 * No matching pcb found; discard datagram. 322 * (No need to send an ICMP Port Unreachable 323 * for a broadcast or multicast datgram.) 324 */ --- 5 unchanged lines hidden (view full) --- 330 /* 331 * Check AH/ESP integrity. 332 */ 333 if (ipsec6_in_reject_so(m, last->inp_socket)) { 334 ipsec6stat.in_polvio++; 335 goto bad; 336 } 337#endif /* IPSEC */ | 302 } 303 304 if (last == NULL) { 305 /* 306 * No matching pcb found; discard datagram. 307 * (No need to send an ICMP Port Unreachable 308 * for a broadcast or multicast datgram.) 309 */ --- 5 unchanged lines hidden (view full) --- 315 /* 316 * Check AH/ESP integrity. 317 */ 318 if (ipsec6_in_reject_so(m, last->inp_socket)) { 319 ipsec6stat.in_polvio++; 320 goto bad; 321 } 322#endif /* IPSEC */ |
338 if (last->in6p_flags & IN6P_CONTROLOPTS) | 323 if (last->in6p_flags & IN6P_CONTROLOPTS 324 || last->in6p_socket->so_options & SO_TIMESTAMP) |
339 ip6_savecontrol(last, &opts, ip6, m); | 325 ip6_savecontrol(last, &opts, ip6, m); |
340 else { 341 SOCK_LOCK(last->in6p_socket); 342 if (last->in6p_socket->so_options & SO_TIMESTAMP) { 343 SOCK_UNLOCK(last->in6p_socket); 344 ip6_savecontrol(last, &opts, ip6, m); 345 } else 346 SOCK_UNLOCK(last->in6p_socket); 347 } | |
348 349 m_adj(m, off + sizeof(struct udphdr)); 350 if (sbappendaddr(&last->in6p_socket->so_rcv, 351 (struct sockaddr *)&udp_in6, 352 m, opts) == 0) { 353 udpstat.udps_fullsock++; 354 goto bad; 355 } | 326 327 m_adj(m, off + sizeof(struct udphdr)); 328 if (sbappendaddr(&last->in6p_socket->so_rcv, 329 (struct sockaddr *)&udp_in6, 330 m, opts) == 0) { 331 udpstat.udps_fullsock++; 332 goto bad; 333 } |
356 SOCK_LOCK(last->in6p_socket); | |
357 sorwakeup(last->in6p_socket); | 334 sorwakeup(last->in6p_socket); |
358 SOCK_UNLOCK(last->in6p_socket); | |
359 return IPPROTO_DONE; 360 } 361 /* 362 * Locate pcb for datagram. 363 */ 364 in6p = in6_pcblookup_hash(&udbinfo, &ip6->ip6_src, uh->uh_sport, 365 &ip6->ip6_dst, uh->uh_dport, 1, 366 m->m_pkthdr.rcvif); --- 27 unchanged lines hidden (view full) --- 394#endif /* IPSEC */ 395 396 /* 397 * Construct sockaddr format source address. 398 * Stuff source address and datagram in user buffer. 399 */ 400 init_sin6(&udp_in6, m); /* general init */ 401 udp_in6.sin6_port = uh->uh_sport; | 335 return IPPROTO_DONE; 336 } 337 /* 338 * Locate pcb for datagram. 339 */ 340 in6p = in6_pcblookup_hash(&udbinfo, &ip6->ip6_src, uh->uh_sport, 341 &ip6->ip6_dst, uh->uh_dport, 1, 342 m->m_pkthdr.rcvif); --- 27 unchanged lines hidden (view full) --- 370#endif /* IPSEC */ 371 372 /* 373 * Construct sockaddr format source address. 374 * Stuff source address and datagram in user buffer. 375 */ 376 init_sin6(&udp_in6, m); /* general init */ 377 udp_in6.sin6_port = uh->uh_sport; |
402 if (in6p->in6p_flags & IN6P_CONTROLOPTS) | 378 if (in6p->in6p_flags & IN6P_CONTROLOPTS 379 || in6p->in6p_socket->so_options & SO_TIMESTAMP) |
403 ip6_savecontrol(in6p, &opts, ip6, m); | 380 ip6_savecontrol(in6p, &opts, ip6, m); |
404 else { 405 SOCK_LOCK(in6p->in6p_socket); 406 if (in6p->in6p_socket->so_options & SO_TIMESTAMP) { 407 SOCK_UNLOCK(in6p->in6p_socket); 408 ip6_savecontrol(in6p, &opts, ip6, m); 409 } else 410 SOCK_UNLOCK(in6p->in6p_socket); 411 } | |
412 m_adj(m, off + sizeof(struct udphdr)); 413 if (sbappendaddr(&in6p->in6p_socket->so_rcv, 414 (struct sockaddr *)&udp_in6, 415 m, opts) == 0) { 416 udpstat.udps_fullsock++; 417 goto bad; 418 } | 381 m_adj(m, off + sizeof(struct udphdr)); 382 if (sbappendaddr(&in6p->in6p_socket->so_rcv, 383 (struct sockaddr *)&udp_in6, 384 m, opts) == 0) { 385 udpstat.udps_fullsock++; 386 goto bad; 387 } |
419 SOCK_LOCK(in6p->in6p_socket); | |
420 sorwakeup(in6p->in6p_socket); | 388 sorwakeup(in6p->in6p_socket); |
421 SOCK_UNLOCK(in6p->in6p_socket); | |
422 return IPPROTO_DONE; 423bad: 424 if (m) 425 m_freem(m); 426 if (opts) 427 m_freem(opts); 428 return IPPROTO_DONE; 429} --- 107 unchanged lines hidden (view full) --- 537udp6_abort(struct socket *so) 538{ 539 struct inpcb *inp; 540 int s; 541 542 inp = sotoinpcb(so); 543 if (inp == 0) 544 return EINVAL; /* ??? possible? panic instead? */ | 389 return IPPROTO_DONE; 390bad: 391 if (m) 392 m_freem(m); 393 if (opts) 394 m_freem(opts); 395 return IPPROTO_DONE; 396} --- 107 unchanged lines hidden (view full) --- 504udp6_abort(struct socket *so) 505{ 506 struct inpcb *inp; 507 int s; 508 509 inp = sotoinpcb(so); 510 if (inp == 0) 511 return EINVAL; /* ??? possible? panic instead? */ |
545 SOCK_LOCK(so); | |
546 soisdisconnected(so); | 512 soisdisconnected(so); |
547 SOCK_UNLOCK(so); | |
548 s = splnet(); 549 in6_pcbdetach(inp); 550 splx(s); 551 return 0; 552} 553 554static int 555udp6_attach(struct socket *so, int proto, struct thread *td) --- 88 unchanged lines hidden (view full) --- 644 return EISCONN; 645 in6_sin6_2_sin(&sin, sin6_p); 646 s = splnet(); 647 error = in_pcbconnect(inp, (struct sockaddr *)&sin, td); 648 splx(s); 649 if (error == 0) { 650 inp->inp_vflag |= INP_IPV4; 651 inp->inp_vflag &= ~INP_IPV6; | 513 s = splnet(); 514 in6_pcbdetach(inp); 515 splx(s); 516 return 0; 517} 518 519static int 520udp6_attach(struct socket *so, int proto, struct thread *td) --- 88 unchanged lines hidden (view full) --- 609 return EISCONN; 610 in6_sin6_2_sin(&sin, sin6_p); 611 s = splnet(); 612 error = in_pcbconnect(inp, (struct sockaddr *)&sin, td); 613 splx(s); 614 if (error == 0) { 615 inp->inp_vflag |= INP_IPV4; 616 inp->inp_vflag &= ~INP_IPV6; |
652 SOCK_LOCK(so); | |
653 soisconnected(so); | 617 soisconnected(so); |
654 SOCK_UNLOCK(so); | |
655 } 656 return error; 657 } 658 } 659 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) 660 return EISCONN; 661 s = splnet(); 662 error = in6_pcbconnect(inp, nam, td); 663 splx(s); 664 if (error == 0) { 665 if (ip6_mapped_addr_on) { /* should be non mapped addr */ 666 inp->inp_vflag &= ~INP_IPV4; 667 inp->inp_vflag |= INP_IPV6; 668 } | 618 } 619 return error; 620 } 621 } 622 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) 623 return EISCONN; 624 s = splnet(); 625 error = in6_pcbconnect(inp, nam, td); 626 splx(s); 627 if (error == 0) { 628 if (ip6_mapped_addr_on) { /* should be non mapped addr */ 629 inp->inp_vflag &= ~INP_IPV4; 630 inp->inp_vflag |= INP_IPV6; 631 } |
669 SOCK_LOCK(so); | |
670 soisconnected(so); | 632 soisconnected(so); |
671 SOCK_UNLOCK(so); | |
672 } 673 return error; 674} 675 676static int 677udp6_detach(struct socket *so) 678{ 679 struct inpcb *inp; --- 27 unchanged lines hidden (view full) --- 707 708 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) 709 return ENOTCONN; 710 711 s = splnet(); 712 in6_pcbdisconnect(inp); 713 inp->in6p_laddr = in6addr_any; 714 splx(s); | 633 } 634 return error; 635} 636 637static int 638udp6_detach(struct socket *so) 639{ 640 struct inpcb *inp; --- 27 unchanged lines hidden (view full) --- 668 669 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) 670 return ENOTCONN; 671 672 s = splnet(); 673 in6_pcbdisconnect(inp); 674 inp->in6p_laddr = in6addr_any; 675 splx(s); |
715 SOCK_LOCK(so); | |
716 so->so_state &= ~SS_ISCONNECTED; /* XXX */ | 676 so->so_state &= ~SS_ISCONNECTED; /* XXX */ |
717 SOCK_UNLOCK(so); | |
718 return 0; 719} 720 721static int 722udp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 723 struct mbuf *control, struct thread *td) 724{ 725 struct inpcb *inp; --- 57 unchanged lines hidden --- | 677 return 0; 678} 679 680static int 681udp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 682 struct mbuf *control, struct thread *td) 683{ 684 struct inpcb *inp; --- 57 unchanged lines hidden --- |