日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

由STGW下载慢问题引发的网络传输学习之旅

發(fā)布時(shí)間:2024/2/28 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 由STGW下载慢问题引发的网络传输学习之旅 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

導(dǎo)語(yǔ):本文分享了筆者現(xiàn)網(wǎng)遇到的一個(gè)文件下載慢的問(wèn)題。最開始嘗試過(guò)很多辦法,包括域名解析,網(wǎng)絡(luò)鏈路分析,AB環(huán)境測(cè)試,網(wǎng)絡(luò)抓包等,但依然找不到原因。然后利用網(wǎng)絡(luò)命令和報(bào)文得到的蛛絲馬跡,結(jié)合內(nèi)核網(wǎng)絡(luò)協(xié)議棧的實(shí)現(xiàn)代碼,找到了一個(gè)內(nèi)核隱藏很久但在最近版本解決了的BUG。如果你也想了解如何分析和解決詭異的網(wǎng)絡(luò)問(wèn)題,如果你也想溫習(xí)一下課堂上曾經(jīng)學(xué)習(xí)過(guò)的慢啟動(dòng)、擁塞避免、快速重傳、AIMD等老掉牙的知識(shí),如果你也渴望學(xué)習(xí)課本上完全沒(méi)介紹過(guò)的TCP的一系列優(yōu)化比如混合慢啟動(dòng)、尾包探測(cè)甚至BBR等,那么本文或許可以給你一些經(jīng)驗(yàn)和啟發(fā)。

問(wèn)題背景

線上用戶經(jīng)過(guò)STGW(Secure Tencent Gateway,騰訊安全網(wǎng)關(guān)-七層轉(zhuǎn)發(fā)代理)下載一個(gè)50M左右的文件,與直連用戶自己的服務(wù)器相比,下載速度明顯變慢,需要定位原因。在了解到用戶的問(wèn)題之后,相關(guān)的同事在線下做了如下嘗試:

1. 從廣州和上海直接訪問(wèn)用戶的回源VIP(Virtual IP,提供服務(wù)的公網(wǎng)IP地址)下載,都耗時(shí)4s+,正常;

2. 只經(jīng)過(guò)TGW(Tencent Gateway,騰訊網(wǎng)關(guān)-四層負(fù)載均衡系統(tǒng)),不經(jīng)過(guò)STGW訪問(wèn),從廣州和上海訪問(wèn)上海的TGW,耗時(shí)都是4s+,正常;

3. 經(jīng)過(guò)STGW,從上海訪問(wèn)上海的STGW VIP,耗時(shí)4s+,正常;

4. 經(jīng)過(guò)STGW,從廣州訪問(wèn)上海的STGW VIP,耗時(shí)12s+,異常。

前面的三種情況都是符合預(yù)期,而第四種情況是不符合預(yù)期的,這個(gè)也是本文要討論的問(wèn)題。

前期定位排查

發(fā)現(xiàn)下載慢的問(wèn)題后,我們分析了整體的鏈路情況,按照鏈路經(jīng)過(guò)的節(jié)點(diǎn)順序有了如下的排查思路:

(1)從客戶端側(cè)來(lái)排查,DNS解析慢,客戶端讀取響應(yīng)慢或者接受窗口小等;

(2)從鏈路側(cè)來(lái)排查,公網(wǎng)鏈路問(wèn)題,中間交換機(jī)設(shè)備問(wèn)題,丟包等;

(3)從業(yè)務(wù)服務(wù)側(cè)來(lái)排查,業(yè)務(wù)服務(wù)側(cè)發(fā)送響應(yīng)較慢,發(fā)送窗口較小等;

(4)從自身轉(zhuǎn)發(fā)服務(wù)來(lái)排查,TGW或STGW轉(zhuǎn)發(fā)程序問(wèn)題,STGW擁塞窗口緩存等;

按照上面的這些思路,我們分別做了如下的排查:

1.是否是由于異常客戶端的DNS服務(wù)器解析慢導(dǎo)致的?

用戶下載小文件沒(méi)有問(wèn)題,并且直接訪問(wèn)VIP,配置hosts訪問(wèn),發(fā)現(xiàn)問(wèn)題依然復(fù)現(xiàn),排除。

2.是否是由于客戶端讀取響應(yīng)慢或者接收窗口較小導(dǎo)致的?

抓包分析客戶端的數(shù)據(jù)包處理情況,發(fā)現(xiàn)客戶端收包處理很快,并且接收窗口一直都是有很大空間。排除。

3.是否是廣州到上海的公網(wǎng)鏈路或者交換機(jī)等設(shè)備問(wèn)題,導(dǎo)致訪問(wèn)變慢?

從廣州的客戶端上ping上海的VIP,延時(shí)很低,并且測(cè)試不經(jīng)過(guò)STGW,從該客戶端直接訪問(wèn)TGW再到回源服務(wù)器,下載正常,排除。

4.是否是STGW到回源VIP這條鏈路上有問(wèn)題?

在STGW上直接訪問(wèn)用戶的回源VIP,耗時(shí)4s+,是正常的。并且打開了STGW LD(LoadBalance Director,負(fù)載均衡節(jié)點(diǎn))與后端server之間的響應(yīng)緩存,抓包可以看到,后端數(shù)據(jù)4s左右全部發(fā)送到STGW LD上,是STGW LD往客戶端回包比較慢,基本可以確認(rèn)是Client->STGW這條鏈路上有問(wèn)題。排除。

5.是否是由于TGW或STGW轉(zhuǎn)發(fā)程序有問(wèn)題?

由于異地訪問(wèn)必定會(huì)復(fù)現(xiàn),同城訪問(wèn)就是正常的。而TGW只做四層轉(zhuǎn)發(fā),無(wú)法感知源IP的地域信息,并且抓包也確認(rèn)TGW上并沒(méi)有出現(xiàn)大量丟包或者重傳的現(xiàn)象。STGW是一個(gè)應(yīng)用層的反向代理轉(zhuǎn)發(fā),也不會(huì)對(duì)于不同地域的cip有不同的處理邏輯。排除。

6.是否是由于TGW是fullnat影響了擁塞窗口緩存?

因?yàn)橹坝捎趂ullnat出現(xiàn)過(guò)一些類似于本例中下載慢的問(wèn)題,當(dāng)時(shí)定位的原因是由于STGW LD上開啟了擁塞窗口緩存,在fullnat的情況下,會(huì)影響擁塞窗口緩存的準(zhǔn)確性,導(dǎo)致部分請(qǐng)求下載慢。但是這里將擁塞窗口緩存選項(xiàng) sysctl -w net.ipv4.tcp_no_metrics_save=1 關(guān)閉之后測(cè)試,發(fā)現(xiàn)問(wèn)題依然存在,并且線下用另外一個(gè)fullnat的vip測(cè)試,發(fā)現(xiàn)并沒(méi)有復(fù)現(xiàn)用戶的問(wèn)題。排除。

根據(jù)一些以往的經(jīng)驗(yàn)和常規(guī)的定位手段都嘗試了以后,發(fā)現(xiàn)仍然還是沒(méi)有找到原因,那到底是什么導(dǎo)致的呢

問(wèn)題分析

首先,在復(fù)現(xiàn)的STGW LD上抓包,抓到Client與STGW LD的包如下圖,從抓包的信息來(lái)看是STGW回包給客戶端很慢,每次都只發(fā)很少的一部分到Client。

這里有一個(gè)很奇怪的地方就是為什么第7號(hào)包發(fā)生了重傳?不過(guò)暫時(shí)可以先將這個(gè)疑問(wèn)放到一邊,因?yàn)榫退?號(hào)包發(fā)生了一個(gè)包的重傳,這中間也并沒(méi)有發(fā)生丟包,LD發(fā)送數(shù)據(jù)也并不應(yīng)該這么慢。那既然LD發(fā)送數(shù)據(jù)這么慢,肯定要么是Client的接收窗口小,要么是LD的擁塞窗口比較小。

對(duì)端的接收窗口,抓包就可以看到,實(shí)際上Client的接收窗口并不小,而且有很大的空間。那是否有辦法可以看到LD的發(fā)送窗口呢?答案是肯定的:ss -it,這個(gè)指令可以看到每條連接的rtt,ssthresh,cwnd等信息。有了這些信息就好辦了,再次復(fù)現(xiàn),并寫了個(gè)命令將cwnd等信息記錄到文件:

while true; do date +"%T.%6N" >> cwnd.log; ss -it >> cwnd.log; done


復(fù)現(xiàn)得到的cwnd.log如上圖,找到對(duì)應(yīng)的連接,grep出來(lái)后對(duì)照來(lái)看。果然發(fā)現(xiàn)在前面幾個(gè)包中,擁塞窗口就直接被置為7,并且ssthresh也等于7,并且可以看到后面窗口增加的很慢,直接進(jìn)入了擁塞避免,這么小的發(fā)送窗口,增長(zhǎng)又很緩慢,自然發(fā)送數(shù)據(jù)就會(huì)很慢了。

那么到底是什么原因?qū)е逻@里直接在前幾個(gè)包就進(jìn)入擁塞避免呢?從現(xiàn)有的信息來(lái)看,沒(méi)辦法直接確定原因,只能去啃代碼了,但tcp擁塞控制相關(guān)的代碼這么多,如何能快速定位呢

觀察上面異常數(shù)據(jù)包的cwnd信息,可以看到一個(gè)很明顯的特征,最開始ssthresh是沒(méi)有顯示出來(lái)的,經(jīng)過(guò)了幾個(gè)數(shù)據(jù)包之后,ssthresh與cwnd是相等的,所以嘗試按照"snd_ssthresh ="和"snd_cwnd ="的關(guān)鍵字來(lái)搜索,按照snd_cwnd = snd_ssthresh的原則來(lái)找,排除掉一些不太可能的函數(shù)之后,最后找到了tcp_end_cwnd_reduction這個(gè)函數(shù)。

再查找這個(gè)函數(shù)引用的地方,有兩處:tcp_fastretrans_alert和tcp_process_tlp_ack這兩個(gè)函數(shù)。

tcp_fastretrans_alert看名字就知道是跟快速重傳相關(guān)的函數(shù),我們知道快速重傳觸發(fā)的條件是收到了三個(gè)重復(fù)的ack包。但根據(jù)前面的抓包及分析來(lái)看,并不滿足快速重傳的條件,所以疑點(diǎn)就落在了這個(gè)tcp_process_tlp_ack函數(shù)上面。那么到底什么是TLP呢

什么是TLP(Tail Loss Probe)

在講TLP之前,我們先來(lái)回顧下大學(xué)課本里學(xué)到的擁塞控制算法,祭出這張經(jīng)典的擁塞控制圖。?

TCP的擁塞控制主要分為四個(gè)階段:慢啟動(dòng),擁塞避免,快重傳,快恢復(fù)。長(zhǎng)久以來(lái),我們聽到的說(shuō)法都是,最開始擁塞窗口從1開始慢啟動(dòng),以指數(shù)級(jí)遞增,收到三個(gè)重復(fù)的ack后,將ssthresh設(shè)置為當(dāng)前cwnd的一半,并且置cwnd=ssthresh,開始執(zhí)行擁塞避免,cwnd加法遞增。

這里我們來(lái)思考一個(gè)問(wèn)題,發(fā)生丟包時(shí),為什么要將ssthresh設(shè)置為cwnd的一半?

想象一個(gè)場(chǎng)景,A與B之間發(fā)送數(shù)據(jù),假設(shè)二者發(fā)包和收包頻率是一致的,由于A與B之間存在空間距離,中間要經(jīng)過(guò)很多個(gè)路由器,交換機(jī)等,A在持續(xù)發(fā)包,當(dāng)B收到第一個(gè)包時(shí),這時(shí)A與B之間的鏈路里的包的個(gè)數(shù)為N,此時(shí)由于B一直在接收包,因此A還可以繼續(xù)發(fā),直到第一個(gè)包的ack回到A,這時(shí)A發(fā)送的包的個(gè)數(shù)就是當(dāng)前A與B之間最大的擁塞窗口,即為2N,因?yàn)槿绻@時(shí)A多發(fā)送,肯定就丟包了。

ssthresh代表的就是當(dāng)前鏈路上可以發(fā)送的最大的擁塞窗口大小,理想情況下,ssthresh就是2N,但現(xiàn)實(shí)的環(huán)境很復(fù)雜,不可能剛好cwnd經(jīng)過(guò)慢啟動(dòng)就可以直接到達(dá)2N,發(fā)送丟包的時(shí)候,肯定是N<1/2*cwnd<2N,因此此時(shí)將ssthresh設(shè)置為1/2*cwnd,然后再?gòu)拇颂幖臃ㄔ黾勇倪_(dá)到理想窗口,不能增長(zhǎng)過(guò)快,因?yàn)橐氨苊鈸砣薄?/p>

實(shí)際上,各個(gè)擁塞控制算法都有自己的實(shí)現(xiàn),初始cwnd的值也一直在優(yōu)化,在linux 3.0版本以后,內(nèi)核CUBIC的實(shí)現(xiàn)里,采用了Google在RFC6928的建議,將初始的cwnd的值設(shè)置為10。而在linux 3.0版本之前,采取的是RFC3390中的策略,根據(jù)不同的MSS,設(shè)置了不同的初始化cwnd。具體的策略為:

If (MSS <= 1095 bytes)

? ? then cwnd=4;

If (1095 bytes < MSS < 2190 bytes)

? ? then cwnd=3;

If (2190 bytes <= MSS)

? ? then cwnd=2;

并且在執(zhí)行擁塞避免時(shí),當(dāng)前CUBIC的實(shí)現(xiàn)里也不是將ssthresh設(shè)置為cwnd的一半,而是717/1024≈0.7左右,RFC8312也提到了這樣做的原因。

Principle 4: To balance between the scalability and convergence speed, CUBIC sets the multiplicative window decrease factor to 0.7 while Standard TCP uses 0.5. While this improves the scalability of CUBIC, a side effect of this decision is slower convergence, especially under low statistical multiplexing environments.

從上面的描述可以看到,在TCP的擁塞控制算法里,最核心的點(diǎn)就是ssthresh的確定,如何能快速準(zhǔn)確的確定ssthresh,就可以更加高效的傳輸。而現(xiàn)實(shí)的網(wǎng)絡(luò)環(huán)境很復(fù)雜,在有些情況下,沒(méi)有辦法滿足快速重傳的條件,如果每次都以丟包作為反饋,代價(jià)太大。比如,考慮如下的幾個(gè)場(chǎng)景:

  • 是否可以探測(cè)到ssthresh的值,不依賴丟包來(lái)觸發(fā)進(jìn)入擁塞避免,主動(dòng)退出慢啟動(dòng)?

  • 如果沒(méi)有足夠的dup ack(大于0,小于3)來(lái)觸發(fā)快速重傳,如何處理?

  • 如果沒(méi)有任何的dup ack(等于0),比如尾丟包的情況,如何處理?

  • 是否可以主動(dòng)探測(cè)網(wǎng)絡(luò)帶寬,基于反饋驅(qū)動(dòng)來(lái)調(diào)整窗口,而不是丟包等事件驅(qū)動(dòng)來(lái)執(zhí)行擁塞控制?

針對(duì)上面的前三種情況,TCP協(xié)議棧分別都做了相應(yīng)的優(yōu)化,對(duì)應(yīng)的優(yōu)化算法分別為:hystart(Hybrid Slow Start),ER(Early Retransmit)和TLP(Tail Loss Probe)。對(duì)于第四種情況,Google給出了答案,創(chuàng)造了一種新的擁塞控制算法,它的名字叫BBR,從linux 4.19開始,內(nèi)核已經(jīng)將默認(rèn)的擁塞控制算法從CUBIC改成了BBR。受限于本文的篇幅有限,無(wú)法對(duì)BBR算法做詳盡的介紹,下面僅結(jié)合內(nèi)核CUBIC的代碼來(lái)分別介紹前面的這三種優(yōu)化算法。

1. 慢啟動(dòng)的hystart優(yōu)化

混合慢啟動(dòng)的思想是在論文《Hybrid Slow Start for High-Bandwidth and Long-Distance Networks》里首次提出的,前面我也說(shuō)過(guò),如果每次判斷擁塞都依賴丟包來(lái)作為反饋,代價(jià)太大,hystart也是在這個(gè)方向上做優(yōu)化,它主要想解決的問(wèn)題就是不依賴丟包作為反饋來(lái)退出慢啟動(dòng),它提出的退出條件有兩類:

  • 判斷在同一批發(fā)出去的數(shù)據(jù)包收到的ack包(對(duì)應(yīng)論文中的acks train length)的總時(shí)間大于min(rtt)/2;

  • 判斷一批樣本中的最小rtt是否大于全局最小rtt加一個(gè)閾值的和;

內(nèi)核CUBIC的實(shí)現(xiàn)里默認(rèn)都是開啟了hystart,在bictcp_init函數(shù)里判斷是否開啟并做初始化

static inline void bictcp_hystart_reset(struct sock *sk) {struct tcp_sock *tp = tcp_sk(sk);struct bictcp *ca = inet_csk_ca(sk);ca->round_start = ca->last_ack = bictcp_clock();ca->end_seq = tp->snd_nxt;ca->curr_rtt = 0;ca->sample_cnt = 0; } static void bictcp_init(struct sock *sk) {struct bictcp *ca = inet_csk_ca(sk);bictcp_reset(ca);ca->loss_cwnd = 0;if (hystart)//如果開啟了hystart,那么做初始化bictcp_hystart_reset(sk);if (!hystart && initial_ssthresh)tcp_sk(sk)->snd_ssthresh = initial_ssthresh; }

核心的判斷是否退出慢啟動(dòng)的函數(shù)在hystart_update里

static void hystart_update(struct sock *sk, u32 delay) {struct tcp_sock *tp = tcp_sk(sk);struct bictcp *ca = inet_csk_ca(sk);if (!(ca->found & hystart_detect)) {u32 now = bictcp_clock();/* first detection parameter - ack-train detection *///判斷如果連續(xù)兩個(gè)ack的間隔小于hystart_ack_delta(2ms),則為一個(gè)acks trainif ((s32)(now - ca->last_ack) <= hystart_ack_delta) {ca->last_ack = now;//如果ack_train的總長(zhǎng)度大于1/2 * min_rtt,則退出慢啟動(dòng),ca->delay_min = 8*min_rttif ((s32)(now - ca->round_start) > ca->delay_min >> 4)ca->found |= HYSTART_ACK_TRAIN;}/* obtain the minimum delay of more than sampling packets *///如果小于HYSTART_MIN_SAMPLES(8)個(gè)樣本則直接計(jì)數(shù)if (ca->sample_cnt < HYSTART_MIN_SAMPLES) {if (ca->curr_rtt == 0 || ca->curr_rtt > delay)ca->curr_rtt = delay;ca->sample_cnt++;} else {/** 否則,判斷這些樣本中的最小rtt是否要大于全局的最小rtt+有范圍變化的閾值,* 如果是,則說(shuō)明發(fā)生了擁塞*/if (ca->curr_rtt > ca->delay_min +HYSTART_DELAY_THRESH(ca->delay_min>>4))ca->found |= HYSTART_DELAY;}/** Either one of two conditions are met,* we exit from slow start immediately.*///判斷ca->found如果為真,則退出慢啟動(dòng),進(jìn)入擁塞避免if (ca->found & hystart_detect)tp->snd_ssthresh = tp->snd_cwnd;} }

2. ER(Early?Retransmit)算法

我們知道,快重傳的條件是必須收到三個(gè)相同的dup ack,才會(huì)觸發(fā),那如果在有些情況下,沒(méi)有足夠的dup ack,只能依賴rto超時(shí),再進(jìn)行重傳,并且開始執(zhí)行慢啟動(dòng),這樣的代價(jià)太大,ER算法就是為了解決這樣的場(chǎng)景,RFC5827詳細(xì)介紹了這個(gè)算法。

算法的基本思想:

ER_ssthresh = 3 //ER_ssthresh代表觸發(fā)快速重傳的dup ack的個(gè)數(shù) if (unacked segments < 4 && no new data send)if (sack is unable) // 如果SACK選項(xiàng)不支持,則使用還未ack包的個(gè)數(shù)減一作為閾值ER_ssthresh = unacked segments - 1elif (sacked packets == unacked segments - 1) // 否則,只有當(dāng)還有一個(gè)包還未sack,才能啟用ER,并且置閾值為還未ack包的個(gè)數(shù)減一ER_ssthresh = unacked segments - 1

對(duì)應(yīng)到代碼里的函數(shù)為tcp_time_to_recover:

static bool tcp_time_to_recover(struct sock *sk, int flag) {.../* Trick#6: TCP early retransmit, per RFC5827. To avoid spurious* retransmissions due to small network reorderings, we implement* Mitigation A.3 in the RFC and delay the retransmission for a short* interval if appropriate.*/if (tp->do_early_retrans //開啟ER算法&& !tp->retrans_out //沒(méi)有重傳數(shù)據(jù)&& tp->sacked_out //當(dāng)前收到了dupack包&& (tp->packets_out >= (tp->sacked_out + 1) && tp->packets_out < 4) //滿足ER的觸發(fā)條件&& !tcp_may_send_now(sk)) //沒(méi)有新的數(shù)據(jù)發(fā)送return !tcp_pause_early_retransmit(sk, flag);//判斷是立即進(jìn)入ER還是需要delay 1/4 rttreturn false; } /** 這里內(nèi)核的實(shí)現(xiàn)與rfc5827有一點(diǎn)不同,就是引入了delay ER的概念,主要是防止過(guò)多減小的dupack 閾值帶來(lái)的* 無(wú)效的重傳,所以默認(rèn)加了一個(gè)1/4 RTT的delay,在ER的基礎(chǔ)上又做了一個(gè)折中,等一段時(shí)間再判斷是否要重傳。* 如果是false,則立即進(jìn)入ER,如果是true,則delay max(RTT/4,2msec)再進(jìn)入ER*/ static bool tcp_pause_early_retransmit(struct sock *sk, int flag) {struct tcp_sock *tp = tcp_sk(sk);unsigned long delay;/* Delay early retransmit and entering fast recovery for* max(RTT/4, 2msec) unless ack has ECE mark, no RTT samples* available, or RTO is scheduled to fire first.*///內(nèi)核提供了一個(gè)參數(shù)tcp_early_retrans來(lái)控制ER和delay ER,等于2和3時(shí),是打開了delay ERif (sysctl_tcp_early_retrans < 2 || sysctl_tcp_early_retrans > 3 ||(flag & FLAG_ECE) || !tp->srtt)return false;delay = max_t(unsigned long, (tp->srtt >> 5), msecs_to_jiffies(2));if (!time_after(inet_csk(sk)->icsk_timeout, (jiffies + delay)))return false;//設(shè)置delay ER的定時(shí)器inet_csk_reset_xmit_timer(sk, ICSK_TIME_EARLY_RETRANS, delay,TCP_RTO_MAX);return true; }

delay ER的定時(shí)器超時(shí)的處理函數(shù)tcp_resume_early_retransmit。

void tcp_resume_early_retransmit(struct sock *sk) {struct tcp_sock *tp = tcp_sk(sk);tcp_rearm_rto(sk);/* Stop if ER is disabled after the delayed ER timer is scheduled */if (!tp->do_early_retrans)return;//執(zhí)行快速重傳tcp_enter_recovery(sk, false);tcp_update_scoreboard(sk, 1);tcp_xmit_retransmit_queue(sk); }

內(nèi)核提供了一個(gè)開關(guān),tcp_early_retrans用于開啟和關(guān)閉TLP和ER算法,默認(rèn)是3,即打開了delay ER和TLP算法。

sysctl_tcp_early_retrans (defalut:3)0 disables ER1 enables ER2 enables ER but delays fast recovery and fast retransmit by a fourth of RTT.3 enables delayed ER and TLP.4 enables TLP only.

到此,這就是內(nèi)核設(shè)計(jì)ER算法的相關(guān)的代碼。ER算法在cwnd比較小的情況下,是可以有一些改善的,但個(gè)人認(rèn)為,實(shí)際的效果可能一般。因?yàn)槿绻鹀wnd較小,執(zhí)行慢啟動(dòng)與執(zhí)行快速重傳再進(jìn)入擁塞避免相比,二者的實(shí)際傳輸效率可能相差并不大。

3.TLP(Tail Loss Probe)算法

TLP想解決的問(wèn)題是:如果尾包發(fā)生了丟包,沒(méi)有新包可發(fā)送觸發(fā)多余的dup ack來(lái)實(shí)現(xiàn)快速重傳,如果完全依賴RTO超時(shí)來(lái)重傳,代價(jià)太大,那如何能優(yōu)化解決這種尾丟包的情況。

TLP算法是2013年谷歌在論文《Tail Loss Probe (TLP): An Algorithm for Fast Recovery of Tail Losses》中提出來(lái)的,它提出的基本思想是:

在每個(gè)發(fā)送的數(shù)據(jù)包的時(shí)候,都更新一個(gè)定時(shí)器PTO(probe timeout),這個(gè)PTO是動(dòng)態(tài)變化的,當(dāng)發(fā)出的包中存在未ack的包,并且在PTO時(shí)間內(nèi)都未收到一個(gè)ack,那么就會(huì)發(fā)送一個(gè)新包或者重傳最后的一個(gè)數(shù)據(jù)包,探測(cè)一下當(dāng)前網(wǎng)絡(luò)是否真的擁塞發(fā)生丟包了。

如果收到了tail包的dup ack,則說(shuō)明沒(méi)有發(fā)生丟包,繼續(xù)執(zhí)行當(dāng)前的流程;否則說(shuō)明發(fā)生了丟包,需要執(zhí)行減窗,并且進(jìn)入擁塞避免。

這里其中一個(gè)比較重要的點(diǎn)是PTO如何設(shè)置,設(shè)置的策略如下:

if unacked packets == 0:no need set PTO else if unacked packets == 1:PTO=max(2rtt, 1.5*rtt+TCP_DELACK_MAX, 10ms) else:PTO=max(2rtt, 10ms) 注:TCP_DELACK_MAX = 200ms

對(duì)應(yīng)到代碼里的tcp_schedule_loss_probe函數(shù):

bool tcp_schedule_loss_probe(struct sock *sk) {struct inet_connection_sock *icsk = inet_csk(sk);struct tcp_sock *tp = tcp_sk(sk);u32 timeout, tlp_time_stamp, rto_time_stamp;u32 rtt = tp->srtt >> 3;if (WARN_ON(icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS))return false;/* No consecutive loss probes. */if (WARN_ON(icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)) {tcp_rearm_rto(sk);return false;}/* Don't do any loss probe on a Fast Open connection before 3WHS* finishes.*/if (sk->sk_state == TCP_SYN_RECV)return false;/* TLP is only scheduled when next timer event is RTO. */if (icsk->icsk_pending != ICSK_TIME_RETRANS)return false;/* Schedule a loss probe in 2*RTT for SACK capable connections* in Open state, that are either limited by cwnd or application.*///判斷是否開啟了TLP及一些觸發(fā)條件if (sysctl_tcp_early_retrans < 3 || !rtt || !tp->packets_out ||!tcp_is_sack(tp) || inet_csk(sk)->icsk_ca_state != TCP_CA_Open)return false;if ((tp->snd_cwnd > tcp_packets_in_flight(tp)) &&tcp_send_head(sk))return false;/* Probe timeout is at least 1.5*rtt + TCP_DELACK_MAX to account* for delayed ack when there's one outstanding packet.*///這個(gè)與上面描述的策略是一致的timeout = rtt << 1;if (tp->packets_out == 1)timeout = max_t(u32, timeout,(rtt + (rtt >> 1) + TCP_DELACK_MAX));timeout = max_t(u32, timeout, msecs_to_jiffies(10));/* If RTO is shorter, just schedule TLP in its place. */tlp_time_stamp = tcp_time_stamp + timeout;rto_time_stamp = (u32)inet_csk(sk)->icsk_timeout;if ((s32)(tlp_time_stamp - rto_time_stamp) > 0) {s32 delta = rto_time_stamp - tcp_time_stamp;if (delta > 0)timeout = delta;}//設(shè)置PTO定時(shí)器inet_csk_reset_xmit_timer(sk, ICSK_TIME_LOSS_PROBE, timeout,TCP_RTO_MAX);return true; }

?PTO超時(shí)之后,會(huì)觸發(fā)tcp_send_loss_probe發(fā)送TLP包:

/* When probe timeout (PTO) fires, send a new segment if one exists, else* retransmit the last segment.*/ void tcp_send_loss_probe(struct sock *sk) {struct tcp_sock *tp = tcp_sk(sk);struct sk_buff *skb;int pcount;int mss = tcp_current_mss(sk);int err = -1;//如果還可以發(fā)送新數(shù)據(jù),那么就發(fā)送新數(shù)據(jù)if (tcp_send_head(sk) != NULL) {err = tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC);goto rearm_timer;}/* At most one outstanding TLP retransmission. *///一次最多只有一個(gè)TLP探測(cè)包if (tp->tlp_high_seq)goto rearm_timer;/* Retransmit last segment. *///如果沒(méi)有新數(shù)據(jù)可發(fā)送,就重新發(fā)送最后的一個(gè)數(shù)據(jù)包skb = tcp_write_queue_tail(sk);if (WARN_ON(!skb))goto rearm_timer;pcount = tcp_skb_pcount(skb);if (WARN_ON(!pcount))goto rearm_timer;if ((pcount > 1) && (skb->len > (pcount - 1) * mss)) {if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss)))goto rearm_timer;skb = tcp_write_queue_tail(sk);}if (WARN_ON(!skb || !tcp_skb_pcount(skb)))goto rearm_timer;err = __tcp_retransmit_skb(sk, skb);/* Record snd_nxt for loss detection. */if (likely(!err))tp->tlp_high_seq = tp->snd_nxt; rearm_timer:inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,inet_csk(sk)->icsk_rto,TCP_RTO_MAX);if (likely(!err))NET_INC_STATS_BH(sock_net(sk),LINUX_MIB_TCPLOSSPROBES);return; }

發(fā)送TLP探測(cè)包后,在tcp_process_tlp_ack里判斷是否發(fā)生了丟包,做相應(yīng)的處理:

/* This routine deals with acks during a TLP episode.* Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe.*/ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) {struct tcp_sock *tp = tcp_sk(sk);//判斷這個(gè)包是否是tlp包的dup ack包bool is_tlp_dupack = (ack == tp->tlp_high_seq) &&!(flag & (FLAG_SND_UNA_ADVANCED |FLAG_NOT_DUP | FLAG_DATA_SACKED));/* Mark the end of TLP episode on receiving TLP dupack or when* ack is after tlp_high_seq.*///如果是dup ack,說(shuō)明沒(méi)有發(fā)生丟包,繼續(xù)當(dāng)前的流程if (is_tlp_dupack) {tp->tlp_high_seq = 0;return;}//否則,減窗,并進(jìn)入擁塞避免if (after(ack, tp->tlp_high_seq)) {tp->tlp_high_seq = 0;/* Don't reduce cwnd if DSACK arrives for TLP retrans. */if (!(flag & FLAG_DSACKING_ACK)) {tcp_init_cwnd_reduction(sk, true);tcp_set_ca_state(sk, TCP_CA_CWR);tcp_end_cwnd_reduction(sk);tcp_try_keep_open(sk);NET_INC_STATS_BH(sock_net(sk),LINUX_MIB_TCPLOSSPROBERECOVERY);}} }

TLP算法的設(shè)計(jì)思路還是挺好的,主動(dòng)提前發(fā)現(xiàn)網(wǎng)絡(luò)是否擁塞,而不是被動(dòng)的去依賴丟包來(lái)作為反饋。在大多數(shù)情況下是可以提高網(wǎng)絡(luò)傳輸?shù)男实?#xff0c;但在某些情況下可能會(huì)"適得其反",而本文遇到的問(wèn)題就是"適得其反"的一個(gè)例子。

問(wèn)題的解決

回到我們的這個(gè)問(wèn)題上,如何確認(rèn)確實(shí)是由于TLP引起的呢

繼續(xù)查看代碼可以看到,TLP的loss probe和loss recovery次數(shù),內(nèi)核都有相應(yīng)的計(jì)數(shù)器跟蹤。

既然有計(jì)數(shù)器就好辦了,復(fù)現(xiàn)的時(shí)候netstat -s就可以查看是否命中TLP了。寫了個(gè)腳本將結(jié)果寫入到文件里。

while true; do date +"%T.%6N" >> loss.log; netstat -s | grep Loss >> loss.log; done

?

查看計(jì)數(shù)器增長(zhǎng)的情況,結(jié)合抓包文件來(lái)看,基本確認(rèn)肯定是命中TLP了。知道原因那就好辦了,關(guān)掉TLP驗(yàn)證一下應(yīng)該就可以解決了。

如上面介紹ER算法時(shí)提到,內(nèi)核提供了一個(gè)開關(guān),tcp_early_retrans可用于開啟和關(guān)閉ER和TLP,默認(rèn)是3(enable TLP and delayed ER),sysctl -w net.ipv4.tcp_early_retrans=2 關(guān)掉TLP,再次重新測(cè)試,發(fā)現(xiàn)問(wèn)題解決了:

窗口增加的很快,最終的ssthresh為941,下載速度4s+,也是符合預(yù)期,到此用戶的問(wèn)題已經(jīng)解決,但所有的疑問(wèn)都得到了正確的解答了嗎

真正的真相

雖然用戶的問(wèn)題已經(jīng)得到了解決,但至少還有兩個(gè)問(wèn)題沒(méi)有得到答案:

1. 為什么會(huì)每次都在握手完的前幾個(gè)包里就會(huì)觸發(fā)TLP?

2. 雖然觸發(fā)了TLP,但從抓包來(lái)看,已經(jīng)收到了尾包的dup ack包,那說(shuō)明沒(méi)有發(fā)生丟包,為什么還是進(jìn)入了擁塞避免?

先回答第一個(gè)問(wèn)題,根據(jù)文章最前面的網(wǎng)絡(luò)結(jié)構(gòu)圖可以看到,STGW是掛在TGW的后面。在本場(chǎng)景中,用戶訪問(wèn)的是TGW的高防VIP,高防VIP有一個(gè)默認(rèn)開啟的功能就是SYN代理。

syn代理指的是client發(fā)起連接時(shí),首先是由tgw代答syn ack包,client真正開始發(fā)送數(shù)據(jù)包時(shí),tgw再發(fā)送三次握手的包到rs,并轉(zhuǎn)發(fā)數(shù)據(jù)包。

在本例中,tgw的rs就是stgw,也就是說(shuō),stgw的收到三次握手包的rtt是基于與tgw計(jì)算出來(lái)的,而后面的數(shù)據(jù)包才是真正與client之間的通信。前面背景描述中提到,用戶同城訪問(wèn)(上海client訪問(wèn)上海的vip)也是沒(méi)有問(wèn)題的,跨城訪問(wèn)就有問(wèn)題。

這是因?yàn)橥窃L問(wèn)的情況下,tgw與stgw之間的rtt與client與stgw之間的rtt,相差并不大,并沒(méi)有滿足觸發(fā)tlp的條件。而跨城訪問(wèn)后,三次握手的數(shù)據(jù)包的rtt是基于與tgw來(lái)計(jì)算的,比較小,后面收到數(shù)據(jù)包后,計(jì)算的是client到stgw之間的rtt,一下子增大了很多,并且滿足了tlp的觸發(fā)條件

PTO=max(2rtt, 10ms)

設(shè)置的PTO定時(shí)器超時(shí)了,協(xié)議棧認(rèn)為是不是由于網(wǎng)絡(luò)發(fā)生了擁塞,所以重傳了尾包探測(cè)一下查看是否真的發(fā)生了擁塞,這就是為什么每次都是在握手完隨后的幾個(gè)包里就會(huì)有重傳包,觸發(fā)了TLP的原因。

再回到第二個(gè)問(wèn)題,從抓包來(lái)看,很明顯,網(wǎng)絡(luò)并沒(méi)有發(fā)生擁塞或丟包,stgw已經(jīng)收到了尾包的dup ack包,按照TLP的原理來(lái)看,不應(yīng)該進(jìn)入擁塞避免的,到底是什么原因?qū)е碌摹0偎疾坏闷浣?#xff0c;只能再繼續(xù)啃代碼了,再回到tlp_ack的這一部分代碼來(lái)看。

只有當(dāng)is_tlp_dupack為false時(shí),才會(huì)進(jìn)入到下面部分,進(jìn)入擁塞避免,也就是說(shuō)這里is_tlp_dupack肯定是為false的。ack == tp->tlp_high_seq這個(gè)條件是滿足的,那么問(wèn)題就出在了幾個(gè)flag上面,看下幾個(gè)flag的定義:

#define FLAG_SND_UNA_ADVANCED 0x400 #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) #define FLAG_DATA_SACKED 0x20 /* New SACK.

也就是說(shuō),只要flag包含了上面幾個(gè)中的任意一個(gè),都會(huì)將is_tlp_dupack置為false,那到底flag包含了哪一個(gè)呢?如何繼續(xù)排查呢

調(diào)試內(nèi)核信息,最常用的工具就是ftracesystemtap

這里首先嘗試了ftrace,發(fā)現(xiàn)它并不能滿足我的需求。ftrace最主要的功能是可以跟蹤函數(shù)的調(diào)用信息,并且可以知道各個(gè)函數(shù)的執(zhí)行時(shí)間,在有些場(chǎng)景下非常好用,但原生的ftrace命令用起來(lái)很不方便,ftrace團(tuán)隊(duì)也意識(shí)到了這個(gè)問(wèn)題,因此提供了另外一個(gè)工具trace-cmd,使用起來(lái)非常簡(jiǎn)單。

trace-cmd record -p function_graph -P 3252 //跟蹤pid 3252的函數(shù)調(diào)用情況 trace-cmd report > report.log //以可視化的方式展示ftrace的結(jié)果并重定向到文件里

下圖是使用trace-cmd跟蹤的一個(gè)例子部分截圖,可以看到完整打印了內(nèi)核函數(shù)的調(diào)用信息及對(duì)應(yīng)的執(zhí)行時(shí)間。

但在當(dāng)前的這個(gè)問(wèn)題里,主要是想確認(rèn)flag這個(gè)變量的值,ftrace沒(méi)有辦法打印出變量的值,因此考慮下一個(gè)強(qiáng)大的工具:systemtap

systemtap是一個(gè)很強(qiáng)大的動(dòng)態(tài)追蹤工具,利用它可以很方便的調(diào)試內(nèi)核信息,跟蹤內(nèi)核函數(shù),打印變量信息等,很顯然它是符合我們的需求的。systemptap的使用需要安裝內(nèi)核調(diào)試信息包(kernel-debuginfo),但由于復(fù)現(xiàn)的那臺(tái)機(jī)器上的內(nèi)核版本較老,沒(méi)有debug包,無(wú)法使用stap工具,因此這條路也走不通。

最后,聯(lián)系了h_tlinux_Helper尋求幫助,他幫忙找到了復(fù)現(xiàn)機(jī)器內(nèi)核版本的dev包,并在tcp_process_tlp_ack函數(shù)里打印了一些變量,并輸出堆棧信息。重新安裝了調(diào)試的內(nèi)核,復(fù)現(xiàn)后打印了如下的堆棧及變量信息:

綠色標(biāo)記處的那一行,就是收到的dup ack的那個(gè)包,可以看到flag的標(biāo)記為0x4902,換算成宏定義為:

FLAG_UPDATE_TS_RECENT | FLAG_DSACKING_ACK | FLAG_SLOWPATH | FLAG_WIN_UPDATE

再對(duì)照tcp_process_tlp_ack函數(shù)看一下,正是FLAG_WIN_UPDATE這個(gè)標(biāo)記導(dǎo)致了is_tlp_dupack = false。那在什么情況下,flag會(huì)被置為FLAG_WIN_UPDATE呢

繼續(xù)看代碼,對(duì)端回復(fù)的每個(gè)ack包基本會(huì)進(jìn)入到tcp_ack_update_window函數(shù)。

看到這里flag被置為FLAG_WIN_UPDATE的條件是tcp_may_update_window返回true。

?

再看到tcp_may_update_window函數(shù)這里,after(ack_seq, tp->snd_wl1)?是基本都會(huì)命中的,因?yàn)椴还艽翱谟袥](méi)有變化,ack_seq都會(huì)比snd_wl1 大的,ack_seq都是遞增的,snd_wl1在tcp_update_wl中又會(huì)被更新成上一次的ack_seq。因此絕大多數(shù)的包的flag都會(huì)被打上FLAG_WIN_UPDATE標(biāo)記。

如果是這樣的話,那is_tlp_dupack不就是都為false了嗎?不管有沒(méi)有收到dup ack包,TLP都會(huì)進(jìn)入擁塞避免,這個(gè)就不符合TLP的設(shè)計(jì)初衷了,這里是否是內(nèi)核實(shí)現(xiàn)的Bug

隨后我查看了linux 4.14內(nèi)核代碼:

發(fā)現(xiàn)從內(nèi)核版本linux 4.0開始,BUG就已經(jīng)被修復(fù)了,去掉了flag的一些不合理的判斷條件,這才是真正的符合TLP的設(shè)計(jì)原理。

到此,整個(gè)問(wèn)題的所有疑點(diǎn)才都得到了解釋。

總結(jié)

本文從一個(gè)下載慢的線上問(wèn)題入手,首先介紹了一些常規(guī)的排查思路和手段,發(fā)現(xiàn)仍然不能定位到原因。然后分享了一個(gè)可以查詢每條連接的擁塞窗口命令,結(jié)合內(nèi)核代碼分析了TCP擁塞控制ssthresh的設(shè)計(jì)理念及混合慢啟動(dòng),ER和尾包探測(cè)(TLP)等優(yōu)化算法,并介紹了兩個(gè)常用的內(nèi)核調(diào)試工具:ftrace和systemtap,最終定位到是內(nèi)核的TLP實(shí)現(xiàn)BUG導(dǎo)致的下載慢的問(wèn)題,從內(nèi)核4.0版本之后已經(jīng)修復(fù)了這個(gè)問(wèn)題。

總結(jié)

以上是生活随笔為你收集整理的由STGW下载慢问题引发的网络传输学习之旅的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

草久在线播放 | 亚洲精品国产精品国自产 | 国产精品久久久久久久99 | 国产精品美女久久久久久久久久久 | 91精品国自产在线偷拍蜜桃 | 丁香六月欧美 | 国内精品久久久久久中文字幕 | 亚洲视频精品 | 国产精品成人免费一区久久羞羞 | 久久久久成人精品亚洲国产 | 97超碰国产精品女人人人爽 | 日韩草比| 国产精品扒开做爽爽的视频 | 日日爱av| 中文高清av| 欧美老人xxxx18 | 超碰在线91| 99免费在线 | 91成人网在线观看 | 色婷婷综合久久久 | 久久精品99久久久久久2456 | 国产精品va最新国产精品视频 | 国产探花视频在线播放 | 精品一区三区 | 国产香蕉视频在线观看 | 欧美性免费 | 在线观看视频三级 | 伊人射 | 亚洲免费视频在线观看 | 国产精品一区二区电影 | 国产特黄色片 | www黄免费 | 97精品国产91久久久久久久 | 麻豆久久精品 | 欧美日韩国产精品爽爽 | 在线小视频你懂得 | 亚洲精品欧洲精品 | 伊色综合久久之综合久久 | 色福利网站 | 国产精品免费一区二区三区 | 狠狠狠色狠狠色综合 | 成人三级av | 久久久久久久99精品免费观看 | 激情五月五月婷婷 | 国产区网址 | 在线观看91 | 欧洲成人av | 亚洲狠狠丁香婷婷综合久久久 | 国产99在线 | 免费高清在线观看成人 | 国产系列在线观看 | 久久精品国产亚洲a | 久久蜜臀av | 91中文在线视频 | 一级黄色片在线观看 | 日本视频网| 一级黄色电影网站 | 88av视频 | 99r在线精品 | 国产一区二区免费 | 国产午夜亚洲精品 | 99久久超碰中文字幕伊人 | 中文字幕在线免费看 | 青草草在线视频 | 婷婷久久综合九色综合 | www欧美日韩| 精品视频免费在线 | 玖玖视频网 | 狠狠色丁香九九婷婷综合五月 | 五月婷婷在线播放 | 日韩高清一区二区 | 九九视频一区 | 国产在线精品区 | 国内丰满少妇猛烈精品播 | 日本中文字幕免费观看 | 久久久www| 国产美女视频一区 | 国产精品一区二区电影 | 国产一级高清 | 久久这里只有精品9 | 久久久黄色 | av九九 | 午夜国产福利视频 | 久久国产精品99久久久久 | 九九久久免费视频 | 国产99免费视频 | 国产一级特黄电影 | 国产97碰免费视频 | 亚洲成人网av| 久久露脸国产精品 | 久久国产三级 | 成 人 黄 色 视频免费播放 | 色午夜| av黄免费看 | 精品视频99| 激情动态 | 欧美精品首页 | 久99精品| 久草在线视频精品 | 久久免费的精品国产v∧ | 亚洲黄色区 | 欧美一二在线 | 午夜丰满寂寞少妇精品 | 国产一级二级在线播放 | japanese黑人亚洲人4k | 欧美伦理一区二区三区 | 成人蜜桃视频 | 国产一区二区三区久久久 | 久久五月天色综合 | 国外av在线 | 欧美精品亚洲精品日韩精品 | 9在线观看免费高清完整版 玖玖爱免费视频 | 婷婷五综合 | 国产对白av | 国产精品一区专区欧美日韩 | 欧美性做爰猛烈叫床潮 | 久久久久久久久久久综合 | 在线观看视频黄色 | 正在播放国产一区 | 国产在线中文 | 国产视频69 | 日日草夜夜操 | 97电影在线看视频 | 在线观看免费福利 | 97在线观看 | 9色在线视频 | www最近高清中文国语在线观看 | japanesexxxhd奶水 91在线精品一区二区 | 免费福利在线观看 | 在线 视频 一区二区 | 成+人+色综合 | 日本精品一区二区三区在线观看 | 国产第一页在线观看 | 在线中文字幕观看 | 国产美女视频黄a视频免费 久久综合九色欧美综合狠狠 | 亚洲日本三级 | 少妇bbb | 日韩精品一区二区三区中文字幕 | 成人av影院在线观看 | 亚洲狠狠婷婷综合久久久 | 97香蕉久久国产在线观看 | 最近日本字幕mv免费观看在线 | 最近中文字幕国语免费av | 日本高清中文字幕有码在线 | 操久 | 欧美视频二区 | 久草免费在线视频 | 国产精品18久久久久久久久 | 在线日韩一区 | 亚洲欧美精品一区二区 | 349k.cc看片app | 欧美乱码精品一区二区 | 日韩影视在线观看 | 韩日电影在线 | 久久久国产一区二区 | 国产在线黄色 | 六月天色婷婷 | 97视频入口免费观看 | 久久人人97超碰精品888 | 日本久久久精品视频 | 久久久精品小视频 | 久久久.com | 天天干天天拍 | 亚洲欧洲av | 粉嫩av一区二区三区免费 | 久久久久久中文字幕 | 黄色毛片视频免费观看中文 | 婷婷国产在线 | 国产艹b视频 | 午夜av在线免费 | 中文字幕在线第一页 | 亚洲精品国产第一综合99久久 | 免费h精品视频在线播放 | 色福利网站 | 在线观看911视频 | 超碰97国产精品人人cao | 国产精品久久在线 | 中文国产成人精品久久一 | 欧美极品xxxx | 在线久久 | 手机看片午夜 | 欧美最新大片在线看 | 日韩免费一级电影 | 夜夜躁日日躁狠狠久久av | 涩五月婷婷| 欧美日韩精品影院 | 美女av电影 | 青草视频免费观看 | 日韩有码第一页 | 久久综合久久综合九色 | 久久精品com | 国产成人综合在线观看 | 免费精品国产 | 久久免费中文视频 | 国产成人久 | 91九色视频在线播放 | 国产韩国精品一区二区三区 | 91 在线视频播放 | 国产99久久久欧美黑人 | 最近中文字幕完整视频高清1 | 91精品国产一区二区三区 | 亚洲狠狠干 | 久久精品aaa| 免费视频 你懂的 | 中文字幕在线资源 | www.婷婷色 | 九九久久精品视频 | 69视频永久免费观看 | 97超碰精品 | 日韩a免费 | 99精品在线观看 | 在线成人高清电影 | 91av在| 亚洲桃花综合 | 九九精品视频在线观看 | 日日天天| 国产精品原创av片国产免费 | 欧美国产日韩一区二区三区 | 美女精品网站 | 久久综合中文色婷婷 | 久久人视频 | 欧美性网站 | 国产精品久久久久久久久久久久午夜 | 青青久草在线视频 | 免费久久久久久久 | 超碰97.com| 国产精品美女免费看 | 91免费观看国产 | 开心色激情网 | 一区二区视频免费在线观看 | 人人射人人射 | 国产一级特黄毛片在线毛片 | 成人一级电影在线观看 | 久草免费手机视频 | 国产一区在线精品 | 日韩午夜视频在线观看 | 日本女人的性生活视频 | 国产免费久久av | 日韩a在线观看 | 欧美国产日韩一区二区三区 | 日韩精品在线一区 | 久久在线看 | 天天爽网站| 国产婷婷久久 | 狠狠狠的干 | 精品主播网红福利资源观看 | 日韩高清在线一区 | 日韩午夜三级 | 成人动漫精品一区二区 | 中文在线字幕免 | 日韩在线观看 | 亚洲人人精品 | 久久精品国产成人精品 | 一级片免费观看 | 亚洲精品在线电影 | 日日夜夜免费精品视频 | 日韩视频免费 | www.99在线观看 | 99精品在线看 | 国产美女视频免费观看的网站 | 在线观看亚洲电影 | 亚洲每日更新 | 欧美国产日韩久久 | 91看片在线播放 | 中文字幕在线视频第一页 | 深夜免费小视频 | 国产美女久久久 | 午夜精品一区二区三区在线 | 亚洲激情视频在线 | 一本到在线 | 日韩电影一区二区在线观看 | 在线观看91久久久久久 | 天天在线操 | a v在线视频 | 中文在线a∨在线 | 久草在线高清视频 | 国产免费观看久久黄 | 久久久免费国产 | 免费看短 | 久久精品欧美日韩精品 | 欧美性色综合网站 | 91视频国产高清 | 国产在线看 | 伊人久久在线观看 | 69久久久久久久 | 911久久 | 国产精品99久久久久的智能播放 | 日韩激情免费视频 | 国产一区二区三区久久久 | 中文久草 | 又黄又爽又无遮挡的视频 | 香蕉精品在线观看 | 中文字幕888 | 成人97人人超碰人人99 | 久久这里只有精品首页 | 91xav| 欧美日韩伦理在线 | 国产精品18久久久久vr手机版特色 | 成人一区二区三区中文字幕 | 亚洲欧洲精品在线 | 麻豆传媒视频在线免费观看 | www.五月天激情 | 亚洲视频综合在线 | 亚洲精品a区 | 看av免费| 五月婷婷丁香激情 | 免费黄av | 久久午夜鲁丝片 | 日韩色综合 | 网站在线观看日韩 | 丁香婷婷综合五月 | 久久久久久久免费看 | 国产精品麻豆三级一区视频 | 国产精品丝袜在线 | 中文字幕日韩精品有码视频 | 久久久久久久久久久久久国产精品 | 午夜精品久久久久久久99 | 久草在线久草在线2 | 久久久精品国产免费观看同学 | 狠狠激情中文字幕 | 欧美激情精品久久久久久免费印度 | 国产精品久久毛片 | 国产日韩欧美在线看 | 久久国产露脸精品国产 | 欧美日韩三区二区 | 免费看的黄网站 | 国产精品色婷婷视频 | 日韩中文字幕免费在线观看 | 国产高清无线码2021 | 日韩字幕| 91看片一区二区三区 | 国产美腿白丝袜足在线av | 国内精品久久久久影院一蜜桃 | 亚洲精品综合一二三区在线观看 | 成人小视频在线观看免费 | 最新av在线播放 | 精品美女在线视频 | 欧美中文字幕久久 | 91综合视频在线观看 | 亚洲精品成人免费 | 伊人午夜视频 | 亚洲欧美综合 | 日韩欧美高清视频在线观看 | 在线综合色 | 日韩亚洲国产精品 | 国产日韩欧美中文 | 久久精品电影网 | 丁香电影小说免费视频观看 | 中文字幕在线色 | 2021国产在线 | 欧洲视频一区 | 日韩高清一区 | 国产视频精品久久 | 在线播放国产一区二区三区 | 日韩精品久久久免费观看夜色 | 久久尤物电影视频在线观看 | 午夜精品一二三区 | 999久久久国产精品 高清av免费观看 | 天天操综 | 国产精品美女久久 | 国内精品福利视频 | 成人动态视频 | 日韩黄色中文字幕 | 国产精品国产亚洲精品看不卡15 | 欧美日韩三级 | 日韩在线电影一区 | 三级黄色网址 | 日日夜夜人人天天 | 日韩激情在线 | 久热免费 | 91在线在线观看 | 韩日av在线 | 日韩精品视频一二三 | 国产精品激情偷乱一区二区∴ | 日韩理论在线 | 麻豆传媒视频观看 | 免费的国产精品 | 日韩欧美精品在线视频 | 久久99国产精品免费 | 久久久久久伊人 | 欧美精品免费一区二区 | 99久久精品国产亚洲 | 99热.com| av 一区二区三区 | 最近中文字幕国语免费高清6 | 国产精品美女在线 | 超级碰碰免费视频 | 日韩毛片在线一区二区毛片 | 97国产大学生情侣酒店的特点 | 国产精品一码二码三码在线 | 国产精品系列在线播放 | 国产精品九色 | 91在线播放国产 | 久久精品视频在线观看免费 | 国产精品国产三级在线专区 | 欧美日韩国产xxx | 久久精品毛片 | 中文字幕 国产 一区 | 黄色一级性片 | 国产免费又爽又刺激在线观看 | 久久无码av一区二区三区电影网 | 国产精品毛片网 | 欧美日韩中文字幕在线视频 | 玖玖视频免费在线 | 久久试看 | 日韩啪视频 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 9797在线看片亚洲精品 | 天天爱天天草 | 欧美va天堂va视频va在线 | 9在线观看免费高清完整版在线观看明 | 精品国产欧美 | 在线免费观看黄色小说 | 丁香狠狠| 久久全国免费视频 | 最新一区二区三区 | 国产 日韩 在线 亚洲 字幕 中文 | 久久任你操 | 午夜精品视频一区 | 97在线精品 | 国产91精品一区二区麻豆网站 | 久久试看 | 精品国产乱子伦一区二区 | 在线观看激情av | 91 在线视频播放 | 国产伦精品一区二区三区… | 国内精品久久久久影院优 | 亚洲日本在线视频观看 | 91九色蝌蚪视频在线 | 中文字幕一区二区三区在线观看 | 日日夜夜爱 | 成人a免费看 | 亚州国产精品久久久 | 97超碰在线视 | 97精品超碰一区二区三区 | 色成人亚洲 | 91精品国产综合久久婷婷香蕉 | 天堂av在线免费观看 | 波多野结衣一区 | 久久国产精品免费视频 | 免费福利在线视频 | 国产精品久久久久久久久久了 | 黄网站色视频 | 成人小电影在线看 | 国内精品久久久久国产 | 人人干,人人爽 | 亚洲少妇天堂 | 免费十分钟 | 2024av在线播放| 日韩高清 一区 | av日韩av| 九九久久久久久久久激情 | 一区三区视频 | 日本aa在线| 亚洲精品免费看 | 99视频久| 99精品电影| 中文字幕在线观看第一页 | 日韩中文幕 | 黄p网站在线观看 | 99免在线观看免费视频高清 | 在线国产一区 | 97综合网 | 日韩在线观看电影 | 久久久免费av | 久久久免费看 | 激情深爱 | 又爽又黄又刺激的视频 | 免费在线观看成年人视频 | 69久久夜色精品国产69 | 精品久久久久久久 | 亚洲天天摸日日摸天天欢 | 成人午夜影视 | 国产中文视 | 日韩精选在线 | 精品国产精品久久一区免费式 | 国产一区二区三区高清播放 | 精品国产一区二区三区不卡 | www.看片网站 | 视频国产精品 | 亚洲精品黄色在线观看 | 91视频在线观看免费 | 一级特黄aaa大片在线观看 | 丁香激情综合久久伊人久久 | 又粗又长又大又爽又黄少妇毛片 | 97视频免费观看2区 亚洲视屏 | 色久天 | www.午夜| 国产精品电影一区 | 国产精品久久久久免费 | 欧美嫩草影院 | 天干啦夜天干天干在线线 | 欧美一级久久 | 日本性高潮视频 | 91网址在线看 | 亚洲国产综合在线 | 99视频网址 | 夜又临在线观看 | www.色午夜.com| av视屏在线播放 | 色在线视频网 | 黄色片网站 | 菠萝菠萝蜜在线播放 | 99热99re6国产在线播放 | 国产精品一区二区免费视频 | 国产蜜臀av | av九九九| 亚州精品在线视频 | 免费成人在线视频网站 | 久久久电影网站 | 最新一区二区三区 | 久久精品欧美 | 欧美日韩国产一区二区三区 | 欧美在线视频日韩 | 一级淫片在线观看 | 久久精品美女 | 狠狠色丁香婷婷综合欧美 | 五月天久久狠狠 | 99热这里只有精品1 av中文字幕日韩 | 伊人色**天天综合婷婷 | 国产精品美女毛片真酒店 | 久久久免费观看 | 91精品一区国产高清在线gif | 日本高清免费中文字幕 | 99re久久资源最新地址 | 精品国产免费看 | 日韩精品极品视频 | 欧美作爱视频 | 偷拍精品一区二区三区 | 婷婷婷国产在线视频 | 久久优 | 九九激情视频 | 欧美日韩免费观看一区二区三区 | 美女免费视频黄 | 日韩免费在线网站 | 国产91精品欧美 | 狠狠操.com | 亚洲一级黄色大片 | www夜夜操com | 91一区二区三区久久久久国产乱 | 欧美激情综合色综合啪啪五月 | 欧美日韩免费一区二区 | 婷婷丁香在线观看 | 国产成人精品亚洲精品 | 久久9精品 | 国产免费叼嘿网站免费 | 波多野结衣电影一区 | 成年人三级网站 | 亚洲 欧美 变态 国产 另类 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 久久免费高清 | 亚洲精品视频免费 | 久久网站最新地址 | 亚洲精品国产综合久久 | 久久国产一二区 | 欧美成人免费在线 | 在线免费观看的av网站 | 国产又粗又长又硬免费视频 | 日韩中字在线 | 黄色毛片在线观看 | 久久久免费毛片 | 精品影院 | 国产成人精品一区二区在线观看 | 亚洲精品乱码久久久久久蜜桃91 | 久久久九色精品国产一区二区三区 | 三上悠亚一区二区在线观看 | 国产 精品 资源 | 日韩,精品电影 | 在线不卡视频 | 在线免费观看麻豆 | 国产精品久久久久久久久免费看 | 日韩精品视频在线观看网址 | 中文国产成人精品久久一 | 日韩精品免费在线观看 | 亚洲国产网站 | 欧美日韩不卡一区 | 亚洲美女视频网 | 成全在线视频免费观看 | 久久精品三级 | 亚洲日本va午夜在线影院 | 久久久www免费电影网 | 欧美做受69| 不卡视频在线看 | 夜夜骑天天操 | 欧美黑人性猛交 | 亚洲1级片 | 国产日韩欧美在线看 | 天天草天天草 | 久久激情久久 | 久久天堂精品视频 | 日韩素人在线观看 | 国色天香在线 | 午夜999 | 日韩欧美一区二区不卡 | 黄色毛片视频免费观看中文 | 中文字幕123区 | 天天色天天操天天爽 | 人人舔人人干 | 国产精品久久久久久久午夜片 | 国产伦精品一区二区三区无广告 | 精品在线免费视频 | 特黄色大片 | 欧美国产精品一区二区 | 欧美aa级 | 精品国产伦一区二区三区观看体验 | 91精品国产乱码在线观看 | 国产又粗又猛又爽又黄的视频免费 | 国产精品久久久久久久久久不蜜月 | 伊人伊成久久人综合网站 | 欧洲黄色片 | 毛片网在线观看 | 九九九视频精品 | 久久激情小视频 | 亚洲视频免费在线看 | 色丁香色婷婷 | 亚洲国产中文字幕在线视频综合 | 操久| 国产私拍在线 | 欧美日韩国产色综合一二三四 | 免费成视频| www.色午夜.com | 国产精品视频99 | 国产精品黄色在线观看 | 亚洲成年人av| 国产精品国产自产拍高清av | 黄色成年片 | 国内综合精品午夜久久资源 | 久久丁香 | 久久久久国产免费免费 | 亚洲无吗视频在线 | 日韩欧美精品在线观看 | 丝袜+亚洲+另类+欧美+变态 | 九九久| 亚洲五月婷婷 | 四虎国产精品成人免费4hu | 又黄又爽又无遮挡免费的网站 | 99精品欧美一区二区三区 | 99精品免费久久久久久久久 | 国产aa精品 | 久久久高清免费视频 | 免费看黄色毛片 | 又爽又黄又刺激的视频 | 91欧美精品 | 色综合婷婷久久 | 国产精品久久一区二区三区, | 99视频在线精品国自产拍免费观看 | 国产黄色片一级三级 | 奇米网网址 | 天天色成人网 | 最新国产在线 | 国产精品理论片在线观看 | 美女一级毛片视频 | 色先锋资源网 | 草久视频在线观看 | 国产黄色一级大片 | 久久久久久激情 | 日日夜夜精品免费 | 国产99在线播放 | 久久这里只有精品视频99 | 国产视频亚洲精品 | 日韩免费在线 | 婷色在线 | 欧美尹人 | 久久综合婷婷 | 日韩高清激情 | av电影在线播放 | 一区二区三区电影大全 | 日韩精品免费在线播放 | 成人午夜久久 | 成人高清av在线 | 亚洲91av | 成人h电影在线观看 | 五月综合色 | 国产69久久 | 国语对白少妇爽91 | 国产精品一区二区你懂的 | 日本中文字幕电影在线免费观看 | 中文字幕在线播出 | 亚洲在线资源 | 国产裸体永久免费视频网站 | 亚洲国产福利视频 | 狠色在线 | 好看的国产精品视频 | 国产亚洲视频系列 | 中文字幕一区二区在线播放 | 国产精品久久久久三级 | 久草在线免费资源站 | 欧美精品第一 | 91视频免费国产 | 免费在线播放视频 | 久久久久综合精品福利啪啪 | 国产精品久久免费看 | 亚洲视频在线观看 | 欧美午夜精品久久久久久浪潮 | 国产 日韩 欧美 在线 | 啪啪免费视频网站 | 婷婷在线免费 | 美女免费黄网站 | 久久草网站 | 久久狠狠一本精品综合网 | 天天爱天天操天天干 | 国产亚洲人成网站在线观看 | 久久精品视频3 | 97超碰超碰久久福利超碰 | 2023天天干 | 成人aⅴ视频 | av资源网在线播放 | 精品一区二区在线免费观看 | 免费视频 三区 | 久草在线视频网站 | 中文字幕精品久久 | 国产成人a亚洲精品 | 久久精品牌麻豆国产大山 | a在线v| 欧美亚洲另类在线视频 | 中文字幕无吗 | 91大神视频网站 | 天天干天天射天天爽 | 国内视频在线 | 91.麻豆视频| 99人成在线观看视频 | 欧美热久久 | 天天综合成人 | 2018精品视频 | 久久天| 久久久久国产一区二区三区四区 | 69av久久| 亚洲天堂激情 | 在线观看亚洲视频 | 天天色天天草天天射 | 永久免费看av | 夜夜躁日日躁狠狠久久av | 国产精品精品 | 亚洲精品美女在线 | 国产中文字幕视频在线观看 | 99r在线播放 | 久久久91精品国产一区二区精品 | 干天天| 国产精品视频全国免费观看 | av电影在线免费观看 | 日韩大陆欧美高清视频区 | 久精品一区 | 久久无码精品一区二区三区 | 成人国产精品久久久久久亚洲 | 国产成人精品在线播放 | 少妇bbw揉bbb欧美 | 国产系列在线观看 | 天天玩夜夜操 | 国产一区二区久久精品 | 精品少妇一区二区三区在线 | 亚洲综合激情网 | 成人作爱视频 | 一级黄色片在线播放 | 成在线播放 | 人人爽人人干 | www五月天婷婷 | 国产无套视频 | 99精品免费网 | www.香蕉 | www.综合网.com| 免费a网站| 日韩在线看片 | 欧美最新大片在线看 | 欧洲性视频 | 精品国产一区二区三区四区vr | 国产亚洲小视频 | 国产精品系列在线播放 | 国产精品一区二区吃奶在线观看 | 久草综合在线观看 | 国产成人91 | 国产精品 国内视频 | 一区二区中文字幕在线观看 | 国产久草在线 | 在线观看欧美成人 | a天堂一码二码专区 | 在线免费观看视频a | 欧美日韩国产精品一区二区 | 97香蕉视频| 久久亚洲美女 | 麻豆视频免费播放 | 婷婷久久综合九色综合 | 右手影院亚洲欧美 | 毛片精品免费在线观看 | 日韩免费二区 | 欧美日韩国产一区二区在线观看 | 亚洲va欧美va人人爽春色影视 | 人人舔人人爽 | 激情五月开心 | 久久久人人爽 | 国产精品亚洲片在线播放 | 久久精品一区二区三区视频 | 91亚州| 国产永久免费观看 | 蜜桃av人人夜夜澡人人爽 | 久久一线 | 成人午夜免费剧场 | 国产一线天在线观看 | 国产传媒中文字幕 | 色网站在线观看 | 欧美一级爽 | 在线免费中文字幕 | 五月天六月丁香 | av大片免费看 | 亚洲免费观看视频 | 久久九九免费 | 超碰人人做 | 91视频在线自拍 | 国产在线免费av | 亚洲国产欧美在线人成大黄瓜 | 麻豆视频在线免费看 | 久草在线视频国产 | 日韩激情综合 | 欧美日韩成人一区 | 91精品小视频 | 天天操 夜夜操 | 粉嫩高清一区二区三区 | 免费的成人av | 久草在线在线视频 | 国产精品精品国产婷婷这里av | 国产无遮挡又黄又爽馒头漫画 | 蜜臀av性久久久久av蜜臀妖精 | 国产美女黄网站免费 | 最新的av网站| 日韩精品亚洲专区在线观看 | 久久久久亚洲精品成人网小说 | 亚洲 欧美 成人 | 在线观看视频91 | 超碰夜夜| 久久久www成人免费毛片 | 久久99国产精品久久 | 视频一区在线免费观看 | 91九色网站 | 久久爱资源网 | 欧美日韩免费观看一区=区三区 | 99精品欧美一区二区三区 | 日韩精品免费一区二区三区 | 欧美一级视频在线观看 | 日韩精品久久中文字幕 | 婷婷免费视频 | 欧美日韩亚洲在线 | 色美女在线 | 国产伦精品一区二区三区在线 | 欧美性大战久久久久 | zzijzzij亚洲日本少妇熟睡 | 精品国产亚洲一区二区麻豆 | 精品国产一区二区三区久久久蜜臀 | 亚洲黄色免费观看 | 日韩首页 | 免费黄色一区 | 国产美女久久 | www.五月婷婷.com | 人人爽人人爽人人爽学生一级 | 东方av免费在线观看 | 日韩av看片 | 五月天久久 | 欧美久久久久久久久久久久久 | 在线观看免费高清视频大全追剧 | 国产a级免费 | 国产97视频在线 | 成人在线视频网 | 日韩亚洲欧美中文字幕 | 在线播放 日韩专区 | 中文字幕在线看视频国产 | 久99久在线视频 | 精品国产乱码久久久久久久 | 中文字幕色综合网 | 国产91精品一区二区麻豆亚洲 | 亚洲国产高清视频 | 日韩三区在线 | 激情大尺度视频 | 免费观看一级视频 | 国产人免费人成免费视频 | 天堂久色 | 成人动漫一区二区 | 久久一区二区三区国产精品 | 日韩三级免费 | 久久污视频 | 久久久久久国产精品 | 亚洲国产成人精品在线观看 | 午夜精品视频福利 | 久久久久久毛片精品免费不卡 | 中文字幕日本在线 | 欧美韩国日本在线 | 成人全视频免费观看在线看 | 中文字幕在线影视资源 | 欧美最新另类人妖 | 婷婷丁香在线观看 | 精品国模一区二区三区 | 婷婷精品在线视频 | 久久夜色精品国产欧美乱 | 久草在线在线视频 | 婷婷深爱| 99r国产精品 | 欧美一级性 | 亚洲欧美精品一区 | 国产视频在 | 在线日韩| 婷婷精品国产一区二区三区日韩 | 成人性生交大片免费看中文网站 | 国产一级在线免费观看 | 成+人+色综合 | 中文字幕av全部资源www中文字幕在线观看 | 天天干 夜夜操 | 国产一区免费观看 | 一区在线观看 | wwxxxx日本| 狠狠色综合网站久久久久久久 | 91在线视频免费 | 色综合久久久久综合体桃花网 | 九九热精品视频在线播放 | 久久视频这里有精品 | 久久国产精品久久精品国产演员表 | 国产黄色片免费 | 日韩免费一区二区三区 | 日本精油按摩3 | 中文字幕视频一区 | 久久久久久久久影院 | 热久久视久久精品18亚洲精品 | 久久久久久久久久久精 | 久久综合偷偷噜噜噜色 | 国产一区播放 | 美女免费视频一区二区 | 国产一卡二卡四卡国 | 二区三区精品 | 日韩视频免费观看高清 | 青青河边草手机免费 | 国内精品久久久 | 日本中文在线播放 | 麻豆免费在线播放 | 美女久久久久久 | 日本性xxx | 欧美国产日韩一区二区 | 中文字幕在线观看不卡 | 日b视频国产 | 亚洲成色777777在线观看影院 | 色综合激情网 | 91麻豆精品国产自产在线游戏 | 91激情视频在线观看 | 国产精品资源在线 | 国产在线高清精品 | 玖玖玖精品 | 99精品黄色片免费大全 | 精选久久 | 日韩欧美综合精品 | 亚洲精品在线国产 | 国产 日韩 欧美 在线 | 久久久久网址 | 久久精品www人人爽人人 | 亚洲国产精品va在线看黑人动漫 | 午夜国产福利在线观看 | 97在线影院 | 亚洲视频在线看 | 久草在线中文888 | 亚洲精品美女久久久 | 国产成人免费 | 超碰97在线资源站 | 日韩欧美高清一区二区 | 久久精品一区二区三 | 人人爱在线视频 | 天天操天天干天天操天天干 | av在线h| 精品伊人久久久 | 天天夜夜操 | 黄色网址国产 | 国产视频久久久久 | 日本久久久久久科技有限公司 | 一级黄色片在线 | 狠狠的日 | 热久久视久久精品18亚洲精品 | av性网站 | 六月婷婷色 | 成人黄色视 | 福利网在线 | 日韩精品资源 | 中文字幕在线日本 | 99操视频| 国产99在线 | 337p西西人体大胆瓣开下部 | 亚洲欧美日韩国产 | 精品不卡av | 中文成人字幕 | 国产盗摄精品一区二区 | 制服丝袜在线 | 91视频在线免费 | 99精品免费网 | 5月丁香婷婷综合 | 久免费 | 午夜精品一区二区三区在线视频 | 亚洲天堂毛片 | 一级性视频 | 国产又粗又猛又黄 | 国产无遮挡猛进猛出免费软件 | 亚洲激情在线视频 | 亚洲精品资源 | 国产精品久久久久高潮 | 国产拍揄自揄精品视频麻豆 | 精品久久久久久久久久岛国gif | 国产精品美女久久久久久免费 |