| 8068 | } |
| 8069 | |
| 8070 | static void |
| 8071 | bbr_collapsed_window(struct tcp_bbr *bbr) |
| 8072 | { |
| 8073 | /* |
| 8074 | * Now we must walk the |
| 8075 | * send map and divide the |
| 8076 | * ones left stranded. These |
| 8077 | * guys can't cause us to abort |
| 8078 | * the connection and are really |
| 8079 | * "unsent". However if a buggy |
| 8080 | * client actually did keep some |
| 8081 | * of the data i.e. collapsed the win |
| 8082 | * and refused to ack and then opened |
| 8083 | * the win and acked that data. We would |
| 8084 | * get into an ack war, the simplier |
| 8085 | * method then of just pretending we |
| 8086 | * did not send those segments something |
| 8087 | * won't work. |
| 8088 | */ |
| 8089 | struct bbr_sendmap *rsm, *nrsm; |
| 8090 | tcp_seq max_seq; |
| 8091 | uint32_t maxseg; |
| 8092 | int can_split = 0; |
| 8093 | int fnd = 0; |
| 8094 | |
| 8095 | maxseg = bbr->rc_tp->t_maxseg - bbr->rc_last_options; |
| 8096 | max_seq = bbr->rc_tp->snd_una + bbr->rc_tp->snd_wnd; |
| 8097 | bbr_log_type_rwnd_collapse(bbr, max_seq, 1, 0); |
| 8098 | TAILQ_FOREACH(rsm, &bbr->r_ctl.rc_map, r_next) { |
| 8099 | /* Find the first seq past or at maxseq */ |
| 8100 | if (rsm->r_flags & BBR_RWND_COLLAPSED) |
| 8101 | rsm->r_flags &= ~BBR_RWND_COLLAPSED; |
| 8102 | if (SEQ_GEQ(max_seq, rsm->r_start) && |
| 8103 | SEQ_GEQ(rsm->r_end, max_seq)) { |
| 8104 | fnd = 1; |
| 8105 | break; |
| 8106 | } |
| 8107 | } |
| 8108 | bbr->rc_has_collapsed = 0; |
| 8109 | if (!fnd) { |
| 8110 | /* Nothing to do strange */ |
| 8111 | return; |
| 8112 | } |
| 8113 | /* |
| 8114 | * Now can we split? |
| 8115 | * |
| 8116 | * We don't want to split if splitting |
| 8117 | * would generate too many small segments |
| 8118 | * less we let an attacker fragment our |
| 8119 | * send_map and leave us out of memory. |
| 8120 | */ |
| 8121 | if ((max_seq != rsm->r_start) && |
| 8122 | (max_seq != rsm->r_end)){ |
| 8123 | /* can we split? */ |
| 8124 | int res1, res2; |
| 8125 | |
| 8126 | res1 = max_seq - rsm->r_start; |
| 8127 | res2 = rsm->r_end - max_seq; |
no test coverage detected