一年十二月  誰主春秋
關注:基礎系統工程 密碼學 人工智能
C++博客
首頁
新隨筆
聯系
聚合
管理
隨筆-159 評論-223 文章-30 trackbacks-0
Linux ICMP消息的產生與轉換
ICMP在IP系統間傳遞差錯和管理報文,是任何IP系統必須實現的組成部分。Linux 2.6.34中ICMP模塊的實現在linux/icmp.h,net/icmp.h和ipv4/icmp.c中,導出了
icmp_err_convert
數組和
icmp_send
函數,供其它網絡子系統使用。在其它網絡子系統中,當檢測到錯誤時,調用icmp_send產生并發送相應的ICMP差錯消息到源主機;當源主機收到ICMP不可達差錯消息,傳遞到原始套接字和傳輸層,而它們使用icmp_err_convert把對應的消息代碼轉換成套接字層比較容易理解的錯誤代碼。在內核空間中可發送的ICMP消息包括查詢應答和差錯報文,下面總結了產生這兩類消息的網絡子系統(及函數)與錯誤轉換。
應答消息
應答消息由ICMP模塊的內部函數icmp_reply而非icmp_send發送。根據
RFC1122 3.2.2.9
規范, 除非一個主機作為地址掩碼代理,否則不能發送回復,這對應ICMP的icmp_address實現為空,因此上表沒有列出地址掩碼應答項(內核符號為ICMP_ADDRESSREPLY)。
差錯消息
差錯消息由中間路由器或目的主機產生,當數據報不能成功提交給目的主機時。從上表可見,在IP層的接收、本地處理、轉發和輸出各過程中,都可能產生差錯消息;在傳輸層如果對應的端口沒有打開,那么UDP會產生ICMP端口不可達差錯,而
TCP則會使用自己的差錯處理機制發送一個RST復位包,這也是上表沒有列出TCP子系統的原因
。對于重定向差錯,由ICMP模塊的icmp_redirect調用ip_rt_redirect更新路由;其它差錯則由icmp_unreach處理。
錯誤轉換
第2列為icmp_err_convert數組索引,第4列也就是調用socket API出錯時返回的errno,最后1列為icmp_err_convert中的fatal成員取值,0表示非致命錯誤,1表示致命錯誤,需要報告給用戶進程。錯誤轉換會被RAW的raw_err、TCP的tcp_v4_err和UDP的udp_err用到,對于ICMP_DEST_UNREACH類型的差錯,使用上表轉換;ICMP_SOURCE_QUENCH類型的忽略不處理;ICMP_PARAMETERPROB類型的轉換成
EPROTO
(協議錯誤);ICMP_TIME_EXCEEDED類型的轉換成
EHOSTUNREACH
。
在這要注意,從ICMP_PORT_UNREACH到ECONNREFUSED的轉換,不適用于TCP,原因已在
上節
說明;而對于UDP的
未連接
套接字,如果主機在線而端口沒打開,調用sendto得不到ECONNREFUSED錯誤,但recvfrom會阻塞,這是因為雖然內核收到了ICMP差錯,但沒上報給應用進程。盡管如此,如果想得到ECONNREFUSED錯誤,那么可以寫個ICMP守護進程,應用進程先把它的套接字描述符通過unix域套接口傳遞到ICMP守護進程,而守護進程使用raw socket來接收ICMP差錯,再發給應用進程。
發送限速
不論一般差錯消息還是重定向差錯消息,發送限速針對的都是特定目標主機。
一般限速
在使用icmp_send發送差錯消息(PMTU消息除外)時,為減少網絡擁塞而限制了發送的速率,限速由xrlim_allow函數實現,定義在ipv4/icmp.c中。
1
#define
XRLIM_BURST_FACTOR
6
2
int
xrlim_allow
(
struct
dst_entry
*
dst,
int
timeout)
3
{
4
unsigned
long
now, token
=
dst
->
rate_tokens;
5
int
rc
=
0
;
6
7
now
=
jiffies;
8
token
+=
now
-
dst
->
rate_last;
9
dst
->
rate_last
=
now;
10
if
(token
>
XRLIM_BURST_FACTOR
*
timeout)
11
token
=
XRLIM_BURST_FACTOR
*
timeout;
12
if
(token
>=
timeout)
{
13
token
-=
timeout;
14
rc
=
1
;
15
}
16
dst
->
rate_tokens
=
token;
17
return
rc;
18
}
dst為目標路由緩存,timeout為允許發送的超時(單位為jiffies),dst->rate_tokens記錄令牌的個數,當令牌個數不小于timeout時,則減少timeout并允許發送一個消息;反之則不能發送,需等到令牌個數累積到大于timeout時才能發送,但是不能無限大,否則就會導致在一個可能很短的timeout內,發送遠多于6個的消息,引起ICMP風暴,所以這里限制了令牌的最大值為XRLIM_BURST_FACTOR*timeout即6倍的超時,也就是說在一個timeout內,最多能發送6個差錯消息。
重定向限速
路由子系統使用ip_rt_send_redirect來發送重定向消息,定義在ipv4/route.c中,該函數內部調用icmp_send實現,在它的限速基礎上,使用
指數回退算法
控制發送速率。
1
void
ip_rt_send_redirect
(
struct
sk_buff
*
skb)
2
{
3
struct
rtable
*
rt
=
skb_rtable(skb);
4
5
6
/**/
/*
No redirected packets during ip_rt_redirect_silence;
7
* reset the algorithm.
8
*/
9
if
(time_after(jiffies, rt
->
u.dst.rate_last
+
ip_rt_redirect_silence
))
10
rt
->
u.dst.rate_tokens
=
0
;
11
12
/**/
/*
Too many ignored redirects; do not send anything
13
* set u.dst.rate_last to the last seen redirected packet.
14
*/
15
if
(rt
->
u.dst.rate_tokens
>=
ip_rt_redirect_number
)
{
16
rt
->
u.dst.rate_last
=
jiffies;
17
return
;
18
}
19
20
/**/
/*
Check for load limit; set rate_last to the latest sent
21
* redirect.
22
*/
23
if
(rt
->
u.dst.rate_tokens
==
0
||
time_after(jiffies,
(rt
->
u.dst.rate_last
+
(
ip_rt_redirect_load
<<
rt
->
u.dst.rate_tokens))))
{
24
icmp_sen
d
(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt
->
rt_gateway);
25
rt
->
u.dst.rate_last
=
jiffies;
26
++
rt
->
u.dst.rate_tokens;
27
28
}
29
}
重定向差錯使用ip_rt_redirect_silence(默認為(HZ/50)<<10)、ip_rt_redirect_number(默認為9)和ip_rt_redirect_load(默認為HZ/50)3個量來控制發送的速率;rt->u.dst.rate_last記錄上次發送的時間,rt->u.dst.rate_tokens累計發送總數,最大值為ip_rt_redirect_number;當兩次發送的時間間隔超過ip_rt_redirect_silence或ip_rt_redirect_load<<rt->u.dst.rate_tokens,并且發送總數不超過ip_rt_redirect_number時,才允許發送一個,這樣一來,在ip_rt_redirect_silence間隔內,每次發送的超時呈2的指數增長,達到了變減速發送的效果,直到總數達到ip_rt_redirect_number時停止發送,這是因為源主機可能忽略了重定向消息所以停止發送;當ip_rt_redirect_silence時間過后,又允許發送了,這是因為認為源主機沒有更新路由所以又需要發送。
posted on 2015-05-18 19:52
春秋十二月
閱讀(2796)
評論(0)
編輯
收藏
引用
所屬分類:
Network
只有注冊用戶
登錄
后才能發表評論。
【推薦】100%開源!大型工業跨平臺軟件C++源碼提供,建模,組態!
相關文章:
基于X509證書的身份認證思考小結
使用HiRedis實現自動重連Redis
基于ENet實現可靠UDP通信的同步模型
總結網絡路由走向診斷方法
深入理解SSL/TLS技術內幕
一種攔截Linux原始套接字IO的方法
一種P2P代理中TCP連接調度的方法
TCP分組丟失時的狀態變遷
Linux ICMP消息的產生與轉換
Linux套接字與虛擬文件系統(2):操作和銷毀
網站導航:
博客園
IT新聞
BlogJava
博問
Chat2DB
管理
本博客所有隨筆均為原創,因為不定期維護更新,所以轉載請注明出處,如有問題和建議,請留言或評論,發表您的寶貴意見,藉此平臺以分享交流、共同進步。
聯系方式:微信theory-math
<
2015年5月
>
日
一
二
三
四
五
六
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
常用鏈接
我的隨筆
我的評論
我參與的隨筆
留言簿
(74)
給我留言
查看公開留言
查看私人留言
隨筆分類
(158)
Algorithm(46)
C/C++(24)
Compiler(25)
Compute Theory(5)
Database(4)
Network(17)
Opensrc(13)
System(24)
隨筆檔案
(159)
2025年4月 (2)
2024年12月 (1)
2024年11月 (1)
2024年9月 (1)
2024年8月 (2)
2024年6月 (1)
2024年5月 (1)
2024年4月 (1)
2024年3月 (2)
2024年2月 (2)
2023年12月 (1)
2023年11月 (2)
2023年10月 (2)
2023年9月 (37)
2021年12月 (1)
2021年10月 (1)
2021年9月 (1)
2021年2月 (1)
2020年5月 (3)
2020年4月 (1)
2019年11月 (4)
2019年7月 (1)
2018年11月 (1)
2017年12月 (1)
2016年12月 (1)
2016年11月 (2)
2016年10月 (1)
2016年9月 (1)
2016年8月 (3)
2016年7月 (4)
2016年5月 (1)
2015年10月 (2)
2015年9月 (1)
2015年6月 (2)
2015年5月 (3)
2015年2月 (1)
2015年1月 (1)
2014年12月 (2)
2014年4月 (2)
2014年3月 (1)
2014年1月 (1)
2013年10月 (1)
2013年9月 (1)
2013年8月 (3)
2013年5月 (1)
2013年3月 (1)
2012年11月 (1)
2012年9月 (3)
2012年8月 (1)
2012年7月 (1)
2012年6月 (5)
2012年5月 (3)
2011年12月 (5)
2011年11月 (1)
2011年10月 (5)
2011年8月 (7)
2011年7月 (6)
2011年6月 (6)
2010年6月 (1)
2009年12月 (1)
2009年8月 (1)
2009年7月 (1)
2009年6月 (1)
2009年4月 (3)
文章分類
(30)
詩詞作品集(30)
關注的開源項目
LLVM
編譯系統
nginx
高性能Web服務器
OpenSSL
密碼學庫
suricata
網絡IPS引擎
最新隨筆
1.?二元二次型的相似變換與正定性
2.?關于群的一些結論及應用
3.?不定方程的代數數論解法
4.?關于橢圓曲線的驗證計算
5.?不可約多項式判別算法的改正
6.?論證有限域上平方根的求解
7.?求解離散對數問題的Terr算法
8.?簡單私鑰加密構造的驗證及安全性分析
9.?二元有限域及其擴域上的計算
10.?簡單連分數攻擊RSA的迭代次數分析
積分與排名
積分 - 412879
排名 - 56
最新評論
1.?re: 一種攔截Linux原始套接字IO的方法[未登錄]
很有前途和很有錢途啊。
--chipset
2.?re: 一種攔截Linux原始套接字IO的方法[未登錄]
@chipset
是的
--春秋十二月
3.?re: 一種攔截Linux原始套接字IO的方法[未登錄]
工作是做網絡安全?
--chipset
4.?re: 一種使用函數指針實現狀態機的方法
函數指針實現狀態機
--linda
5.?re: 多標簽視圖類CTabView的設計實現
為啥代碼缺少一些呢,給新手個完整點的啊
--pekingliu
6.?re: 工作線程與消息循環
從消息隊列取出消息 mark了
--mmocake
7.?re: 一種簡單的跨平臺套接字管道
評論內容較長,點擊標題查看
--IT搬運工
8.?re: 一種簡單的跨平臺套接字管道
windows僅支持af_init和af_init6地址族有錯別字么?
af_init和af_init6
--IT搬運工
9.?re: Shell應用(8):使用awk定位反匯編輸出[未登錄]
厲害
--Chipset
10.?re: TCP分組丟失時的狀態變遷
不錯
--Binky
閱讀排行榜
1.?基于OpenSSL實現的安全連接(13956)
2.?字符串16進制顯示(12856)
3.?基于boost asio實現的ssl socket框架(12308)
4.?Linux套接字與虛擬文件系統(1):初始化和創建(8635)
5.?關于數據庫的一些學習研究心得(8086)
6.?使用CString GetBuffer自適應獲取計算機名稱(7973)
7.?使用正則表達式解析URL(7929)
8.?basic_string內存泄露問題之分析解決(7732)
9.?Shell應用(4): 使用sed刪除行尾的^M字符(7647)
10.?nginx iocp(1):tcp異步連接(7625)
評論排行榜
1.?basic_string內存泄露問題之分析解決(19)
2.?求單向鏈表倒序第m個元素(11)
3.?基于順序存儲實現的多叉樹(1):深度優先存儲(9)
4.?字符大小寫轉換(7)
5.?字符串16進制顯示(6)
6.?面向對象鎖框架的設計與實現(6)
7.?Shell應用(4): 使用sed刪除行尾的^M字符(5)
8.?工作線程與消息循環(5)
9.?使用正則表達式解析URL(5)
10.?十進制整數千位分隔符(4)
Powered by:
博客園
模板提供:
滬江博客
Copyright ©2025 春秋十二月
亚洲一区二区三区日本久久九
|
欧美熟妇另类久久久久久不卡
|
伊人久久大香线蕉影院95
|
人人狠狠综合久久亚洲88
|
久久91这里精品国产2020
|
国内精品伊人久久久久妇
|
精品国产乱码久久久久久郑州公司
|
精品久久一区二区
|
免费精品久久久久久中文字幕
|
一本色道久久88精品综合
|
久久久久久久99精品免费观看
|
日本精品一区二区久久久
|
久久久久亚洲AV成人片
|
人人狠狠综合久久亚洲高清
|
久久久精品2019免费观看
|
国产精品内射久久久久欢欢
|
噜噜噜色噜噜噜久久
|
99热成人精品热久久669
|
久久久黄色大片
|
精品久久久久久无码免费
|
久久青青草原亚洲av无码app
|
久久人人爽人人爽AV片
|
久久精品国产亚洲一区二区
|
中文精品久久久久人妻不卡
|
免费一级欧美大片久久网
|
麻豆精品久久精品色综合
|
日韩人妻无码精品久久免费一
|
久久天天躁狠狠躁夜夜av浪潮
|
久久精品国内一区二区三区
|
久久99国产精品尤物
|
日本欧美久久久久免费播放网
|
国产精品久久久久久久久软件
|
久久久久成人精品无码
|
久久婷婷综合中文字幕
|
久久精品国产亚洲网站
|
久久99精品国产自在现线小黄鸭
|
成人亚洲欧美久久久久
|
久久国产精品99精品国产987
|
久久精品国产亚洲AV高清热
|
久久影院综合精品
|
国内精品久久九九国产精品
|