summaryrefslogtreecommitdiff
path: root/net/sctp/associola.c
diff options
context:
space:
mode:
authorSridhar Samudrala <sri@us.ibm.com>2003-02-17 18:09:28 -0800
committerSridhar Samudrala <sri@us.ibm.com>2003-02-17 18:09:28 -0800
commit9967b51fc01aae6d822ad62ff031ff2d656d5b10 (patch)
treee956f79d598e25a7a42faab23d0794ec992c20fa /net/sctp/associola.c
parent611f4c044cbd8595d40d09a34981e57aa8aa5f30 (diff)
parent13970d8e1ff3451967050309ce14ae2b6160bfd5 (diff)
Merge us.ibm.com:/home/sridhar/BK/linux-2.5.62
into us.ibm.com:/home/sridhar/BK/lksctp-2.5.62
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r--net/sctp/associola.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 1f8e0b094a73..916c11d97ac1 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -95,7 +95,7 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
sctp_scope_t scope,
int priority)
{
- sctp_opt_t *sp;
+ struct sctp_opt *sp;
int i;
/* Retrieve the SCTP per socket area. */
@@ -241,8 +241,8 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
asoc->peer.sack_needed = 1;
/* Create an input queue. */
- sctp_inqueue_init(&asoc->base.inqueue);
- sctp_inqueue_set_th_handler(&asoc->base.inqueue,
+ sctp_inq_init(&asoc->base.inqueue);
+ sctp_inq_set_th_handler(&asoc->base.inqueue,
(void (*)(void *))sctp_assoc_bh_rcv,
asoc);
@@ -260,7 +260,6 @@ sctp_association_t *sctp_association_init(sctp_association_t *asoc,
/* Set up the tsn tracking. */
sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0);
- asoc->peer.next_dup_tsn = 0;
skb_queue_head_init(&asoc->addip_chunks);
@@ -311,7 +310,7 @@ void sctp_association_free(sctp_association_t *asoc)
sctp_ulpq_free(&asoc->ulpq);
/* Dispose of any pending chunks on the inqueue. */
- sctp_inqueue_free(&asoc->base.inqueue);
+ sctp_inq_free(&asoc->base.inqueue);
/* Free ssnmap storage. */
sctp_ssnmap_free(asoc->ssnmap);
@@ -368,7 +367,7 @@ struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc,
int priority)
{
struct sctp_transport *peer;
- sctp_opt_t *sp;
+ struct sctp_opt *sp;
unsigned short port;
/* AF_INET and AF_INET6 share common port field. */
@@ -505,7 +504,7 @@ void sctp_assoc_control_transport(sctp_association_t *asoc,
struct sctp_transport *t = NULL;
struct sctp_transport *first;
struct sctp_transport *second;
- sctp_ulpevent_t *event;
+ struct sctp_ulpevent *event;
struct list_head *pos;
int spc_state = 0;
@@ -776,7 +775,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
sctp_endpoint_t *ep;
sctp_chunk_t *chunk;
struct sock *sk;
- sctp_inqueue_t *inqueue;
+ struct sctp_inq *inqueue;
int state, subtype;
sctp_assoc_t associd = sctp_assoc2id(asoc);
int error = 0;
@@ -786,7 +785,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
sk = asoc->base.sk;
inqueue = &asoc->base.inqueue;
- while (NULL != (chunk = sctp_pop_inqueue(inqueue))) {
+ while (NULL != (chunk = sctp_inq_pop(inqueue))) {
state = asoc->state;
subtype = chunk->chunk_hdr->type;
@@ -795,6 +794,8 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
*/
if (sctp_chunk_is_data(chunk))
asoc->peer.last_data_from = chunk->transport;
+ else
+ SCTP_INC_STATS(SctpInCtrlChunks);
if (chunk->transport)
chunk->transport->last_time_heard = jiffies;
@@ -819,7 +820,7 @@ static void sctp_assoc_bh_rcv(sctp_association_t *asoc)
/* This routine moves an association from its old sk to a new sk. */
void sctp_assoc_migrate(sctp_association_t *assoc, struct sock *newsk)
{
- sctp_opt_t *newsp = sctp_sk(newsk);
+ struct sctp_opt *newsp = sctp_sk(newsk);
/* Delete the association from the old endpoint's list of
* associations.
@@ -848,7 +849,6 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new)
/* Copy in new parameters of peer. */
asoc->c = new->c;
asoc->peer.rwnd = new->peer.rwnd;
- asoc->peer.next_dup_tsn = new->peer.next_dup_tsn;
asoc->peer.sack_needed = new->peer.sack_needed;
asoc->peer.i = new->peer.i;
sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE,
@@ -887,26 +887,19 @@ void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new)
}
-/* Choose the transport for sending a shutdown packet.
+/* Update the retran path for sending a retransmitted packet.
* Round-robin through the active transports, else round-robin
* through the inactive transports as this is the next best thing
* we can try.
*/
-struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc)
+void sctp_assoc_update_retran_path(sctp_association_t *asoc)
{
struct sctp_transport *t, *next;
struct list_head *head = &asoc->peer.transport_addr_list;
struct list_head *pos;
- /* If this is the first time SHUTDOWN is sent, use the active
- * path.
- */
- if (!asoc->shutdown_last_sent_to)
- return asoc->peer.active_path;
-
- /* Otherwise, find the next transport in a round-robin fashion. */
-
- t = asoc->shutdown_last_sent_to;
+ /* Find the next transport in a round-robin fashion. */
+ t = asoc->peer.retran_path;
pos = &t->transports;
next = NULL;
@@ -935,13 +928,30 @@ struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *
* other active transports. If so, use the next
* transport.
*/
- if (t == asoc->shutdown_last_sent_to) {
+ if (t == asoc->peer.retran_path) {
t = next;
break;
}
}
- return t;
+ asoc->peer.retran_path = t;
+}
+
+/* Choose the transport for sending a SHUTDOWN packet. */
+struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc)
+{
+ /* If this is the first time SHUTDOWN is sent, use the active path,
+ * else use the retran path. If the last SHUTDOWN was sent over the
+ * retran path, update the retran path and use it.
+ */
+ if (!asoc->shutdown_last_sent_to)
+ return asoc->peer.active_path;
+ else {
+ if (asoc->shutdown_last_sent_to == asoc->peer.retran_path)
+ sctp_assoc_update_retran_path(asoc);
+ return asoc->peer.retran_path;
+ }
+
}
/* Update the association's pmtu and frag_point by going through all the
@@ -990,13 +1000,13 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
asoc->rwnd += len;
}
- SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) - %u\n",
- __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over,
- asoc->a_rwnd);
+ SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) "
+ "- %u\n", __FUNCTION__, asoc, len, asoc->rwnd,
+ asoc->rwnd_over, asoc->a_rwnd);
/* Send a window update SACK if the rwnd has increased by at least the
* minimum of the association's PMTU and half of the receive buffer.
- * The algorithm used is similar to the one described in
+ * The algorithm used is similar to the one described in
* Section 4.2.3.3 of RFC 1122.
*/
if ((asoc->state == SCTP_STATE_ESTABLISHED) &&
@@ -1006,15 +1016,14 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
SCTP_DEBUG_PRINTK("%s: Sending window update SACK- asoc: %p "
"rwnd: %u a_rwnd: %u\n",
__FUNCTION__, asoc, asoc->rwnd, asoc->a_rwnd);
- sack = sctp_make_sack(asoc);
+ sack = sctp_make_sack(asoc);
if (!sack)
- return;
+ return;
/* Update the last advertised rwnd value. */
asoc->a_rwnd = asoc->rwnd;
asoc->peer.sack_needed = 0;
- asoc->peer.next_dup_tsn = 0;
sctp_outq_tail(&asoc->outqueue, sack);
@@ -1022,7 +1031,7 @@ void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
if (timer_pending(timer) && del_timer(timer))
sctp_association_put(asoc);
- }
+ }
}
/* Decrease asoc's rwnd by len. */