mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
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
This commit is contained in:
parent
038699a8f1
commit
644cffe67f
|
@ -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,
|
||||
|
|
|
@ -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 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||
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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue