| 1115 | } |
| 1116 | |
| 1117 | int |
| 1118 | sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb) |
| 1119 | { |
| 1120 | struct sctp_nets *alt, *net; |
| 1121 | struct sctp_tmit_chunk *strrst = NULL, *chk = NULL; |
| 1122 | |
| 1123 | if (stcb->asoc.stream_reset_outstanding == 0) { |
| 1124 | return (0); |
| 1125 | } |
| 1126 | /* find the existing STRRESET, we use the seq number we sent out on */ |
| 1127 | (void)sctp_find_stream_reset(stcb, stcb->asoc.str_reset_seq_out, &strrst); |
| 1128 | if (strrst == NULL) { |
| 1129 | return (0); |
| 1130 | } |
| 1131 | net = strrst->whoTo; |
| 1132 | /* do threshold management */ |
| 1133 | if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) { |
| 1134 | /* Assoc is over */ |
| 1135 | return (1); |
| 1136 | } |
| 1137 | /* |
| 1138 | * Cleared threshold management, now lets backoff the address and |
| 1139 | * select an alternate |
| 1140 | */ |
| 1141 | sctp_backoff_on_timeout(stcb, net, 1, 0, 0); |
| 1142 | alt = sctp_find_alternate_net(stcb, net, 0); |
| 1143 | strrst->whoTo = alt; |
| 1144 | atomic_add_int(&alt->ref_count, 1); |
| 1145 | |
| 1146 | /* See if a ECN Echo is also stranded */ |
| 1147 | TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) { |
| 1148 | if ((chk->whoTo == net) && |
| 1149 | (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) { |
| 1150 | sctp_free_remote_addr(chk->whoTo); |
| 1151 | if (chk->sent != SCTP_DATAGRAM_RESEND) { |
| 1152 | chk->sent = SCTP_DATAGRAM_RESEND; |
| 1153 | chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; |
| 1154 | sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); |
| 1155 | } |
| 1156 | chk->whoTo = alt; |
| 1157 | atomic_add_int(&alt->ref_count, 1); |
| 1158 | } |
| 1159 | } |
| 1160 | if (!(net->dest_state & SCTP_ADDR_REACHABLE)) { |
| 1161 | /* |
| 1162 | * If the address went un-reachable, we need to move to |
| 1163 | * alternates for ALL chk's in queue |
| 1164 | */ |
| 1165 | sctp_move_chunks_from_net(stcb, net); |
| 1166 | } |
| 1167 | sctp_free_remote_addr(net); |
| 1168 | |
| 1169 | /* mark the retran info */ |
| 1170 | if (strrst->sent != SCTP_DATAGRAM_RESEND) |
| 1171 | sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); |
| 1172 | strrst->sent = SCTP_DATAGRAM_RESEND; |
| 1173 | strrst->flags |= CHUNK_FLAGS_FRAGMENT_OK; |
| 1174 |
no test coverage detected