From a8657c4fc04fb9cc82100f648810d51ec6ab155a Mon Sep 17 00:00:00 2001 From: t00fcxen Date: Sat, 2 Aug 2014 22:05:33 +0000 Subject: Sync with Mavericks sources. git-svn-id: http://sctp-refimpl.googlecode.com/svn/trunk/KERN/usrsctp/usrsctplib@8944 9df1edf5-d72c-5b5f-11c0-5f5209eb73f7 --- netinet/sctp.h | 3 ++- netinet/sctp_indata.c | 16 +++++++------- netinet/sctp_input.c | 7 +++--- netinet/sctp_output.c | 44 ++++++++++++++++++++++-------------- netinet/sctp_pcb.c | 11 +++++---- netinet/sctp_pcb.h | 3 ++- netinet/sctp_peeloff.c | 4 +++- netinet/sctp_structs.h | 7 +++--- netinet/sctp_sysctl.c | 12 +++++++++- netinet/sctp_sysctl.h | 9 +++++++- netinet/sctp_timer.c | 10 ++++----- netinet/sctp_usrreq.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-- netinet/sctputil.c | 5 +++-- user_socket.c | 2 ++ usrsctp.h | 1 + 15 files changed, 144 insertions(+), 50 deletions(-) diff --git a/netinet/sctp.h b/netinet/sctp.h index 4db083b..885cf89 100755 --- a/netinet/sctp.h +++ b/netinet/sctp.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269448 2014-08-02 21:36:40Z tuexen $"); #endif #ifndef _NETINET_SCTP_H_ @@ -132,6 +132,7 @@ struct sctp_paramhdr { #define SCTP_PEER_ADDR_THLDS 0x00000023 #define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024 #define SCTP_ECN_SUPPORTED 0x00000025 +#define SCTP_PR_SUPPORTED 0x00000026 /* * read-only options diff --git a/netinet/sctp_indata.c b/netinet/sctp_indata.c index cbc8546..22a551f 100755 --- a/netinet/sctp_indata.c +++ b/netinet/sctp_indata.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 269376 2014-08-01 12:42:37Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -2978,7 +2978,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, num_dests_sacked++; } } - if (stcb->asoc.peer_supports_prsctp) { + if (stcb->asoc.prsctp_supported) { (void)SCTP_GETTIME_TIMEVAL(&now); } TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { @@ -2999,7 +2999,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, /* done */ break; } - if (stcb->asoc.peer_supports_prsctp) { + if (stcb->asoc.prsctp_supported) { if ((PR_SCTP_TTL_ENABLED(tp1->flags)) && tp1->sent < SCTP_DATAGRAM_ACKED) { /* Is it expired? */ #ifndef __FreeBSD__ @@ -3252,7 +3252,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, /* remove from the total flight */ sctp_total_flight_decrease(stcb, tp1); - if ((stcb->asoc.peer_supports_prsctp) && + if ((stcb->asoc.prsctp_supported) && (PR_SCTP_RTX_ENABLED(tp1->flags))) { /* Has it been retransmitted tv_sec times? - we store the retran count there. */ if (tp1->snd_count > tp1->rec.data.timetodrop.tv_sec) { @@ -3384,7 +3384,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb, struct timeval now; int now_filled = 0; - if (asoc->peer_supports_prsctp == 0) { + if (asoc->prsctp_supported == 0) { return (NULL); } TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { @@ -4068,7 +4068,7 @@ again: asoc->advanced_peer_ack_point = cumack; } /* PR-Sctp issues need to be addressed too */ - if ((asoc->peer_supports_prsctp) && (asoc->pr_sctp_cnt > 0)) { + if ((asoc->prsctp_supported) && (asoc->pr_sctp_cnt > 0)) { struct sctp_tmit_chunk *lchk; uint32_t old_adv_peer_ack_point; @@ -4506,7 +4506,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, sctp_free_bufspace(stcb, asoc, tp1, 1); sctp_m_freem(tp1->data); tp1->data = NULL; - if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) { + if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(tp1->flags)) { asoc->sent_queue_cnt_removeable--; } } @@ -4941,7 +4941,7 @@ again: asoc->advanced_peer_ack_point = cum_ack; } /* C2. try to further move advancedPeerAckPoint ahead */ - if ((asoc->peer_supports_prsctp) && (asoc->pr_sctp_cnt > 0)) { + if ((asoc->prsctp_supported) && (asoc->pr_sctp_cnt > 0)) { struct sctp_tmit_chunk *lchk; uint32_t old_adv_peer_ack_point; diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c index 1f4e29c..53c4755 100755 --- a/netinet/sctp_input.c +++ b/netinet/sctp_input.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -1122,7 +1122,7 @@ sctp_process_unrecog_chunk(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr, sctp_asconf_cleanup(stcb, net); break; case SCTP_FORWARD_CUM_TSN: - stcb->asoc.peer_supports_prsctp = 0; + stcb->asoc.prsctp_supported = 0; break; default: SCTPDBG(SCTP_DEBUG_INPUT2, @@ -1146,7 +1146,7 @@ sctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr) switch (ntohs(pbad->param_type)) { /* pr-sctp draft */ case SCTP_PRSCTP_SUPPORTED: - stcb->asoc.peer_supports_prsctp = 0; + stcb->asoc.prsctp_supported = 0; break; case SCTP_SUPPORTED_CHUNK_EXT: break; @@ -2927,6 +2927,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset, inp->sctp_frag_point = (*inp_p)->sctp_frag_point; inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off; inp->ecn_supported = (*inp_p)->ecn_supported; + inp->prsctp_supported = (*inp_p)->prsctp_supported; inp->partial_delivery_point = (*inp_p)->partial_delivery_point; inp->sctp_context = (*inp_p)->sctp_context; inp->local_strreset_support = (*inp_p)->local_strreset_support; diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c index dba19be..cc73e61 100755 --- a/netinet/sctp_output.c +++ b/netinet/sctp_output.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -5143,12 +5143,14 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked chunk_len += parameter_len; } - /* And now tell the peer we do support PR-SCTP. */ - parameter_len = (uint16_t)sizeof(struct sctp_paramhdr); - ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len); - ph->param_type = htons(SCTP_PRSCTP_SUPPORTED); - ph->param_length = htons(parameter_len); - chunk_len += parameter_len; + /* PR-SCTP supported parameter */ + if (stcb->asoc.prsctp_supported == 1) { + parameter_len = (uint16_t)sizeof(struct sctp_paramhdr); + ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len); + ph->param_type = htons(SCTP_PRSCTP_SUPPORTED); + ph->param_length = htons(parameter_len); + chunk_len += parameter_len; + } /* Add NAT friendly parameter. */ if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) { @@ -5165,7 +5167,9 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT); pr_supported->chunk_types[num_ext++] = SCTP_ASCONF; pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK; - pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN; + if (stcb->asoc.prsctp_supported == 1) { + pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN; + } pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED; pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET; if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) { @@ -6307,12 +6311,15 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, chunk_len += parameter_len; } - /* And now tell the peer we do pr-sctp */ - parameter_len = (uint16_t)sizeof(struct sctp_paramhdr); - ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len); - ph->param_type = htons(SCTP_PRSCTP_SUPPORTED); - ph->param_length = htons(parameter_len); - chunk_len += parameter_len; + /* PR-SCTP supported parameter */ + if (((asoc != NULL) && (asoc->prsctp_supported == 1)) || + ((asoc == NULL) && (inp->prsctp_supported == 1))) { + parameter_len = (uint16_t)sizeof(struct sctp_paramhdr); + ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len); + ph->param_type = htons(SCTP_PRSCTP_SUPPORTED); + ph->param_length = htons(parameter_len); + chunk_len += parameter_len; + } /* Add NAT friendly parameter */ if (nat_friendly) { @@ -6329,7 +6336,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT); pr_supported->chunk_types[num_ext++] = SCTP_ASCONF; pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK; - pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN; + if (((asoc != NULL) && (asoc->prsctp_supported == 1)) || + ((asoc == NULL) && (inp->prsctp_supported == 1))) { + pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN; + } pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED; pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET; if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) { @@ -6515,7 +6525,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk, *nchk; SCTP_TCB_LOCK_ASSERT(stcb); - if ((asoc->peer_supports_prsctp) && + if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) { TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { /* @@ -13954,7 +13964,7 @@ skip_preblock: continue; } /* PR-SCTP? */ - if ((asoc->peer_supports_prsctp) && (asoc->sent_queue_cnt_removeable > 0)) { + if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) { /* This is ugly but we must assure locking order */ if (hold_tcblock == 0) { SCTP_TCB_LOCK(stcb); diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c index bd394b4..a31c5fa 100755 --- a/netinet/sctp_pcb.c +++ b/netinet/sctp_pcb.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -2842,6 +2842,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off); inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable); + inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable); #if defined(__Userspace__) inp->ulp_info = NULL; inp->recv_callback = NULL; @@ -7107,6 +7108,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, uint32_t keylen; int got_random = 0, got_hmacs = 0, got_chklist = 0; uint8_t ecn_supported; + uint8_t prsctp_supported; #ifdef INET struct sockaddr_in sin; #endif @@ -7138,6 +7140,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, } /* Turn off ECN until we get through all params */ ecn_supported = 0; + prsctp_supported = 0; TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { /* mark all addresses that we have currently on the list */ net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC; @@ -7460,7 +7463,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, stcb->asoc.peer_supports_nat = 1; } else if (ptype == SCTP_PRSCTP_SUPPORTED) { /* Peer supports pr-sctp */ - stcb->asoc.peer_supports_prsctp = 1; + prsctp_supported = 1; } else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) { /* A supported extension chunk */ struct sctp_supported_chunk_types_param *pr_supported; @@ -7473,7 +7476,6 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, return (-25); } stcb->asoc.peer_supports_asconf = 0; - stcb->asoc.peer_supports_prsctp = 0; stcb->asoc.peer_supports_pktdrop = 0; stcb->asoc.peer_supports_strreset = 0; stcb->asoc.peer_supports_nr_sack = 0; @@ -7487,7 +7489,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, stcb->asoc.peer_supports_asconf = 1; break; case SCTP_FORWARD_CUM_TSN: - stcb->asoc.peer_supports_prsctp = 1; + prsctp_supported = 1; break; case SCTP_PACKET_DROPPED: stcb->asoc.peer_supports_pktdrop = 1; @@ -7637,6 +7639,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, } } stcb->asoc.ecn_supported &= ecn_supported; + stcb->asoc.prsctp_supported &= prsctp_supported; /* validate authentication required parameters */ if (got_random && got_hmacs) { stcb->asoc.peer_supports_auth = 1; diff --git a/netinet/sctp_pcb.h b/netinet/sctp_pcb.h index 3b4dbac..7ba6dec 100755 --- a/netinet/sctp_pcb.h +++ b/netinet/sctp_pcb.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 269448 2014-08-02 21:36:40Z tuexen $"); #endif #ifndef _NETINET_SCTP_PCB_H_ @@ -481,6 +481,7 @@ struct sctp_inpcb { uint8_t local_strreset_support; uint32_t sctp_cmt_on_off; uint8_t ecn_supported; + uint8_t prsctp_supported; struct sctp_nonpad_sndrcvinfo def_send; /*- * These three are here for the sosend_dgram diff --git a/netinet/sctp_peeloff.c b/netinet/sctp_peeloff.c index 1cc505a..d184a25 100755 --- a/netinet/sctp_peeloff.c +++ b/netinet/sctp_peeloff.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -126,6 +126,7 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id) n_inp->sctp_frag_point = inp->sctp_frag_point; n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off; n_inp->ecn_supported = inp->ecn_supported; + n_inp->prsctp_supported = inp->prsctp_supported; n_inp->partial_delivery_point = inp->partial_delivery_point; n_inp->sctp_context = inp->sctp_context; n_inp->local_strreset_support = inp->local_strreset_support; @@ -235,6 +236,7 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error) n_inp->sctp_frag_point = inp->sctp_frag_point; n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off; n_inp->ecn_supported = inp->ecn_supported; + n_inp->prsctp_supported = inp->prsctp_supported; n_inp->partial_delivery_point = inp->partial_delivery_point; n_inp->sctp_context = inp->sctp_context; n_inp->local_strreset_support = inp->local_strreset_support; diff --git a/netinet/sctp_structs.h b/netinet/sctp_structs.h index 91e26c5..9ef1c2b 100755 --- a/netinet/sctp_structs.h +++ b/netinet/sctp_structs.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269448 2014-08-02 21:36:40Z tuexen $"); #endif #ifndef _NETINET_SCTP_STRUCTS_H_ @@ -1200,8 +1200,9 @@ struct sctp_association { * sum is updated as well. */ - /* Flag to tell if ECN is allowed */ + /* Flags whether an extension is supported or not */ uint8_t ecn_supported; + uint8_t prsctp_supported; /* Did the peer make the stream config (add out) request */ uint8_t peer_req_out; @@ -1210,8 +1211,6 @@ struct sctp_association { uint8_t peer_supports_asconf; /* EY - flag to indicate if peer can do nr_sack*/ uint8_t peer_supports_nr_sack; - /* pr-sctp support flag */ - uint8_t peer_supports_prsctp; /* peer authentication support flag */ uint8_t peer_supports_auth; /* stream resets are supported by the peer */ diff --git a/netinet/sctp_sysctl.c b/netinet/sctp_sysctl.c index 29aee2a..b8114c5 100755 --- a/netinet/sctp_sysctl.c +++ b/netinet/sctp_sysctl.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 269396 2014-08-01 20:49:27Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -61,6 +61,7 @@ sctp_init_sysctls() SCTP_BASE_SYSCTL(sctp_auto_asconf) = SCTPCTL_AUTOASCONF_DEFAULT; SCTP_BASE_SYSCTL(sctp_multiple_asconfs) = SCTPCTL_MULTIPLEASCONFS_DEFAULT; SCTP_BASE_SYSCTL(sctp_ecn_enable) = SCTPCTL_ECN_ENABLE_DEFAULT; + SCTP_BASE_SYSCTL(sctp_pr_enable) = SCTPCTL_PR_ENABLE_DEFAULT; SCTP_BASE_SYSCTL(sctp_strict_sacks) = SCTPCTL_STRICT_SACKS_DEFAULT; #if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000) #if !defined(SCTP_WITH_NO_CSUM) @@ -772,6 +773,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS) RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX); #endif RANGECHK(SCTP_BASE_SYSCTL(sctp_ecn_enable), SCTPCTL_ECN_ENABLE_MIN, SCTPCTL_ECN_ENABLE_MAX); + RANGECHK(SCTP_BASE_SYSCTL(sctp_pr_enable), SCTPCTL_PR_ENABLE_MIN, SCTPCTL_PR_ENABLE_MAX); RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX); #if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000) #if !defined(SCTP_WITH_NO_CSUM) @@ -1081,6 +1083,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, ecn_enable, CTLTYPE_UINT|CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sysctl_sctp_check, "IU", SCTPCTL_ECN_ENABLE_DESC); +SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, pr_enable, CTLTYPE_UINT|CTLFLAG_RW, + &SCTP_BASE_SYSCTL(sctp_pr_enable), 0, sysctl_sctp_check, "IU", + SCTPCTL_PR_ENABLE_DESC); + SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, strict_sacks, CTLTYPE_UINT|CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sysctl_sctp_check, "IU", SCTPCTL_STRICT_SACKS_DESC); @@ -1420,6 +1426,10 @@ void sysctl_setup_sctp(void) &SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sysctl_sctp_check, SCTPCTL_ECN_ENABLE_DESC); + sysctl_add_oid(&sysctl_oid_top, "pr_enable", CTLTYPE_INT|CTLFLAG_RW, + &SCTP_BASE_SYSCTL(sctp_pr_enable), 0, sysctl_sctp_check, + SCTPCTL_PR_ENABLE_DESC); + sysctl_add_oid(&sysctl_oid_top, "strict_sacks", CTLTYPE_INT|CTLFLAG_RW, &SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sysctl_sctp_check, SCTPCTL_STRICT_SACKS_DESC); diff --git a/netinet/sctp_sysctl.h b/netinet/sctp_sysctl.h index 54a8cbd..21acb20 100755 --- a/netinet/sctp_sysctl.h +++ b/netinet/sctp_sysctl.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 269396 2014-08-01 20:49:27Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 269448 2014-08-02 21:36:40Z tuexen $"); #endif #ifndef _NETINET_SCTP_SYSCTL_H_ @@ -47,6 +47,7 @@ struct sctp_sysctl { uint32_t sctp_auto_asconf; uint32_t sctp_multiple_asconfs; uint32_t sctp_ecn_enable; + uint32_t sctp_pr_enable; uint32_t sctp_fr_max_burst_default; uint32_t sctp_strict_sacks; #if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000) @@ -171,6 +172,12 @@ struct sctp_sysctl { #define SCTPCTL_ECN_ENABLE_MAX 1 #define SCTPCTL_ECN_ENABLE_DEFAULT 1 +/* pr_enable: Enable PR-SCTP */ +#define SCTPCTL_PR_ENABLE_DESC "Enable PR-SCTP" +#define SCTPCTL_PR_ENABLE_MIN 0 +#define SCTPCTL_PR_ENABLE_MAX 1 +#define SCTPCTL_PR_ENABLE_DEFAULT 1 + /* strict_sacks: Enable SCTP Strict SACK checking */ #define SCTPCTL_STRICT_SACKS_DESC "Enable SCTP Strict SACK checking" #define SCTPCTL_STRICT_SACKS_MIN 0 diff --git a/netinet/sctp_timer.c b/netinet/sctp_timer.c index 29f94f3..574a213 100755 --- a/netinet/sctp_timer.c +++ b/netinet/sctp_timer.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 268526 2014-07-11 06:52:48Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #define _IP_VHL @@ -441,7 +441,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb) sctp_free_bufspace(stcb, asoc, chk, 1); sctp_m_freem(chk->data); chk->data = NULL; - if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) { + if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(chk->flags)) { asoc->sent_queue_cnt_removeable--; } } @@ -599,7 +599,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, continue; } } - if (stcb->asoc.peer_supports_prsctp && PR_SCTP_TTL_ENABLED(chk->flags)) { + if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) { /* Is it expired? */ #ifndef __FreeBSD__ if (timercmp(&now, &chk->rec.data.timetodrop, >)) { @@ -617,7 +617,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, continue; } } - if (stcb->asoc.peer_supports_prsctp && PR_SCTP_RTX_ENABLED(chk->flags)) { + if (stcb->asoc.prsctp_supported && PR_SCTP_RTX_ENABLED(chk->flags)) { /* Has it been retransmitted tv_sec times? */ if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) { if (chk->data) { @@ -964,7 +964,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp, sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net); return (0); } - if (stcb->asoc.peer_supports_prsctp) { + if (stcb->asoc.prsctp_supported) { struct sctp_tmit_chunk *lchk; lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc); diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c index 3431751..63eb913 100755 --- a/netinet/sctp_usrreq.c +++ b/netinet/sctp_usrreq.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -4029,6 +4029,33 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, } break; } + case SCTP_PR_SUPPORTED: + { + struct sctp_assoc_value *av; + + SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); + SCTP_FIND_STCB(inp, stcb, av->assoc_id); + + if (stcb) { + av->assoc_value = stcb->asoc.prsctp_supported; + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (av->assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_RLOCK(inp); + av->assoc_value = inp->prsctp_supported; + SCTP_INP_RUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + if (error == 0) { + *optsize = sizeof(struct sctp_assoc_value); + } + break; + } case SCTP_ENABLE_STREAM_RESET: { struct sctp_assoc_value *av; @@ -6808,7 +6835,36 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, if (av->assoc_value == 0) { inp->ecn_supported = 0; } else { - inp->ecn_supported = 0; + inp->ecn_supported = 1; + } + SCTP_INP_WUNLOCK(inp); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + } + break; + } + case SCTP_PR_SUPPORTED: + { + struct sctp_assoc_value *av; + + SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); + SCTP_FIND_STCB(inp, stcb, av->assoc_id); + + if (stcb) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + SCTP_TCB_UNLOCK(stcb); + } else { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || + (av->assoc_id == SCTP_FUTURE_ASSOC)) { + SCTP_INP_WLOCK(inp); + if (av->assoc_value == 0) { + inp->prsctp_supported = 0; + } else { + inp->prsctp_supported = 1; } SCTP_INP_WUNLOCK(inp); } else { diff --git a/netinet/sctputil.c b/netinet/sctputil.c index b1007c9..5e4887c 100755 --- a/netinet/sctputil.c +++ b/netinet/sctputil.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include -__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 269436 2014-08-02 17:35:13Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 269448 2014-08-02 21:36:40Z tuexen $"); #endif #include @@ -973,6 +973,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, asoc->cookie_life = inp->sctp_ep.def_cookie_life; asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off; asoc->ecn_supported = inp->ecn_supported; + asoc->prsctp_supported = inp->prsctp_supported; asoc->sctp_nr_sack_on_off = (uint8_t)SCTP_BASE_SYSCTL(sctp_nr_sack_on_off); asoc->sctp_cmt_pf = (uint8_t)0; asoc->sctp_frag_point = inp->sctp_frag_point; @@ -2739,7 +2740,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, if (notif_len > sizeof(struct sctp_assoc_change)) { if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) { i = 0; - if (stcb->asoc.peer_supports_prsctp) { + if (stcb->asoc.prsctp_supported) { sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR; } if (stcb->asoc.peer_supports_auth) { diff --git a/user_socket.c b/user_socket.c index b771e62..07ff67d 100755 --- a/user_socket.c +++ b/user_socket.c @@ -3247,6 +3247,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_recvspace) USRSCTP_SYSCTL_SET_DEF(sctp_auto_asconf) USRSCTP_SYSCTL_SET_DEF(sctp_multiple_asconfs) USRSCTP_SYSCTL_SET_DEF(sctp_ecn_enable) +USRSCTP_SYSCTL_SET_DEF(sctp_pr_enable) USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks) #if !defined(SCTP_WITH_NO_CSUM) USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback) @@ -3325,6 +3326,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_recvspace) USRSCTP_SYSCTL_GET_DEF(sctp_auto_asconf) USRSCTP_SYSCTL_GET_DEF(sctp_multiple_asconfs) USRSCTP_SYSCTL_GET_DEF(sctp_ecn_enable) +USRSCTP_SYSCTL_GET_DEF(sctp_pr_enable) USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks) #if !defined(SCTP_WITH_NO_CSUM) USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback) diff --git a/usrsctp.h b/usrsctp.h index a3446de..24741b9 100644 --- a/usrsctp.h +++ b/usrsctp.h @@ -992,6 +992,7 @@ USRSCTP_SYSCTL_DECL(sctp_recvspace) USRSCTP_SYSCTL_DECL(sctp_auto_asconf) USRSCTP_SYSCTL_DECL(sctp_multiple_asconfs) USRSCTP_SYSCTL_DECL(sctp_ecn_enable) +USRSCTP_SYSCTL_DECL(sctp_pr_enable) USRSCTP_SYSCTL_DECL(sctp_strict_sacks) #if !defined(SCTP_WITH_NO_CSUM) USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback) -- cgit v1.2.3