Author: tuexen Date: Mon Oct 20 05:17:16 2014 New Revision: 273303 URL: https://svnweb.freebsd.org/changeset/base/273303
Log: MFC10 r273275 (r273168 in head): Fix the reported streams in a SCTP_STREAM_RESET_EVENT, if a sent incoming stream reset request was responded with failed or denied. Thanks to Peter Bostroem from Google for reporting the issue. Approved by: re (hrs) Sponsored 2y: Modified: releng/10.1/sys/netinet/sctp_header.h releng/10.1/sys/netinet/sctp_input.c releng/10.1/sys/netinet/sctp_input.h Directory Properties: releng/10.1/ (props changed) Modified: releng/10.1/sys/netinet/sctp_header.h ============================================================================== --- releng/10.1/sys/netinet/sctp_header.h Mon Oct 20 04:42:28 2014 (r273302) +++ releng/10.1/sys/netinet/sctp_header.h Mon Oct 20 05:17:16 2014 (r273303) @@ -450,6 +450,11 @@ struct sctp_pktdrop_chunk { /**********STREAM RESET STUFF ******************/ +struct sctp_stream_reset_request { + struct sctp_paramhdr ph; + uint32_t request_seq; +} SCTP_PACKED; + struct sctp_stream_reset_out_request { struct sctp_paramhdr ph; uint32_t request_seq; /* monotonically increasing seq no */ @@ -464,7 +469,6 @@ struct sctp_stream_reset_in_request { uint16_t list_of_streams[]; /* if not all list of streams */ } SCTP_PACKED; - struct sctp_stream_reset_tsn_request { struct sctp_paramhdr ph; uint32_t request_seq; Modified: releng/10.1/sys/netinet/sctp_input.c ============================================================================== --- releng/10.1/sys/netinet/sctp_input.c Mon Oct 20 04:42:28 2014 (r273302) +++ releng/10.1/sys/netinet/sctp_input.c Mon Oct 20 05:17:16 2014 (r273303) @@ -3496,12 +3496,12 @@ sctp_reset_out_streams(struct sctp_tcb * } -struct sctp_stream_reset_out_request * +struct sctp_stream_reset_request * sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, struct sctp_tmit_chunk **bchk) { struct sctp_association *asoc; struct sctp_chunkhdr *ch; - struct sctp_stream_reset_out_request *r; + struct sctp_stream_reset_request *r; struct sctp_tmit_chunk *chk; int len, clen; @@ -3524,7 +3524,7 @@ sctp_find_stream_reset(struct sctp_tcb * } clen = chk->send_size; ch = mtod(chk->data, struct sctp_chunkhdr *); - r = (struct sctp_stream_reset_out_request *)(ch + 1); + r = (struct sctp_stream_reset_request *)(ch + 1); if (ntohl(r->request_seq) == seq) { /* found it */ return (r); @@ -3532,7 +3532,7 @@ sctp_find_stream_reset(struct sctp_tcb * len = SCTP_SIZE32(ntohs(r->ph.param_length)); if (clen > (len + (int)sizeof(struct sctp_chunkhdr))) { /* move to the next one, there can only be a max of two */ - r = (struct sctp_stream_reset_out_request *)((caddr_t)r + len); + r = (struct sctp_stream_reset_request *)((caddr_t)r + len); if (ntohl(r->request_seq) == seq) { return (r); } @@ -3576,7 +3576,9 @@ sctp_handle_stream_reset_response(struct int lparm_len; struct sctp_association *asoc = &stcb->asoc; struct sctp_tmit_chunk *chk; - struct sctp_stream_reset_out_request *srparam; + struct sctp_stream_reset_request *req_param; + struct sctp_stream_reset_out_request *req_out_param; + struct sctp_stream_reset_in_request *req_in_param; uint32_t number_entries; if (asoc->stream_reset_outstanding == 0) { @@ -3584,35 +3586,36 @@ sctp_handle_stream_reset_response(struct return (0); } if (seq == stcb->asoc.str_reset_seq_out) { - srparam = sctp_find_stream_reset(stcb, seq, &chk); - if (srparam) { + req_param = sctp_find_stream_reset(stcb, seq, &chk); + if (req_param != NULL) { stcb->asoc.str_reset_seq_out++; - type = ntohs(srparam->ph.param_type); - lparm_len = ntohs(srparam->ph.param_length); + type = ntohs(req_param->ph.param_type); + lparm_len = ntohs(req_param->ph.param_length); if (type == SCTP_STR_RESET_OUT_REQUEST) { + req_out_param = (struct sctp_stream_reset_out_request *)req_param; number_entries = (lparm_len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t); asoc->stream_reset_out_is_outstanding = 0; if (asoc->stream_reset_outstanding) asoc->stream_reset_outstanding--; if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) { /* do it */ - sctp_reset_out_streams(stcb, number_entries, srparam->list_of_streams); + sctp_reset_out_streams(stcb, number_entries, req_out_param->list_of_streams); } else if (action == SCTP_STREAM_RESET_RESULT_DENIED) { - sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED); + sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED); } else { - sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED); + sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED); } } else if (type == SCTP_STR_RESET_IN_REQUEST) { - /* Answered my request */ + req_in_param = (struct sctp_stream_reset_in_request *)req_param; number_entries = (lparm_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t); if (asoc->stream_reset_outstanding) asoc->stream_reset_outstanding--; if (action == SCTP_STREAM_RESET_RESULT_DENIED) { sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_IN, stcb, - number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED); + number_entries, req_in_param->list_of_streams, SCTP_SO_NOT_LOCKED); } else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) { sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_IN, stcb, - number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED); + number_entries, req_in_param->list_of_streams, SCTP_SO_NOT_LOCKED); } } else if (type == SCTP_STR_RESET_ADD_OUT_STREAMS) { /* Ok we now may have more streams */ Modified: releng/10.1/sys/netinet/sctp_input.h ============================================================================== --- releng/10.1/sys/netinet/sctp_input.h Mon Oct 20 04:42:28 2014 (r273302) +++ releng/10.1/sys/netinet/sctp_input.h Mon Oct 20 05:17:16 2014 (r273303) @@ -48,7 +48,7 @@ sctp_common_input_processing(struct mbuf uint8_t, uint32_t, uint32_t, uint16_t); -struct sctp_stream_reset_out_request * +struct sctp_stream_reset_request * sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, struct sctp_tmit_chunk **bchk); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"