sctp_usrreq.c (168124) | sctp_usrreq.c (168299) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_usrreq.c,v 1.48 2005/03/07 23:26:08 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 168124 2007-03-31 11:47:30Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 168299 2007-04-03 11:15:32Z rrs $"); |
35#include <netinet/sctp_os.h> 36#include <sys/proc.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctp_header.h> 39#include <netinet/sctp_var.h> 40#if defined(INET6) 41#include <netinet6/sctp6_var.h> 42#endif 43#include <netinet/sctp_sysctl.h> 44#include <netinet/sctp_output.h> | 35#include <netinet/sctp_os.h> 36#include <sys/proc.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctp_header.h> 39#include <netinet/sctp_var.h> 40#if defined(INET6) 41#include <netinet6/sctp6_var.h> 42#endif 43#include <netinet/sctp_sysctl.h> 44#include <netinet/sctp_output.h> |
45#include <netinet/sctp_bsd_addr.h> | |
46#include <netinet/sctp_uio.h> 47#include <netinet/sctp_asconf.h> 48#include <netinet/sctputil.h> 49#include <netinet/sctp_indata.h> 50#include <netinet/sctp_timer.h> 51#include <netinet/sctp_auth.h> 52 53 --- 243 unchanged lines hidden (view full) --- 297 int cmd; 298 struct sockaddr *sa; 299 void *vip; 300{ 301 struct ip *ip = vip; 302 struct sctphdr *sh; 303 uint32_t vrf_id; 304 | 45#include <netinet/sctp_uio.h> 46#include <netinet/sctp_asconf.h> 47#include <netinet/sctputil.h> 48#include <netinet/sctp_indata.h> 49#include <netinet/sctp_timer.h> 50#include <netinet/sctp_auth.h> 51 52 --- 243 unchanged lines hidden (view full) --- 296 int cmd; 297 struct sockaddr *sa; 298 void *vip; 299{ 300 struct ip *ip = vip; 301 struct sctphdr *sh; 302 uint32_t vrf_id; 303 |
304 /* FIX, for non-bsd is this right? */ |
|
305 vrf_id = SCTP_DEFAULT_VRFID; 306 if (sa->sa_family != AF_INET || 307 ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { 308 return; 309 } 310 if (PRC_IS_REDIRECT(cmd)) { 311 ip = 0; 312 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) { --- 57 unchanged lines hidden (view full) --- 370 struct xucred xuc; 371 struct sockaddr_in addrs[2]; 372 struct sctp_inpcb *inp; 373 struct sctp_nets *net; 374 struct sctp_tcb *stcb; 375 int error; 376 uint32_t vrf_id; 377 | 305 vrf_id = SCTP_DEFAULT_VRFID; 306 if (sa->sa_family != AF_INET || 307 ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { 308 return; 309 } 310 if (PRC_IS_REDIRECT(cmd)) { 311 ip = 0; 312 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) { --- 57 unchanged lines hidden (view full) --- 370 struct xucred xuc; 371 struct sockaddr_in addrs[2]; 372 struct sctp_inpcb *inp; 373 struct sctp_nets *net; 374 struct sctp_tcb *stcb; 375 int error; 376 uint32_t vrf_id; 377 |
378 379 /* FIX, for non-bsd is this right? */ |
|
378 vrf_id = SCTP_DEFAULT_VRFID; | 380 vrf_id = SCTP_DEFAULT_VRFID; |
381 |
|
379 /* 380 * XXXRW: Other instances of getcred use SUSER_ALLOWJAIL, as socket 381 * visibility is scoped using cr_canseesocket(), which it is not 382 * here. 383 */ 384 error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, 385 SUSER_ALLOWJAIL); 386 if (error) --- 455 unchanged lines hidden (view full) --- 842 return (0); 843 } 844 } 845 SCTP_TCB_UNLOCK(stcb); 846 SCTP_INP_RUNLOCK(inp); 847 return (0); 848 } 849 /* not reached */ | 382 /* 383 * XXXRW: Other instances of getcred use SUSER_ALLOWJAIL, as socket 384 * visibility is scoped using cr_canseesocket(), which it is not 385 * here. 386 */ 387 error = priv_check_cred(req->td->td_ucred, PRIV_NETINET_GETCRED, 388 SUSER_ALLOWJAIL); 389 if (error) --- 455 unchanged lines hidden (view full) --- 845 return (0); 846 } 847 } 848 SCTP_TCB_UNLOCK(stcb); 849 SCTP_INP_RUNLOCK(inp); 850 return (0); 851 } 852 /* not reached */ |
853 printf("Not reached reached?\n"); |
|
850 } else { 851 /* UDP model does not support this */ 852 SCTP_INP_RUNLOCK(inp); 853 return EOPNOTSUPP; 854 } 855} 856 857int --- 26 unchanged lines hidden (view full) --- 884 885 stcb = LIST_FIRST(&inp->sctp_asoc_list); 886 if (stcb == NULL) { 887 /* 888 * Ok we hit the case that the shutdown call was 889 * made after an abort or something. Nothing to do 890 * now. 891 */ | 854 } else { 855 /* UDP model does not support this */ 856 SCTP_INP_RUNLOCK(inp); 857 return EOPNOTSUPP; 858 } 859} 860 861int --- 26 unchanged lines hidden (view full) --- 888 889 stcb = LIST_FIRST(&inp->sctp_asoc_list); 890 if (stcb == NULL) { 891 /* 892 * Ok we hit the case that the shutdown call was 893 * made after an abort or something. Nothing to do 894 * now. 895 */ |
896 SCTP_INP_RUNLOCK(inp); |
|
892 return (0); 893 } 894 SCTP_TCB_LOCK(stcb); 895 asoc = &stcb->asoc; 896 if (TAILQ_EMPTY(&asoc->send_queue) && 897 TAILQ_EMPTY(&asoc->sent_queue) && 898 (asoc->stream_queue_cnt == 0)) { 899 if (asoc->locked_on_sending) { --- 431 unchanged lines hidden (view full) --- 1331 error = EINVAL; 1332 goto out_now; 1333 } 1334 } 1335#endif /* INET6 */ 1336 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 1337 SCTP_PCB_FLAGS_UNBOUND) { 1338 /* Bind a ephemeral port */ | 897 return (0); 898 } 899 SCTP_TCB_LOCK(stcb); 900 asoc = &stcb->asoc; 901 if (TAILQ_EMPTY(&asoc->send_queue) && 902 TAILQ_EMPTY(&asoc->sent_queue) && 903 (asoc->stream_queue_cnt == 0)) { 904 if (asoc->locked_on_sending) { --- 431 unchanged lines hidden (view full) --- 1336 error = EINVAL; 1337 goto out_now; 1338 } 1339 } 1340#endif /* INET6 */ 1341 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 1342 SCTP_PCB_FLAGS_UNBOUND) { 1343 /* Bind a ephemeral port */ |
1339 SCTP_INP_WUNLOCK(inp); | |
1340 error = sctp_inpcb_bind(so, NULL, p); 1341 if (error) { 1342 goto out_now; 1343 } | 1344 error = sctp_inpcb_bind(so, NULL, p); 1345 if (error) { 1346 goto out_now; 1347 } |
1344 } else { 1345 SCTP_INP_WUNLOCK(inp); | |
1346 } | 1348 } |
1347 | |
1348 /* FIX ME: do we want to pass in a vrf on the connect call? */ 1349 vrf_id = inp->def_vrf_id; 1350 1351 /* We are GOOD to go */ 1352 stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id); 1353 if (stcb == NULL) { 1354 /* Gak! no memory */ 1355 goto out_now; --- 890 unchanged lines hidden (view full) --- 2246 2247 SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize); 2248 2249 SCTP_INP_RLOCK(inp); 2250 hmaclist = inp->sctp_ep.local_hmacs; 2251 if (hmaclist == NULL) { 2252 /* no HMACs to return */ 2253 *optsize = sizeof(*shmac); | 1349 /* FIX ME: do we want to pass in a vrf on the connect call? */ 1350 vrf_id = inp->def_vrf_id; 1351 1352 /* We are GOOD to go */ 1353 stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id); 1354 if (stcb == NULL) { 1355 /* Gak! no memory */ 1356 goto out_now; --- 890 unchanged lines hidden (view full) --- 2247 2248 SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize); 2249 2250 SCTP_INP_RLOCK(inp); 2251 hmaclist = inp->sctp_ep.local_hmacs; 2252 if (hmaclist == NULL) { 2253 /* no HMACs to return */ 2254 *optsize = sizeof(*shmac); |
2255 SCTP_INP_RUNLOCK(inp); |
|
2254 break; 2255 } 2256 /* is there room for all of the hmac ids? */ 2257 size = sizeof(*shmac) + (hmaclist->num_algo * 2258 sizeof(shmac->shmac_idents[0])); 2259 if ((size_t)(*optsize) < size) { 2260 error = EINVAL; 2261 SCTP_INP_RUNLOCK(inp); --- 115 unchanged lines hidden (view full) --- 2377 printf("optval is NULL\n"); 2378 return (EINVAL); 2379 } 2380 inp = (struct sctp_inpcb *)so->so_pcb; 2381 if (inp == 0) { 2382 printf("inp is NULL?\n"); 2383 return EINVAL; 2384 } | 2256 break; 2257 } 2258 /* is there room for all of the hmac ids? */ 2259 size = sizeof(*shmac) + (hmaclist->num_algo * 2260 sizeof(shmac->shmac_idents[0])); 2261 if ((size_t)(*optsize) < size) { 2262 error = EINVAL; 2263 SCTP_INP_RUNLOCK(inp); --- 115 unchanged lines hidden (view full) --- 2379 printf("optval is NULL\n"); 2380 return (EINVAL); 2381 } 2382 inp = (struct sctp_inpcb *)so->so_pcb; 2383 if (inp == 0) { 2384 printf("inp is NULL?\n"); 2385 return EINVAL; 2386 } |
2385 vrf_id = SCTP_DEFAULT_VRFID; | 2387 vrf_id = inp->def_vrf_id; |
2386 2387 error = 0; 2388 switch (optname) { 2389 case SCTP_NODELAY: 2390 case SCTP_AUTOCLOSE: 2391 case SCTP_AUTO_ASCONF: 2392 case SCTP_EXPLICIT_EOR: 2393 case SCTP_DISABLE_FRAGMENTS: --- 1156 unchanged lines hidden (view full) --- 3550 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 3551 /* We are already connected AND the TCP model */ 3552 error = EADDRINUSE; 3553 goto out_now; 3554 } 3555 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3556 SCTP_INP_RLOCK(inp); 3557 stcb = LIST_FIRST(&inp->sctp_asoc_list); | 2388 2389 error = 0; 2390 switch (optname) { 2391 case SCTP_NODELAY: 2392 case SCTP_AUTOCLOSE: 2393 case SCTP_AUTO_ASCONF: 2394 case SCTP_EXPLICIT_EOR: 2395 case SCTP_DISABLE_FRAGMENTS: --- 1156 unchanged lines hidden (view full) --- 3552 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 3553 /* We are already connected AND the TCP model */ 3554 error = EADDRINUSE; 3555 goto out_now; 3556 } 3557 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 3558 SCTP_INP_RLOCK(inp); 3559 stcb = LIST_FIRST(&inp->sctp_asoc_list); |
3558 if (stcb) 3559 SCTP_TCB_UNLOCK(stcb); | |
3560 SCTP_INP_RUNLOCK(inp); 3561 } else { 3562 /* 3563 * We increment here since sctp_findassociation_ep_addr() 3564 * wil do a decrement if it finds the stcb as long as the 3565 * locked tcb (last argument) is NOT a TCB.. aka NULL. 3566 */ 3567 SCTP_INP_INCR_REF(inp); 3568 stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 3569 if (stcb == NULL) { 3570 SCTP_INP_DECR_REF(inp); | 3560 SCTP_INP_RUNLOCK(inp); 3561 } else { 3562 /* 3563 * We increment here since sctp_findassociation_ep_addr() 3564 * wil do a decrement if it finds the stcb as long as the 3565 * locked tcb (last argument) is NOT a TCB.. aka NULL. 3566 */ 3567 SCTP_INP_INCR_REF(inp); 3568 stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 3569 if (stcb == NULL) { 3570 SCTP_INP_DECR_REF(inp); |
3571 } else { 3572 SCTP_TCB_LOCK(stcb); |
|
3571 } 3572 } 3573 if (stcb != NULL) { 3574 /* Already have or am bring up an association */ 3575 error = EALREADY; 3576 goto out_now; 3577 } | 3573 } 3574 } 3575 if (stcb != NULL) { 3576 /* Already have or am bring up an association */ 3577 error = EALREADY; 3578 goto out_now; 3579 } |
3578 vrf_id = SCTP_DEFAULT_VRFID; | 3580 vrf_id = inp->def_vrf_id; |
3579 /* We are GOOD to go */ 3580 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id); 3581 if (stcb == NULL) { 3582 /* Gak! no memory */ 3583 goto out_now; 3584 } 3585 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 3586 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 3587 /* Set the connected flag so we can queue data */ 3588 soisconnecting(so); 3589 } 3590 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT; 3591 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 3592 3593 /* initialize authentication parameters for the assoc */ 3594 sctp_initialize_auth_params(inp, stcb); 3595 3596 sctp_send_initiate(inp, stcb); | 3581 /* We are GOOD to go */ 3582 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf_id); 3583 if (stcb == NULL) { 3584 /* Gak! no memory */ 3585 goto out_now; 3586 } 3587 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 3588 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 3589 /* Set the connected flag so we can queue data */ 3590 soisconnecting(so); 3591 } 3592 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT; 3593 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 3594 3595 /* initialize authentication parameters for the assoc */ 3596 sctp_initialize_auth_params(inp, stcb); 3597 3598 sctp_send_initiate(inp, stcb); |
3599 SCTP_TCB_UNLOCK(stcb); |
|
3597out_now: 3598 if (create_lock_on) 3599 SCTP_ASOC_CREATE_UNLOCK(inp); 3600 | 3600out_now: 3601 if (create_lock_on) 3602 SCTP_ASOC_CREATE_UNLOCK(inp); 3603 |
3601 if (stcb) 3602 SCTP_TCB_UNLOCK(stcb); | |
3603 SCTP_INP_DECR_REF(inp); 3604 return error; 3605} 3606 3607int 3608sctp_listen(struct socket *so, int backlog, struct thread *p) 3609{ 3610 /* --- 70 unchanged lines hidden (view full) --- 3681 3682 inp = (struct sctp_inpcb *)so->so_pcb; 3683 3684 if (inp == 0) { 3685 return (ECONNRESET); 3686 } 3687 SCTP_INP_RLOCK(inp); 3688 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { | 3604 SCTP_INP_DECR_REF(inp); 3605 return error; 3606} 3607 3608int 3609sctp_listen(struct socket *so, int backlog, struct thread *p) 3610{ 3611 /* --- 70 unchanged lines hidden (view full) --- 3682 3683 inp = (struct sctp_inpcb *)so->so_pcb; 3684 3685 if (inp == 0) { 3686 return (ECONNRESET); 3687 } 3688 SCTP_INP_RLOCK(inp); 3689 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { |
3690 SCTP_INP_RUNLOCK(inp); |
|
3689 return (ENOTSUP); 3690 } 3691 if (so->so_state & SS_ISDISCONNECTED) { 3692 SCTP_INP_RUNLOCK(inp); 3693 return (ECONNABORTED); 3694 } 3695 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3696 if (stcb == NULL) { --- 106 unchanged lines hidden (view full) --- 3803 break; 3804 } 3805 } 3806 if ((!fnd) || (sin_a == NULL)) { 3807 /* punt */ 3808 SCTP_TCB_UNLOCK(stcb); 3809 goto notConn; 3810 } | 3691 return (ENOTSUP); 3692 } 3693 if (so->so_state & SS_ISDISCONNECTED) { 3694 SCTP_INP_RUNLOCK(inp); 3695 return (ECONNABORTED); 3696 } 3697 stcb = LIST_FIRST(&inp->sctp_asoc_list); 3698 if (stcb == NULL) { --- 106 unchanged lines hidden (view full) --- 3805 break; 3806 } 3807 } 3808 if ((!fnd) || (sin_a == NULL)) { 3809 /* punt */ 3810 SCTP_TCB_UNLOCK(stcb); 3811 goto notConn; 3812 } |
3811 vrf_id = SCTP_DEFAULT_VRFID; 3812 | 3813 vrf_id = inp->def_vrf_id; |
3813 sctp_ifa = sctp_source_address_selection(inp, 3814 stcb, | 3814 sctp_ifa = sctp_source_address_selection(inp, 3815 stcb, |
3815 (struct route *)&net->ro, | 3816 (sctp_route_t *) & net->ro, |
3816 net, 0, vrf_id); 3817 if (sctp_ifa) { 3818 sin->sin_addr = sctp_ifa->address.sin.sin_addr; 3819 sctp_free_ifa(sctp_ifa); 3820 } 3821 SCTP_TCB_UNLOCK(stcb); 3822 } else { 3823 /* For the bound all case you get back 0 */ --- 105 unchanged lines hidden --- | 3817 net, 0, vrf_id); 3818 if (sctp_ifa) { 3819 sin->sin_addr = sctp_ifa->address.sin.sin_addr; 3820 sctp_free_ifa(sctp_ifa); 3821 } 3822 SCTP_TCB_UNLOCK(stcb); 3823 } else { 3824 /* For the bound all case you get back 0 */ --- 105 unchanged lines hidden --- |