summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/sctp.h3
-rw-r--r--sys/netinet/sctp_constants.h2
-rw-r--r--sys/netinet/sctp_input.c67
-rw-r--r--sys/netinet/sctp_pcb.c30
-rw-r--r--sys/netinet/sctp_structs.h1
-rw-r--r--sys/netinet/sctp_sysctl.c2
-rw-r--r--sys/netinet/sctp_sysctl.h4
-rw-r--r--sys/netinet/sctp_timer.c3
-rw-r--r--sys/netinet/sctputil.c3
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;
OpenPOWER on IntegriCloud