summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_timer.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-03-15 11:27:14 +0000
committerrrs <rrs@FreeBSD.org>2007-03-15 11:27:14 +0000
commitbd8786ed778eb3e2e64f4bc1078d8653aa1a6d54 (patch)
tree3a099c736ba497f25dc6fd964a7995f33f2282ad /sys/netinet/sctp_timer.c
parent7f1d3da162e9e7e9561d1b1ab3e88b00622c7b5e (diff)
downloadFreeBSD-src-bd8786ed778eb3e2e64f4bc1078d8653aa1a6d54.zip
FreeBSD-src-bd8786ed778eb3e2e64f4bc1078d8653aa1a6d54.tar.gz
- Sysctl's move to seperate file
- moved away from ifn/ifa access to sctp_ifa/sctp_ifn built and managed by the add-ip code. - cleaned up add-ip code to use the iterator - made iterator be a thread, which enables auto-asconf now. - rewrote and cleaned up source address selection (also made it use new structures). - Fixed a couple of memory leaks. - DACK now settable as to how many packets to delay as well as time. - connectx() to latest socket API, new associd arg. - Fixed issue with revoking and loosing potential to send when we inflate the flight size. We now inflate the cwnd too and deflate it later when the revoked chunk is sent or acked. - Got rid of some temp debug code - src addr selection moved to a common file (sctp_output.c) - Support for simple VRF's (we have support for multi-vfr via compile switch that is scrubbed from BSD but we won't need multi-vrf until we first get VRF :-D) - Rest of mib work for address information now done - Limit number of addresses in INIT/INIT-ACK to a #def (30). Reviewed by: gnn
Diffstat (limited to 'sys/netinet/sctp_timer.c')
-rw-r--r--sys/netinet/sctp_timer.c71
1 files changed, 57 insertions, 14 deletions
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index 62de925..1d6902e 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/sctp6_var.h>
#endif
#include <netinet/sctp_var.h>
+#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_timer.h>
#include <netinet/sctputil.h>
#include <netinet/sctp_output.h>
@@ -51,13 +52,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_uio.h>
-#ifdef SCTP_DEBUG
-extern uint32_t sctp_debug_on;
-
-#endif /* SCTP_DEBUG */
-
-
-extern unsigned int sctp_early_fr_msec;
void
sctp_early_fr_timer(struct sctp_inpcb *inp,
@@ -224,6 +218,7 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (net->dest_state & SCTP_ADDR_REACHABLE) {
net->dest_state &= ~SCTP_ADDR_REACHABLE;
net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
+ net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
if (net == stcb->asoc.primary_destination) {
net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
}
@@ -368,6 +363,10 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
if (sin6->sin6_family == AF_INET6) {
(void)sa6_recoverscope(sin6);
}
+ if (alt->ro._s_addr) {
+ sctp_free_ifa(alt->ro._s_addr);
+ alt->ro._s_addr = NULL;
+ }
alt->src_addr_selected = 0;
}
if (
@@ -441,8 +440,6 @@ sctp_backoff_on_timeout(struct sctp_tcb *stcb,
}
}
-extern int sctp_peer_chunk_oh;
-
static int
sctp_mark_all_for_resend(struct sctp_tcb *stcb,
struct sctp_nets *net,
@@ -635,6 +632,11 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
}
if (stcb->asoc.total_flight_count > 0)
stcb->asoc.total_flight_count--;
+ if (chk->rec.data.chunk_was_revoked) {
+ /* deflate the cwnd */
+ chk->whoTo->cwnd -= chk->book_size;
+ chk->rec.data.chunk_was_revoked = 0;
+ }
chk->sent = SCTP_DATAGRAM_RESEND;
SCTP_STAT_INCR(sctps_markedretrans);
net->marked_retrans++;
@@ -934,6 +936,10 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
(struct sockaddr *)NULL,
alt) == 0) {
net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
+ if (net->ro._s_addr) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ }
net->src_addr_selected = 0;
}
}
@@ -1387,6 +1393,15 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
if (net) {
if (net->hb_responded == 0) {
+ if (net->ro._s_addr) {
+ /*
+ * Invalidate the src address if we did not
+ * get a response last time.
+ */
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ net->src_addr_selected = 0;
+ }
sctp_backoff_on_timeout(stcb, net, 1, 0);
}
/* Zero PBA, if it needs it */
@@ -1415,10 +1430,18 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
(net->dest_state & SCTP_ADDR_REACHABLE)) {
cnt_sent++;
+ if (net->hb_responded == 0) {
+ /* Did we respond last time? */
+ if (net->ro._s_addr) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ net->src_addr_selected = 0;
+ }
+ }
if (sctp_send_hb(stcb, 1, net) == 0) {
break;
}
- if (cnt_sent >= stcb->asoc.max_burst)
+ if (cnt_sent >= sctp_hb_maxburst)
break;
}
}
@@ -1598,6 +1621,7 @@ void
sctp_iterator_timer(struct sctp_iterator *it)
{
int iteration_count = 0;
+ int inp_skip = 0;
/*
* only one iterator can run at a time. This is the only way we can
@@ -1610,7 +1634,7 @@ sctp_iterator_timer(struct sctp_iterator *it)
done_with_iterator:
SCTP_ITERATOR_UNLOCK();
SCTP_INP_INFO_WLOCK();
- LIST_REMOVE(it, sctp_nxt_itr);
+ TAILQ_REMOVE(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
/* stopping the callout is not needed, in theory */
SCTP_INP_INFO_WUNLOCK();
SCTP_OS_TIMER_STOP(&it->tmr.timer);
@@ -1650,14 +1674,24 @@ select_a_new_ep:
SCTP_INP_WUNLOCK(it->inp);
SCTP_INP_RLOCK(it->inp);
/* now go through each assoc which is in the desired state */
+ if (it->done_current_ep == 0) {
+ if (it->function_inp != NULL)
+ inp_skip = (*it->function_inp) (it->inp, it->pointer, it->val);
+ it->done_current_ep = 1;
+ }
if (it->stcb == NULL) {
/* run the per instance function */
- if (it->function_inp != NULL)
- (*it->function_inp) (it->inp, it->pointer, it->val);
-
it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
}
SCTP_INP_RUNLOCK(it->inp);
+ if ((inp_skip) || it->stcb == NULL) {
+ if (it->function_inp_end != NULL) {
+ inp_skip = (*it->function_inp_end) (it->inp,
+ it->pointer,
+ it->val);
+ }
+ goto no_stcb;
+ }
if ((it->stcb) &&
(it->stcb->asoc.stcb_starting_point_for_iterator == it)) {
it->stcb->asoc.stcb_starting_point_for_iterator = NULL;
@@ -1695,8 +1729,17 @@ select_a_new_ep:
SCTP_TCB_UNLOCK(it->stcb);
next_assoc:
it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
+ if (it->stcb == NULL) {
+ if (it->function_inp_end != NULL) {
+ inp_skip = (*it->function_inp_end) (it->inp,
+ it->pointer,
+ it->val);
+ }
+ }
}
+no_stcb:
/* done with all assocs on this endpoint, move on to next endpoint */
+ it->done_current_ep = 0;
SCTP_INP_WLOCK(it->inp);
it->inp->inp_starting_point_for_iterator = NULL;
SCTP_INP_WUNLOCK(it->inp);
OpenPOWER on IntegriCloud