aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/sctp_output.c
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2024-02-24 18:16:36 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2024-02-24 18:16:36 +0000
commit644cffe67f61ad5b36b60d621d1c630ff2a50412 (patch)
tree24f7cf70f5d252560ef595c106deaab3bb24162a /sys/netinet/sctp_output.c
parent038699a8f18a0a651ee06b85fa1dbbee1eab56f1 (diff)
Diffstat (limited to 'sys/netinet/sctp_output.c')
-rw-r--r--sys/netinet/sctp_output.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index c988a8426fe8..a8facff6b917 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -4918,7 +4918,8 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
int param_offset, int *abort_processing,
struct sctp_chunkhdr *cp,
int *nat_friendly,
- int *cookie_found)
+ int *cookie_found,
+ uint32_t *edmid)
{
/*
* Given a mbuf containing an INIT or INIT-ACK with the param_offset
@@ -4934,8 +4935,8 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
* hoped that this routine may be reused in the future by new
* features.
*/
+ struct sctp_zero_checksum_acceptable zero_chksum, *zero_chksum_p;
struct sctp_paramhdr *phdr, params;
-
struct mbuf *mat, *m_tmp, *op_err, *op_err_last;
int at, limit, pad_needed;
uint16_t ptype, plen, padded_size;
@@ -4944,6 +4945,9 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
if (cookie_found != NULL) {
*cookie_found = 0;
}
+ if (edmid != NULL) {
+ *edmid = SCTP_EDMID_NONE;
+ }
mat = in_initpkt;
limit = ntohs(cp->chunk_length) - sizeof(struct sctp_init_chunk);
at = param_offset;
@@ -4999,6 +5003,22 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
}
at += padded_size;
break;
+ case SCTP_ZERO_CHECKSUM_ACCEPTABLE:
+ if (padded_size != sizeof(struct sctp_zero_checksum_acceptable)) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error checksum acceptable %d\n", plen);
+ goto invalid_size;
+ }
+ if (edmid != NULL) {
+ phdr = sctp_get_next_param(mat, at,
+ (struct sctp_paramhdr *)&zero_chksum,
+ sizeof(struct sctp_zero_checksum_acceptable));
+ if (phdr != NULL) {
+ zero_chksum_p = (struct sctp_zero_checksum_acceptable *)phdr;
+ *edmid = ntohl(zero_chksum_p->edmid);
+ }
+ }
+ at += padded_size;
+ break;
case SCTP_RANDOM:
if (padded_size > (sizeof(struct sctp_auth_random) + SCTP_RANDOM_MAX_SIZE)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error random %d\n", plen);
@@ -5513,7 +5533,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int nat_friendly = 0;
int error;
struct socket *so;
+ uint32_t edmid;
uint16_t num_ext, chunk_len, padding_len, parameter_len;
+ bool use_zero_crc;
if (stcb) {
asoc = &stcb->asoc;
@@ -5554,7 +5576,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
(offset + sizeof(struct sctp_init_chunk)),
&abort_flag,
(struct sctp_chunkhdr *)init_chk,
- &nat_friendly, NULL);
+ &nat_friendly, NULL, &edmid);
if (abort_flag) {
do_a_abort:
if (op_err == NULL) {
@@ -6155,12 +6177,18 @@ do_a_abort:
over_addr = NULL;
}
+ if (asoc != NULL) {
+ use_zero_crc = (asoc->rcv_edmid != SCTP_EDMID_NONE) && (asoc->rcv_edmid == edmid);
+ } else {
+ use_zero_crc = (inp->rcv_edmid != SCTP_EDMID_NONE) && (inp->rcv_edmid == edmid);
+ }
+
if ((error = sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, NULL, 0, 0,
0, 0,
inp->sctp_lport, sh->src_port, init_chk->init.initiate_tag,
port, over_addr,
mflowtype, mflowid,
- false, /* XXXMT: Improve this! */
+ use_zero_crc,
SCTP_SO_NOT_LOCKED))) {
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Gak send error %d\n", error);
if (error == ENOBUFS) {