Deleted Added
full compact
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 ---