@@ -324,13 +324,81 @@ static void qc_handle_newly_acked_frm(struct quic_conn *qc, struct quic_frame *f
324
324
qc_release_frm (qc , frm );
325
325
}
326
326
else {
327
- //eb64_insert(&stream->acked_frms, &strm_frm->offset);
327
+ struct eb64_node * less , * more ;
328
+ struct qf_stream * less_strm = NULL , * more_strm = NULL ;
328
329
struct qc_stream_buf * stream_buf ;
329
330
struct eb64_node * buf_node ;
330
331
331
332
buf_node = eb64_lookup_le (& stream -> buf_tree , offset );
332
333
stream_buf = eb64_entry (buf_node , struct qc_stream_buf , offset_node );
333
- eb64_insert (& stream_buf -> acked_frms , & strm_frm -> offset );
334
+
335
+ more = eb64_lookup_ge (& stream_buf -> acked_frms , strm_frm -> offset .key );
336
+ if (more )
337
+ more_strm = eb64_entry (more , struct qf_stream , offset );
338
+
339
+ less = eb64_lookup_le (& stream_buf -> acked_frms , strm_frm -> offset .key );
340
+ if (less && more != less )
341
+ less_strm = eb64_entry (less , struct qf_stream , offset );
342
+
343
+ if ((more_strm &&
344
+ strm_frm -> offset .key == more_strm -> offset .key &&
345
+ strm_frm -> offset .key + strm_frm -> len <= more_strm -> offset .key + more_strm -> len ) ||
346
+ (less_strm &&
347
+ strm_frm -> offset .key + strm_frm -> len <= less_strm -> offset .key + less_strm -> len )) {
348
+ /* A frame was already buffered which covered
349
+ * the same range or more. Discard the current
350
+ * frame.
351
+ */
352
+ TRACE_DEVEL ("already covered stream range" , QUIC_EV_CONN_ACKSTRM , qc );
353
+ qc_release_frm (qc , frm );
354
+ }
355
+ else {
356
+ /* Loop until there is no overlap between current frame and a next entry. */
357
+ while (more_strm &&
358
+ strm_frm -> offset .key + strm_frm -> len >= more_strm -> offset .key ) {
359
+ struct quic_frame * more_frm ;
360
+ struct eb64_node * next ;
361
+
362
+ more_frm = container_of (more_strm , struct quic_frame , stream );
363
+ if (strm_frm -> offset .key + strm_frm -> len < more_strm -> offset .key + more_strm -> len ) {
364
+ /* Extend current frame to cover next entry. */
365
+ strm_frm -> len += (more_strm -> offset .key + more_strm -> len ) -
366
+ (strm_frm -> offset .key + strm_frm -> len );
367
+ if (more_frm -> type & QUIC_STREAM_FRAME_TYPE_FIN_BIT )
368
+ frm -> type |= QUIC_STREAM_FRAME_TYPE_FIN_BIT ;
369
+ }
370
+
371
+ /* Remove next entry as it is covered by current frame. */
372
+ TRACE_DEVEL ("removing overlapping stream range" , QUIC_EV_CONN_ACKSTRM , qc );
373
+ next = eb64_next (more );
374
+ eb64_delete (more );
375
+ qc_release_frm (qc , more_frm );
376
+
377
+ more = next ;
378
+ more_strm = more ? eb64_entry (more , struct qf_stream , offset ) : NULL ;
379
+ }
380
+
381
+ /* Check if there is overlap between current frame and a previous entry. */
382
+ if (less_strm &&
383
+ less_strm -> offset .key + less_strm -> len >= strm_frm -> offset .key ) {
384
+ struct quic_frame * less_frm ;
385
+
386
+ /* Extend previous entry to cover fully the current frame. */
387
+ less_strm -> len += (strm_frm -> offset .key + strm_frm -> len ) -
388
+ (less_strm -> offset .key + less_strm -> len );
389
+
390
+ less_frm = container_of (less_strm , struct quic_frame , stream );
391
+ if (frm -> type & QUIC_STREAM_FRAME_TYPE_FIN_BIT )
392
+ less_frm -> type |= QUIC_STREAM_FRAME_TYPE_FIN_BIT ;
393
+
394
+ /* Discard current frame. */
395
+ TRACE_DEVEL ("using smaller overlapping stream range, discard current frame" , QUIC_EV_CONN_ACKSTRM , qc );
396
+ qc_release_frm (qc , frm );
397
+ }
398
+ else {
399
+ eb64_insert (& stream_buf -> acked_frms , & strm_frm -> offset );
400
+ }
401
+ }
334
402
}
335
403
}
336
404
break ;
0 commit comments