欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Linux網(wǎng)絡(luò)中數(shù)據(jù)包的接收過程是怎樣的

本篇文章為大家展示了Linux網(wǎng)絡(luò)中數(shù)據(jù)包的接收過程是怎樣的,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司成立于2013年,我們提供高端成都網(wǎng)站建設(shè)成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、網(wǎng)站定制、全網(wǎng)整合營銷推廣、微信小程序、微信公眾號開發(fā)、seo優(yōu)化排名服務(wù),提供專業(yè)營銷思路、內(nèi)容策劃、視覺設(shè)計(jì)、程序開發(fā)來完成項(xiàng)目落地,為成都加固企業(yè)提供源源不斷的流量和訂單咨詢。

下面將介紹在Linux系統(tǒng)中,數(shù)據(jù)包是如何一步一步從網(wǎng)卡傳到進(jìn)程手中的。

如果英文沒有問題,強(qiáng)烈建議閱讀后面參考里的兩篇文章,里面介紹的更詳細(xì)。

小編只討論以太網(wǎng)的物理網(wǎng)卡,不涉及虛擬設(shè)備,并且以一個UDP包的接收過程作為示例.

示例里列出的函數(shù)調(diào)用關(guān)系來自于kernel  3.13.0,如果你的內(nèi)核不是這個版本,函數(shù)名稱和相關(guān)路徑可能不一樣,但背后的原理應(yīng)該是一樣的(或者有細(xì)微差別)

網(wǎng)卡到內(nèi)存

網(wǎng)卡需要有驅(qū)動才能工作,驅(qū)動是加載到內(nèi)核中的模塊,負(fù)責(zé)銜接網(wǎng)卡和內(nèi)核的網(wǎng)絡(luò)模塊,驅(qū)動在加載的時候?qū)⒆约鹤赃M(jìn)網(wǎng)絡(luò)模塊,當(dāng)相應(yīng)的網(wǎng)卡收到數(shù)據(jù)包時,網(wǎng)絡(luò)模塊會調(diào)用相應(yīng)的驅(qū)動程序處理數(shù)據(jù)。

下圖展示了數(shù)據(jù)包(packet)如何進(jìn)入內(nèi)存,并被內(nèi)核的網(wǎng)絡(luò)模塊開始處理:

                   +-----+                    |     |                            Memroy +--------+   1     |     |  2  DMA     +--------+--------+--------+--------+ | Packet |-------->| NIC |------------>| Packet | Packet | Packet | ...... | +--------+         |     |             +--------+--------+--------+--------+                    |     |<--------+                    +-----+         |                       |            +---------------+                       |                            |                     3 | Raise IRQ                  | Disable IRQ                       |                          5 |                       |                            |                       &darr;                            |                    +-----+                   +------------+                    |     |  Run IRQ handler  |            |                    | CPU |------------------>| NIC Driver |                    |     |       4           |            |                    +-----+                   +------------+                                                    |                                                 6  | Raise soft IRQ                                                    |                                                    &darr;

1: 數(shù)據(jù)包從外面的網(wǎng)絡(luò)進(jìn)入物理網(wǎng)卡。如果目的地址不是該網(wǎng)卡,且該網(wǎng)卡沒有開啟混雜模式,該包會被網(wǎng)卡丟棄。

2: 網(wǎng)卡將數(shù)據(jù)包通過DMA的方式寫入到指定的內(nèi)存地址,該地址由網(wǎng)卡驅(qū)動分配并初始化。注: 老的網(wǎng)卡可能不支持DMA,不過新的網(wǎng)卡一般都支持。

3: 網(wǎng)卡通過硬件中斷(IRQ)通知CPU,告訴它有數(shù)據(jù)來了

4: CPU根據(jù)中斷表,調(diào)用已經(jīng)注冊的中斷函數(shù),這個中斷函數(shù)會調(diào)到驅(qū)動程序(NIC Driver)中相應(yīng)的函數(shù)

5:  驅(qū)動先禁用網(wǎng)卡的中斷,表示驅(qū)動程序已經(jīng)知道內(nèi)存中有數(shù)據(jù)了,告訴網(wǎng)卡下次再收到數(shù)據(jù)包直接寫內(nèi)存就可以了,不要再通知CPU了,這樣可以提高效率,避免CPU不停的被中斷。

6:  啟動軟中斷。這步結(jié)束后,硬件中斷處理函數(shù)就結(jié)束返回了。由于硬中斷處理程序執(zhí)行的過程中不能被中斷,所以如果它執(zhí)行時間過長,會導(dǎo)致CPU沒法響應(yīng)其它硬件的中斷,于是內(nèi)核引入軟中斷,這樣可以將硬中斷處理函數(shù)中耗時的部分移到軟中斷處理函數(shù)里面來慢慢處理。

內(nèi)核的網(wǎng)絡(luò)模塊

軟中斷會觸發(fā)內(nèi)核網(wǎng)絡(luò)模塊中的軟中斷處理函數(shù),后續(xù)流程如下

                                            +-----+                                     14      |     |                                +----------->| NIC |                                |            |     |                                |Enable IRQ  +-----+                                |                                |                          +------------+                                      Memroy                          |            |        Read           +--------+--------+--------+--------+         +--------------->| NIC Driver |<--------------------- | Packet | Packet | Packet | ...... |         |                |            |          9            +--------+--------+--------+--------+         |                +------------+         |                      |    |        skb    Poll | 8      Raise softIRQ | 6  +-----------------+         |                      |             10       |         |                      &darr;                      &darr; +---------------+  Call  +-----------+        +------------------+ | net_rx_action |<-------| ksoftirqd |        | napi_gro_receive | +---------------+   7    +-----------+        +------------------+                                                       |                                                       | 11                                                       &darr;                                            +--------------------------+    12      +------------------------+                                            | __netif_receive_skb_core |----------->| packet taps(AF_PACKET) |                                            +--------------------------+            +------------------------+                                                       |                                                       | 13                                                       &darr;                                              +-----------------+                                              | protocol layers |                                              +-----------------+

7:  內(nèi)核中的ksoftirqd進(jìn)程專門負(fù)責(zé)軟中斷的處理,當(dāng)它收到軟中斷后,就會調(diào)用相應(yīng)軟中斷所對應(yīng)的處理函數(shù),對于上面第6步中是網(wǎng)卡驅(qū)動模塊拋出的軟中斷,ksoftirqd會調(diào)用網(wǎng)絡(luò)模塊的net_rx_action函數(shù)

8: net_rx_action調(diào)用網(wǎng)卡驅(qū)動里的poll函數(shù)來一個一個的處理數(shù)據(jù)包

9: 在pool函數(shù)中,驅(qū)動會一個接一個的讀取網(wǎng)卡寫到內(nèi)存中的數(shù)據(jù)包,內(nèi)存中數(shù)據(jù)包的格式只有驅(qū)動知道

10: 驅(qū)動程序?qū)?nèi)存中的數(shù)據(jù)包轉(zhuǎn)換成內(nèi)核網(wǎng)絡(luò)模塊能識別的skb格式,然后調(diào)用napi_gro_receive函數(shù)

11:  napi_gro_receive會處理GRO相關(guān)的內(nèi)容,也就是將可以合并的數(shù)據(jù)包進(jìn)行合并,這樣就只需要調(diào)用一次協(xié)議棧,接著調(diào)用__netif_receive_skb_core

12:  看是不是有AF_PACKET類型的socket(也就是我們常說的原始套接字),如果有的話,拷貝一份數(shù)據(jù)給它。tcpdump抓包就是抓的這里的包。

13: 調(diào)用協(xié)議棧相應(yīng)的函數(shù),將數(shù)據(jù)包交給協(xié)議棧處理。

14: 待內(nèi)存中的所有數(shù)據(jù)包被處理完成后(即poll函數(shù)執(zhí)行完成),啟用網(wǎng)卡的硬中斷,這樣下次網(wǎng)卡再收到數(shù)據(jù)的時候就會通知CPU

協(xié)議棧

IP層

由于是UDP包,所以***步會進(jìn)入IP層,然后一級一級的函數(shù)往下調(diào):

|           |           &darr;         promiscuous mode &&       +--------+    PACKET_OTHERHOST (set by driver)   +-----------------+       | ip_rcv |-------------------------------------->| drop this packet|       +--------+                                       +-----------------+           |           |           &darr; +---------------------+ | NF_INET_PRE_ROUTING | +---------------------+           |           |           &darr;       +---------+       |         | enabled ip forword  +------------+        +----------------+       | routing |-------------------->| ip_forward |------->| NF_INET_FOWARD |       |         |                     +------------+        +----------------+       +---------+                                                   |           |                                                         |           | destination IP is local                                 &darr;           &darr;                                                 +---------------+  +------------------+                                       | dst_output_sk |  | ip_local_deliver |                                       +---------------+  +------------------+           |           |           &darr;  +------------------+  | NF_INET_LOCAL_IN |  +------------------+           |           |           &darr;     +-----------+     | UDP layer |     +-----------+
  • ip_rcv:  ip_rcv函數(shù)是IP模塊的入口函數(shù),在該函數(shù)里面,***件事就是將垃圾數(shù)據(jù)包(目的mac地址不是當(dāng)前網(wǎng)卡,但由于網(wǎng)卡設(shè)置了混雜模式而被接收進(jìn)來)直接丟掉,然后調(diào)用注冊在NF_INET_PRE_ROUTING上的函數(shù)

  • NF_INET_PRE_ROUTING:  netfilter放在協(xié)議棧中的鉤子,可以通過iptables來注入一些數(shù)據(jù)包處理函數(shù),用來修改或者丟棄數(shù)據(jù)包,如果數(shù)據(jù)包沒被丟棄,將繼續(xù)往下走

  • routing: 進(jìn)行路由,如果是目的IP不是本地IP,且沒有開啟ip forward功能,那么數(shù)據(jù)包將被丟棄,如果開啟了ip  forward功能,那將進(jìn)入ip_forward函數(shù)

  • ip_forward:  ip_forward會先調(diào)用netfilter注冊的NF_INET_FORWARD相關(guān)函數(shù),如果數(shù)據(jù)包沒有被丟棄,那么將繼續(xù)往后調(diào)用dst_output_sk函數(shù)

  • dst_output_sk: 該函數(shù)會調(diào)用IP層的相應(yīng)函數(shù)將該數(shù)據(jù)包發(fā)送出去,同下一篇要介紹的數(shù)據(jù)包發(fā)送流程的后半部分一樣。

  • ip_local_deliver:如果上面routing的時候發(fā)現(xiàn)目的IP是本地IP,那么將會調(diào)用該函數(shù),在該函數(shù)中,會先調(diào)用NF_INET_LOCAL_IN相關(guān)的鉤子程序,如果通過,數(shù)據(jù)包將會向下發(fā)送到UDP層

UDP層

 |          |          &darr;      +---------+            +-----------------------+      | udp_rcv |----------->| __udp4_lib_lookup_skb |      +---------+            +-----------------------+          |          |          &darr; +--------------------+      +-----------+ | sock_queue_rcv_skb |----->| sk_filter | +--------------------+      +-----------+          |          |          &darr; +------------------+ | __skb_queue_tail | +------------------+          |          |          &darr;  +---------------+  | sk_data_ready |  +---------------+
  • udp_rcv:  udp_rcv函數(shù)是UDP模塊的入口函數(shù),它里面會調(diào)用其它的函數(shù),主要是做一些必要的檢查,其中一個重要的調(diào)用是__udp4_lib_lookup_skb,該函數(shù)會根據(jù)目的IP和端口找對應(yīng)的socket,如果沒有找到相應(yīng)的socket,那么該數(shù)據(jù)包將會被丟棄,否則繼續(xù)

  • sock_queue_rcv_skb: 主要干了兩件事,一是檢查這個socket的receive  buffer是不是滿了,如果滿了的話,丟棄該數(shù)據(jù)包,然后就是調(diào)用sk_filter看這個包是否是滿足條件的包,如果當(dāng)前socket上設(shè)置了filter,且該包不滿足條件的話,這個數(shù)據(jù)包也將被丟棄(在Linux里面,每個socket上都可以像tcpdump里面一樣定義filter,不滿足條件的數(shù)據(jù)包將會被丟棄)

  • __skb_queue_tail: 將數(shù)據(jù)包放入socket接收隊(duì)列的末尾

  • sk_data_ready: 通知socket數(shù)據(jù)包已經(jīng)準(zhǔn)備好

調(diào)用完sk_data_ready之后,一個數(shù)據(jù)包處理完成,等待應(yīng)用層程序來讀取,上面所有函數(shù)的執(zhí)行過程都在軟中斷的上下文中。

socket

應(yīng)用層一般有兩種方式接收數(shù)據(jù),一種是recvfrom函數(shù)阻塞在那里等著數(shù)據(jù)來,這種情況下當(dāng)socket收到通知后,recvfrom就會被喚醒,然后讀取接收隊(duì)列的數(shù)據(jù);另一種是通過epoll或者select監(jiān)聽相應(yīng)的socket,當(dāng)收到通知后,再調(diào)用recvfrom函數(shù)去讀取接收隊(duì)列的數(shù)據(jù)。兩種情況都能正常的接收到相應(yīng)的數(shù)據(jù)包。

上述內(nèi)容就是Linux網(wǎng)絡(luò)中數(shù)據(jù)包的接收過程是怎樣的,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章標(biāo)題:Linux網(wǎng)絡(luò)中數(shù)據(jù)包的接收過程是怎樣的
URL地址:http://aaarwkj.com/article26/gpijjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、網(wǎng)站維護(hù)商城網(wǎng)站、軟件開發(fā)、面包屑導(dǎo)航、網(wǎng)頁設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
日日夜夜精品天天综合| 国产姐弟操大率悠荡笕| 国产自愉自愉免费精品七| 久久久精品国产亚洲av色哟哟| 亚洲精品一区二区影院| 午夜激情毛片在线观看| 久久热在线观看免费高清| 中文字幕亚洲精品四区| 青青草原精品资源视频| 日韩精品欧美精品一区二区| 97视频精品在线播放| 日韩最新视频一区二区三| 夫妻性生活黄色录像视频| 国产模特一区二区三区| 亚洲熟女午夜毛片av毛片| 国产传媒在线播放一区| 日本一区二区电影大全| 午夜两性做爰免费视频| 亚洲1区2区中文字幕| 欧美一区二区三区久久束缚| 欧美午夜福利在线视频| 91精品国产综合久久男男| 欧美日韩国产精品精品| 日韩av大片一区二区三区| 蜜桃成人一区二区三区| 久久精品一区二区熟女| 日本欧美精品一区二区精选| 亚洲av成人三区国产精品| 亚洲人妻不卡一区二区| 久久精品国产亚洲成人av| 国产精品白丝一区二区三区| 日本电影在线看一区二区| 日本特黄高清免费大片| 成熟性性生活免费视频| 日本一区二区三区三州免费观看| 色日韩在线观看视频| 国产精品推荐不卡一区| 欧美一级特黄大片做受| 日韩精品中文字幕欧美乱| 亚洲精品久久麻豆蜜桃| 91日本视频在线播放|