系統技術非業餘研究 » TCP連結主動關閉不發fin包奇怪行為分析
問題描述:
多隆同學在做網路框架的時候,發現一條tcp連結在close的時候,對端會收到econnrest,而不是正常的fin包. 通過抓包發現close系統呼叫的時候,我端發出rst報文, 而不是正常的fin。這個問題比較有意思,我們來演示下:
$ erl Erlang R14B03 (erts-5.8.4) [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.4 (abort with ^G) 1> {ok,Sock} = gen_tcp:connect("baidu.com", 80, [{active,false}]). {ok,#Port<0.582>} 2> gen_tcp:send(Sock, "GET / HTTP/1.1\r\n\r\n"). ok 3> gen_tcp:close(Sock). ok
我們往baidu的首頁發了個http請求,百度會給我們迴應報文的,我們send完立即呼叫close.
然後我們在另外一個終端開tcpdump抓包確認:
$ sudo tcpdump port 80 -i bond0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on bond0, link-type EN10MB (Ethernet), capture size 96 bytes 17:22:38.246507 IP my031089.sqa.cm4.tbsite.net.19500 > 220.181.111.86.http: S 2228211568:2228211568(0) win 5840 <mss 1460,sackOK,timestamp 2607833238 0,nop,wscale 7> 17:22:38.284602 IP 220.181.111.86.http > my031089.sqa.cm4.tbsite.net.19500: S 3250338304:3250338304(0) ack 2228211569 win 8190 <mss 1436> 17:22:38.284624 IP my031089.sqa.cm4.tbsite.net.19500 > 220.181.111.86.http: . ack 1 win 5840 17:22:52.748468 IP my031089.sqa.cm4.tbsite.net.19500 > 220.181.111.86.http: P 1:19(18) ack 1 win 5840 17:22:52.786855 IP 220.181.111.86.http > my031089.sqa.cm4.tbsite.net.19500: . ack 19 win 5840 17:22:52.787194 IP 220.181.111.86.http > my031089.sqa.cm4.tbsite.net.19500: P 1:179(178) ack 19 win 5840 17:22:52.787203 IP my031089.sqa.cm4.tbsite.net.19500 > 220.181.111.86.http: . ack 179 win 6432 17:22:52.787209 IP 220.181.111.86.http > my031089.sqa.cm4.tbsite.net.19500: P 179:486(307) ack 19 win 5840 17:22:52.787214 IP my031089.sqa.cm4.tbsite.net.19500 > 220.181.111.86.http: . ack 486 win 7504 17:23:01.564358 IP my031089.sqa.cm4.tbsite.net.19500 > 220.181.111.86.http: R 19:19(0) ack 486 win 7504 ...
我們可以清楚的看到 R 19:19(0) ack 486 win 7504,發了個rst包,通過strace系統呼叫也確認erlang確實呼叫了close系統呼叫。
那為什麼呢? @淘寶雕樑,tcp協議棧專家回答了這個問題:
在net/ipv4/tcp.c:1900附近
... /* As outlined in RFC 2525, section 2.17, we send a RST here because * data was lost. To witness the awful effects of the old behavior of * always doing a FIN, run an older 2.1.x kernel or 2.0.x, start a bulk * GET in an FTP client, suspend the process, wait for the client to * advertise a zero window, then kill -9 the FTP client, wheee... * Note: timeout is always zero in such a case. */ if (data_was_unread) { /* Unread data was tossed, zap the connection. */ NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); tcp_set_state(sk, TCP_CLOSE); tcp_send_active_reset(sk, sk->sk_allocation); ..
程式碼裡面寫的很清楚,如果你的接收緩衝去還有資料,協議棧就會發rst代替fin.
我們再來驗證一下:
$ erl Erlang R14B03 (erts-5.8.4) [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.4 (abort with ^G) 1> {ok,Sock} = gen_tcp:connect("baidu.com", 80, [{active,false}]). {ok,#Port<0.582>} 2> gen_tcp:send(Sock, "GET / HTTP/1.1\r\n\r\n"). ok 3> gen_tcp:recv(Sock,0). {ok,"HTTP/1.1 400 Bad Request\r\nDate: Fri, 01 Jul 2011 09:24:37 GMT\r\nServer: Apache\r\nConnection: Keep-Alive\r\nTransfer-Encoding: chunked\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n127\r\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<HTML><HEAD>\n<TITLE>400 Bad Request</TITLE>\n</HEAD><BODY>\n<H1>Bad Request</H1>\nYour browser sent a request that this server could not understand.<P>\nclient sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /<P>\n</BODY></HTML>\n\r\n0\r\n\r\n"} 4> gen_tcp:close(Sock). ok 5>
這次我們把接收緩衝區裡的東西拉乾淨了。
再看下tcpdump:
... 17:36:07.236627 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: S 3086473299:3086473299(0) win 5840 <mss 1460,sackOK,timestamp 2608642228 0,nop,wscale 7> 17:36:07.274661 IP 123.125.114.144.http > my031089.sqa.cm4.tbsite.net.9405: S 738551248:738551248(0) ack 3086473300 win 8190 <mss 1436> 17:36:07.274685 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: . ack 1 win 5840 17:36:10.295795 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: P 1:19(18) ack 1 win 5840 17:36:10.334280 IP 123.125.114.144.http > my031089.sqa.cm4.tbsite.net.9405: . ack 19 win 5840 17:36:10.334547 IP 123.125.114.144.http > my031089.sqa.cm4.tbsite.net.9405: P 1:179(178) ack 19 win 5840 17:36:10.334554 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: . ack 179 win 6432 17:36:10.334563 IP 123.125.114.144.http > my031089.sqa.cm4.tbsite.net.9405: P 179:486(307) ack 19 win 5840 17:36:10.334566 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: . ack 486 win 7504 17:36:19.671374 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: F 19:19(0) ack 486 win 7504 17:36:19.709619 IP 123.125.114.144.http > my031089.sqa.cm4.tbsite.net.9405: . ack 20 win 5840 17:36:19.709643 IP 123.125.114.144.http > my031089.sqa.cm4.tbsite.net.9405: F 486:486(0) ack 20 win 5840 17:36:19.709652 IP my031089.sqa.cm4.tbsite.net.9405 > 123.125.114.144.http: . ack 487 win 7504 ...
這次是發fin包了。
多隆同學再進一步,找出來之前squid client程式碼中不能理解的一句話:
client_side.c
... /* prevent those nasty RST packets */ { char buf[SQUID_TCP_SO_RCVBUF]; while (FD_READ_METHOD(fd, buf, SQUID_TCP_SO_RCVBUF) > 0); } ...
總算明白了這句話的意思了!
小結:認真學習協議棧太重要了。
玩得開心!
Post Footer automatically generated by wp-posturl plugin for wordpress.
No related posts.
相關推薦
系統技術非業餘研究 » TCP連結主動關閉不發fin包奇怪行為分析
問題描述: 多隆同學在做網路框架的時候,發現一條tcp連結在close的時候,對端會收到econnrest,而不是正常的fin包. 通過抓包發現close系統呼叫的時候,我端發出rst報文, 而不是正常的fin。這個問題比較有意思,我們來演示下: $ erl Erlang R14B03 (e
系統技術非業餘研究 » gen_tcp連線半關閉問題
很久之前我發在javaeye論壇上,預防丟了抄過來: 原文:http://erlang.group.iteye.com/group/wiki/1422-gen_tcp-half-closed 當tcp對端呼叫shutdown(RD/WR) 時候, 宿主程序預設將收到{tcp_closed, Soc
系統技術非業餘研究 » ss is one another utility to investigate sockets(特適合大規模tcp連結)
具體的可以參考這裡 他的最大特點是快, 當你的系統有上萬個tcp連結要了解的時候的時候, 你就知道我說什麼了. netstat等常規工具變成廢鐵了, 這時候他的作用就非常明顯了. /proc interface is inadequate, unfortunately. When amount
系統技術非業餘研究 » gen_tcp接受連結時enfile的問題分析及解決
最近我們為了安全方面的原因,在RDS伺服器上做了個代理程式把普通的MYSQL TCP連線變成了SSL連結,在測試的時候,皓庭同學發現Tsung發起了幾千個TCP連結後Erlang做的SSL PROXY老是報告gen_tcp:accept返回{error, enfile}錯誤。針對這個問題,我展開了
系統技術非業餘研究 » 看圖學TCP API以及狀態變遷
client的connect呼叫和server端之間的三根線應該對應著三次握手過程,這裡有一點問題。 client傳送的sync到達應該在server端accpet之前,所以橙色線應該指向accpet前面。 同樣,server端響應ack,sync是在accpet呼叫前的,因此粉色線也應該放在a
系統技術非業餘研究 » 最快的Erlang http hello world 伺服器調優指南 (20Khttp短連結請求/S每桌面CPU)
erl的虛擬機器有2種方式 plain版本的和smp版本的。 smp版本由於鎖的開銷相比要比plain版本的慢很多。而32位機器由於記憶體訪問比64位的少,也會快出很多。所有我選擇在32位的linux系統下調優這個httpd伺服器。這個伺服器就是實現個簡單的功能,在browser下返回hello
系統技術非業餘研究 » Erlang版TCP伺服器對抗攻擊解決方案
網際網路上的TCP伺服器面對的環境情況比企業私有的伺服器要複雜很多。常見的針對tcp伺服器的攻擊有以下幾種: 1. 偽造協議,導致伺服器crash. 比如說某條命令的欄位長度,協議最大規定是1024,偽造個4096的。 2. 偽造大的報文,比如說一個包有1024M這麼大。 3. 消耗伺服器資源。開
系統技術非業餘研究 » Erlang程序簡單的主動負載管制實現
我們知道Erlang的排程器是公平的,當程序的時間片用完了後,會強制切出,但是這個粒度是比較粗的。比如說程序進行了大量的Io操作,這個操作換成時間片是不準確的,會導致某些CPU計算密集型的比較吃虧,IO密集型的合算。 為了避免這個情況,IO密集型的經常可以互動要求短暫放棄執行,最簡單的方法就是用訊
系統技術非業餘研究
ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼
系統技術非業餘研究 » MySQL資料庫架構的演化觀察
MySQL資料庫架構的演化觀察 December 14th, 2017 Categories: 資料庫 Tags: mysql
系統技術非業餘研究 » inet_dist_connect_options
Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke
系統技術非業餘研究 » 推薦工作機會
最後更新時間:2014/11/28 請賜簡歷至:[email protected], 感謝您對加入我們公司有興趣,我們希望能早日和您共事。 以下幾個職位1年內有效,歡迎內部轉崗: 資深資料工程師 公司:阿里(核心系統資料庫組) 工作地點:杭州(西溪園區) 崗位描述: 分析雲服務產生的海
系統技術非業餘研究 » 新的工作和研究方向
和大家更新下: 做了將近8年資料庫後,我的工作和研究方向將會延伸到虛擬化和計算相關的雲服務,希望能夠和大家一起進步,Happy New Year! 預祝大家玩得開心! Post Footer automatically generated by wp-posturl plugin for w
系統技術非業餘研究 » 叢集引入inet_dist_{listen,connect}_options更精細引數微調
Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke
系統技術非業餘研究 » 2017升的最快的幾個資料庫無責任點評
ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼
系統技術非業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小
Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co
系統技術非業餘研究 » inet_dist_listen_options
Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke
系統技術非業餘研究 » 老生常談: ulimit問題及其影響
ulimit最初設計是用來限制程序對資源的使用情況的,因為早期的系統系統資源包括記憶體,CPU都是非常有限的,系統要保持公平,就要限制大家的使用,以達到一個相對公平的環境。以下是典型的機器預設的限制情況: $ ulimit -a core file size (blocks,
系統技術非業餘研究 » 求賢帖
原創文章,轉載請註明: 轉載自系統技術非業餘研究 本文連結地址: 求賢帖 作為一個優秀的工程師,你其實不缺少才華,你缺少的是神一樣的隊友、充滿挑戰的世界級技術難題,和一個可以施展自己才華的大舞臺。加入阿里核心系統資料庫開發團隊吧,你缺的這裡都有。來吧,戳這裡,給我們見識你的機會:http://b
系統技術非業餘研究 » Erlang R16B03釋出,R17已發力
Erlang R16B03釋出了,通常03版本是bug fix版本,進入生產版本,官方的說明如下: OTP R16B03 is a service release with mostly a number of small corrections and user contributions. B