| 3471 | } |
| 3472 | |
| 3473 | static int |
| 3474 | sctp_handle_stream_reset_response(struct sctp_tcb *stcb, |
| 3475 | uint32_t seq, uint32_t action, |
| 3476 | struct sctp_stream_reset_response *respin) |
| 3477 | { |
| 3478 | uint16_t type; |
| 3479 | int lparam_len; |
| 3480 | struct sctp_association *asoc = &stcb->asoc; |
| 3481 | struct sctp_tmit_chunk *chk; |
| 3482 | struct sctp_stream_reset_request *req_param; |
| 3483 | struct sctp_stream_reset_out_request *req_out_param; |
| 3484 | struct sctp_stream_reset_in_request *req_in_param; |
| 3485 | uint32_t number_entries; |
| 3486 | |
| 3487 | if (asoc->stream_reset_outstanding == 0) { |
| 3488 | /* duplicate */ |
| 3489 | return (0); |
| 3490 | } |
| 3491 | if (seq == stcb->asoc.str_reset_seq_out) { |
| 3492 | req_param = sctp_find_stream_reset(stcb, seq, &chk); |
| 3493 | if (req_param != NULL) { |
| 3494 | stcb->asoc.str_reset_seq_out++; |
| 3495 | type = ntohs(req_param->ph.param_type); |
| 3496 | lparam_len = ntohs(req_param->ph.param_length); |
| 3497 | if (type == SCTP_STR_RESET_OUT_REQUEST) { |
| 3498 | int no_clear = 0; |
| 3499 | |
| 3500 | req_out_param = (struct sctp_stream_reset_out_request *)req_param; |
| 3501 | number_entries = (lparam_len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t); |
| 3502 | asoc->stream_reset_out_is_outstanding = 0; |
| 3503 | if (asoc->stream_reset_outstanding) |
| 3504 | asoc->stream_reset_outstanding--; |
| 3505 | if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) { |
| 3506 | /* do it */ |
| 3507 | sctp_reset_out_streams(stcb, number_entries, req_out_param->list_of_streams); |
| 3508 | } else if (action == SCTP_STREAM_RESET_RESULT_DENIED) { |
| 3509 | sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED); |
| 3510 | } else if (action == SCTP_STREAM_RESET_RESULT_IN_PROGRESS) { |
| 3511 | /* |
| 3512 | * Set it up so we don't stop |
| 3513 | * retransmitting |
| 3514 | */ |
| 3515 | asoc->stream_reset_outstanding++; |
| 3516 | stcb->asoc.str_reset_seq_out--; |
| 3517 | asoc->stream_reset_out_is_outstanding = 1; |
| 3518 | no_clear = 1; |
| 3519 | } else { |
| 3520 | sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED); |
| 3521 | } |
| 3522 | if (no_clear == 0) { |
| 3523 | sctp_reset_clear_pending(stcb, number_entries, req_out_param->list_of_streams); |
| 3524 | } |
| 3525 | } else if (type == SCTP_STR_RESET_IN_REQUEST) { |
| 3526 | req_in_param = (struct sctp_stream_reset_in_request *)req_param; |
| 3527 | number_entries = (lparam_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t); |
| 3528 | if (asoc->stream_reset_outstanding) |
| 3529 | asoc->stream_reset_outstanding--; |
| 3530 | if (action == SCTP_STREAM_RESET_RESULT_DENIED) { |
no test coverage detected