| 8411 | } |
| 8412 | |
| 8413 | static void |
| 8414 | rack_collapsed_window(struct tcp_rack *rack) |
| 8415 | { |
| 8416 | /* |
| 8417 | * Now we must walk the |
| 8418 | * send map and divide the |
| 8419 | * ones left stranded. These |
| 8420 | * guys can't cause us to abort |
| 8421 | * the connection and are really |
| 8422 | * "unsent". However if a buggy |
| 8423 | * client actually did keep some |
| 8424 | * of the data i.e. collapsed the win |
| 8425 | * and refused to ack and then opened |
| 8426 | * the win and acked that data. We would |
| 8427 | * get into an ack war, the simplier |
| 8428 | * method then of just pretending we |
| 8429 | * did not send those segments something |
| 8430 | * won't work. |
| 8431 | */ |
| 8432 | struct rack_sendmap *rsm, *nrsm, fe, *insret; |
| 8433 | tcp_seq max_seq; |
| 8434 | |
| 8435 | max_seq = rack->rc_tp->snd_una + rack->rc_tp->snd_wnd; |
| 8436 | memset(&fe, 0, sizeof(fe)); |
| 8437 | fe.r_start = max_seq; |
| 8438 | /* Find the first seq past or at maxseq */ |
| 8439 | rsm = RB_FIND(rack_rb_tree_head, &rack->r_ctl.rc_mtree, &fe); |
| 8440 | if (rsm == NULL) { |
| 8441 | /* Nothing to do strange */ |
| 8442 | rack->rc_has_collapsed = 0; |
| 8443 | return; |
| 8444 | } |
| 8445 | /* |
| 8446 | * Now do we need to split at |
| 8447 | * the collapse point? |
| 8448 | */ |
| 8449 | if (SEQ_GT(max_seq, rsm->r_start)) { |
| 8450 | nrsm = rack_alloc_limit(rack, RACK_LIMIT_TYPE_SPLIT); |
| 8451 | if (nrsm == NULL) { |
| 8452 | /* We can't get a rsm, mark all? */ |
| 8453 | nrsm = rsm; |
| 8454 | goto no_split; |
| 8455 | } |
| 8456 | /* Clone it */ |
| 8457 | rack_clone_rsm(rack, nrsm, rsm, max_seq); |
| 8458 | insret = RB_INSERT(rack_rb_tree_head, &rack->r_ctl.rc_mtree, nrsm); |
| 8459 | #ifdef INVARIANTS |
| 8460 | if (insret != NULL) { |
| 8461 | panic("Insert in rb tree of %p fails ret:%p rack:%p rsm:%p", |
| 8462 | nrsm, insret, rack, rsm); |
| 8463 | } |
| 8464 | #endif |
| 8465 | if (rsm->r_in_tmap) { |
| 8466 | TAILQ_INSERT_AFTER(&rack->r_ctl.rc_tmap, rsm, nrsm, r_tnext); |
| 8467 | nrsm->r_in_tmap = 1; |
| 8468 | } |
| 8469 | /* |
| 8470 | * Set in the new RSM as the |
no test coverage detected