BT源代碼學習心得(八):跟蹤服務器(Tracker)的代碼分析(用戶請求的實際處理)

BT源代碼學習心得(八):跟蹤服務器(Tracker)的代碼分析(用戶請求的實際處理)

發信人: wolfenstein (NeverSayNever), 個人文集
標  題: BT源代碼學習心得(八):跟蹤服務器(Tracker)的代碼分析(用戶請求的實際處理)
發信站: 水木社區 (Wed Aug 10 21:52:50 2005), 文集
(本文包含HTML標記,終端模式下可能無法正確瀏覽)
    通過上一次的分析,我們已經知道了Tracker採用http協議和客戶端通信,這一次我們
就可以直接分析Tracker.get函數的代碼,看看跟蹤服務器是如何處理用戶的請求的。
    首先是檢查IP,一個是通過網絡連接直接得到的IP(這個有可能是對方的http代理服務
器的IP),另一個是從請求的頭部數據中解析出來的IP,通過分析函數get_forwarded_ip和
_get_forwarded_ip我們可以發現,它的原理是從頭部數據中看有沒有這些關鍵字:
http_x_forwarded_for,http_client_ip,http_via,http_from,如果有的話,就說明當
前的http連接中的網絡的另一頭是一個代理服務器,而不是實際的客戶端,有些http代理服
務器會提交這些http請求的頭部數據告訴服務器客戶端的真實IP地址。還有就是要檢查這些
IP地址是否合法,是否爲本地地址(10.*.*.*,127.*.*.*,169.254.*.*,
172.16.*.*-172.31.*.*,192.168.*.*)等,然後確認真實的IP值。接下來準備好
paramslist準備處理請求參數,這是一個字典,但是它的每個元素的值是一個列表,這種情
況在http請求的參數列表中很常見。
    接下來用urlparse把用戶的http請求分成標準的幾部分,例如,類似如下的請求:
     [ http://xxx.xxx.xxx/path;parameters?query1=a&query2=b&query3=c#fragment ]
http://xxx.xxx.xxx/path;parameters?query1=a&query2=b&query3=c#fragment
    將被分割成這樣的6塊:http,xxx.xxx.xxx,path,parameters,
query1=a&query2=b&query3=c,fragment
    接下來把query中的值按照'&'以及'='進行處理,把它們填入到paramslist中,確認出
請求的參數。下面就是根據各種情況返回給用戶適當的結果了。
    首先,如果用戶請求路徑是空的或者是'index.html'(對應於 [ http://xxx.xxx.xxx/
] http://xxx.xxx.xxx/或者 [ http://xxx.xxx.xxx/index.html ]
http://xxx.xxx.xxx/index.html),那麼就返回給用戶一個信息頁面,使用get_infopage函
數完成,當然,在實際運行中,可以把配置文件設置爲不允許顯示信息頁面,這樣
get_infopage就會返回HTTP404代碼,否則,生成一個頁面文件,它包含了一些基本信息,
以及該跟蹤服務器目前關注的種子文件的列表以及它們的一些統計情況。接下來的情況是用
戶請求路徑'scrape'或者'file',也是返回相應的信息給用戶。其中,get_scrape返回的各
個種子文件的統計信息,例如某個種子有多少下載完了,多少人還沒下載完成等。而'
file'則是直接獲取某個種子文件(即允許用戶直接從跟蹤服務器下載種子文件)。注意在以
上的請求過程中,表示某個具體的種子文件的關鍵字是它的信息部分的消息摘要值
(infohash)。
    在處理完另一種情況,用戶要求返回圖標文件後,接下來就是跟蹤服務器的主要功能,
announce了。所以如果路徑不是announce的話,那就返回HTTP404。下面先獲取infohash,
即客戶端請求的是哪個種子文件的情況,然後進行check_allowed檢查,排除有些種子不能
在此跟蹤服務器上下載的情況。這樣可以及時得對跟蹤服務器做一些授權方面的操作,例如
如果發現有人發佈了有違反國家法律法規的內容的種子,跟蹤服務器的維護人員只需要及時
得把這個種子的infohash添加到這個列表中,就再沒有人可以下載這個種子了。
    在排除了各種意外的情況後,就可以用add_data把用戶的信息添加進去了。一個跟蹤服
務器在獲取了一個客戶端要求下載某個種子文件的請求後,它把這個客戶的信息記錄起來,
這樣他就知道有哪些客戶對某個具體的種子文件感興趣。然後再根據這些列表,選取一些客
戶的信息返回給客戶,而要下載這個種子文件中的實際共享資源?自己去找其它客戶(客戶
稱呼其它客戶時應該叫對等客戶)解決吧,跟蹤服務器上一個字節都沒有。
    add_data首先從downloads這個字典中找到關鍵字爲infohash的項,賦值到peers中,如
果downloads中沒有這項,則新建這項(setdefault,詳見python庫參考手冊之內建類型字典
的詳細說明),然後檢查傳進來的參數是否合法,如peerid必須是20個字節,event(如果有
)只能是'started','completed','stopped','snooped'中的一項等。peers是一個以
peerid爲關鍵字的字典,因此先看看原來有沒有這個peer,用peerid把它取出來。然後準備
好rsize,這個是返回的項(即返回多少個對等客戶的信息給客戶)的數目,它由客戶的要求
以及服務器的配置參數共同決定。然後如果用戶的請求中有event=stopped項,則刪除該客
戶的信息,否則,如果peer爲空(peers中沒有這個peerid的peer),則設置好一個新的peer
的信息,然後添加進去,如果peer已經存在了,那麼就更新一下它的信息。最後返回rsize
完成任務。其中有一個NAT處理的類,定義在BitTorrent/NatCheck.py中,它通過往用戶聲
稱的IP和端口進行一次連接,看看有沒有反應,以確認NAT情況,並且記錄下來。最後還要
把這些數據放到becache中,這個地方存放經過一定格式處理後的客戶數據,可以加快返回
客戶信息的函數的處理過程。becache中所有的客戶信息都按照下載完成(做種)和未完成分
開了,這個可以方便服務器返回一定的做種peers和非做種peers給客戶。
    在add_data把客戶的數據更新好後,接下來就是用peerlist函數返回一定量的客戶信息
了。它根據用戶的要求(rsize),以及所有的peers中種子數佔的比例,決定返回給客戶的信
息中,有多少是做種的peers,即返回給客戶的做種peers佔所有返回給客戶的peers的比例
,應該接近於所有在下載這個種子的做種peers和全部peers的比例。然後把兩部分的信息復
制到一個cache中,再用shuffle把它們打亂,最後把這些信息返回給客戶。因此我們可以看
到,跟蹤服務器返回用戶信息的準則是,在保持種子所佔的比例接近全局的種子比例的情況
下,隨機選取客戶信息返回給客戶。
   今天把跟蹤服務器的代碼全部分析完了,下一次就可以開始客戶端源代碼分析了。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章