diff options
Diffstat (limited to 'net/sctp/socket.c')
| -rw-r--r-- | net/sctp/socket.c | 138 |
1 files changed, 97 insertions, 41 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b811691c35bf..3fe906d65069 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -57,7 +57,6 @@ | |||
| 57 | * be incorporated into the next SCTP release. | 57 | * be incorporated into the next SCTP release. |
| 58 | */ | 58 | */ |
| 59 | 59 | ||
| 60 | #include <linux/config.h> | ||
| 61 | #include <linux/types.h> | 60 | #include <linux/types.h> |
| 62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
| 63 | #include <linux/wait.h> | 62 | #include <linux/wait.h> |
| @@ -370,7 +369,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
| 370 | 369 | ||
| 371 | /* Use GFP_ATOMIC since BHs are disabled. */ | 370 | /* Use GFP_ATOMIC since BHs are disabled. */ |
| 372 | addr->v4.sin_port = ntohs(addr->v4.sin_port); | 371 | addr->v4.sin_port = ntohs(addr->v4.sin_port); |
| 373 | ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC); | 372 | ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); |
| 374 | addr->v4.sin_port = htons(addr->v4.sin_port); | 373 | addr->v4.sin_port = htons(addr->v4.sin_port); |
| 375 | sctp_write_unlock(&ep->base.addr_lock); | 374 | sctp_write_unlock(&ep->base.addr_lock); |
| 376 | sctp_local_bh_enable(); | 375 | sctp_local_bh_enable(); |
| @@ -492,6 +491,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk, | |||
| 492 | struct sctp_chunk *chunk; | 491 | struct sctp_chunk *chunk; |
| 493 | struct sctp_sockaddr_entry *laddr; | 492 | struct sctp_sockaddr_entry *laddr; |
| 494 | union sctp_addr *addr; | 493 | union sctp_addr *addr; |
| 494 | union sctp_addr saveaddr; | ||
| 495 | void *addr_buf; | 495 | void *addr_buf; |
| 496 | struct sctp_af *af; | 496 | struct sctp_af *af; |
| 497 | struct list_head *pos; | 497 | struct list_head *pos; |
| @@ -559,14 +559,26 @@ static int sctp_send_asconf_add_ip(struct sock *sk, | |||
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | retval = sctp_send_asconf(asoc, chunk); | 561 | retval = sctp_send_asconf(asoc, chunk); |
| 562 | if (retval) | ||
| 563 | goto out; | ||
| 562 | 564 | ||
| 563 | /* FIXME: After sending the add address ASCONF chunk, we | 565 | /* Add the new addresses to the bind address list with |
| 564 | * cannot append the address to the association's binding | 566 | * use_as_src set to 0. |
| 565 | * address list, because the new address may be used as the | ||
| 566 | * source of a message sent to the peer before the ASCONF | ||
| 567 | * chunk is received by the peer. So we should wait until | ||
| 568 | * ASCONF_ACK is received. | ||
| 569 | */ | 567 | */ |
| 568 | sctp_local_bh_disable(); | ||
| 569 | sctp_write_lock(&asoc->base.addr_lock); | ||
| 570 | addr_buf = addrs; | ||
| 571 | for (i = 0; i < addrcnt; i++) { | ||
| 572 | addr = (union sctp_addr *)addr_buf; | ||
| 573 | af = sctp_get_af_specific(addr->v4.sin_family); | ||
| 574 | memcpy(&saveaddr, addr, af->sockaddr_len); | ||
| 575 | saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port); | ||
| 576 | retval = sctp_add_bind_addr(bp, &saveaddr, 0, | ||
| 577 | GFP_ATOMIC); | ||
| 578 | addr_buf += af->sockaddr_len; | ||
| 579 | } | ||
| 580 | sctp_write_unlock(&asoc->base.addr_lock); | ||
| 581 | sctp_local_bh_enable(); | ||
| 570 | } | 582 | } |
| 571 | 583 | ||
| 572 | out: | 584 | out: |
| @@ -677,12 +689,15 @@ static int sctp_send_asconf_del_ip(struct sock *sk, | |||
| 677 | struct sctp_sock *sp; | 689 | struct sctp_sock *sp; |
| 678 | struct sctp_endpoint *ep; | 690 | struct sctp_endpoint *ep; |
| 679 | struct sctp_association *asoc; | 691 | struct sctp_association *asoc; |
| 692 | struct sctp_transport *transport; | ||
| 680 | struct sctp_bind_addr *bp; | 693 | struct sctp_bind_addr *bp; |
| 681 | struct sctp_chunk *chunk; | 694 | struct sctp_chunk *chunk; |
| 682 | union sctp_addr *laddr; | 695 | union sctp_addr *laddr; |
| 696 | union sctp_addr saveaddr; | ||
| 683 | void *addr_buf; | 697 | void *addr_buf; |
| 684 | struct sctp_af *af; | 698 | struct sctp_af *af; |
| 685 | struct list_head *pos; | 699 | struct list_head *pos, *pos1; |
| 700 | struct sctp_sockaddr_entry *saddr; | ||
| 686 | int i; | 701 | int i; |
| 687 | int retval = 0; | 702 | int retval = 0; |
| 688 | 703 | ||
| @@ -749,14 +764,42 @@ static int sctp_send_asconf_del_ip(struct sock *sk, | |||
| 749 | goto out; | 764 | goto out; |
| 750 | } | 765 | } |
| 751 | 766 | ||
| 752 | retval = sctp_send_asconf(asoc, chunk); | 767 | /* Reset use_as_src flag for the addresses in the bind address |
| 768 | * list that are to be deleted. | ||
| 769 | */ | ||
| 770 | sctp_local_bh_disable(); | ||
| 771 | sctp_write_lock(&asoc->base.addr_lock); | ||
| 772 | addr_buf = addrs; | ||
| 773 | for (i = 0; i < addrcnt; i++) { | ||
| 774 | laddr = (union sctp_addr *)addr_buf; | ||
| 775 | af = sctp_get_af_specific(laddr->v4.sin_family); | ||
| 776 | memcpy(&saveaddr, laddr, af->sockaddr_len); | ||
| 777 | saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port); | ||
| 778 | list_for_each(pos1, &bp->address_list) { | ||
| 779 | saddr = list_entry(pos1, | ||
| 780 | struct sctp_sockaddr_entry, | ||
| 781 | list); | ||
| 782 | if (sctp_cmp_addr_exact(&saddr->a, &saveaddr)) | ||
| 783 | saddr->use_as_src = 0; | ||
| 784 | } | ||
| 785 | addr_buf += af->sockaddr_len; | ||
| 786 | } | ||
| 787 | sctp_write_unlock(&asoc->base.addr_lock); | ||
| 788 | sctp_local_bh_enable(); | ||
| 753 | 789 | ||
| 754 | /* FIXME: After sending the delete address ASCONF chunk, we | 790 | /* Update the route and saddr entries for all the transports |
| 755 | * cannot remove the addresses from the association's bind | 791 | * as some of the addresses in the bind address list are |
| 756 | * address list, because there maybe some packet send to | 792 | * about to be deleted and cannot be used as source addresses. |
| 757 | * the delete addresses, so we should wait until ASCONF_ACK | ||
| 758 | * packet is received. | ||
| 759 | */ | 793 | */ |
| 794 | list_for_each(pos1, &asoc->peer.transport_addr_list) { | ||
| 795 | transport = list_entry(pos1, struct sctp_transport, | ||
| 796 | transports); | ||
| 797 | dst_release(transport->dst); | ||
| 798 | sctp_transport_route(transport, NULL, | ||
| 799 | sctp_sk(asoc->base.sk)); | ||
| 800 | } | ||
| 801 | |||
| 802 | retval = sctp_send_asconf(asoc, chunk); | ||
| 760 | } | 803 | } |
| 761 | out: | 804 | out: |
| 762 | return retval; | 805 | return retval; |
| @@ -1246,9 +1289,13 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
| 1246 | } | 1289 | } |
| 1247 | } | 1290 | } |
| 1248 | 1291 | ||
| 1249 | if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) | 1292 | if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { |
| 1250 | sctp_primitive_ABORT(asoc, NULL); | 1293 | struct sctp_chunk *chunk; |
| 1251 | else | 1294 | |
| 1295 | chunk = sctp_make_abort_user(asoc, NULL, 0); | ||
| 1296 | if (chunk) | ||
| 1297 | sctp_primitive_ABORT(asoc, chunk); | ||
| 1298 | } else | ||
| 1252 | sctp_primitive_SHUTDOWN(asoc, NULL); | 1299 | sctp_primitive_SHUTDOWN(asoc, NULL); |
| 1253 | } | 1300 | } |
| 1254 | 1301 | ||
| @@ -1477,8 +1524,16 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1477 | goto out_unlock; | 1524 | goto out_unlock; |
| 1478 | } | 1525 | } |
| 1479 | if (sinfo_flags & SCTP_ABORT) { | 1526 | if (sinfo_flags & SCTP_ABORT) { |
| 1527 | struct sctp_chunk *chunk; | ||
| 1528 | |||
| 1529 | chunk = sctp_make_abort_user(asoc, msg, msg_len); | ||
| 1530 | if (!chunk) { | ||
| 1531 | err = -ENOMEM; | ||
| 1532 | goto out_unlock; | ||
| 1533 | } | ||
| 1534 | |||
| 1480 | SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); | 1535 | SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); |
| 1481 | sctp_primitive_ABORT(asoc, msg); | 1536 | sctp_primitive_ABORT(asoc, chunk); |
| 1482 | err = 0; | 1537 | err = 0; |
| 1483 | goto out_unlock; | 1538 | goto out_unlock; |
| 1484 | } | 1539 | } |
| @@ -2026,13 +2081,13 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
| 2026 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | 2081 | * SPP_SACKDELAY_ENABLE, setting both will have undefined |
| 2027 | * results. | 2082 | * results. |
| 2028 | */ | 2083 | */ |
| 2029 | int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | 2084 | static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, |
| 2030 | struct sctp_transport *trans, | 2085 | struct sctp_transport *trans, |
| 2031 | struct sctp_association *asoc, | 2086 | struct sctp_association *asoc, |
| 2032 | struct sctp_sock *sp, | 2087 | struct sctp_sock *sp, |
| 2033 | int hb_change, | 2088 | int hb_change, |
| 2034 | int pmtud_change, | 2089 | int pmtud_change, |
| 2035 | int sackdelay_change) | 2090 | int sackdelay_change) |
| 2036 | { | 2091 | { |
| 2037 | int error; | 2092 | int error; |
| 2038 | 2093 | ||
| @@ -2915,7 +2970,7 @@ SCTP_STATIC struct sock *sctp_accept(struct sock *sk, int flags, int *err) | |||
| 2915 | goto out; | 2970 | goto out; |
| 2916 | } | 2971 | } |
| 2917 | 2972 | ||
| 2918 | timeo = sock_rcvtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK); | 2973 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
| 2919 | 2974 | ||
| 2920 | error = sctp_wait_for_accept(sk, timeo); | 2975 | error = sctp_wait_for_accept(sk, timeo); |
| 2921 | if (error) | 2976 | if (error) |
| @@ -2990,14 +3045,14 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 2990 | sp->initmsg.sinit_num_ostreams = sctp_max_outstreams; | 3045 | sp->initmsg.sinit_num_ostreams = sctp_max_outstreams; |
| 2991 | sp->initmsg.sinit_max_instreams = sctp_max_instreams; | 3046 | sp->initmsg.sinit_max_instreams = sctp_max_instreams; |
| 2992 | sp->initmsg.sinit_max_attempts = sctp_max_retrans_init; | 3047 | sp->initmsg.sinit_max_attempts = sctp_max_retrans_init; |
| 2993 | sp->initmsg.sinit_max_init_timeo = jiffies_to_msecs(sctp_rto_max); | 3048 | sp->initmsg.sinit_max_init_timeo = sctp_rto_max; |
| 2994 | 3049 | ||
| 2995 | /* Initialize default RTO related parameters. These parameters can | 3050 | /* Initialize default RTO related parameters. These parameters can |
| 2996 | * be modified for with the SCTP_RTOINFO socket option. | 3051 | * be modified for with the SCTP_RTOINFO socket option. |
| 2997 | */ | 3052 | */ |
| 2998 | sp->rtoinfo.srto_initial = jiffies_to_msecs(sctp_rto_initial); | 3053 | sp->rtoinfo.srto_initial = sctp_rto_initial; |
| 2999 | sp->rtoinfo.srto_max = jiffies_to_msecs(sctp_rto_max); | 3054 | sp->rtoinfo.srto_max = sctp_rto_max; |
| 3000 | sp->rtoinfo.srto_min = jiffies_to_msecs(sctp_rto_min); | 3055 | sp->rtoinfo.srto_min = sctp_rto_min; |
| 3001 | 3056 | ||
| 3002 | /* Initialize default association related parameters. These parameters | 3057 | /* Initialize default association related parameters. These parameters |
| 3003 | * can be modified with the SCTP_ASSOCINFO socket option. | 3058 | * can be modified with the SCTP_ASSOCINFO socket option. |
| @@ -3006,8 +3061,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 3006 | sp->assocparams.sasoc_number_peer_destinations = 0; | 3061 | sp->assocparams.sasoc_number_peer_destinations = 0; |
| 3007 | sp->assocparams.sasoc_peer_rwnd = 0; | 3062 | sp->assocparams.sasoc_peer_rwnd = 0; |
| 3008 | sp->assocparams.sasoc_local_rwnd = 0; | 3063 | sp->assocparams.sasoc_local_rwnd = 0; |
| 3009 | sp->assocparams.sasoc_cookie_life = | 3064 | sp->assocparams.sasoc_cookie_life = sctp_valid_cookie_life; |
| 3010 | jiffies_to_msecs(sctp_valid_cookie_life); | ||
| 3011 | 3065 | ||
| 3012 | /* Initialize default event subscriptions. By default, all the | 3066 | /* Initialize default event subscriptions. By default, all the |
| 3013 | * options are off. | 3067 | * options are off. |
| @@ -3017,10 +3071,10 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 3017 | /* Default Peer Address Parameters. These defaults can | 3071 | /* Default Peer Address Parameters. These defaults can |
| 3018 | * be modified via SCTP_PEER_ADDR_PARAMS | 3072 | * be modified via SCTP_PEER_ADDR_PARAMS |
| 3019 | */ | 3073 | */ |
| 3020 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); | 3074 | sp->hbinterval = sctp_hb_interval; |
| 3021 | sp->pathmaxrxt = sctp_max_retrans_path; | 3075 | sp->pathmaxrxt = sctp_max_retrans_path; |
| 3022 | sp->pathmtu = 0; // allow default discovery | 3076 | sp->pathmtu = 0; // allow default discovery |
| 3023 | sp->sackdelay = jiffies_to_msecs(sctp_sack_timeout); | 3077 | sp->sackdelay = sctp_sack_timeout; |
| 3024 | sp->param_flags = SPP_HB_ENABLE | | 3078 | sp->param_flags = SPP_HB_ENABLE | |
| 3025 | SPP_PMTUD_ENABLE | | 3079 | SPP_PMTUD_ENABLE | |
| 3026 | SPP_SACKDELAY_ENABLE; | 3080 | SPP_SACKDELAY_ENABLE; |
| @@ -3030,8 +3084,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 3030 | */ | 3084 | */ |
| 3031 | sp->disable_fragments = 0; | 3085 | sp->disable_fragments = 0; |
| 3032 | 3086 | ||
| 3033 | /* Turn on/off any Nagle-like algorithm. */ | 3087 | /* Enable Nagle algorithm by default. */ |
| 3034 | sp->nodelay = 1; | 3088 | sp->nodelay = 0; |
| 3035 | 3089 | ||
| 3036 | /* Enable by default. */ | 3090 | /* Enable by default. */ |
| 3037 | sp->v4mapped = 1; | 3091 | sp->v4mapped = 1; |
| @@ -4843,7 +4897,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog) | |||
| 4843 | int sctp_inet_listen(struct socket *sock, int backlog) | 4897 | int sctp_inet_listen(struct socket *sock, int backlog) |
| 4844 | { | 4898 | { |
| 4845 | struct sock *sk = sock->sk; | 4899 | struct sock *sk = sock->sk; |
| 4846 | struct crypto_tfm *tfm=NULL; | 4900 | struct crypto_hash *tfm = NULL; |
| 4847 | int err = -EINVAL; | 4901 | int err = -EINVAL; |
| 4848 | 4902 | ||
| 4849 | if (unlikely(backlog < 0)) | 4903 | if (unlikely(backlog < 0)) |
| @@ -4856,7 +4910,7 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
| 4856 | 4910 | ||
| 4857 | /* Allocate HMAC for generating cookie. */ | 4911 | /* Allocate HMAC for generating cookie. */ |
| 4858 | if (sctp_hmac_alg) { | 4912 | if (sctp_hmac_alg) { |
| 4859 | tfm = sctp_crypto_alloc_tfm(sctp_hmac_alg, 0); | 4913 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
| 4860 | if (!tfm) { | 4914 | if (!tfm) { |
| 4861 | err = -ENOSYS; | 4915 | err = -ENOSYS; |
| 4862 | goto out; | 4916 | goto out; |
| @@ -4882,7 +4936,7 @@ out: | |||
| 4882 | sctp_release_sock(sk); | 4936 | sctp_release_sock(sk); |
| 4883 | return err; | 4937 | return err; |
| 4884 | cleanup: | 4938 | cleanup: |
| 4885 | sctp_crypto_free_tfm(tfm); | 4939 | crypto_free_hash(tfm); |
| 4886 | goto out; | 4940 | goto out; |
| 4887 | } | 4941 | } |
| 4888 | 4942 | ||
| @@ -4978,7 +5032,7 @@ static struct sctp_bind_bucket *sctp_bucket_create( | |||
| 4978 | /* Caller must hold hashbucket lock for this tb with local BH disabled */ | 5032 | /* Caller must hold hashbucket lock for this tb with local BH disabled */ |
| 4979 | static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) | 5033 | static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) |
| 4980 | { | 5034 | { |
| 4981 | if (hlist_empty(&pp->owner)) { | 5035 | if (pp && hlist_empty(&pp->owner)) { |
| 4982 | if (pp->next) | 5036 | if (pp->next) |
| 4983 | pp->next->pprev = pp->pprev; | 5037 | pp->next->pprev = pp->pprev; |
| 4984 | *(pp->pprev) = pp->next; | 5038 | *(pp->pprev) = pp->next; |
| @@ -5564,6 +5618,8 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
| 5564 | /* Copy the bind_addr list from the original endpoint to the new | 5618 | /* Copy the bind_addr list from the original endpoint to the new |
| 5565 | * endpoint so that we can handle restarts properly | 5619 | * endpoint so that we can handle restarts properly |
| 5566 | */ | 5620 | */ |
| 5621 | if (PF_INET6 == assoc->base.sk->sk_family) | ||
| 5622 | flags = SCTP_ADDR6_ALLOWED; | ||
| 5567 | if (assoc->peer.ipv4_address) | 5623 | if (assoc->peer.ipv4_address) |
| 5568 | flags |= SCTP_ADDR4_PEERSUPP; | 5624 | flags |= SCTP_ADDR4_PEERSUPP; |
| 5569 | if (assoc->peer.ipv6_address) | 5625 | if (assoc->peer.ipv6_address) |
