Skip to content

Commit

Permalink
Allow sending packets with INIT ACK chunks and zero checksum
Browse files Browse the repository at this point in the history
  • Loading branch information
tuexen committed Feb 28, 2024
1 parent 265f205 commit 848eca8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
2 changes: 1 addition & 1 deletion usrsctplib/netinet/sctp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,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,
Expand Down
45 changes: 39 additions & 6 deletions usrsctplib/netinet/sctp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -5370,7 +5370,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
Expand All @@ -5386,8 +5387,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;
Expand All @@ -5396,6 +5397,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;
Expand Down Expand Up @@ -5451,6 +5455,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);
Expand Down Expand Up @@ -5491,11 +5511,16 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
at += padded_size;
break;
case SCTP_HAS_NAT_SUPPORT:
if (padded_size != sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error nat support %d\n", plen);
goto invalid_size;
}
*nat_friendly = 1;
/* FALLTHROUGH */
at += padded_size;
break;
case SCTP_PRSCTP_SUPPORTED:
if (padded_size != sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp/nat support %d\n", plen);
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp %d\n", plen);
goto invalid_size;
}
at += padded_size;
Expand Down Expand Up @@ -5992,7 +6017,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;
Expand Down Expand Up @@ -6036,7 +6063,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) {
Expand Down Expand Up @@ -6716,14 +6743,20 @@ 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,
#if defined(__FreeBSD__) && !defined(__Userspace__)
mflowtype, mflowid,
#endif
false, /* XXXMT: Improve this! */
use_zero_crc,
SCTP_SO_NOT_LOCKED))) {
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Gak send error %d\n", error);
if (error == ENOBUFS) {
Expand Down
4 changes: 3 additions & 1 deletion usrsctplib/netinet/sctp_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,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
Expand Down

0 comments on commit 848eca8

Please sign in to comment.