git: 644cffe67f61 - main - sctp: improve sending of packets containing an INIT ACK chunk
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 24 Feb 2024 18:20:03 UTC
The branch main has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=644cffe67f61ad5b36b60d621d1c630ff2a50412 commit 644cffe67f61ad5b36b60d621d1c630ff2a50412 Author: Michael Tuexen <tuexen@FreeBSD.org> AuthorDate: 2024-02-24 18:16:36 +0000 Commit: Michael Tuexen <tuexen@FreeBSD.org> CommitDate: 2024-02-24 18:16:36 +0000 sctp: improve sending of packets containing an INIT ACK chunk If the peer announced support of zero checksums, do so when sending packets containing an INIT ACK chunk. MFC after: 1 week --- sys/netinet/sctp_input.c | 2 +- sys/netinet/sctp_output.c | 36 ++++++++++++++++++++++++++++++++---- sys/netinet/sctp_output.h | 4 +++- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 6937f8a2a43f..a55ef5ac1eab 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -406,7 +406,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, op_err = sctp_arethere_unrecognized_parameters(m, (offset + sizeof(struct sctp_init_chunk)), &abort_flag, (struct sctp_chunkhdr *)cp, - &nat_friendly, &cookie_found); + &nat_friendly, &cookie_found, NULL); if (abort_flag) { /* Send an abort and notify peer */ sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, 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) { diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index 1a1d17221b02..88c12367346a 100644 --- a/sys/netinet/sctp_output.h +++ b/sys/netinet/sctp_output.h @@ -80,7 +80,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf * sctp_arethere_unrecognized_parameters(struct mbuf *, int, int *, - struct sctp_chunkhdr *, int *, int *); + struct sctp_chunkhdr *, int *, int *, + uint32_t *); + void sctp_queue_op_err(struct sctp_tcb *, struct mbuf *); int