0%

擷取封包練習

最近接到一個任務,需要協助團隊重現幾個 DB 連線時的錯誤,例如: connection pool 超過上限爆掉、connection timeout 等等,而其中一個錯誤 Pre-Login handshack 最難重現

1
2
System.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired.  The timeout period elapsed while attempting to consume the pre-login handshake acknowledgement.  This could be because the 
pre-login handshake failed or the server was unable to respond back in time. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=2846; handshake=6765;

這個錯誤推測是在與 SQL Server 連線時 three-way handshake 沒有收到回應導致的失敗,可能屬於網路不穩掉封包問題導致,但問題怎麼證明?

Wireshark

首先得先確認與 SQL Server 連線時到底傳了哪些封包出去,可以透過 wireshark 側錄封包的功能來達成

1. 設定 Capture

1
dst host xxx.xxx.xxx.xxx && port 1433

/images/20210429/1.png

2. 嘗試對 SQL 做一次連線並觀察封包

/images/20210429/2.png
可以發現 Pre-login handshake 應該會有三次封包傳輸

Packet Loss

接著得想辦法重現封包丟失的狀況下,是否會引發相同的 Exception,因為不知道怎麼精準的特定封包攔下來 (如果有人會的話也歡迎留言教學一下),所以這邊透過 Clumsy 這個套件來輔助達成

1. 指定目的地的封包多少比例被攔截下來

1
outbound and ip.DstAddr = xxx.xxx.xxx.xxx

/images/20210429/3.png

2. 增加連線 handshake 的機率

因為無法精準攔截封包,所以採取短時間快速重複連線來增加封包被攔截的碰撞機率,所以我將 Connection Pool 關閉,並且開多執行序只做最簡單的連線與關閉連線,果然很快就碰到 handshake 的封包被攔掉的狀況

/images/20210429/4.png

而最後也證實了只要連線時網路不穩定導致掉封包等狀況時,底層是會引發上述錯誤的狀況