From 62ede05c09f68ad883dcde9455bd4a6941f30819 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 6 Nov 2014 23:43:10 +0900 Subject: [PATCH] Fix heap-use-after-free due to duplicated push of DATA item --- lib/nghttp2_session.c | 53 +++++++++++++++++------------ lib/nghttp2_stream.c | 65 +++++++++++++++++++++++------------- lib/nghttp2_stream.h | 24 ++++++++----- tests/nghttp2_session_test.c | 60 ++++++++++++++++++++------------- 4 files changed, 124 insertions(+), 78 deletions(-) diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c index ba32d12c..0d3fa523 100644 --- a/lib/nghttp2_session.c +++ b/lib/nghttp2_session.c @@ -588,10 +588,11 @@ int nghttp2_session_reprioritize_stream session->roots.num_streams <= NGHTTP2_MAX_DEP_TREE_LENGTH) { rv = nghttp2_stream_dep_all_your_stream_are_belong_to_us - (stream, &session->ob_da_pq, session->last_cycle); + (stream, &session->ob_da_pq, session->last_cycle, session->aob.item); } else { rv = nghttp2_stream_dep_make_root(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); } return rv; @@ -612,7 +613,7 @@ int nghttp2_session_reprioritize_stream nghttp2_stream_dep_remove_subtree(dep_stream); nghttp2_stream_dep_make_root(dep_stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, session->aob.item); } nghttp2_stream_dep_remove_subtree(stream); @@ -625,16 +626,18 @@ int nghttp2_session_reprioritize_stream if(root_stream->num_substreams + stream->num_substreams > NGHTTP2_MAX_DEP_TREE_LENGTH) { rv = nghttp2_stream_dep_make_root(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, session->aob.item); } else { if(pri_spec->exclusive) { rv = nghttp2_stream_dep_insert_subtree(dep_stream, stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); } else { rv = nghttp2_stream_dep_add_subtree(dep_stream, stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); } } @@ -732,7 +735,8 @@ int nghttp2_session_add_item(nghttp2_session *session, item->cycle = session->last_cycle; rv = nghttp2_stream_attach_data(stream, item, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); if(rv != 0) { return rv; @@ -837,7 +841,7 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session, if(pri_spec->exclusive && session->roots.num_streams <= NGHTTP2_MAX_DEP_TREE_LENGTH) { rv = nghttp2_stream_dep_all_your_stream_are_belong_to_us - (stream, &session->ob_da_pq, session->last_cycle); + (stream, &session->ob_da_pq, session->last_cycle, session->aob.item); /* Since no dpri is changed in dependency tree, the above function call never fail. */ @@ -896,7 +900,7 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, item = stream->data_item; rv = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, session->aob.item); if(rv != 0) { return rv; @@ -1790,7 +1794,8 @@ static int session_prep_frame(nghttp2_session *session, int rv2; rv2 = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); if(nghttp2_is_fatal(rv2)) { return rv2; @@ -1811,7 +1816,7 @@ static int session_prep_frame(nghttp2_session *session, rv = nghttp2_stream_defer_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, - &session->ob_da_pq, session->last_cycle); + &session->ob_da_pq, session->last_cycle, session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; @@ -1829,7 +1834,8 @@ static int session_prep_frame(nghttp2_session *session, &item->aux_data.data); if(framerv == NGHTTP2_ERR_DEFERRED) { rv = nghttp2_stream_defer_data(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER, - &session->ob_da_pq, session->last_cycle); + &session->ob_da_pq, session->last_cycle, + session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; @@ -1841,7 +1847,8 @@ static int session_prep_frame(nghttp2_session *session, } if(framerv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { rv = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; @@ -1856,7 +1863,8 @@ static int session_prep_frame(nghttp2_session *session, } if(framerv < 0) { rv = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, + session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; @@ -2196,7 +2204,7 @@ static int session_after_frame_sent(nghttp2_session *session) if(stream && aux_data->eof) { rv = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, aob->item); if(nghttp2_is_fatal(rv)) { return rv; @@ -2255,7 +2263,7 @@ static int session_after_frame_sent(nghttp2_session *session) frame->hd.stream_id) != 0) { if(stream) { rv = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, aob->item); if(nghttp2_is_fatal(rv)) { return rv; @@ -2301,7 +2309,7 @@ static int session_after_frame_sent(nghttp2_session *session) } else { rv = nghttp2_stream_defer_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, - &session->ob_da_pq, session->last_cycle); + &session->ob_da_pq, session->last_cycle, aob->item); if(nghttp2_is_fatal(rv)) { return rv; @@ -2324,7 +2332,7 @@ static int session_after_frame_sent(nghttp2_session *session) if(rv == NGHTTP2_ERR_DEFERRED) { rv = nghttp2_stream_defer_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER, - &session->ob_da_pq, session->last_cycle); + &session->ob_da_pq, session->last_cycle, aob->item); if(nghttp2_is_fatal(rv)) { return rv; @@ -2348,7 +2356,7 @@ static int session_after_frame_sent(nghttp2_session *session) } rv = nghttp2_stream_detach_data(stream, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, aob->item); if(nghttp2_is_fatal(rv)) { return rv; @@ -3283,7 +3291,8 @@ static int update_remote_initial_window_size_func rv = nghttp2_stream_resume_deferred_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, - &arg->session->ob_da_pq, arg->session->last_cycle); + &arg->session->ob_da_pq, arg->session->last_cycle, + arg->session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; @@ -3904,7 +3913,7 @@ static int session_on_stream_window_update_received rv = nghttp2_stream_resume_deferred_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; @@ -5923,7 +5932,7 @@ int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) rv = nghttp2_stream_resume_deferred_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, session->aob.item); if(nghttp2_is_fatal(rv)) { return rv; diff --git a/lib/nghttp2_stream.c b/lib/nghttp2_stream.c index 269d2900..3f0f4cfc 100644 --- a/lib/nghttp2_stream.c +++ b/lib/nghttp2_stream.c @@ -86,13 +86,19 @@ void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) } static int stream_push_data(nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, nghttp2_outbound_item *active_item) { int rv; assert(stream->data_item); assert(stream->data_item->queued == 0); + /* If stream->data_item is now sent, don't push it to the queue. + Otherwise, we may push same item twice. */ + if(active_item == stream->data_item) { + return 0; + } + if(stream->data_item->weight > stream->effective_weight) { stream->data_item->weight = stream->effective_weight; } @@ -297,7 +303,8 @@ static void stream_update_dep_set_top(nghttp2_stream *stream) * Out of memory. */ static int stream_update_dep_queue_top(nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, + nghttp2_outbound_item *active_item) { int rv; nghttp2_stream *si; @@ -310,7 +317,7 @@ static int stream_update_dep_queue_top(nghttp2_stream *stream, nghttp2_pq *pq, if(!stream->data_item->queued) { DEBUGF(fprintf(stderr, "stream: stream=%d enqueue\n", stream->stream_id)); - rv = stream_push_data(stream, pq, cycle); + rv = stream_push_data(stream, pq, cycle, active_item); if(rv != 0) { return rv; @@ -321,7 +328,7 @@ static int stream_update_dep_queue_top(nghttp2_stream *stream, nghttp2_pq *pq, } for(si = stream->dep_next; si; si = si->sib_next) { - rv = stream_update_dep_queue_top(si, pq, cycle); + rv = stream_update_dep_queue_top(si, pq, cycle, active_item); if(rv != 0) { return rv; @@ -379,7 +386,8 @@ static int stream_update_dep_sum_norest_weight(nghttp2_stream *stream) } static int stream_update_dep_on_attach_data(nghttp2_stream *stream, - nghttp2_pq *pq, uint64_t cycle) + nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item) { nghttp2_stream *root_stream; @@ -396,11 +404,12 @@ static int stream_update_dep_on_attach_data(nghttp2_stream *stream, stream_update_dep_sum_norest_weight(root_stream); stream_update_dep_effective_weight(root_stream); - return stream_update_dep_queue_top(root_stream, pq, cycle); + return stream_update_dep_queue_top(root_stream, pq, cycle, active_item); } static int stream_update_dep_on_detach_data(nghttp2_stream *stream, - nghttp2_pq *pq, uint64_t cycle) + nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item) { nghttp2_stream *root_stream; @@ -413,13 +422,14 @@ static int stream_update_dep_on_detach_data(nghttp2_stream *stream, stream_update_dep_sum_norest_weight(root_stream); stream_update_dep_effective_weight(root_stream); - return stream_update_dep_queue_top(root_stream, pq, cycle); + return stream_update_dep_queue_top(root_stream, pq, cycle, active_item); } int nghttp2_stream_attach_data(nghttp2_stream *stream, nghttp2_outbound_item *data_item, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, + nghttp2_outbound_item *active_item) { assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0); assert(stream->data_item == NULL); @@ -429,11 +439,12 @@ int nghttp2_stream_attach_data(nghttp2_stream *stream, stream->data_item = data_item; - return stream_update_dep_on_attach_data(stream, pq, cycle); + return stream_update_dep_on_attach_data(stream, pq, cycle, active_item); } int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, + nghttp2_outbound_item *active_item) { DEBUGF(fprintf(stderr, "stream: stream=%d detach data=%p\n", stream->stream_id, stream->data_item)); @@ -441,11 +452,12 @@ int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq, stream->data_item = NULL; stream->flags &= ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL; - return stream_update_dep_on_detach_data(stream, pq, cycle); + return stream_update_dep_on_detach_data(stream, pq, cycle, active_item); } int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags, - nghttp2_pq *pq, uint64_t cycle) + nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item) { assert(stream->data_item); @@ -454,11 +466,12 @@ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags, stream->flags |= flags; - return stream_update_dep_on_detach_data(stream, pq, cycle); + return stream_update_dep_on_detach_data(stream, pq, cycle, active_item); } int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, uint8_t flags, - nghttp2_pq *pq, uint64_t cycle) + nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item) { assert(stream->data_item); @@ -471,7 +484,7 @@ int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, uint8_t flags, return 0; } - return stream_update_dep_on_attach_data(stream, pq, cycle); + return stream_update_dep_on_attach_data(stream, pq, cycle, active_item); } int nghttp2_stream_check_deferred_data(nghttp2_stream *stream) @@ -805,7 +818,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream) int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, + nghttp2_outbound_item *active_item) { nghttp2_stream *last_sib; nghttp2_stream *dep_next; @@ -857,13 +871,14 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, stream_update_dep_sum_norest_weight(root_stream); stream_update_dep_effective_weight(root_stream); - return stream_update_dep_queue_top(root_stream, pq, cycle); + return stream_update_dep_queue_top(root_stream, pq, cycle, active_item); } int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, + nghttp2_outbound_item *active_item) { nghttp2_stream *root_stream; @@ -892,7 +907,7 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, stream_update_dep_sum_norest_weight(root_stream); stream_update_dep_effective_weight(root_stream); - return stream_update_dep_queue_top(root_stream, pq, cycle); + return stream_update_dep_queue_top(root_stream, pq, cycle, active_item); } void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) @@ -947,7 +962,8 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) } int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle) + uint64_t cycle, + nghttp2_outbound_item *active_item) { DEBUGF(fprintf(stderr, "stream: dep_make_root stream(%p)=%d\n", stream, stream->stream_id)); @@ -963,11 +979,12 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq, stream_update_dep_sum_norest_weight(stream); stream_update_dep_effective_weight(stream); - return stream_update_dep_queue_top(stream, pq, cycle); + return stream_update_dep_queue_top(stream, pq, cycle, active_item); } int nghttp2_stream_dep_all_your_stream_are_belong_to_us -(nghttp2_stream *stream, nghttp2_pq *pq, uint64_t cycle) +(nghttp2_stream *stream, nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item) { nghttp2_stream *first, *si; @@ -1022,7 +1039,7 @@ int nghttp2_stream_dep_all_your_stream_are_belong_to_us nghttp2_stream_roots_remove_all(stream->roots); - return nghttp2_stream_dep_make_root(stream, pq, cycle); + return nghttp2_stream_dep_make_root(stream, pq, cycle, active_item); } int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) diff --git a/lib/nghttp2_stream.h b/lib/nghttp2_stream.h index e82ac3ed..77417399 100644 --- a/lib/nghttp2_stream.h +++ b/lib/nghttp2_stream.h @@ -216,7 +216,8 @@ void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag); * Out of memory */ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags, - nghttp2_pq *pq, uint64_t cycle); + nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Put back deferred data in this stream to active state. The |flags| @@ -227,7 +228,8 @@ int nghttp2_stream_defer_data(nghttp2_stream *stream, uint8_t flags, * one of flag is still set, data does not become active. */ int nghttp2_stream_resume_deferred_data(nghttp2_stream *stream, uint8_t flags, - nghttp2_pq *pq, uint64_t cycle); + nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Returns nonzero if data item is deferred by whatever reason. @@ -339,7 +341,8 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream); int nghttp2_stream_attach_data(nghttp2_stream *stream, nghttp2_outbound_item *data_item, nghttp2_pq *pq, - uint64_t cycle); + uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Detaches |stream->data_item|. Updates dpri members in this @@ -353,7 +356,8 @@ int nghttp2_stream_attach_data(nghttp2_stream *stream, * Out of memory */ int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle); + uint64_t cycle, + nghttp2_outbound_item *active_item); /* @@ -369,7 +373,8 @@ int nghttp2_stream_detach_data(nghttp2_stream *stream, nghttp2_pq *pq, int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle); + uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Makes the |stream| depend on the |dep_stream|. This dependency is @@ -384,7 +389,8 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream, int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream, nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle); + uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Removes subtree whose root stream is |stream|. Removing subtree @@ -410,7 +416,8 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream); * Out of memory */ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq, - uint64_t cycle); + uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Makes the |stream| as root and all existing root streams become @@ -423,7 +430,8 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq, * Out of memory */ int nghttp2_stream_dep_all_your_stream_are_belong_to_us -(nghttp2_stream *stream, nghttp2_pq *pq, uint64_t cycle); +(nghttp2_stream *stream, nghttp2_pq *pq, uint64_t cycle, + nghttp2_outbound_item *active_item); /* * Returns nonzero if |stream| is in any dependency tree. diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index 14c77a8b..cf756091 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -2564,7 +2564,8 @@ void test_nghttp2_session_on_window_update_received(void) CU_ASSERT(0 == nghttp2_stream_attach_data(stream, data_item, &session->ob_da_pq, - session->last_cycle)); + session->last_cycle, + NULL)); nghttp2_frame_window_update_init(&frame.window_update, NGHTTP2_FLAG_NONE, 1, 16*1024); @@ -2575,7 +2576,7 @@ void test_nghttp2_session_on_window_update_received(void) CU_ASSERT(0 == nghttp2_stream_defer_data (stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL, - &session->ob_da_pq, session->last_cycle)); + &session->ob_da_pq, session->last_cycle, NULL)); CU_ASSERT(0 == nghttp2_session_on_window_update_received(session, &frame)); CU_ASSERT(2 == user_data.frame_recv_cb_called); @@ -5656,7 +5657,7 @@ void test_nghttp2_session_stream_dep_add_subtree(void) */ nghttp2_stream_dep_add_subtree(a, e, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, NULL); /* becomes * a @@ -5708,7 +5709,7 @@ void test_nghttp2_session_stream_dep_add_subtree(void) */ nghttp2_stream_dep_insert_subtree(a, e, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, NULL); /* becomes * a @@ -5901,7 +5902,7 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void) nghttp2_stream_dep_remove_subtree(c); CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us - (c, &session->ob_da_pq, session->last_cycle)); + (c, &session->ob_da_pq, session->last_cycle, NULL)); /* * c @@ -5939,7 +5940,7 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void) nghttp2_stream_dep_remove_subtree(c); CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us - (c, &session->ob_da_pq, session->last_cycle)); + (c, &session->ob_da_pq, session->last_cycle, NULL)); /* * c @@ -5976,7 +5977,7 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void) nghttp2_stream_dep_remove_subtree(c); CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us - (c, &session->ob_da_pq, session->last_cycle)); + (c, &session->ob_da_pq, session->last_cycle, NULL)); /* * c @@ -6029,7 +6030,8 @@ void test_nghttp2_session_stream_attach_data(void) db = create_data_ob_item(); - nghttp2_stream_attach_data(b, db, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(b, db, &session->ob_da_pq, session->last_cycle, + NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6044,7 +6046,8 @@ void test_nghttp2_session_stream_attach_data(void) dc = create_data_ob_item(); - nghttp2_stream_attach_data(c, dc, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(c, dc, &session->ob_da_pq, session->last_cycle, + NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6060,7 +6063,8 @@ void test_nghttp2_session_stream_attach_data(void) da = create_data_ob_item(); - nghttp2_stream_attach_data(a, da, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(a, da, &session->ob_da_pq, session->last_cycle, + NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_REST == b->dpri); @@ -6071,7 +6075,7 @@ void test_nghttp2_session_stream_attach_data(void) CU_ASSERT(1 == da->queued); - nghttp2_stream_detach_data(a, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_detach_data(a, &session->ob_da_pq, session->last_cycle, NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6083,7 +6087,8 @@ void test_nghttp2_session_stream_attach_data(void) dd = create_data_ob_item(); - nghttp2_stream_attach_data(d, dd, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(d, dd, &session->ob_da_pq, session->last_cycle, + NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6095,7 +6100,7 @@ void test_nghttp2_session_stream_attach_data(void) CU_ASSERT(0 == dd->queued); - nghttp2_stream_detach_data(c, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_detach_data(c, &session->ob_da_pq, session->last_cycle, NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6106,7 +6111,7 @@ void test_nghttp2_session_stream_attach_data(void) CU_ASSERT(0 == dd->queued); - nghttp2_stream_detach_data(b, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_detach_data(b, &session->ob_da_pq, session->last_cycle, NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == b->dpri); @@ -6148,11 +6153,13 @@ void test_nghttp2_session_stream_attach_data_subtree(void) de = create_data_ob_item(); - nghttp2_stream_attach_data(e, de, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(e, de, &session->ob_da_pq, session->last_cycle, + NULL); db = create_data_ob_item(); - nghttp2_stream_attach_data(b, db, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(b, db, &session->ob_da_pq, session->last_cycle, + NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6168,7 +6175,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void) nghttp2_stream_dep_remove_subtree(e); nghttp2_stream_dep_insert_subtree(a, e, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, NULL); /* * a @@ -6193,7 +6200,8 @@ void test_nghttp2_session_stream_attach_data_subtree(void) nghttp2_stream_dep_remove_subtree(b); - nghttp2_stream_dep_make_root(b, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_dep_make_root(b, &session->ob_da_pq, session->last_cycle, + NULL); /* * a b @@ -6219,7 +6227,8 @@ void test_nghttp2_session_stream_attach_data_subtree(void) nghttp2_stream_dep_remove_subtree(a); - nghttp2_stream_dep_make_root(a, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_dep_make_root(a, &session->ob_da_pq, session->last_cycle, + NULL); CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == a->dpri); CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == b->dpri); @@ -6232,7 +6241,8 @@ void test_nghttp2_session_stream_attach_data_subtree(void) nghttp2_stream_dep_remove_subtree(c); - nghttp2_stream_dep_make_root(c, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_dep_make_root(c, &session->ob_da_pq, session->last_cycle, + NULL); /* * a b c @@ -6251,13 +6261,14 @@ void test_nghttp2_session_stream_attach_data_subtree(void) dd = create_data_ob_item(); - nghttp2_stream_attach_data(d, dd, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_attach_data(d, dd, &session->ob_da_pq, session->last_cycle, + NULL); /* Add subtree c to a */ nghttp2_stream_dep_remove_subtree(c); nghttp2_stream_dep_add_subtree(a, c, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, NULL); /* * a b @@ -6284,7 +6295,7 @@ void test_nghttp2_session_stream_attach_data_subtree(void) nghttp2_stream_dep_remove_subtree(b); nghttp2_stream_dep_insert_subtree(a, b, &session->ob_da_pq, - session->last_cycle); + session->last_cycle, NULL); /* * a @@ -6311,7 +6322,8 @@ void test_nghttp2_session_stream_attach_data_subtree(void) /* Remove subtree b */ nghttp2_stream_dep_remove_subtree(b); - nghttp2_stream_dep_make_root(b, &session->ob_da_pq, session->last_cycle); + nghttp2_stream_dep_make_root(b, &session->ob_da_pq, session->last_cycle, + NULL); /* * b a