是什麼阻止了我們的 UDP 數據包(它如何知道路由已關閉)?
我們有一台伺服器(攝像頭)通過 UDP 發送 RTSP 影片數據包。在客戶站點,它會經過幾跳,其中一個可能是不可靠的 WiFi 連結,它丟棄了一個或五個奇數數據包。通常這不會被注意到,但有時它會在幾秒鐘內終止流並引起客戶不滿(我知道,他們的 cr*p 網路在某種程度上是我們的問題……)
在使用
tc
模擬狡猾的連接進行測試時,我們發現了一個奇怪的情況:如果我們在返回方向斷開連接(數據包被靜默丟棄),幾秒鐘後來自我們相機的 UDP 數據包流停止,即使 RTSP 客戶端(Live555 Wis-Streamer) 仍然認為它正在愉快地將 UDP 數據包噴射到管道上。這很奇怪,因為顯然 UDP 數據包沒有 ACK 並且物理連結永遠不會掉線,所以我們的系統無法知道數據包是否會掉入鏈上更遠的位桶中,並且流媒體無法知道沒有人在聽它(流媒體會話超時直到稍後才會過期)。
編輯:在 UDP 數據包停止到來的那一刻,我們看到 ARPing(誰有 < client >),但在這之前沒有任何數據包會告訴堆棧連接已斷開。
所以我有兩個問題:
- 網路堆棧是否有其他機制可以告訴連接有問題?
- 在某些情況下,網路堆棧是否會靜默丟棄數據包?
為了展示我們的測試設置:
正常狀態,雙向連通:
Our server <==> Switch <==> TC <==> Switch <==> PC | | Wireshark <-- TAP | | Wireshark <----------------------- TAP
故障狀態,TC丟包返回我們的伺服器:
Our server --> Switch --> TC <==> Switch <==> PC | | Wireshark <-- TAP | | Wireshark <----------------------- TAP
好吧,看起來是 ARP 表過時了(即使我們像瘋了一樣流式傳輸 UDP,也不會觸發 ARP 超時,並且 TCP 流量在正常操作下更加稀疏)增加超時阻止了問題的出現對於不到 2 分鐘的“休息”(此時 RTSP 客戶端會話無論如何都會超時):
ARP gc_staletime extended from 60sec to 360sec ARP base_unreachable time extended from 30sec to 240sec
不幸的是,當我們在 Busybox 上沒有
arp
可用的命令時,這需要花費相當多的時間,但現在對於我們試圖處理的情況來說似乎是可靠的。我仍然很想了解網路堆棧是如何工作的——在 ARP 表/條目過時的那一刻,它會停止發送數據包,但似乎不會在嘗試發送數據包的程式碼鏈中進一步導致錯誤。
一旦斷開連接,您應該開始接收 ICMP 目標不可達數據包,以通知您連接已斷開。這是正常的 IP 行為。
有一些工具可以監視和顯示 ICMP 數據包。其他工具可用於轉儲或擷取與選擇標準匹配的所有流量。
使用自定義代理伺服器丟棄數據包可能會更好。