This patch fixes a LOR that happens during INIT-ACK collision.
We were calling select_a_tag() inside sctp_send_initate_ack(). During collision cases we have a stcb and thus a SCTP_LOCK. When we call select_a_tag it (below it) locks the INFO lock. We now 1) pre-select the nonce-tie-tags in sctputil.c during setup of a tcb. 2) In the other case where we have to select tags, we unlock after incr the ref cnt (so assoc won't go away0 and then do the tag selection followed by a relock and decr the refcnt. Approved by: gnn
This commit is contained in:
parent
50bb724108
commit
463be3f37d
@ -3371,14 +3371,8 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* populate any tie tags */
|
||||
if (asoc != NULL) {
|
||||
/* unlock before tag selections */
|
||||
if (asoc->my_vtag_nonce == 0)
|
||||
asoc->my_vtag_nonce = sctp_select_a_tag(inp);
|
||||
stc.tie_tag_my_vtag = asoc->my_vtag_nonce;
|
||||
|
||||
if (asoc->peer_vtag_nonce == 0)
|
||||
asoc->peer_vtag_nonce = sctp_select_a_tag(inp);
|
||||
stc.tie_tag_peer_vtag = asoc->peer_vtag_nonce;
|
||||
|
||||
stc.cookie_life = asoc->cookie_life;
|
||||
net = asoc->primary_destination;
|
||||
} else {
|
||||
@ -3628,9 +3622,19 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
initackm_out->msg.init.initiate_tag = htonl(asoc->my_vtag);
|
||||
initackm_out->msg.init.initial_tsn = htonl(asoc->init_seq_number);
|
||||
} else {
|
||||
initackm_out->msg.init.initiate_tag = htonl(sctp_select_a_tag(inp));
|
||||
/* get a TSN to use too */
|
||||
initackm_out->msg.init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
|
||||
if (asoc) {
|
||||
atomic_add_int(&asoc->refcnt, 1);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
initackm_out->msg.init.initiate_tag = htonl(sctp_select_a_tag(inp));
|
||||
/* get a TSN to use too */
|
||||
initackm_out->msg.init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_add_int(&asoc->refcnt, -1);
|
||||
} else {
|
||||
initackm_out->msg.init.initiate_tag = htonl(sctp_select_a_tag(inp));
|
||||
/* get a TSN to use too */
|
||||
initackm_out->msg.init.initial_tsn = htonl(sctp_select_initial_TSN(&inp->sctp_ep));
|
||||
}
|
||||
}
|
||||
/* save away my tag to */
|
||||
stc.my_vtag = initackm_out->msg.init.initiate_tag;
|
||||
|
@ -1020,6 +1020,10 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
|
||||
} else {
|
||||
asoc->my_vtag = sctp_select_a_tag(m);
|
||||
}
|
||||
/* Get the nonce tags */
|
||||
asoc->my_vtag_nonce = sctp_select_a_tag(m);
|
||||
asoc->peer_vtag_nonce = sctp_select_a_tag(m);
|
||||
|
||||
if (sctp_is_feature_on(m, SCTP_PCB_FLAGS_DONOT_HEARTBEAT))
|
||||
asoc->hb_is_disabled = 1;
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user