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 261da177e4SLinus Torvalds * along with GNU CC; see the file COPYING. If not, write to 271da177e4SLinus Torvalds * the Free Software Foundation, 59 Temple Place - Suite 330, 281da177e4SLinus Torvalds * Boston, MA 02111-1307, USA. 291da177e4SLinus Torvalds * 301da177e4SLinus Torvalds * Please send any bug reports or fixes you make to the 311da177e4SLinus Torvalds * email address(es): 321da177e4SLinus Torvalds * lksctp developers <lksctp-developers@lists.sourceforge.net> 331da177e4SLinus Torvalds * 341da177e4SLinus Torvalds * Or submit a bug report through the following website: 351da177e4SLinus Torvalds * http://www.sf.net/projects/lksctp 361da177e4SLinus Torvalds * 371da177e4SLinus Torvalds * Written or modified by: 381da177e4SLinus Torvalds * La Monte H.P. Yarroll <piggy@acm.org> 391da177e4SLinus Torvalds * Karl Knutson <karl@athena.chicago.il.us> 401da177e4SLinus Torvalds * Jon Grimm <jgrimm@austin.ibm.com> 411da177e4SLinus Torvalds * Daisy Chang <daisyc@us.ibm.com> 421da177e4SLinus Torvalds * Dajiang Zhang <dajiang.zhang@nokia.com> 431da177e4SLinus Torvalds * 441da177e4SLinus Torvalds * Any bugs reported given to us we will try to fix... any fixes shared will 451da177e4SLinus Torvalds * be incorporated into the next SCTP release. 461da177e4SLinus Torvalds */ 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds #include <linux/types.h> 491da177e4SLinus Torvalds #include <linux/slab.h> 501da177e4SLinus Torvalds #include <linux/in.h> 511da177e4SLinus Torvalds #include <linux/random.h> /* get_random_bytes() */ 521da177e4SLinus Torvalds #include <linux/crypto.h> 531da177e4SLinus Torvalds #include <net/sock.h> 541da177e4SLinus Torvalds #include <net/ipv6.h> 551da177e4SLinus Torvalds #include <net/sctp/sctp.h> 561da177e4SLinus Torvalds #include <net/sctp/sm.h> 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds /* Forward declarations for internal helpers. */ 59c4028958SDavid Howells static void sctp_endpoint_bh_rcv(struct work_struct *work); 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds /* 621da177e4SLinus Torvalds * Initialize the base fields of the endpoint structure. 631da177e4SLinus Torvalds */ 641da177e4SLinus Torvalds static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, 653182cd84SAlexey Dobriyan struct sock *sk, 66dd0fc66fSAl Viro gfp_t gfp) 671da177e4SLinus Torvalds { 68e1fc3b14SEric W. Biederman struct net *net = sock_net(sk); 69a29a5bd4SVlad Yasevich struct sctp_hmac_algo_param *auth_hmacs = NULL; 70a29a5bd4SVlad Yasevich struct sctp_chunks_param *auth_chunks = NULL; 71a29a5bd4SVlad Yasevich struct sctp_shared_key *null_key; 72a29a5bd4SVlad Yasevich int err; 73a29a5bd4SVlad Yasevich 74b68dbcabSVlad Yasevich ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); 75b68dbcabSVlad Yasevich if (!ep->digest) 76b68dbcabSVlad Yasevich return NULL; 77b68dbcabSVlad Yasevich 78e1fc3b14SEric W. Biederman if (net->sctp.auth_enable) { 79a29a5bd4SVlad Yasevich /* Allocate space for HMACS and CHUNKS authentication 80a29a5bd4SVlad Yasevich * variables. There are arrays that we encode directly 81a29a5bd4SVlad Yasevich * into parameters to make the rest of the operations easier. 82a29a5bd4SVlad Yasevich */ 83a29a5bd4SVlad Yasevich auth_hmacs = kzalloc(sizeof(sctp_hmac_algo_param_t) + 84a29a5bd4SVlad Yasevich sizeof(__u16) * SCTP_AUTH_NUM_HMACS, gfp); 85a29a5bd4SVlad Yasevich if (!auth_hmacs) 86a29a5bd4SVlad Yasevich goto nomem; 87a29a5bd4SVlad Yasevich 88a29a5bd4SVlad Yasevich auth_chunks = kzalloc(sizeof(sctp_chunks_param_t) + 89a29a5bd4SVlad Yasevich SCTP_NUM_CHUNK_TYPES, gfp); 90a29a5bd4SVlad Yasevich if (!auth_chunks) 91a29a5bd4SVlad Yasevich goto nomem; 92a29a5bd4SVlad Yasevich 93a29a5bd4SVlad Yasevich /* Initialize the HMACS parameter. 94a29a5bd4SVlad Yasevich * SCTP-AUTH: Section 3.3 95a29a5bd4SVlad Yasevich * Every endpoint supporting SCTP chunk authentication MUST 96a29a5bd4SVlad Yasevich * support the HMAC based on the SHA-1 algorithm. 97a29a5bd4SVlad Yasevich */ 98a29a5bd4SVlad Yasevich auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO; 99a29a5bd4SVlad Yasevich auth_hmacs->param_hdr.length = 100a29a5bd4SVlad Yasevich htons(sizeof(sctp_paramhdr_t) + 2); 101a29a5bd4SVlad Yasevich auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1); 102a29a5bd4SVlad Yasevich 103a29a5bd4SVlad Yasevich /* Initialize the CHUNKS parameter */ 104a29a5bd4SVlad Yasevich auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; 1055e739d17SVlad Yasevich auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t)); 106a29a5bd4SVlad Yasevich 107a29a5bd4SVlad Yasevich /* If the Add-IP functionality is enabled, we must 108a29a5bd4SVlad Yasevich * authenticate, ASCONF and ASCONF-ACK chunks 109a29a5bd4SVlad Yasevich */ 110e1fc3b14SEric W. Biederman if (net->sctp.addip_enable) { 111a29a5bd4SVlad Yasevich auth_chunks->chunks[0] = SCTP_CID_ASCONF; 112a29a5bd4SVlad Yasevich auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; 113cb0dc77dSAl Viro auth_chunks->param_hdr.length = 114cb0dc77dSAl Viro htons(sizeof(sctp_paramhdr_t) + 2); 115a29a5bd4SVlad Yasevich } 116a29a5bd4SVlad Yasevich } 117a29a5bd4SVlad Yasevich 1181da177e4SLinus Torvalds /* Initialize the base structure. */ 1191da177e4SLinus Torvalds /* What type of endpoint are we? */ 1201da177e4SLinus Torvalds ep->base.type = SCTP_EP_TYPE_SOCKET; 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds /* Initialize the basic object fields. */ 1231da177e4SLinus Torvalds atomic_set(&ep->base.refcnt, 1); 1241da177e4SLinus Torvalds ep->base.dead = 0; 1251da177e4SLinus Torvalds ep->base.malloced = 1; 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds /* Create an input queue. */ 1281da177e4SLinus Torvalds sctp_inq_init(&ep->base.inqueue); 1291da177e4SLinus Torvalds 1301da177e4SLinus Torvalds /* Set its top-half handler */ 131c4028958SDavid Howells sctp_inq_set_th_handler(&ep->base.inqueue, sctp_endpoint_bh_rcv); 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds /* Initialize the bind addr area */ 1341da177e4SLinus Torvalds sctp_bind_addr_init(&ep->base.bind_addr, 0); 1351da177e4SLinus Torvalds 1361da177e4SLinus Torvalds /* Remember who we are attached to. */ 1371da177e4SLinus Torvalds ep->base.sk = sk; 1381da177e4SLinus Torvalds sock_hold(ep->base.sk); 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds /* Create the lists of associations. */ 1411da177e4SLinus Torvalds INIT_LIST_HEAD(&ep->asocs); 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds /* Use SCTP specific send buffer space queues. */ 144e1fc3b14SEric W. Biederman ep->sndbuf_policy = net->sctp.sndbuf_policy; 1454d93df0aSNeil Horman 146561b1733SWei Yongjun sk->sk_data_ready = sctp_data_ready; 1471da177e4SLinus Torvalds sk->sk_write_space = sctp_write_space; 1481da177e4SLinus Torvalds sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1491da177e4SLinus Torvalds 150049b3ff5SNeil Horman /* Get the receive buffer policy for this endpoint */ 151e1fc3b14SEric W. Biederman ep->rcvbuf_policy = net->sctp.rcvbuf_policy; 152049b3ff5SNeil Horman 1531da177e4SLinus Torvalds /* Initialize the secret key used with cookie. */ 154570617e7SDaniel Borkmann get_random_bytes(ep->secret_key, sizeof(ep->secret_key)); 1551da177e4SLinus Torvalds 156a29a5bd4SVlad Yasevich /* SCTP-AUTH extensions*/ 157a29a5bd4SVlad Yasevich INIT_LIST_HEAD(&ep->endpoint_shared_keys); 15881ce0dbcSDan Carpenter null_key = sctp_auth_shkey_create(0, gfp); 159a29a5bd4SVlad Yasevich if (!null_key) 160a29a5bd4SVlad Yasevich goto nomem; 161a29a5bd4SVlad Yasevich 162a29a5bd4SVlad Yasevich list_add(&null_key->key_list, &ep->endpoint_shared_keys); 163a29a5bd4SVlad Yasevich 16402582e9bSMasanari Iida /* Allocate and initialize transorms arrays for supported HMACs. */ 165a29a5bd4SVlad Yasevich err = sctp_auth_init_hmacs(ep, gfp); 166a29a5bd4SVlad Yasevich if (err) 167a29a5bd4SVlad Yasevich goto nomem_hmacs; 168a29a5bd4SVlad Yasevich 169a29a5bd4SVlad Yasevich /* Add the null key to the endpoint shared keys list and 170a29a5bd4SVlad Yasevich * set the hmcas and chunks pointers. 171a29a5bd4SVlad Yasevich */ 172a29a5bd4SVlad Yasevich ep->auth_hmacs_list = auth_hmacs; 173a29a5bd4SVlad Yasevich ep->auth_chunk_list = auth_chunks; 174a29a5bd4SVlad Yasevich 1751da177e4SLinus Torvalds return ep; 176a29a5bd4SVlad Yasevich 177a29a5bd4SVlad Yasevich nomem_hmacs: 178a29a5bd4SVlad Yasevich sctp_auth_destroy_keys(&ep->endpoint_shared_keys); 179a29a5bd4SVlad Yasevich nomem: 180a29a5bd4SVlad Yasevich /* Free all allocations */ 181a29a5bd4SVlad Yasevich kfree(auth_hmacs); 182a29a5bd4SVlad Yasevich kfree(auth_chunks); 183a29a5bd4SVlad Yasevich kfree(ep->digest); 184a29a5bd4SVlad Yasevich return NULL; 185a29a5bd4SVlad Yasevich 1861da177e4SLinus Torvalds } 1871da177e4SLinus Torvalds 1881da177e4SLinus Torvalds /* Create a sctp_endpoint with all that boring stuff initialized. 1891da177e4SLinus Torvalds * Returns NULL if there isn't enough memory. 1901da177e4SLinus Torvalds */ 191dd0fc66fSAl Viro struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, gfp_t gfp) 1921da177e4SLinus Torvalds { 1931da177e4SLinus Torvalds struct sctp_endpoint *ep; 1941da177e4SLinus Torvalds 1951da177e4SLinus Torvalds /* Build a local endpoint. */ 1961da177e4SLinus Torvalds ep = t_new(struct sctp_endpoint, gfp); 1971da177e4SLinus Torvalds if (!ep) 1981da177e4SLinus Torvalds goto fail; 1991da177e4SLinus Torvalds if (!sctp_endpoint_init(ep, sk, gfp)) 2001da177e4SLinus Torvalds goto fail_init; 2011da177e4SLinus Torvalds ep->base.malloced = 1; 2021da177e4SLinus Torvalds SCTP_DBG_OBJCNT_INC(ep); 2031da177e4SLinus Torvalds return ep; 2041da177e4SLinus Torvalds 2051da177e4SLinus Torvalds fail_init: 2061da177e4SLinus Torvalds kfree(ep); 2071da177e4SLinus Torvalds fail: 2081da177e4SLinus Torvalds return NULL; 2091da177e4SLinus Torvalds } 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds /* Add an association to an endpoint. */ 2121da177e4SLinus Torvalds void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, 2131da177e4SLinus Torvalds struct sctp_association *asoc) 2141da177e4SLinus Torvalds { 2151da177e4SLinus Torvalds struct sock *sk = ep->base.sk; 2161da177e4SLinus Torvalds 217de76e695SVlad Yasevich /* If this is a temporary association, don't bother 218de76e695SVlad Yasevich * since we'll be removing it shortly and don't 219de76e695SVlad Yasevich * want anyone to find it anyway. 220de76e695SVlad Yasevich */ 221de76e695SVlad Yasevich if (asoc->temp) 222de76e695SVlad Yasevich return; 223de76e695SVlad Yasevich 2241da177e4SLinus Torvalds /* Now just add it to our list of asocs */ 2251da177e4SLinus Torvalds list_add_tail(&asoc->asocs, &ep->asocs); 2261da177e4SLinus Torvalds 2271da177e4SLinus Torvalds /* Increment the backlog value for a TCP-style listening socket. */ 2281da177e4SLinus Torvalds if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) 2291da177e4SLinus Torvalds sk->sk_ack_backlog++; 2301da177e4SLinus Torvalds } 2311da177e4SLinus Torvalds 2321da177e4SLinus Torvalds /* Free the endpoint structure. Delay cleanup until 2331da177e4SLinus Torvalds * all users have released their reference count on this structure. 2341da177e4SLinus Torvalds */ 2351da177e4SLinus Torvalds void sctp_endpoint_free(struct sctp_endpoint *ep) 2361da177e4SLinus Torvalds { 2371da177e4SLinus Torvalds ep->base.dead = 1; 238cfdeef32SVlad Yasevich 239cfdeef32SVlad Yasevich ep->base.sk->sk_state = SCTP_SS_CLOSED; 240cfdeef32SVlad Yasevich 241cfdeef32SVlad Yasevich /* Unlink this endpoint, so we can't find it again! */ 242cfdeef32SVlad Yasevich sctp_unhash_endpoint(ep); 243cfdeef32SVlad Yasevich 2441da177e4SLinus Torvalds sctp_endpoint_put(ep); 2451da177e4SLinus Torvalds } 2461da177e4SLinus Torvalds 2471da177e4SLinus Torvalds /* Final destructor for endpoint. */ 2481da177e4SLinus Torvalds static void sctp_endpoint_destroy(struct sctp_endpoint *ep) 2491da177e4SLinus Torvalds { 2501da177e4SLinus Torvalds SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); 2511da177e4SLinus Torvalds 2521da177e4SLinus Torvalds /* Free up the HMAC transform. */ 2531b489e11SHerbert Xu crypto_free_hash(sctp_sk(ep->base.sk)->hmac); 2541da177e4SLinus Torvalds 255b68dbcabSVlad Yasevich /* Free the digest buffer */ 256b68dbcabSVlad Yasevich kfree(ep->digest); 257b68dbcabSVlad Yasevich 258a29a5bd4SVlad Yasevich /* SCTP-AUTH: Free up AUTH releated data such as shared keys 259a29a5bd4SVlad Yasevich * chunks and hmacs arrays that were allocated 260a29a5bd4SVlad Yasevich */ 261a29a5bd4SVlad Yasevich sctp_auth_destroy_keys(&ep->endpoint_shared_keys); 262a29a5bd4SVlad Yasevich kfree(ep->auth_hmacs_list); 263a29a5bd4SVlad Yasevich kfree(ep->auth_chunk_list); 264a29a5bd4SVlad Yasevich 265a29a5bd4SVlad Yasevich /* AUTH - Free any allocated HMAC transform containers */ 266a29a5bd4SVlad Yasevich sctp_auth_destroy_hmacs(ep->auth_hmacs); 267a29a5bd4SVlad Yasevich 2681da177e4SLinus Torvalds /* Cleanup. */ 2691da177e4SLinus Torvalds sctp_inq_free(&ep->base.inqueue); 2701da177e4SLinus Torvalds sctp_bind_addr_free(&ep->base.bind_addr); 2711da177e4SLinus Torvalds 272570617e7SDaniel Borkmann memset(ep->secret_key, 0, sizeof(ep->secret_key)); 273b5c37fe6SDaniel Borkmann 2741da177e4SLinus Torvalds /* Remove and free the port */ 2751da177e4SLinus Torvalds if (sctp_sk(ep->base.sk)->bind_hash) 2761da177e4SLinus Torvalds sctp_put_port(ep->base.sk); 2771da177e4SLinus Torvalds 2781da177e4SLinus Torvalds /* Give up our hold on the sock. */ 2791da177e4SLinus Torvalds if (ep->base.sk) 2801da177e4SLinus Torvalds sock_put(ep->base.sk); 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds /* Finally, free up our memory. */ 2831da177e4SLinus Torvalds if (ep->base.malloced) { 2841da177e4SLinus Torvalds kfree(ep); 2851da177e4SLinus Torvalds SCTP_DBG_OBJCNT_DEC(ep); 2861da177e4SLinus Torvalds } 2871da177e4SLinus Torvalds } 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds /* Hold a reference to an endpoint. */ 2901da177e4SLinus Torvalds void sctp_endpoint_hold(struct sctp_endpoint *ep) 2911da177e4SLinus Torvalds { 2921da177e4SLinus Torvalds atomic_inc(&ep->base.refcnt); 2931da177e4SLinus Torvalds } 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds /* Release a reference to an endpoint and clean up if there are 2961da177e4SLinus Torvalds * no more references. 2971da177e4SLinus Torvalds */ 2981da177e4SLinus Torvalds void sctp_endpoint_put(struct sctp_endpoint *ep) 2991da177e4SLinus Torvalds { 3001da177e4SLinus Torvalds if (atomic_dec_and_test(&ep->base.refcnt)) 3011da177e4SLinus Torvalds sctp_endpoint_destroy(ep); 3021da177e4SLinus Torvalds } 3031da177e4SLinus Torvalds 3041da177e4SLinus Torvalds /* Is this the endpoint we are looking for? */ 3051da177e4SLinus Torvalds struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep, 3064cdadcbcSEric W. Biederman struct net *net, 3071da177e4SLinus Torvalds const union sctp_addr *laddr) 3081da177e4SLinus Torvalds { 309559cf710SVlad Yasevich struct sctp_endpoint *retval = NULL; 3101da177e4SLinus Torvalds 3114cdadcbcSEric W. Biederman if ((htons(ep->base.bind_addr.port) == laddr->v4.sin_port) && 3124cdadcbcSEric W. Biederman net_eq(sock_net(ep->base.sk), net)) { 3131da177e4SLinus Torvalds if (sctp_bind_addr_match(&ep->base.bind_addr, laddr, 314559cf710SVlad Yasevich sctp_sk(ep->base.sk))) 3151da177e4SLinus Torvalds retval = ep; 3161da177e4SLinus Torvalds } 3171da177e4SLinus Torvalds 3181da177e4SLinus Torvalds return retval; 3191da177e4SLinus Torvalds } 3201da177e4SLinus Torvalds 3211da177e4SLinus Torvalds /* Find the association that goes with this chunk. 3221da177e4SLinus Torvalds * We do a linear search of the associations for this endpoint. 3231da177e4SLinus Torvalds * We return the matching transport address too. 3241da177e4SLinus Torvalds */ 3251da177e4SLinus Torvalds static struct sctp_association *__sctp_endpoint_lookup_assoc( 3261da177e4SLinus Torvalds const struct sctp_endpoint *ep, 3271da177e4SLinus Torvalds const union sctp_addr *paddr, 3281da177e4SLinus Torvalds struct sctp_transport **transport) 3291da177e4SLinus Torvalds { 330123ed979SVlad Yasevich struct sctp_association *asoc = NULL; 331deb85a6eSVlad Yasevich struct sctp_association *tmp; 332123ed979SVlad Yasevich struct sctp_transport *t = NULL; 333123ed979SVlad Yasevich struct sctp_hashbucket *head; 334123ed979SVlad Yasevich struct sctp_ep_common *epb; 335d970dbf8SVlad Yasevich struct hlist_node *node; 336123ed979SVlad Yasevich int hash; 3371da177e4SLinus Torvalds int rport; 3381da177e4SLinus Torvalds 3391da177e4SLinus Torvalds *transport = NULL; 340deb85a6eSVlad Yasevich 341deb85a6eSVlad Yasevich /* If the local port is not set, there can't be any associations 342deb85a6eSVlad Yasevich * on this endpoint. 343deb85a6eSVlad Yasevich */ 344deb85a6eSVlad Yasevich if (!ep->base.bind_addr.port) 345deb85a6eSVlad Yasevich goto out; 346deb85a6eSVlad Yasevich 347123ed979SVlad Yasevich rport = ntohs(paddr->v4.sin_port); 348123ed979SVlad Yasevich 3494110cc25SEric W. Biederman hash = sctp_assoc_hashfn(sock_net(ep->base.sk), ep->base.bind_addr.port, 3504110cc25SEric W. Biederman rport); 351123ed979SVlad Yasevich head = &sctp_assoc_hashtable[hash]; 352123ed979SVlad Yasevich read_lock(&head->lock); 353d970dbf8SVlad Yasevich sctp_for_each_hentry(epb, node, &head->chain) { 354deb85a6eSVlad Yasevich tmp = sctp_assoc(epb); 355deb85a6eSVlad Yasevich if (tmp->ep != ep || rport != tmp->peer.port) 356deb85a6eSVlad Yasevich continue; 357123ed979SVlad Yasevich 358deb85a6eSVlad Yasevich t = sctp_assoc_lookup_paddr(tmp, paddr); 359123ed979SVlad Yasevich if (t) { 360deb85a6eSVlad Yasevich asoc = tmp; 361123ed979SVlad Yasevich *transport = t; 362123ed979SVlad Yasevich break; 363123ed979SVlad Yasevich } 364123ed979SVlad Yasevich } 365123ed979SVlad Yasevich read_unlock(&head->lock); 366deb85a6eSVlad Yasevich out: 367123ed979SVlad Yasevich return asoc; 3681da177e4SLinus Torvalds } 3691da177e4SLinus Torvalds 3701da177e4SLinus Torvalds /* Lookup association on an endpoint based on a peer address. BH-safe. */ 3711da177e4SLinus Torvalds struct sctp_association *sctp_endpoint_lookup_assoc( 3721da177e4SLinus Torvalds const struct sctp_endpoint *ep, 3731da177e4SLinus Torvalds const union sctp_addr *paddr, 3741da177e4SLinus Torvalds struct sctp_transport **transport) 3751da177e4SLinus Torvalds { 3761da177e4SLinus Torvalds struct sctp_association *asoc; 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvalds sctp_local_bh_disable(); 3791da177e4SLinus Torvalds asoc = __sctp_endpoint_lookup_assoc(ep, paddr, transport); 3801da177e4SLinus Torvalds sctp_local_bh_enable(); 3811da177e4SLinus Torvalds 3821da177e4SLinus Torvalds return asoc; 3831da177e4SLinus Torvalds } 3841da177e4SLinus Torvalds 3851da177e4SLinus Torvalds /* Look for any peeled off association from the endpoint that matches the 3861da177e4SLinus Torvalds * given peer address. 3871da177e4SLinus Torvalds */ 3881da177e4SLinus Torvalds int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep, 3891da177e4SLinus Torvalds const union sctp_addr *paddr) 3901da177e4SLinus Torvalds { 3911da177e4SLinus Torvalds struct sctp_sockaddr_entry *addr; 3921da177e4SLinus Torvalds struct sctp_bind_addr *bp; 3934110cc25SEric W. Biederman struct net *net = sock_net(ep->base.sk); 3941da177e4SLinus Torvalds 3951da177e4SLinus Torvalds bp = &ep->base.bind_addr; 396559cf710SVlad Yasevich /* This function is called with the socket lock held, 397559cf710SVlad Yasevich * so the address_list can not change. 398559cf710SVlad Yasevich */ 399559cf710SVlad Yasevich list_for_each_entry(addr, &bp->address_list, list) { 4004110cc25SEric W. Biederman if (sctp_has_association(net, &addr->a, paddr)) 4011da177e4SLinus Torvalds return 1; 4021da177e4SLinus Torvalds } 4031da177e4SLinus Torvalds 4041da177e4SLinus Torvalds return 0; 4051da177e4SLinus Torvalds } 4061da177e4SLinus Torvalds 4071da177e4SLinus Torvalds /* Do delayed input processing. This is scheduled by sctp_rcv(). 4081da177e4SLinus Torvalds * This may be called on BH or task time. 4091da177e4SLinus Torvalds */ 410c4028958SDavid Howells static void sctp_endpoint_bh_rcv(struct work_struct *work) 4111da177e4SLinus Torvalds { 412c4028958SDavid Howells struct sctp_endpoint *ep = 413c4028958SDavid Howells container_of(work, struct sctp_endpoint, 414c4028958SDavid Howells base.inqueue.immediate); 4151da177e4SLinus Torvalds struct sctp_association *asoc; 4161da177e4SLinus Torvalds struct sock *sk; 41755e26eb9SEric W. Biederman struct net *net; 4181da177e4SLinus Torvalds struct sctp_transport *transport; 4191da177e4SLinus Torvalds struct sctp_chunk *chunk; 4201da177e4SLinus Torvalds struct sctp_inq *inqueue; 4211da177e4SLinus Torvalds sctp_subtype_t subtype; 4221da177e4SLinus Torvalds sctp_state_t state; 4231da177e4SLinus Torvalds int error = 0; 42442b2aa86SJustin P. Mattock int first_time = 1; /* is this the first time through the loop */ 4251da177e4SLinus Torvalds 4261da177e4SLinus Torvalds if (ep->base.dead) 4271da177e4SLinus Torvalds return; 4281da177e4SLinus Torvalds 4291da177e4SLinus Torvalds asoc = NULL; 4301da177e4SLinus Torvalds inqueue = &ep->base.inqueue; 4311da177e4SLinus Torvalds sk = ep->base.sk; 43255e26eb9SEric W. Biederman net = sock_net(sk); 4331da177e4SLinus Torvalds 4341da177e4SLinus Torvalds while (NULL != (chunk = sctp_inq_pop(inqueue))) { 4351da177e4SLinus Torvalds subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); 4361da177e4SLinus Torvalds 437bbd0d598SVlad Yasevich /* If the first chunk in the packet is AUTH, do special 438bbd0d598SVlad Yasevich * processing specified in Section 6.3 of SCTP-AUTH spec 439bbd0d598SVlad Yasevich */ 440bbd0d598SVlad Yasevich if (first_time && (subtype.chunk == SCTP_CID_AUTH)) { 441bbd0d598SVlad Yasevich struct sctp_chunkhdr *next_hdr; 442bbd0d598SVlad Yasevich 443bbd0d598SVlad Yasevich next_hdr = sctp_inq_peek(inqueue); 444bbd0d598SVlad Yasevich if (!next_hdr) 445bbd0d598SVlad Yasevich goto normal; 446bbd0d598SVlad Yasevich 447bbd0d598SVlad Yasevich /* If the next chunk is COOKIE-ECHO, skip the AUTH 448bbd0d598SVlad Yasevich * chunk while saving a pointer to it so we can do 449bbd0d598SVlad Yasevich * Authentication later (during cookie-echo 450bbd0d598SVlad Yasevich * processing). 451bbd0d598SVlad Yasevich */ 452bbd0d598SVlad Yasevich if (next_hdr->type == SCTP_CID_COOKIE_ECHO) { 453bbd0d598SVlad Yasevich chunk->auth_chunk = skb_clone(chunk->skb, 454bbd0d598SVlad Yasevich GFP_ATOMIC); 455bbd0d598SVlad Yasevich chunk->auth = 1; 456bbd0d598SVlad Yasevich continue; 457bbd0d598SVlad Yasevich } 458bbd0d598SVlad Yasevich } 459bbd0d598SVlad Yasevich normal: 4601da177e4SLinus Torvalds /* We might have grown an association since last we 4611da177e4SLinus Torvalds * looked, so try again. 4621da177e4SLinus Torvalds * 4631da177e4SLinus Torvalds * This happens when we've just processed our 4641da177e4SLinus Torvalds * COOKIE-ECHO chunk. 4651da177e4SLinus Torvalds */ 4661da177e4SLinus Torvalds if (NULL == chunk->asoc) { 4671da177e4SLinus Torvalds asoc = sctp_endpoint_lookup_assoc(ep, 4681da177e4SLinus Torvalds sctp_source(chunk), 4691da177e4SLinus Torvalds &transport); 4701da177e4SLinus Torvalds chunk->asoc = asoc; 4711da177e4SLinus Torvalds chunk->transport = transport; 4721da177e4SLinus Torvalds } 4731da177e4SLinus Torvalds 4741da177e4SLinus Torvalds state = asoc ? asoc->state : SCTP_STATE_CLOSED; 475bbd0d598SVlad Yasevich if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth) 476bbd0d598SVlad Yasevich continue; 4771da177e4SLinus Torvalds 4781da177e4SLinus Torvalds /* Remember where the last DATA chunk came from so we 4791da177e4SLinus Torvalds * know where to send the SACK. 4801da177e4SLinus Torvalds */ 4811da177e4SLinus Torvalds if (asoc && sctp_chunk_is_data(chunk)) 4821da177e4SLinus Torvalds asoc->peer.last_data_from = chunk->transport; 483196d6759SMichele Baldessari else { 484b01a2407SEric W. Biederman SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS); 485196d6759SMichele Baldessari if (asoc) 486196d6759SMichele Baldessari asoc->stats.ictrlchunks++; 487196d6759SMichele Baldessari } 4881da177e4SLinus Torvalds 4891da177e4SLinus Torvalds if (chunk->transport) 4901da177e4SLinus Torvalds chunk->transport->last_time_heard = jiffies; 4911da177e4SLinus Torvalds 49255e26eb9SEric W. Biederman error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype, state, 4931da177e4SLinus Torvalds ep, asoc, chunk, GFP_ATOMIC); 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds if (error && chunk) 4961da177e4SLinus Torvalds chunk->pdiscard = 1; 4971da177e4SLinus Torvalds 4981da177e4SLinus Torvalds /* Check to see if the endpoint is freed in response to 4991da177e4SLinus Torvalds * the incoming chunk. If so, get out of the while loop. 5001da177e4SLinus Torvalds */ 5011da177e4SLinus Torvalds if (!sctp_sk(sk)->ep) 5021da177e4SLinus Torvalds break; 503bbd0d598SVlad Yasevich 504bbd0d598SVlad Yasevich if (first_time) 505bbd0d598SVlad Yasevich first_time = 0; 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds } 508