Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 254899
b: refs/heads/master
c: cd4fcc7
h: refs/heads/master
i:
  254897: 3b58c0f
  254895: 2654326
v: v3
  • Loading branch information
Thomas Graf authored and David S. Miller committed Jul 8, 2011
1 parent a10661d commit 7bc78f2
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3f97fae9482dac1dbdd870a25c89033d3a0b35dc
refs/heads/master: cd4fcc704f30f2064ab30b5300d44d431e46db50
2 changes: 1 addition & 1 deletion trunk/include/net/sctp/ulpevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb)

void sctp_ulpevent_free(struct sctp_ulpevent *);
int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
void sctp_queue_purge_ulpevents(struct sk_buff_head *list);
unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list);

struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
const struct sctp_association *asoc,
Expand Down
13 changes: 8 additions & 5 deletions trunk/net/sctp/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
struct sctp_endpoint *ep;
struct sctp_association *asoc;
struct list_head *pos, *temp;
unsigned int data_was_unread;

SCTP_DEBUG_PRINTK("sctp_close(sk: 0x%p, timeout:%ld)\n", sk, timeout);

Expand All @@ -1393,6 +1394,10 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)

ep = sctp_sk(sk)->ep;

/* Clean up any skbs sitting on the receive queue. */
data_was_unread = sctp_queue_purge_ulpevents(&sk->sk_receive_queue);
data_was_unread += sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby);

/* Walk all associations on an endpoint. */
list_for_each_safe(pos, temp, &ep->asocs) {
asoc = list_entry(pos, struct sctp_association, asocs);
Expand All @@ -1410,7 +1415,9 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
}
}

if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
if (data_was_unread || !skb_queue_empty(&asoc->ulpq.lobby) ||
!skb_queue_empty(&asoc->ulpq.reasm) ||
(sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) {
struct sctp_chunk *chunk;

chunk = sctp_make_abort_user(asoc, NULL, 0);
Expand All @@ -1420,10 +1427,6 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
sctp_primitive_SHUTDOWN(asoc, NULL);
}

/* Clean up any skbs sitting on the receive queue. */
sctp_queue_purge_ulpevents(&sk->sk_receive_queue);
sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby);

/* On a TCP-style socket, block for at most linger_time if set. */
if (sctp_style(sk, TCP) && timeout)
sctp_wait_for_close(sk, timeout);
Expand Down
16 changes: 13 additions & 3 deletions trunk/net/sctp/ulpevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -1081,9 +1081,19 @@ void sctp_ulpevent_free(struct sctp_ulpevent *event)
}

/* Purge the skb lists holding ulpevents. */
void sctp_queue_purge_ulpevents(struct sk_buff_head *list)
unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list)
{
struct sk_buff *skb;
while ((skb = skb_dequeue(list)) != NULL)
sctp_ulpevent_free(sctp_skb2event(skb));
unsigned int data_unread = 0;

while ((skb = skb_dequeue(list)) != NULL) {
struct sctp_ulpevent *event = sctp_skb2event(skb);

if (!sctp_ulpevent_is_notification(event))
data_unread += skb->len;

sctp_ulpevent_free(event);
}

return data_unread;
}

0 comments on commit 7bc78f2

Please sign in to comment.