diff options
author | rrs <rrs@FreeBSD.org> | 2007-06-13 01:31:53 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-06-13 01:31:53 +0000 |
commit | 20ad8ecfb0af809f13b9dc6e5ab994548e0d785c (patch) | |
tree | 8d5bbe40650c2eb2f33e58ff8a55f66ae96d6c38 | |
parent | ec70de06d657f80cf4eaa0dee9fa7938ca45ac46 (diff) | |
download | FreeBSD-src-20ad8ecfb0af809f13b9dc6e5ab994548e0d785c.zip FreeBSD-src-20ad8ecfb0af809f13b9dc6e5ab994548e0d785c.tar.gz |
- Fixed cookie handling to calc an RTO when
its an INIT collision case.
- Fixed RTO calc to maintain a seperate variable to track
if a RTO calc as been done, this allows the RTO var to be
doubled during initial timeouts.
- Reduces the amount of stack used by process control.
- Use a constant for the peer chunk overhead.
- Name change to spell candidate correctly.
-rw-r--r-- | sys/netinet/sctp.h | 3 | ||||
-rw-r--r-- | sys/netinet/sctp_constants.h | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_input.c | 67 | ||||
-rw-r--r-- | sys/netinet/sctp_pcb.c | 30 | ||||
-rw-r--r-- | sys/netinet/sctp_structs.h | 1 | ||||
-rw-r--r-- | sys/netinet/sctp_sysctl.c | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_sysctl.h | 4 | ||||
-rw-r--r-- | sys/netinet/sctp_timer.c | 3 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 3 |
9 files changed, 57 insertions, 58 deletions
diff --git a/sys/netinet/sctp.h b/sys/netinet/sctp.h index c11fa34..0f81850 100644 --- a/sys/netinet/sctp.h +++ b/sys/netinet/sctp.h @@ -378,6 +378,9 @@ __attribute__((packed)); #define SCTP_PACKET_DROPPED 0x81 /* draft-ietf-stewart-strreset-xxx */ #define SCTP_STREAM_RESET 0x82 + +/* RFC4820 */ +#define SCTP_PAD_CHUNK 0x84 /************0xc0 series ***********/ /* RFC3758 */ #define SCTP_FORWARD_CUM_TSN 0xc0 diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index 73fdb14..c3d2997 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -748,7 +748,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_DEFAULT_MAXSEGMENT 65535 -#define SCTP_CHUNK_BUFFER_SIZE 2048 +#define SCTP_CHUNK_BUFFER_SIZE 512 #define SCTP_PARAM_BUFFER_SIZE 512 #define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index d1dff3c..1042159 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -1144,6 +1144,8 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, * double things */ net->hb_responded = 1; + net->RTO = sctp_calculate_rto(stcb, asoc, net, + &cookie->time_entered); if (stcb->asoc.sctp_autoclose_ticks && (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))) { @@ -1718,9 +1720,10 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset, } /* respond with a COOKIE-ACK */ /* calculate the RTT */ - if ((netp) && (*netp)) + if ((netp) && (*netp)) { (*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp, &cookie->time_entered); + } sctp_send_cookie_ack(stcb); return (stcb); } @@ -3673,14 +3676,20 @@ process_control_chunks: } return (NULL); } - } else if (ch->chunk_type == SCTP_COOKIE_ECHO) { + } else { + /* + * For cookies and all other chunks. if the + */ if (chk_length > sizeof(chunk_buf)) { /* * use just the size of the chunk buffer so - * the front part of our cookie is intact. - * The rest of cookie processing should use - * the sctp_m_getptr() function to access - * the other parts. + * the front part of our chunks fit in + * contiguous space up to the chunk buffer + * size (508 bytes). For chunks that need to + * get more than that they mus use the + * sctp_m_getptr() function or other means + * (know how to parse mbuf chains). Cookies + * do this already. */ ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, (sizeof(chunk_buf) - 4), @@ -3694,44 +3703,16 @@ process_control_chunks: } } else { /* We can fit it all */ - goto all_fits; - } - } else { - /* get a complete chunk... */ - if (chk_length > sizeof(chunk_buf)) { - struct mbuf *oper; - struct sctp_paramhdr *phdr; - - oper = NULL; - if (stcb) { - oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), - 0, M_DONTWAIT, 1, MT_DATA); - - if (oper) { - /* pre-reserve some space */ - SCTP_BUF_RESV_UF(oper, sizeof(struct sctp_chunkhdr)); - SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr); - phdr = mtod(oper, struct sctp_paramhdr *); - phdr->param_type = htons(SCTP_CAUSE_OUT_OF_RESC); - phdr->param_length = htons(sizeof(struct sctp_paramhdr)); - sctp_queue_op_err(stcb, oper); + ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, + chk_length, chunk_buf); + if (ch == NULL) { + SCTP_PRINTF("sctp_process_control: Can't get the all data....\n"); + *offset = length; + if (locked_tcb) { + SCTP_TCB_UNLOCK(locked_tcb); } + return (NULL); } - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); - } - all_fits: - ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset, - chk_length, chunk_buf); - if (ch == NULL) { - SCTP_PRINTF("sctp_process_control: Can't get the all data....\n"); - *offset = length; - if (locked_tcb) { - SCTP_TCB_UNLOCK(locked_tcb); - } - return (NULL); } } num_chunks++; @@ -3814,6 +3795,8 @@ process_control_chunks: } return (NULL); break; + case SCTP_PAD_CHUNK: + break; case SCTP_INITIATION_ACK: /* must be first and only chunk */ SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n"); diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 1db8d33..ce71edc 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -1274,7 +1274,8 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, */ struct sctp_tcb * sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from, - struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, uint32_t vrf_id) + struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, + uint32_t vrf_id) { struct sctp_inpcb *inp = NULL; struct sctp_tcb *retval; @@ -1282,9 +1283,11 @@ sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from, SCTP_INP_INFO_RLOCK(); if (find_tcp_pool) { if (inp_p != NULL) { - retval = sctp_tcb_special_locate(inp_p, from, to, netp, vrf_id); + retval = sctp_tcb_special_locate(inp_p, from, to, netp, + vrf_id); } else { - retval = sctp_tcb_special_locate(&inp, from, to, netp, vrf_id); + retval = sctp_tcb_special_locate(&inp, from, to, netp, + vrf_id); } if (retval != NULL) { SCTP_INP_INFO_RUNLOCK(); @@ -1307,9 +1310,11 @@ sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from, * inbound packet side. */ if (inp_p != NULL) { - retval = sctp_findassociation_ep_addr(inp_p, from, netp, to, NULL); + retval = sctp_findassociation_ep_addr(inp_p, from, netp, to, + NULL); } else { - retval = sctp_findassociation_ep_addr(&inp, from, netp, to, NULL); + retval = sctp_findassociation_ep_addr(&inp, from, netp, to, + NULL); } return retval; } @@ -2216,7 +2221,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p) } } } else { - uint16_t first, last, candiate; + uint16_t first, last, candidate; uint16_t count; int done; @@ -2246,11 +2251,11 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p) last = temp; } count = last - first + 1; /* number of candidates */ - candiate = first + sctp_select_initial_TSN(&inp->sctp_ep) % (count); + candidate = first + sctp_select_initial_TSN(&inp->sctp_ep) % (count); done = 0; while (!done) { - if (sctp_isport_inuse(inp, htons(candiate), inp->def_vrf_id) == 0) { + if (sctp_isport_inuse(inp, htons(candidate), inp->def_vrf_id) == 0) { done = 1; } if (!done) { @@ -2260,13 +2265,13 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p) SCTP_INP_INFO_WUNLOCK(); return (EADDRINUSE); } - if (candiate == last) - candiate = first; + if (candidate == last) + candidate = first; else - candiate = candiate + 1; + candidate = candidate + 1; } } - lport = htons(candiate); + lport = htons(candidate); } SCTP_INP_DECR_REF(inp); if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | @@ -3063,6 +3068,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, * initial value */ net->RTO = 0; + net->RTO_measured = 0; stcb->asoc.numnets++; *(&net->ref_count) = 1; net->tos_flowlabel = 0; diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index acfd6f9..3274860 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -262,6 +262,7 @@ struct sctp_nets { * indicate if a new pseudo-cumack or * rtx-pseudo-cumack has been received */ uint8_t window_probe; /* Doing a window probe? */ + uint8_t RTO_measured; /* Have we done the first measure */ #ifdef SCTP_HIGH_SPEED uint8_t last_hs_used; /* index into the last HS table entry we used */ #endif diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index c76b01f..04bb078 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -58,7 +58,7 @@ uint32_t sctp_strict_init = 1; uint32_t sctp_abort_if_one_2_one_hits_limit = 0; uint32_t sctp_strict_data_order = 0; -uint32_t sctp_peer_chunk_oh = sizeof(struct mbuf); +uint32_t sctp_peer_chunk_oh = SCTPCTL_PEER_CHKOH_DEFAULT; uint32_t sctp_max_burst_default = SCTP_DEF_MAX_BURST; uint32_t sctp_use_cwnd_based_maxburst = 1; uint32_t sctp_do_drain = 1; diff --git a/sys/netinet/sctp_sysctl.h b/sys/netinet/sctp_sysctl.h index 609146f..e54bb6a 100644 --- a/sys/netinet/sctp_sysctl.h +++ b/sys/netinet/sctp_sysctl.h @@ -101,7 +101,7 @@ __FBSDID("$FreeBSD$"); #define SCTPCTL_PEER_CHKOH_DESC "Amount to debit peers rwnd per chunk sent" #define SCTPCTL_PEER_CHKOH_MIN 0 #define SCTPCTL_PEER_CHKOH_MAX 0xFFFFFFFF -#define SCTPCTL_PEER_CHKOH_DEFAULT 0 /* sizeof struct mbuf */ +#define SCTPCTL_PEER_CHKOH_DEFAULT 256 /* maxburst: Default max burst for sctp endpoints */ #define SCTPCTL_MAXBURST 10 @@ -327,6 +327,8 @@ __FBSDID("$FreeBSD$"); #define SCTPCTL_NAT_FRIENDLY_MAX 1 #define SCTPCTL_NAT_FRIENDLY_DEFAULT 1 + + /* abc_l_var: SCTP ABC max increase per SACK (L) */ #define SCTPCTL_ABC_L_VAR 42 #define SCTPCTL_ABC_L_VAR_DESC "SCTP ABC max increase per SACK (L)" diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 39f46d06..b66ca43 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -390,6 +390,9 @@ sctp_backoff_on_timeout(struct sctp_tcb *stcb, int win_probe, int num_marked) { + if (net->RTO == 0) { + net->RTO = stcb->asoc.minrto; + } net->RTO <<= 1; if (net->RTO > stcb->asoc.maxrto) { net->RTO = stcb->asoc.maxrto; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index fb2e1ad..b2f9f99 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -2576,7 +2576,7 @@ sctp_calculate_rto(struct sctp_tcb *stcb, /***************************/ o_calctime = calc_time; /* this is Van Jacobson's integer version */ - if (net->RTO) { + if (net->RTO_measured) { calc_time -= (net->lastsa >> SCTP_RTT_SHIFT); /* take away 1/8th when * shift=3 */ #ifdef SCTP_RTTVAR_LOGGING @@ -2596,6 +2596,7 @@ sctp_calculate_rto(struct sctp_tcb *stcb, } } else { /* First RTO measurment */ + net->RTO_measured = 1; net->lastsa = calc_time << SCTP_RTT_SHIFT; /* Multiply by 8 when * shift=3 */ net->lastsv = calc_time; |