diff options
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r-- | net/sctp/associola.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index df5abbff63e2..3912420cedcc 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -87,9 +87,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
87 | /* Retrieve the SCTP per socket area. */ | 87 | /* Retrieve the SCTP per socket area. */ |
88 | sp = sctp_sk((struct sock *)sk); | 88 | sp = sctp_sk((struct sock *)sk); |
89 | 89 | ||
90 | /* Init all variables to a known value. */ | ||
91 | memset(asoc, 0, sizeof(struct sctp_association)); | ||
92 | |||
93 | /* Discarding const is appropriate here. */ | 90 | /* Discarding const is appropriate here. */ |
94 | asoc->ep = (struct sctp_endpoint *)ep; | 91 | asoc->ep = (struct sctp_endpoint *)ep; |
95 | sctp_endpoint_hold(asoc->ep); | 92 | sctp_endpoint_hold(asoc->ep); |
@@ -762,7 +759,8 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
762 | asoc->peer.retran_path = peer; | 759 | asoc->peer.retran_path = peer; |
763 | } | 760 | } |
764 | 761 | ||
765 | if (asoc->peer.active_path == asoc->peer.retran_path) { | 762 | if (asoc->peer.active_path == asoc->peer.retran_path && |
763 | peer->state != SCTP_UNCONFIRMED) { | ||
766 | asoc->peer.retran_path = peer; | 764 | asoc->peer.retran_path = peer; |
767 | } | 765 | } |
768 | 766 | ||
@@ -1194,8 +1192,10 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
1194 | /* Remove any peer addresses not present in the new association. */ | 1192 | /* Remove any peer addresses not present in the new association. */ |
1195 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { | 1193 | list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { |
1196 | trans = list_entry(pos, struct sctp_transport, transports); | 1194 | trans = list_entry(pos, struct sctp_transport, transports); |
1197 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) | 1195 | if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) { |
1198 | sctp_assoc_del_peer(asoc, &trans->ipaddr); | 1196 | sctp_assoc_rm_peer(asoc, trans); |
1197 | continue; | ||
1198 | } | ||
1199 | 1199 | ||
1200 | if (asoc->state >= SCTP_STATE_ESTABLISHED) | 1200 | if (asoc->state >= SCTP_STATE_ESTABLISHED) |
1201 | sctp_transport_reset(trans); | 1201 | sctp_transport_reset(trans); |
@@ -1318,12 +1318,13 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) | |||
1318 | /* Keep track of the next transport in case | 1318 | /* Keep track of the next transport in case |
1319 | * we don't find any active transport. | 1319 | * we don't find any active transport. |
1320 | */ | 1320 | */ |
1321 | if (!next) | 1321 | if (t->state != SCTP_UNCONFIRMED && !next) |
1322 | next = t; | 1322 | next = t; |
1323 | } | 1323 | } |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | asoc->peer.retran_path = t; | 1326 | if (t) |
1327 | asoc->peer.retran_path = t; | ||
1327 | 1328 | ||
1328 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" | 1329 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" |
1329 | " %p addr: ", | 1330 | " %p addr: ", |
@@ -1483,7 +1484,7 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) | |||
1483 | if (asoc->rwnd >= len) { | 1484 | if (asoc->rwnd >= len) { |
1484 | asoc->rwnd -= len; | 1485 | asoc->rwnd -= len; |
1485 | if (over) { | 1486 | if (over) { |
1486 | asoc->rwnd_press = asoc->rwnd; | 1487 | asoc->rwnd_press += asoc->rwnd; |
1487 | asoc->rwnd = 0; | 1488 | asoc->rwnd = 0; |
1488 | } | 1489 | } |
1489 | } else { | 1490 | } else { |