* The oldest packet spent too much time in the reorder queue. * Deliver it and next packets in sequence, if any. */
| 1165 | * Deliver it and next packets in sequence, if any. |
| 1166 | */ |
| 1167 | static void |
| 1168 | ng_pptpgre_reorder_timeout(node_p node, hook_p hook, void *arg1, int arg2) |
| 1169 | { |
| 1170 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 1171 | const hpriv_p hpriv = arg1; |
| 1172 | roqh sendq = SLIST_HEAD_INITIALIZER(sendq); |
| 1173 | struct ng_pptpgre_roq *np, *last = NULL; |
| 1174 | |
| 1175 | priv->stats.recvReorderTimeouts++; |
| 1176 | mtx_lock(&hpriv->mtx); |
| 1177 | if (SLIST_EMPTY(&hpriv->roq)) { /* should not happen */ |
| 1178 | mtx_unlock(&hpriv->mtx); |
| 1179 | return; |
| 1180 | } |
| 1181 | |
| 1182 | last = np = SLIST_FIRST(&hpriv->roq); |
| 1183 | hpriv->roq_len--; |
| 1184 | SLIST_REMOVE_HEAD(&hpriv->roq, next); |
| 1185 | SLIST_INSERT_HEAD(&sendq, np, next); |
| 1186 | |
| 1187 | /* Look if we have more packets in sequence */ |
| 1188 | while (!SLIST_EMPTY(&hpriv->roq)) { |
| 1189 | np = SLIST_FIRST(&hpriv->roq); |
| 1190 | if (PPTP_SEQ_DIFF(np->seq, last->seq) > 1) |
| 1191 | break; /* the gap in the sequence */ |
| 1192 | |
| 1193 | /* Next packet is in sequence, move it to the sendq. */ |
| 1194 | hpriv->roq_len--; |
| 1195 | SLIST_REMOVE_HEAD(&hpriv->roq, next); |
| 1196 | SLIST_INSERT_AFTER(last, np, next); |
| 1197 | last = np; |
| 1198 | } |
| 1199 | |
| 1200 | hpriv->recvSeq = last->seq; |
| 1201 | if (!SLIST_EMPTY(&hpriv->roq)) |
| 1202 | ng_pptpgre_start_reorder_timer(hpriv); |
| 1203 | |
| 1204 | /* We need to acknowledge last packet; do it soon... */ |
| 1205 | ng_pptpgre_ack(hpriv); /* drops lock */ |
| 1206 | ng_pptpgre_sendq(hpriv, &sendq, NULL); |
| 1207 | mtx_assert(&hpriv->mtx, MA_NOTOWNED); |
| 1208 | } |
| 1209 | |
| 1210 | /************************************************************************* |
| 1211 | MISC FUNCTIONS |
nothing calls this directly
no test coverage detected