|
@@ -328,24 +328,34 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
|
|
|
const union sctp_addr *paddr,
|
|
|
struct sctp_transport **transport)
|
|
|
{
|
|
|
+ struct sctp_association *asoc = NULL;
|
|
|
+ struct sctp_transport *t = NULL;
|
|
|
+ struct sctp_hashbucket *head;
|
|
|
+ struct sctp_ep_common *epb;
|
|
|
+ int hash;
|
|
|
int rport;
|
|
|
- struct sctp_association *asoc;
|
|
|
- struct list_head *pos;
|
|
|
|
|
|
+ *transport = NULL;
|
|
|
rport = ntohs(paddr->v4.sin_port);
|
|
|
|
|
|
- list_for_each(pos, &ep->asocs) {
|
|
|
- asoc = list_entry(pos, struct sctp_association, asocs);
|
|
|
- if (rport == asoc->peer.port) {
|
|
|
- *transport = sctp_assoc_lookup_paddr(asoc, paddr);
|
|
|
-
|
|
|
- if (*transport)
|
|
|
- return asoc;
|
|
|
+ hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
|
|
|
+ head = &sctp_assoc_hashtable[hash];
|
|
|
+ read_lock(&head->lock);
|
|
|
+ for (epb = head->chain; epb; epb = epb->next) {
|
|
|
+ asoc = sctp_assoc(epb);
|
|
|
+ if (asoc->ep != ep || rport != asoc->peer.port)
|
|
|
+ goto next;
|
|
|
+
|
|
|
+ t = sctp_assoc_lookup_paddr(asoc, paddr);
|
|
|
+ if (t) {
|
|
|
+ *transport = t;
|
|
|
+ break;
|
|
|
}
|
|
|
+next:
|
|
|
+ asoc = NULL;
|
|
|
}
|
|
|
-
|
|
|
- *transport = NULL;
|
|
|
- return NULL;
|
|
|
+ read_unlock(&head->lock);
|
|
|
+ return asoc;
|
|
|
}
|
|
|
|
|
|
/* Lookup association on an endpoint based on a peer address. BH-safe. */
|