一年十二月  誰主春秋
關(guān)注:基礎(chǔ)系統(tǒng)工程 密碼學(xué) 人工智能
C++博客
首頁
新隨筆
聯(lián)系
聚合
管理
隨筆-161 評論-223 文章-30 trackbacks-0
Linux ICMP消息的產(chǎn)生與轉(zhuǎn)換
ICMP在IP系統(tǒng)間傳遞差錯(cuò)和管理報(bào)文,是任何IP系統(tǒng)必須實(shí)現(xiàn)的組成部分。Linux 2.6.34中ICMP模塊的實(shí)現(xiàn)在linux/icmp.h,net/icmp.h和ipv4/icmp.c中,導(dǎo)出了
icmp_err_convert
數(shù)組和
icmp_send
函數(shù),供其它網(wǎng)絡(luò)子系統(tǒng)使用。在其它網(wǎng)絡(luò)子系統(tǒng)中,當(dāng)檢測到錯(cuò)誤時(shí),調(diào)用icmp_send產(chǎn)生并發(fā)送相應(yīng)的ICMP差錯(cuò)消息到源主機(jī);當(dāng)源主機(jī)收到ICMP不可達(dá)差錯(cuò)消息,傳遞到原始套接字和傳輸層,而它們使用icmp_err_convert把對應(yīng)的消息代碼轉(zhuǎn)換成套接字層比較容易理解的錯(cuò)誤代碼。在內(nèi)核空間中可發(fā)送的ICMP消息包括查詢應(yīng)答和差錯(cuò)報(bào)文,下面總結(jié)了產(chǎn)生這兩類消息的網(wǎng)絡(luò)子系統(tǒng)(及函數(shù))與錯(cuò)誤轉(zhuǎn)換。
應(yīng)答消息
應(yīng)答消息由ICMP模塊的內(nèi)部函數(shù)icmp_reply而非icmp_send發(fā)送。根據(jù)
RFC1122 3.2.2.9
規(guī)范, 除非一個(gè)主機(jī)作為地址掩碼代理,否則不能發(fā)送回復(fù),這對應(yīng)ICMP的icmp_address實(shí)現(xiàn)為空,因此上表沒有列出地址掩碼應(yīng)答項(xiàng)(內(nèi)核符號為ICMP_ADDRESSREPLY)。
差錯(cuò)消息
差錯(cuò)消息由中間路由器或目的主機(jī)產(chǎn)生,當(dāng)數(shù)據(jù)報(bào)不能成功提交給目的主機(jī)時(shí)。從上表可見,在IP層的接收、本地處理、轉(zhuǎn)發(fā)和輸出各過程中,都可能產(chǎn)生差錯(cuò)消息;在傳輸層如果對應(yīng)的端口沒有打開,那么UDP會產(chǎn)生ICMP端口不可達(dá)差錯(cuò),而
TCP則會使用自己的差錯(cuò)處理機(jī)制發(fā)送一個(gè)RST復(fù)位包,這也是上表沒有列出TCP子系統(tǒng)的原因
。對于重定向差錯(cuò),由ICMP模塊的icmp_redirect調(diào)用ip_rt_redirect更新路由;其它差錯(cuò)則由icmp_unreach處理。
錯(cuò)誤轉(zhuǎn)換
第2列為icmp_err_convert數(shù)組索引,第4列也就是調(diào)用socket API出錯(cuò)時(shí)返回的errno,最后1列為icmp_err_convert中的fatal成員取值,0表示非致命錯(cuò)誤,1表示致命錯(cuò)誤,需要報(bào)告給用戶進(jìn)程。錯(cuò)誤轉(zhuǎn)換會被RAW的raw_err、TCP的tcp_v4_err和UDP的udp_err用到,對于ICMP_DEST_UNREACH類型的差錯(cuò),使用上表轉(zhuǎn)換;ICMP_SOURCE_QUENCH類型的忽略不處理;ICMP_PARAMETERPROB類型的轉(zhuǎn)換成
EPROTO
(協(xié)議錯(cuò)誤);ICMP_TIME_EXCEEDED類型的轉(zhuǎn)換成
EHOSTUNREACH
。
在這要注意,從ICMP_PORT_UNREACH到ECONNREFUSED的轉(zhuǎn)換,不適用于TCP,原因已在
上節(jié)
說明;而對于UDP的
未連接
套接字,如果主機(jī)在線而端口沒打開,調(diào)用sendto得不到ECONNREFUSED錯(cuò)誤,但recvfrom會阻塞,這是因?yàn)殡m然內(nèi)核收到了ICMP差錯(cuò),但沒上報(bào)給應(yīng)用進(jìn)程。盡管如此,如果想得到ECONNREFUSED錯(cuò)誤,那么可以寫個(gè)ICMP守護(hù)進(jìn)程,應(yīng)用進(jìn)程先把它的套接字描述符通過unix域套接口傳遞到ICMP守護(hù)進(jìn)程,而守護(hù)進(jìn)程使用raw socket來接收ICMP差錯(cuò),再發(fā)給應(yīng)用進(jìn)程。
發(fā)送限速
不論一般差錯(cuò)消息還是重定向差錯(cuò)消息,發(fā)送限速針對的都是特定目標(biāo)主機(jī)。
一般限速
在使用icmp_send發(fā)送差錯(cuò)消息(PMTU消息除外)時(shí),為減少網(wǎng)絡(luò)擁塞而限制了發(fā)送的速率,限速由xrlim_allow函數(shù)實(shí)現(xiàn),定義在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為目標(biāo)路由緩存,timeout為允許發(fā)送的超時(shí)(單位為jiffies),dst->rate_tokens記錄令牌的個(gè)數(shù),當(dāng)令牌個(gè)數(shù)不小于timeout時(shí),則減少timeout并允許發(fā)送一個(gè)消息;反之則不能發(fā)送,需等到令牌個(gè)數(shù)累積到大于timeout時(shí)才能發(fā)送,但是不能無限大,否則就會導(dǎo)致在一個(gè)可能很短的timeout內(nèi),發(fā)送遠(yuǎn)多于6個(gè)的消息,引起ICMP風(fēng)暴,所以這里限制了令牌的最大值為XRLIM_BURST_FACTOR*timeout即6倍的超時(shí),也就是說在一個(gè)timeout內(nèi),最多能發(fā)送6個(gè)差錯(cuò)消息。
重定向限速
路由子系統(tǒng)使用ip_rt_send_redirect來發(fā)送重定向消息,定義在ipv4/route.c中,該函數(shù)內(nèi)部調(diào)用icmp_send實(shí)現(xiàn),在它的限速基礎(chǔ)上,使用
指數(shù)回退算法
控制發(fā)送速率。
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
}
重定向差錯(cuò)使用ip_rt_redirect_silence(默認(rèn)為(HZ/50)<<10)、ip_rt_redirect_number(默認(rèn)為9)和ip_rt_redirect_load(默認(rèn)為HZ/50)3個(gè)量來控制發(fā)送的速率;rt->u.dst.rate_last記錄上次發(fā)送的時(shí)間,rt->u.dst.rate_tokens累計(jì)發(fā)送總數(shù),最大值為ip_rt_redirect_number;當(dāng)兩次發(fā)送的時(shí)間間隔超過ip_rt_redirect_silence或ip_rt_redirect_load<<rt->u.dst.rate_tokens,并且發(fā)送總數(shù)不超過ip_rt_redirect_number時(shí),才允許發(fā)送一個(gè),這樣一來,在ip_rt_redirect_silence間隔內(nèi),每次發(fā)送的超時(shí)呈2的指數(shù)增長,達(dá)到了變減速發(fā)送的效果,直到總數(shù)達(dá)到ip_rt_redirect_number時(shí)停止發(fā)送,這是因?yàn)樵粗鳈C(jī)可能忽略了重定向消息所以停止發(fā)送;當(dāng)ip_rt_redirect_silence時(shí)間過后,又允許發(fā)送了,這是因?yàn)檎J(rèn)為源主機(jī)沒有更新路由所以又需要發(fā)送。
posted on 2015-05-18 19:52
春秋十二月
閱讀(2803)
評論(0)
編輯
收藏
引用
所屬分類:
Network
只有注冊用戶
登錄
后才能發(fā)表評論。
【推薦】100%開源!大型工業(yè)跨平臺軟件C++源碼提供,建模,組態(tài)!
相關(guān)文章:
基于X509證書的身份認(rèn)證思考小結(jié)
使用HiRedis實(shí)現(xiàn)自動重連Redis
基于ENet實(shí)現(xiàn)可靠UDP通信的同步模型
總結(jié)網(wǎng)絡(luò)路由走向診斷方法
深入理解SSL/TLS技術(shù)內(nèi)幕
一種攔截Linux原始套接字IO的方法
一種P2P代理中TCP連接調(diào)度的方法
TCP分組丟失時(shí)的狀態(tài)變遷
Linux ICMP消息的產(chǎn)生與轉(zhuǎn)換
Linux套接字與虛擬文件系統(tǒng)(2):操作和銷毀
網(wǎng)站導(dǎo)航:
博客園
IT新聞
BlogJava
博問
Chat2DB
管理
本博客所有隨筆均為原創(chuàng),因?yàn)椴欢ㄆ诰S護(hù)更新,所以轉(zhuǎn)載請注明出處,如有問題和建議,請留言或評論,發(fā)表您的寶貴意見,藉此平臺以分享交流、共同進(jìn)步。
聯(lián)系方式:微信math-engineer
<
2015年1月
>
日
一
二
三
四
五
六
28
29
30
31
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
7
常用鏈接
我的隨筆
我的評論
我參與的隨筆
留言簿
(76)
給我留言
查看公開留言
查看私人留言
隨筆分類
(160)
Algorithm(48)
C/C++(24)
Compiler(25)
Compute Theory(5)
Database(4)
Network(17)
Opensrc(13)
System(24)
隨筆檔案
(161)
2025年6月 (2)
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)
關(guān)注的開源項(xiàng)目
LLVM
編譯系統(tǒng)
nginx
高性能Web服務(wù)器
OpenSSL
密碼學(xué)庫
suricata
網(wǎng)絡(luò)IPS引擎
最新隨筆
1.?一個(gè)歐拉數(shù)整除問題的兩種證法
2.?有限域上的特征與指數(shù)和之?dāng)U展
3.?二元二次型的相似變換、正定性與正交分解
4.?關(guān)于群的一些結(jié)論及應(yīng)用
5.?不定方程的代數(shù)數(shù)論解法
6.?關(guān)于橢圓曲線的驗(yàn)證計(jì)算
7.?不可約多項(xiàng)式判別算法的改正
8.?論證有限域上平方根的求解
9.?求解離散對數(shù)問題的Terr算法
10.?簡單私鑰加密構(gòu)造的驗(yàn)證及安全性分析
積分與排名
積分 - 416861
排名 - 56
最新評論
1.?re: 一種攔截Linux原始套接字IO的方法[未登錄]
很有前途和很有錢途啊。
--chipset
2.?re: 一種攔截Linux原始套接字IO的方法[未登錄]
@chipset
是的
--春秋十二月
3.?re: 一種攔截Linux原始套接字IO的方法[未登錄]
工作是做網(wǎng)絡(luò)安全?
--chipset
4.?re: 一種使用函數(shù)指針實(shí)現(xiàn)狀態(tài)機(jī)的方法
函數(shù)指針實(shí)現(xiàn)狀態(tài)機(jī)
--linda
5.?re: 多標(biāo)簽視圖類CTabView的設(shè)計(jì)實(shí)現(xiàn)
為啥代碼缺少一些呢,給新手個(gè)完整點(diǎn)的啊
--pekingliu
6.?re: 工作線程與消息循環(huán)
從消息隊(duì)列取出消息 mark了
--mmocake
7.?re: 一種簡單的跨平臺套接字管道
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--IT搬運(yùn)工
8.?re: 一種簡單的跨平臺套接字管道
windows僅支持af_init和af_init6地址族有錯(cuò)別字么?
af_init和af_init6
--IT搬運(yùn)工
9.?re: Shell應(yīng)用(8):使用awk定位反匯編輸出[未登錄]
厲害
--Chipset
10.?re: TCP分組丟失時(shí)的狀態(tài)變遷
不錯(cuò)
--Binky
閱讀排行榜
1.?基于OpenSSL實(shí)現(xiàn)的安全連接(14001)
2.?字符串16進(jìn)制顯示(12881)
3.?基于boost asio實(shí)現(xiàn)的ssl socket框架(12341)
4.?Linux套接字與虛擬文件系統(tǒng)(1):初始化和創(chuàng)建(8667)
5.?關(guān)于數(shù)據(jù)庫的一些學(xué)習(xí)研究心得(8109)
6.?使用CString GetBuffer自適應(yīng)獲取計(jì)算機(jī)名稱(7985)
7.?使用正則表達(dá)式解析URL(7949)
8.?basic_string內(nèi)存泄露問題之分析解決(7753)
9.?Shell應(yīng)用(4): 使用sed刪除行尾的^M字符(7671)
10.?nginx iocp(1):tcp異步連接(7656)
評論排行榜
1.?basic_string內(nèi)存泄露問題之分析解決(19)
2.?求單向鏈表倒序第m個(gè)元素(11)
3.?基于順序存儲實(shí)現(xiàn)的多叉樹(1):深度優(yōu)先存儲(9)
4.?字符大小寫轉(zhuǎn)換(7)
5.?字符串16進(jìn)制顯示(6)
6.?面向?qū)ο箧i框架的設(shè)計(jì)與實(shí)現(xiàn)(6)
7.?Shell應(yīng)用(4): 使用sed刪除行尾的^M字符(5)
8.?使用正則表達(dá)式解析URL(5)
9.?工作線程與消息循環(huán)(5)
10.?十進(jìn)制整數(shù)千位分隔符(4)
Powered by:
博客園
模板提供:
滬江博客
Copyright ©2025 春秋十二月
久久婷婷激情综合色综合俺也去
|
久久亚洲国产成人精品性色
|
99久久无码一区人妻
|
93精91精品国产综合久久香蕉
|
segui久久国产精品
|
国产日韩久久久精品影院首页
|
人人狠狠综合久久亚洲高清
|
亚洲综合伊人久久大杳蕉
|
久久久久亚洲AV成人片
|
蜜臀久久99精品久久久久久
|
亚洲国产成人精品无码久久久久久综合
|
色播久久人人爽人人爽人人片AV
|
亚洲国产天堂久久综合
|
99久久精品无码一区二区毛片
|
污污内射久久一区二区欧美日韩
|
久久精品人妻中文系列
|
精品午夜久久福利大片
|
久久亚洲国产最新网站
|
99久久人人爽亚洲精品美女
|
97香蕉久久夜色精品国产
|
国产毛片欧美毛片久久久
|
欧美久久综合性欧美
|
丁香色欲久久久久久综合网
|
久久97久久97精品免视看
|
久久精品国产亚洲77777
|
国产精品亚洲综合久久
|
久久久久亚洲av成人无码电影
|
97久久精品国产精品青草
|
精品国产乱码久久久久软件
|
欧美粉嫩小泬久久久久久久
|
国产高清美女一级a毛片久久w
|
国产精品18久久久久久vr
|
亚洲国产美女精品久久久久∴
|
国产精品久久久久久久app
|
亚洲人成无码www久久久
|
国产99久久久国产精免费
|
久久精品人人做人人爽电影
|
国产精品一区二区久久精品
|
精品久久一区二区
|
久久综合久久综合九色
|
2021国产成人精品久久
|