部分域名無法正常彈出portal問題解析

1. 問題現象

前幾天線上設備出現奇怪的現象,部分終端使用UC瀏覽器訪問部分網站無法彈出portal或彈出portal比較慢,但是其他大部分終端訪問卻可以正常彈出portal,真是莫名其妙,到底是怎麼回事?

2. 現象分析

剛開始本地嘗試復現,但是一直沒有出來,線上又不好分析,一度陷入了死局。
後來想起之前有遇到過瀏覽器雲端加速導致訪問異常的情況,所以就懷疑是瀏覽器雲端加速導致的,所以立即進行測試

a. 使用UC瀏覽器,開啓雲端加速,果然portal無法彈出或彈出很慢,關閉後正常。通過抓包發現開啓時,打開網站時,瀏覽器會主動向某些地址發送請求,端口是8081(我們是監控80端口進行彈portal的,8081請求,如果訪問的域名或IP不在白名單中直接丟棄)。

b. 開啓雲端加速,將瀏覽器主動請求的地址加入白名單中,彈出portal正常。

這應該就確定跟雲端加速時,主動訪問其他域名非80端口時,報文被丟棄了,所以就讓測試去搜集不同瀏覽器雲端加速的域名了。

難道真的是這個原因嗎?,如果你也這麼想,那我們都是too young了!

另外一個同事,一直覺得不是這麼簡單,所以他後來又進行了深度的測試,詳細分析了portal彈出失敗時的報文,果然發現真的不是那麼簡單!

通過分析報文發現有兩種情況:
1)將雲端加速訪問的域名加入白名單後,訪問時直接可以上網,不會彈portal
2)關閉雲端加速時,訪問某個網站時,死活不彈portal

3. 解決方案

看到這裏,你應該也會納悶,怎麼回事?

第一種情況:

之前我們測試只是加了一個IP,可能這個IP就只是用來探測連接的,真正數據通信使用的是另外的IP,所以加入後可以正常彈portal(這個需要具體分析下,Mark)。當把域名加進去後,域名對應的所有IP都正常訪問,當你訪問某個域名時,瀏覽器先向雲服務器請求,雲服務器再向這個域名請求,然後將返回的數據,返回給瀏覽器。因爲雲服務器都放行了,這時雲服務器就像代理一樣,你雖然沒有認證過,但是數據都是走雲服務器代理出去的,所以你就可以直接上網了。

針對這種情況該怎麼做呢,這個暫時還沒有方案,待詳細分析下瀏覽器雲端加速原理再說吧!

第二種情況:

通過仔細分析報文,終於發現原來是請求報文分片了,並且第一片數據是在ACK報文中的!代碼中沒有針對ACK攜帶數據進行處理,因爲一般都是PUSH中才會攜帶數據。真是漲了見識,不過也暴露了自己對網絡協議這塊的生疏。

這裏寫圖片描述

這種情況就比較好解決了,只需要添加針對ACK報文的處理了,但是總不能所有的ACK都處理吧!如果ACK沒有攜帶數據,根本就沒必要處理。

那怎麼判斷ACK中有沒有數據呢?

其實很簡單,暴力點,就判斷ip頭總長度是不是大於40,如果是,就判斷ACK攜帶有數據,如果不是,那肯定沒有攜帶數據。修改後,測試,完美解決,搞定!

if (1==tcph->psh
|| (1==tcph->ack && iph->tot_len > 40)) //判斷IP頭大於40,就斷定ACK中攜帶有數據
{
    int ret = -1;
    struct httphdr* http=NULL;

    DCINFO("Reply ack.\n");
    dc_reply_ack(skb,iph,tcph); 

    http = kmalloc(sizeof(struct httphdr),GFP_ATOMIC);
    if(!http)
    {
        DCERR("Malloc failed.");
        return NF_ACCEPT;
    }
    ...
}

至於第一種情況,後面詳細分析下,再好好談論下方案!

這種情況下不解決,會嚴重影響使用雲端加速瀏覽器的用戶體驗!

發佈了48 篇原創文章 · 獲贊 8 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章