summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_pcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/sctp_pcb.c')
-rw-r--r--sys/netinet/sctp_pcb.c114
1 files changed, 73 insertions, 41 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 67ee1fa..fdd70ee 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -2485,6 +2485,12 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
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 (SCTP_BASE_SYSCTL(sctp_auth_disable)) {
+ inp->auth_supported = 0;
+ } else {
+ inp->auth_supported = 1;
+ }
+ inp->asconf_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_asconf_enable);
inp->reconfig_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_reconfig_enable);
inp->nrsack_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_nrsack_enable);
inp->pktdrop_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
@@ -2651,12 +2657,15 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
*/
m->local_hmacs = sctp_default_supported_hmaclist();
m->local_auth_chunks = sctp_alloc_chunklist();
+ if (inp->asconf_supported) {
+ sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks);
+ sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks);
+ }
m->default_dscp = 0;
#ifdef INET6
m->default_flowlabel = 0;
#endif
m->port = 0; /* encapsulation disabled by default */
- sctp_auth_set_default_chunks(m->local_auth_chunks);
LIST_INIT(&m->shared_keys);
/* add default NULL key as key id 0 */
null_key = sctp_alloc_sharedkey();
@@ -6085,11 +6094,14 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sctp_key_t *new_key;
uint32_t keylen;
int got_random = 0, got_hmacs = 0, got_chklist = 0;
- uint8_t ecn_supported;
- uint8_t prsctp_supported;
- uint8_t reconfig_supported;
- uint8_t nrsack_supported;
- uint8_t pktdrop_supported;
+ uint8_t peer_supports_ecn;
+ uint8_t peer_supports_prsctp;
+ uint8_t peer_supports_auth;
+ uint8_t peer_supports_asconf;
+ uint8_t peer_supports_asconf_ack;
+ uint8_t peer_supports_reconfig;
+ uint8_t peer_supports_nrsack;
+ uint8_t peer_supports_pktdrop;
#ifdef INET
struct sockaddr_in sin;
@@ -6118,11 +6130,14 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
} else {
sa = src;
}
- ecn_supported = 0;
- prsctp_supported = 0;
- reconfig_supported = 0;
- nrsack_supported = 0;
- pktdrop_supported = 0;
+ peer_supports_ecn = 0;
+ peer_supports_prsctp = 0;
+ peer_supports_auth = 0;
+ peer_supports_asconf = 0;
+ peer_supports_asconf = 0;
+ peer_supports_reconfig = 0;
+ peer_supports_nrsack = 0;
+ peer_supports_pktdrop = 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;
@@ -6172,12 +6187,6 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
/* the assoc was freed? */
return (-4);
}
- /*
- * peer must explicitly turn this on. This may have been initialized
- * to be "on" in order to allow local addr changes while INIT's are
- * in flight.
- */
- stcb->asoc.peer_supports_asconf = 0;
/* now we must go through each of the params. */
phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
while (phdr) {
@@ -6371,7 +6380,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
} else
#endif
if (ptype == SCTP_ECN_CAPABLE) {
- ecn_supported = 1;
+ peer_supports_ecn = 1;
} else if (ptype == SCTP_ULP_ADAPTATION) {
if (stcb->asoc.state != SCTP_STATE_OPEN) {
struct sctp_adaptation_layer_indication ai,
@@ -6395,7 +6404,9 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
#endif
- stcb->asoc.peer_supports_asconf = 1;
+ if (stcb->asoc.asconf_supported == 0) {
+ return (-100);
+ }
if (plen > sizeof(lstore)) {
return (-23);
}
@@ -6447,7 +6458,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 */
- prsctp_supported = 1;
+ peer_supports_prsctp = 1;
} else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
/* A supported extension chunk */
struct sctp_supported_chunk_types_param *pr_supported;
@@ -6459,30 +6470,29 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
if (phdr == NULL) {
return (-25);
}
- stcb->asoc.peer_supports_asconf = 0;
- stcb->asoc.peer_supports_auth = 0;
pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
num_ent = plen - sizeof(struct sctp_paramhdr);
for (i = 0; i < num_ent; i++) {
switch (pr_supported->chunk_types[i]) {
case SCTP_ASCONF:
+ peer_supports_asconf = 1;
case SCTP_ASCONF_ACK:
- stcb->asoc.peer_supports_asconf = 1;
+ peer_supports_asconf_ack = 1;
break;
case SCTP_FORWARD_CUM_TSN:
- prsctp_supported = 1;
+ peer_supports_prsctp = 1;
break;
case SCTP_PACKET_DROPPED:
- pktdrop_supported = 1;
+ peer_supports_pktdrop = 1;
break;
case SCTP_NR_SELECTIVE_ACK:
- nrsack_supported = 1;
+ peer_supports_nrsack = 1;
break;
case SCTP_STREAM_RESET:
- reconfig_supported = 1;
+ peer_supports_reconfig = 1;
break;
case SCTP_AUTHENTICATION:
- stcb->asoc.peer_supports_auth = 1;
+ peer_supports_auth = 1;
break;
default:
/* one I have not learned yet */
@@ -6619,25 +6629,47 @@ next_param:
}
}
}
- stcb->asoc.ecn_supported &= ecn_supported;
- stcb->asoc.prsctp_supported &= prsctp_supported;
- stcb->asoc.reconfig_supported &= reconfig_supported;
- stcb->asoc.nrsack_supported &= nrsack_supported;
- stcb->asoc.pktdrop_supported &= pktdrop_supported;
- /* validate authentication required parameters */
- if (got_random && got_hmacs) {
- stcb->asoc.peer_supports_auth = 1;
- } else {
- stcb->asoc.peer_supports_auth = 0;
+ if ((stcb->asoc.ecn_supported == 1) &&
+ (peer_supports_ecn == 0)) {
+ stcb->asoc.ecn_supported = 0;
}
- if (!stcb->asoc.peer_supports_auth && got_chklist) {
+ if ((stcb->asoc.prsctp_supported == 1) &&
+ (peer_supports_prsctp == 0)) {
+ stcb->asoc.prsctp_supported = 0;
+ }
+ if ((stcb->asoc.auth_supported == 1) &&
+ ((peer_supports_auth == 0) ||
+ (got_random == 0) || (got_hmacs == 0))) {
+ stcb->asoc.auth_supported = 0;
+ }
+ if ((stcb->asoc.asconf_supported == 1) &&
+ ((peer_supports_asconf == 0) || (peer_supports_asconf_ack == 0) ||
+ (stcb->asoc.auth_supported == 0) ||
+ (saw_asconf == 0) || (saw_asconf_ack == 0))) {
+ stcb->asoc.asconf_supported = 0;
+ }
+ if ((stcb->asoc.reconfig_supported == 1) &&
+ (peer_supports_reconfig == 0)) {
+ stcb->asoc.reconfig_supported = 0;
+ }
+ if ((stcb->asoc.nrsack_supported == 1) &&
+ (peer_supports_nrsack == 0)) {
+ stcb->asoc.nrsack_supported = 0;
+ }
+ if ((stcb->asoc.pktdrop_supported == 1) &&
+ (peer_supports_pktdrop == 0)) {
+ stcb->asoc.pktdrop_supported = 0;
+ }
+ /* validate authentication required parameters */
+ if ((peer_supports_auth == 0) && (got_chklist == 1)) {
/* peer does not support auth but sent a chunks list? */
return (-31);
}
- if (stcb->asoc.peer_supports_asconf && !stcb->asoc.peer_supports_auth) {
+ if ((peer_supports_asconf == 1) && (peer_supports_auth == 0)) {
/* peer supports asconf but not auth? */
return (-32);
- } else if ((stcb->asoc.peer_supports_asconf) && (stcb->asoc.peer_supports_auth) &&
+ } else if ((peer_supports_asconf == 1) &&
+ (peer_supports_auth == 1) &&
((saw_asconf == 0) || (saw_asconf_ack == 0))) {
return (-33);
}
OpenPOWER on IntegriCloud