summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_timer.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-05-08 00:21:05 +0000
committerrrs <rrs@FreeBSD.org>2007-05-08 00:21:05 +0000
commit532412f6c49a9077f90f5cd40b66c87a16efe085 (patch)
tree4db56edaf6063ffdff843e7c1228529525ec2e80 /sys/netinet/sctp_timer.c
parentcaa15fdaeb248ba5c8dd136083da6989cacd1979 (diff)
downloadFreeBSD-src-532412f6c49a9077f90f5cd40b66c87a16efe085.zip
FreeBSD-src-532412f6c49a9077f90f5cd40b66c87a16efe085.tar.gz
- More macros for OS compatabilty
- PR-SCTP would ignore FWD-TSN's above a rwnd's worth of TSN's (1 byte msgs).. this left the peer hopelessly out of sync.. or an attacker. So now we abort the assoc. - New IFN hash, also rename hashes to match addr/ifn now that the vrf has multiple. - Do not enable SCTP_PCB_FLAGS_RECVDATAIOEVNT per default as defined in the Socket API ID. - Export MTU information via sysctl. - Vrf's need table id's. This is default for BSD, but may be other things later when BSD fully supports VRFs. - Additional stream reset bug (caught by cisco dev-test). - Additional validations for the address in sending a message (socket api). -------- and ----- - Fix association notifications not to give the active open side false notifications. - Fix so sendfile and SENDALL will work properly (missing flag to say socket sender is done). - Fix Bug that prevented COOKIES from being retransmitted. - Break out connectx into helper sub-models so that iox routines can reuse the helpers. - When an address is added during system init (non-dynamic mode) make sure that the "defer use" flag is not set. ** its compiling on XR now :-D ** Reviewed by: gnn
Diffstat (limited to 'sys/netinet/sctp_timer.c')
-rw-r--r--sys/netinet/sctp_timer.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index 57ad30d..3e72cc0 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -200,7 +200,6 @@ sctp_audit_retranmission_queue(struct sctp_association *asoc)
#endif /* SCTP_DEBUG */
}
-
int
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net, uint16_t threshold)
@@ -354,20 +353,10 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
alt = TAILQ_FIRST(&stcb->asoc.nets);
}
if (alt->ro.ro_rt == NULL) {
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)&alt->ro._l_addr;
- if (sin6->sin6_family == AF_INET6) {
- (void)sa6_embedscope(sin6, ip6_use_defzone);
- }
- rtalloc_ign((struct route *)&alt->ro, 0UL);
-
- 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;
}
@@ -936,6 +925,22 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
/* Move all pending over too */
sctp_move_all_chunks_to_alt(stcb, net, alt);
+
+ /*
+ * Get the address that failed, to force a new src address
+ * selecton and a route allocation.
+ */
+ if (net->ro._s_addr) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ }
+ net->src_addr_selected = 0;
+
+ /* Force a route allocation too */
+ if (net->ro.ro_rt) {
+ RTFREE(net->ro.ro_rt);
+ net->ro.ro_rt = NULL;
+ }
/* Was it our primary? */
if ((stcb->asoc.primary_destination == net) && (alt != net)) {
/*
@@ -949,11 +954,6 @@ 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;
}
}
}
@@ -1538,16 +1538,27 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
if (next_mtu <= net->mtu) {
/* nothing to do */
return;
- }
- if (net->ro.ro_rt != NULL) {
- /*
- * only if we have a route and interface do we set anything.
- * Note we always restart the timer though just in case it
- * is updated (i.e. the ifp) or route/ifp is populated.
- */
- if (net->ro.ro_rt->rt_ifp != NULL) {
- if (net->ro.ro_rt->rt_ifp->if_mtu > next_mtu) {
- /* ok it will fit out the door */
+ } {
+ uint32_t mtu;
+
+ if ((net->src_addr_selected == 0) ||
+ (net->ro._s_addr == NULL) ||
+ (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
+ if ((net->ro._s_addr == NULL) && (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ net->src_addr_selected = 0;
+ }
+ net->ro._s_addr = sctp_source_address_selection(inp,
+ stcb,
+ (sctp_route_t *) & net->ro,
+ net, 0, stcb->asoc.vrf_id);
+ if (net->ro._s_addr)
+ net->src_addr_selected = 1;
+ }
+ if (net->ro._s_addr) {
+ mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
+ if (mtu > next_mtu) {
net->mtu = next_mtu;
}
}
OpenPOWER on IntegriCloud