160c778b2SVlad Yasevich /* SCTP kernel implementation 21da177e4SLinus Torvalds * Copyright (c) 1999-2000 Cisco, Inc. 31da177e4SLinus Torvalds * Copyright (c) 1999-2001 Motorola, Inc. 41da177e4SLinus Torvalds * Copyright (c) 2001-2002 International Business Machines, Corp. 51da177e4SLinus Torvalds * Copyright (c) 2001 Intel Corp. 61da177e4SLinus Torvalds * Copyright (c) 2001 Nokia, Inc. 71da177e4SLinus Torvalds * Copyright (c) 2001 La Monte H.P. Yarroll 81da177e4SLinus Torvalds * 960c778b2SVlad Yasevich * This file is part of the SCTP kernel implementation 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * This abstraction represents an SCTP endpoint. 121da177e4SLinus Torvalds * 1360c778b2SVlad Yasevich * The SCTP implementation is free software; 141da177e4SLinus Torvalds * you can redistribute it and/or modify it under the terms of 151da177e4SLinus Torvalds * the GNU General Public License as published by 161da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 171da177e4SLinus Torvalds * any later version. 181da177e4SLinus Torvalds * 1960c778b2SVlad Yasevich * The SCTP implementation is distributed in the hope that it 201da177e4SLinus Torvalds * will be useful, but WITHOUT ANY WARRANTY; without even the implied 211da177e4SLinus Torvalds * ************************ 221da177e4SLinus Torvalds * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 231da177e4SLinus Torvalds * See the GNU General Public License for more details. 241da177e4SLinus Torvalds * 251da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 264b2f13a2SJeff Kirsher * along with GNU CC; see the file COPYING. If not, see 274b2f13a2SJeff Kirsher * <http://www.gnu.org/licenses/>. 281da177e4SLinus Torvalds * 291da177e4SLinus Torvalds * Please send any bug reports or fixes you make to the 301da177e4SLinus Torvalds * email address(es): 3191705c61SDaniel Borkmann * lksctp developers <linux-sctp@vger.kernel.org> 321da177e4SLinus Torvalds * 331da177e4SLinus Torvalds * Written or modified by: 341da177e4SLinus Torvalds * La Monte H.P. Yarroll <piggy@acm.org> 351da177e4SLinus Torvalds * Karl Knutson <karl@athena.chicago.il.us> 361da177e4SLinus Torvalds * Jon Grimm <jgrimm@austin.ibm.com> 371da177e4SLinus Torvalds * Daisy Chang <daisyc@us.ibm.com> 381da177e4SLinus Torvalds * Dajiang Zhang <dajiang.zhang@nokia.com> 391da177e4SLinus Torvalds */ 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds #include <linux/types.h> 421da177e4SLinus Torvalds #include <linux/slab.h> 431da177e4SLinus Torvalds #include <linux/in.h> 441da177e4SLinus Torvalds #include <linux/random.h> /* get_random_bytes() */ 451da177e4SLinus Torvalds #include <net/sock.h> 461da177e4SLinus Torvalds #include <net/ipv6.h> 471da177e4SLinus Torvalds #include <net/sctp/sctp.h> 481da177e4SLinus Torvalds #include <net/sctp/sm.h> 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds /* Forward declarations for internal helpers. */ 51c4028958SDavid Howells static void sctp_endpoint_bh_rcv(struct work_struct *work); 521da177e4SLinus Torvalds 531da177e4SLinus Torvalds /* 541da177e4SLinus Torvalds * Initialize the base fields of the endpoint structure. 551da177e4SLinus Torvalds */ 561da177e4SLinus Torvalds static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, 573182cd84SAlexey Dobriyan struct sock *sk, 58dd0fc66fSAl Viro gfp_t gfp) 591da177e4SLinus Torvalds { 60e1fc3b14SEric W. Biederman struct net *net = sock_net(sk); 61a29a5bd4SVlad Yasevich struct sctp_hmac_algo_param *auth_hmacs = NULL; 62a29a5bd4SVlad Yasevich struct sctp_chunks_param *auth_chunks = NULL; 63a29a5bd4SVlad Yasevich struct sctp_shared_key *null_key; 64a29a5bd4SVlad Yasevich int err; 65a29a5bd4SVlad Yasevich 66b68dbcabSVlad Yasevich ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); 67b68dbcabSVlad Yasevich if (!ep->digest) 68b68dbcabSVlad Yasevich return NULL; 69b68dbcabSVlad Yasevich 70b14878ccSVlad Yasevich ep->auth_enable = net->sctp.auth_enable; 71b14878ccSVlad Yasevich if (ep->auth_enable) { 72a29a5bd4SVlad Yasevich /* Allocate space for HMACS and CHUNKS authentication 73a29a5bd4SVlad Yasevich * variables. There are arrays that we encode directly 74a29a5bd4SVlad Yasevich * into parameters to make the rest of the operations easier. 75a29a5bd4SVlad Yasevich */ 761474774aSXin Long auth_hmacs = kzalloc(sizeof(*auth_hmacs) + 77a29a5bd4SVlad Yasevich sizeof(__u16) * SCTP_AUTH_NUM_HMACS, gfp); 78a29a5bd4SVlad Yasevich if (!auth_hmacs) 79a29a5bd4SVlad Yasevich goto nomem; 80a29a5bd4SVlad Yasevich 81a762a9d9SXin Long auth_chunks = kzalloc(sizeof(*auth_chunks) + 82a29a5bd4SVlad Yasevich SCTP_NUM_CHUNK_TYPES, gfp); 83a29a5bd4SVlad Yasevich if (!auth_chunks) 84a29a5bd4SVlad Yasevich goto nomem; 85a29a5bd4SVlad Yasevich 86a29a5bd4SVlad Yasevich /* Initialize the HMACS parameter. 87a29a5bd4SVlad Yasevich * SCTP-AUTH: Section 3.3 88a29a5bd4SVlad Yasevich * Every endpoint supporting SCTP chunk authentication MUST 89a29a5bd4SVlad Yasevich * support the HMAC based on the SHA-1 algorithm. 90a29a5bd4SVlad Yasevich */ 91a29a5bd4SVlad Yasevich auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO; 92a29a5bd4SVlad Yasevich auth_hmacs->param_hdr.length = 933c918704SXin Long htons(sizeof(struct sctp_paramhdr) + 2); 94a29a5bd4SVlad Yasevich auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1); 95a29a5bd4SVlad Yasevich 96a29a5bd4SVlad Yasevich /* Initialize the CHUNKS parameter */ 97a29a5bd4SVlad Yasevich auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; 983c918704SXin Long auth_chunks->param_hdr.length = 993c918704SXin Long htons(sizeof(struct sctp_paramhdr)); 100a29a5bd4SVlad Yasevich 101a29a5bd4SVlad Yasevich /* If the Add-IP functionality is enabled, we must 102a29a5bd4SVlad Yasevich * authenticate, ASCONF and ASCONF-ACK chunks 103a29a5bd4SVlad Yasevich */ 104e1fc3b14SEric W. Biederman if (net->sctp.addip_enable) { 105a29a5bd4SVlad Yasevich auth_chunks->chunks[0] = SCTP_CID_ASCONF; 106a29a5bd4SVlad Yasevich auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; 107cb0dc77dSAl Viro auth_chunks->param_hdr.length = 1083c918704SXin Long htons(sizeof(struct sctp_paramhdr) + 2); 109a29a5bd4SVlad Yasevich } 110a29a5bd4SVlad Yasevich } 111a29a5bd4SVlad Yasevich 1121da177e4SLinus Torvalds /* Initialize the base structure. */ 1131da177e4SLinus Torvalds /* What type of endpoint are we? */ 1141da177e4SLinus Torvalds ep->base.type = SCTP_EP_TYPE_SOCKET; 1151da177e4SLinus Torvalds 1161da177e4SLinus Torvalds /* Initialize the basic object fields. */ 117c638457aSReshetova, Elena refcount_set(&ep->base.refcnt, 1); 1180022d2ddSDaniel Borkmann ep->base.dead = false; 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds /* Create an input queue. */ 1211da177e4SLinus Torvalds sctp_inq_init(&ep->base.inqueue); 1221da177e4SLinus Torvalds 1231da177e4SLinus Torvalds /* Set its top-half handler */ 124c4028958SDavid Howells sctp_inq_set_th_handler(&ep->base.inqueue, sctp_endpoint_bh_rcv); 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds /* Initialize the bind addr area */ 1271da177e4SLinus Torvalds sctp_bind_addr_init(&ep->base.bind_addr, 0); 1281da177e4SLinus Torvalds 1291da177e4SLinus Torvalds /* Remember who we are attached to. */ 1301da177e4SLinus Torvalds ep->base.sk = sk; 1311da177e4SLinus Torvalds sock_hold(ep->base.sk); 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds /* Create the lists of associations. */ 1341da177e4SLinus Torvalds INIT_LIST_HEAD(&ep->asocs); 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds /* Use SCTP specific send buffer space queues. */ 137e1fc3b14SEric W. Biederman ep->sndbuf_policy = net->sctp.sndbuf_policy; 1384d93df0aSNeil Horman 139561b1733SWei Yongjun sk->sk_data_ready = sctp_data_ready; 1401da177e4SLinus Torvalds sk->sk_write_space = sctp_write_space; 1411da177e4SLinus Torvalds sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1421da177e4SLinus Torvalds 143049b3ff5SNeil Horman /* Get the receive buffer policy for this endpoint */ 144e1fc3b14SEric W. Biederman ep->rcvbuf_policy = net->sctp.rcvbuf_policy; 145049b3ff5SNeil Horman 1461da177e4SLinus Torvalds /* Initialize the secret key used with cookie. */ 147570617e7SDaniel Borkmann get_random_bytes(ep->secret_key, sizeof(ep->secret_key)); 1481da177e4SLinus Torvalds 149a29a5bd4SVlad Yasevich /* SCTP-AUTH extensions*/ 150a29a5bd4SVlad Yasevich INIT_LIST_HEAD(&ep->endpoint_shared_keys); 15181ce0dbcSDan Carpenter null_key = sctp_auth_shkey_create(0, gfp); 152a29a5bd4SVlad Yasevich if (!null_key) 153a29a5bd4SVlad Yasevich goto nomem; 154a29a5bd4SVlad Yasevich 155a29a5bd4SVlad Yasevich list_add(&null_key->key_list, &ep->endpoint_shared_keys); 156a29a5bd4SVlad Yasevich 15702582e9bSMasanari Iida /* Allocate and initialize transorms arrays for supported HMACs. */ 158a29a5bd4SVlad Yasevich err = sctp_auth_init_hmacs(ep, gfp); 159a29a5bd4SVlad Yasevich if (err) 160a29a5bd4SVlad Yasevich goto nomem_hmacs; 161a29a5bd4SVlad Yasevich 162a29a5bd4SVlad Yasevich /* Add the null key to the endpoint shared keys list and 163a29a5bd4SVlad Yasevich * set the hmcas and chunks pointers. 164a29a5bd4SVlad Yasevich */ 165a29a5bd4SVlad Yasevich ep->auth_hmacs_list = auth_hmacs; 166a29a5bd4SVlad Yasevich ep->auth_chunk_list = auth_chunks; 16728aa4c26SXin Long ep->prsctp_enable = net->sctp.prsctp_enable; 168c28445c3SXin Long ep->reconf_enable = net->sctp.reconf_enable; 169a29a5bd4SVlad Yasevich 1701da177e4SLinus Torvalds return ep; 171a29a5bd4SVlad Yasevich 172a29a5bd4SVlad Yasevich nomem_hmacs: 173a29a5bd4SVlad Yasevich sctp_auth_destroy_keys(&ep->endpoint_shared_keys); 174a29a5bd4SVlad Yasevich nomem: 175a29a5bd4SVlad Yasevich /* Free all allocations */ 176a29a5bd4SVlad Yasevich kfree(auth_hmacs); 177a29a5bd4SVlad Yasevich kfree(auth_chunks); 178a29a5bd4SVlad Yasevich kfree(ep->digest); 179a29a5bd4SVlad Yasevich return NULL; 180a29a5bd4SVlad Yasevich 1811da177e4SLinus Torvalds } 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds /* Create a sctp_endpoint with all that boring stuff initialized. 1841da177e4SLinus Torvalds * Returns NULL if there isn't enough memory. 1851da177e4SLinus Torvalds */ 186dd0fc66fSAl Viro struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, gfp_t gfp) 1871da177e4SLinus Torvalds { 1881da177e4SLinus Torvalds struct sctp_endpoint *ep; 1891da177e4SLinus Torvalds 1901da177e4SLinus Torvalds /* Build a local endpoint. */ 191939cfa75SDaniel Borkmann ep = kzalloc(sizeof(*ep), gfp); 1921da177e4SLinus Torvalds if (!ep) 1931da177e4SLinus Torvalds goto fail; 194939cfa75SDaniel Borkmann 1951da177e4SLinus Torvalds if (!sctp_endpoint_init(ep, sk, gfp)) 1961da177e4SLinus Torvalds goto fail_init; 197ff2266cdSDaniel Borkmann 1981da177e4SLinus Torvalds SCTP_DBG_OBJCNT_INC(ep); 1991da177e4SLinus Torvalds return ep; 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds fail_init: 2021da177e4SLinus Torvalds kfree(ep); 2031da177e4SLinus Torvalds fail: 2041da177e4SLinus Torvalds return NULL; 2051da177e4SLinus Torvalds } 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds /* Add an association to an endpoint. */ 2081da177e4SLinus Torvalds void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, 2091da177e4SLinus Torvalds struct sctp_association *asoc) 2101da177e4SLinus Torvalds { 2111da177e4SLinus Torvalds struct sock *sk = ep->base.sk; 2121da177e4SLinus Torvalds 213de76e695SVlad Yasevich /* If this is a temporary association, don't bother 214de76e695SVlad Yasevich * since we'll be removing it shortly and don't 215de76e695SVlad Yasevich * want anyone to find it anyway. 216de76e695SVlad Yasevich */ 217de76e695SVlad Yasevich if (asoc->temp) 218de76e695SVlad Yasevich return; 219de76e695SVlad Yasevich 2201da177e4SLinus Torvalds /* Now just add it to our list of asocs */ 2211da177e4SLinus Torvalds list_add_tail(&asoc->asocs, &ep->asocs); 2221da177e4SLinus Torvalds 2231da177e4SLinus Torvalds /* Increment the backlog value for a TCP-style listening socket. */ 2241da177e4SLinus Torvalds if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) 2251da177e4SLinus Torvalds sk->sk_ack_backlog++; 2261da177e4SLinus Torvalds } 2271da177e4SLinus Torvalds 2281da177e4SLinus Torvalds /* Free the endpoint structure. Delay cleanup until 2291da177e4SLinus Torvalds * all users have released their reference count on this structure. 2301da177e4SLinus Torvalds */ 2311da177e4SLinus Torvalds void sctp_endpoint_free(struct sctp_endpoint *ep) 2321da177e4SLinus Torvalds { 2330022d2ddSDaniel Borkmann ep->base.dead = true; 234cfdeef32SVlad Yasevich 235cfdeef32SVlad Yasevich ep->base.sk->sk_state = SCTP_SS_CLOSED; 236cfdeef32SVlad Yasevich 237cfdeef32SVlad Yasevich /* Unlink this endpoint, so we can't find it again! */ 238cfdeef32SVlad Yasevich sctp_unhash_endpoint(ep); 239cfdeef32SVlad Yasevich 2401da177e4SLinus Torvalds sctp_endpoint_put(ep); 2411da177e4SLinus Torvalds } 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds /* Final destructor for endpoint. */ 2441da177e4SLinus Torvalds static void sctp_endpoint_destroy(struct sctp_endpoint *ep) 2451da177e4SLinus Torvalds { 2460a2fbac1SDaniel Borkmann struct sock *sk; 2471da177e4SLinus Torvalds 248bb33381dSDaniel Borkmann if (unlikely(!ep->base.dead)) { 249bb33381dSDaniel Borkmann WARN(1, "Attempt to destroy undead endpoint %p!\n", ep); 250bb33381dSDaniel Borkmann return; 251bb33381dSDaniel Borkmann } 2521da177e4SLinus Torvalds 253b68dbcabSVlad Yasevich /* Free the digest buffer */ 254b68dbcabSVlad Yasevich kfree(ep->digest); 255b68dbcabSVlad Yasevich 256a29a5bd4SVlad Yasevich /* SCTP-AUTH: Free up AUTH releated data such as shared keys 257a29a5bd4SVlad Yasevich * chunks and hmacs arrays that were allocated 258a29a5bd4SVlad Yasevich */ 259a29a5bd4SVlad Yasevich sctp_auth_destroy_keys(&ep->endpoint_shared_keys); 260a29a5bd4SVlad Yasevich kfree(ep->auth_hmacs_list); 261a29a5bd4SVlad Yasevich kfree(ep->auth_chunk_list); 262a29a5bd4SVlad Yasevich 263a29a5bd4SVlad Yasevich /* AUTH - Free any allocated HMAC transform containers */ 264a29a5bd4SVlad Yasevich sctp_auth_destroy_hmacs(ep->auth_hmacs); 265a29a5bd4SVlad Yasevich 2661da177e4SLinus Torvalds /* Cleanup. */ 2671da177e4SLinus Torvalds sctp_inq_free(&ep->base.inqueue); 2681da177e4SLinus Torvalds sctp_bind_addr_free(&ep->base.bind_addr); 2691da177e4SLinus Torvalds 270570617e7SDaniel Borkmann memset(ep->secret_key, 0, sizeof(ep->secret_key)); 271b5c37fe6SDaniel Borkmann 2720a2fbac1SDaniel Borkmann sk = ep->base.sk; 2730a2fbac1SDaniel Borkmann /* Remove and free the port */ 2740a2fbac1SDaniel Borkmann if (sctp_sk(sk)->bind_hash) 2750a2fbac1SDaniel Borkmann sctp_put_port(sk); 2760a2fbac1SDaniel Borkmann 27786fdb344SXin Long sctp_sk(sk)->ep = NULL; 2787f304b9eSXin Long /* Give up our hold on the sock */ 2790a2fbac1SDaniel Borkmann sock_put(sk); 2801da177e4SLinus Torvalds 2811da177e4SLinus Torvalds kfree(ep); 2821da177e4SLinus Torvalds SCTP_DBG_OBJCNT_DEC(ep); 2831da177e4SLinus Torvalds } 2841da177e4SLinus Torvalds 2851da177e4SLinus Torvalds /* Hold a reference to an endpoint. */ 2861da177e4SLinus Torvalds void sctp_endpoint_hold(struct sctp_endpoint *ep) 2871da177e4SLinus Torvalds { 288c638457aSReshetova, Elena refcount_inc(&ep->base.refcnt); 2891da177e4SLinus Torvalds } 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds /* Release a reference to an endpoint and clean up if there are 2921da177e4SLinus Torvalds * no more references. 2931da177e4SLinus Torvalds */ 2941da177e4SLinus Torvalds void sctp_endpoint_put(struct sctp_endpoint *ep) 2951da177e4SLinus Torvalds { 296c638457aSReshetova, Elena if (refcount_dec_and_test(&ep->base.refcnt)) 2971da177e4SLinus Torvalds sctp_endpoint_destroy(ep); 2981da177e4SLinus Torvalds } 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds /* Is this the endpoint we are looking for? */ 3011da177e4SLinus Torvalds struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep, 3024cdadcbcSEric W. Biederman struct net *net, 3031da177e4SLinus Torvalds const union sctp_addr *laddr) 3041da177e4SLinus Torvalds { 305559cf710SVlad Yasevich struct sctp_endpoint *retval = NULL; 3061da177e4SLinus Torvalds 3074cdadcbcSEric W. Biederman if ((htons(ep->base.bind_addr.port) == laddr->v4.sin_port) && 3084cdadcbcSEric W. Biederman net_eq(sock_net(ep->base.sk), net)) { 3091da177e4SLinus Torvalds if (sctp_bind_addr_match(&ep->base.bind_addr, laddr, 310559cf710SVlad Yasevich sctp_sk(ep->base.sk))) 3111da177e4SLinus Torvalds retval = ep; 3121da177e4SLinus Torvalds } 3131da177e4SLinus Torvalds 3141da177e4SLinus Torvalds return retval; 3151da177e4SLinus Torvalds } 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds /* Find the association that goes with this chunk. 3184f008781SXin Long * We lookup the transport from hashtable at first, then get association 3194f008781SXin Long * through t->assoc. 3201da177e4SLinus Torvalds */ 321c79c0666SXin Long struct sctp_association *sctp_endpoint_lookup_assoc( 3221da177e4SLinus Torvalds const struct sctp_endpoint *ep, 3231da177e4SLinus Torvalds const union sctp_addr *paddr, 3241da177e4SLinus Torvalds struct sctp_transport **transport) 3251da177e4SLinus Torvalds { 326123ed979SVlad Yasevich struct sctp_association *asoc = NULL; 3274f008781SXin Long struct sctp_transport *t; 3281da177e4SLinus Torvalds 3291da177e4SLinus Torvalds *transport = NULL; 330deb85a6eSVlad Yasevich 331deb85a6eSVlad Yasevich /* If the local port is not set, there can't be any associations 332deb85a6eSVlad Yasevich * on this endpoint. 333deb85a6eSVlad Yasevich */ 334deb85a6eSVlad Yasevich if (!ep->base.bind_addr.port) 3355cb2cd68SXin Long return NULL; 3365cb2cd68SXin Long 3375cb2cd68SXin Long rcu_read_lock(); 3384f008781SXin Long t = sctp_epaddr_lookup_transport(ep, paddr); 339dd7445adSXin Long if (!t) 3404f008781SXin Long goto out; 341deb85a6eSVlad Yasevich 342123ed979SVlad Yasevich *transport = t; 3434f008781SXin Long asoc = t->asoc; 344deb85a6eSVlad Yasevich out: 3455cb2cd68SXin Long rcu_read_unlock(); 346123ed979SVlad Yasevich return asoc; 3471da177e4SLinus Torvalds } 3481da177e4SLinus Torvalds 3491da177e4SLinus Torvalds /* Look for any peeled off association from the endpoint that matches the 3501da177e4SLinus Torvalds * given peer address. 3511da177e4SLinus Torvalds */ 3521da177e4SLinus Torvalds int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep, 3531da177e4SLinus Torvalds const union sctp_addr *paddr) 3541da177e4SLinus Torvalds { 3551da177e4SLinus Torvalds struct sctp_sockaddr_entry *addr; 3561da177e4SLinus Torvalds struct sctp_bind_addr *bp; 3574110cc25SEric W. Biederman struct net *net = sock_net(ep->base.sk); 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvalds bp = &ep->base.bind_addr; 360559cf710SVlad Yasevich /* This function is called with the socket lock held, 361559cf710SVlad Yasevich * so the address_list can not change. 362559cf710SVlad Yasevich */ 363559cf710SVlad Yasevich list_for_each_entry(addr, &bp->address_list, list) { 3644110cc25SEric W. Biederman if (sctp_has_association(net, &addr->a, paddr)) 3651da177e4SLinus Torvalds return 1; 3661da177e4SLinus Torvalds } 3671da177e4SLinus Torvalds 3681da177e4SLinus Torvalds return 0; 3691da177e4SLinus Torvalds } 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds /* Do delayed input processing. This is scheduled by sctp_rcv(). 3721da177e4SLinus Torvalds * This may be called on BH or task time. 3731da177e4SLinus Torvalds */ 374c4028958SDavid Howells static void sctp_endpoint_bh_rcv(struct work_struct *work) 3751da177e4SLinus Torvalds { 376c4028958SDavid Howells struct sctp_endpoint *ep = 377c4028958SDavid Howells container_of(work, struct sctp_endpoint, 378c4028958SDavid Howells base.inqueue.immediate); 3791da177e4SLinus Torvalds struct sctp_association *asoc; 3801da177e4SLinus Torvalds struct sock *sk; 38155e26eb9SEric W. Biederman struct net *net; 3821da177e4SLinus Torvalds struct sctp_transport *transport; 3831da177e4SLinus Torvalds struct sctp_chunk *chunk; 3841da177e4SLinus Torvalds struct sctp_inq *inqueue; 3851da177e4SLinus Torvalds sctp_subtype_t subtype; 38652106019SXin Long enum sctp_state state; 3871da177e4SLinus Torvalds int error = 0; 38842b2aa86SJustin P. Mattock int first_time = 1; /* is this the first time through the loop */ 3891da177e4SLinus Torvalds 3901da177e4SLinus Torvalds if (ep->base.dead) 3911da177e4SLinus Torvalds return; 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds asoc = NULL; 3941da177e4SLinus Torvalds inqueue = &ep->base.inqueue; 3951da177e4SLinus Torvalds sk = ep->base.sk; 39655e26eb9SEric W. Biederman net = sock_net(sk); 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds while (NULL != (chunk = sctp_inq_pop(inqueue))) { 3991da177e4SLinus Torvalds subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); 4001da177e4SLinus Torvalds 401bbd0d598SVlad Yasevich /* If the first chunk in the packet is AUTH, do special 402bbd0d598SVlad Yasevich * processing specified in Section 6.3 of SCTP-AUTH spec 403bbd0d598SVlad Yasevich */ 404bbd0d598SVlad Yasevich if (first_time && (subtype.chunk == SCTP_CID_AUTH)) { 405bbd0d598SVlad Yasevich struct sctp_chunkhdr *next_hdr; 406bbd0d598SVlad Yasevich 407bbd0d598SVlad Yasevich next_hdr = sctp_inq_peek(inqueue); 408bbd0d598SVlad Yasevich if (!next_hdr) 409bbd0d598SVlad Yasevich goto normal; 410bbd0d598SVlad Yasevich 411bbd0d598SVlad Yasevich /* If the next chunk is COOKIE-ECHO, skip the AUTH 412bbd0d598SVlad Yasevich * chunk while saving a pointer to it so we can do 413bbd0d598SVlad Yasevich * Authentication later (during cookie-echo 414bbd0d598SVlad Yasevich * processing). 415bbd0d598SVlad Yasevich */ 416bbd0d598SVlad Yasevich if (next_hdr->type == SCTP_CID_COOKIE_ECHO) { 417bbd0d598SVlad Yasevich chunk->auth_chunk = skb_clone(chunk->skb, 418bbd0d598SVlad Yasevich GFP_ATOMIC); 419bbd0d598SVlad Yasevich chunk->auth = 1; 420bbd0d598SVlad Yasevich continue; 421bbd0d598SVlad Yasevich } 422bbd0d598SVlad Yasevich } 423bbd0d598SVlad Yasevich normal: 4241da177e4SLinus Torvalds /* We might have grown an association since last we 4251da177e4SLinus Torvalds * looked, so try again. 4261da177e4SLinus Torvalds * 4271da177e4SLinus Torvalds * This happens when we've just processed our 4281da177e4SLinus Torvalds * COOKIE-ECHO chunk. 4291da177e4SLinus Torvalds */ 4301da177e4SLinus Torvalds if (NULL == chunk->asoc) { 4311da177e4SLinus Torvalds asoc = sctp_endpoint_lookup_assoc(ep, 4321da177e4SLinus Torvalds sctp_source(chunk), 4331da177e4SLinus Torvalds &transport); 4341da177e4SLinus Torvalds chunk->asoc = asoc; 4351da177e4SLinus Torvalds chunk->transport = transport; 4361da177e4SLinus Torvalds } 4371da177e4SLinus Torvalds 4381da177e4SLinus Torvalds state = asoc ? asoc->state : SCTP_STATE_CLOSED; 439bbd0d598SVlad Yasevich if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth) 440bbd0d598SVlad Yasevich continue; 4411da177e4SLinus Torvalds 4421da177e4SLinus Torvalds /* Remember where the last DATA chunk came from so we 4431da177e4SLinus Torvalds * know where to send the SACK. 4441da177e4SLinus Torvalds */ 4451da177e4SLinus Torvalds if (asoc && sctp_chunk_is_data(chunk)) 4461da177e4SLinus Torvalds asoc->peer.last_data_from = chunk->transport; 447196d6759SMichele Baldessari else { 448b01a2407SEric W. Biederman SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS); 449196d6759SMichele Baldessari if (asoc) 450196d6759SMichele Baldessari asoc->stats.ictrlchunks++; 451196d6759SMichele Baldessari } 4521da177e4SLinus Torvalds 4531da177e4SLinus Torvalds if (chunk->transport) 454e575235fSDaniel Borkmann chunk->transport->last_time_heard = ktime_get(); 4551da177e4SLinus Torvalds 45655e26eb9SEric W. Biederman error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype, state, 4571da177e4SLinus Torvalds ep, asoc, chunk, GFP_ATOMIC); 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds if (error && chunk) 4601da177e4SLinus Torvalds chunk->pdiscard = 1; 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds /* Check to see if the endpoint is freed in response to 4631da177e4SLinus Torvalds * the incoming chunk. If so, get out of the while loop. 4641da177e4SLinus Torvalds */ 4651da177e4SLinus Torvalds if (!sctp_sk(sk)->ep) 4661da177e4SLinus Torvalds break; 467bbd0d598SVlad Yasevich 468bbd0d598SVlad Yasevich if (first_time) 469bbd0d598SVlad Yasevich first_time = 0; 4701da177e4SLinus Torvalds } 4711da177e4SLinus Torvalds } 472