- 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.
This commit is contained in:
Randall Stewart 2007-06-13 01:31:53 +00:00
parent 8004e6ecc8
commit 9a97252585
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170642
9 changed files with 57 additions and 58 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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 @@ __attribute__((noinline))
}
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 @@ __attribute__((noinline))
}
} 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 @@ __attribute__((noinline))
}
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");

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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)"

View File

@ -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;

View File

@ -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;