* Check for 'stale' completed packets that need to be delivered * * If a link goes down or has a temporary failure, MSEQ can get * "stuck", because no new incoming fragments appear on that link. * This can cause completed packets to never get delivered if * their sequence numbers are all > MSEQ + 1. * * This routine checks how long all of the completed packets have * been sitting in the qu
| 1884 | * from the queue and increments MSEQ to allow them to be delivered. |
| 1885 | */ |
| 1886 | static void |
| 1887 | ng_ppp_frag_checkstale(node_p node) |
| 1888 | { |
| 1889 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 1890 | struct ng_ppp_frag *qent, *beg, *end; |
| 1891 | struct timeval now, age; |
| 1892 | struct mbuf *m; |
| 1893 | int seq; |
| 1894 | item_p item; |
| 1895 | int endseq; |
| 1896 | uint16_t proto; |
| 1897 | |
| 1898 | now.tv_sec = 0; /* uninitialized state */ |
| 1899 | while (1) { |
| 1900 | /* If queue is empty, we're done */ |
| 1901 | if (TAILQ_EMPTY(&priv->frags)) |
| 1902 | break; |
| 1903 | |
| 1904 | /* Find the first complete packet in the queue */ |
| 1905 | beg = end = NULL; |
| 1906 | seq = TAILQ_FIRST(&priv->frags)->seq; |
| 1907 | TAILQ_FOREACH(qent, &priv->frags, f_qent) { |
| 1908 | if (qent->first) |
| 1909 | beg = qent; |
| 1910 | else if (qent->seq != seq) |
| 1911 | beg = NULL; |
| 1912 | if (beg != NULL && qent->last) { |
| 1913 | end = qent; |
| 1914 | break; |
| 1915 | } |
| 1916 | seq = MP_NEXT_RECV_SEQ(priv, seq); |
| 1917 | } |
| 1918 | |
| 1919 | /* If none found, exit */ |
| 1920 | if (end == NULL) |
| 1921 | break; |
| 1922 | |
| 1923 | /* Get current time (we assume we've been up for >= 1 second) */ |
| 1924 | if (now.tv_sec == 0) |
| 1925 | getmicrouptime(&now); |
| 1926 | |
| 1927 | /* Check if packet has been queued too long */ |
| 1928 | age = now; |
| 1929 | timevalsub(&age, &beg->timestamp); |
| 1930 | if (timevalcmp(&age, &ng_ppp_max_staleness, < )) |
| 1931 | break; |
| 1932 | |
| 1933 | /* Throw away junk fragments in front of the completed packet */ |
| 1934 | while ((qent = TAILQ_FIRST(&priv->frags)) != beg) { |
| 1935 | KASSERT(!TAILQ_EMPTY(&priv->frags), |
| 1936 | ("%s: empty q", __func__)); |
| 1937 | priv->bundleStats.dropFragments++; |
| 1938 | TAILQ_REMOVE(&priv->frags, qent, f_qent); |
| 1939 | NG_FREE_M(qent->data); |
| 1940 | TAILQ_INSERT_HEAD(&priv->fragsfree, qent, f_qent); |
| 1941 | } |
| 1942 | |
| 1943 | /* Extract completed packet */ |
no test coverage detected