999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于RFB協議的Linux遠程桌面程序的分析與研究

2022-03-01 13:12:48鐘生海王清理
計算機工程與設計 2022年2期

李 暉,鐘生海,王清理

(中國航天科工集團第二研究院 七〇六所,北京 100854)

0 引 言

遠程桌面技術是利用有線或無線網絡由一個終端遠程控制另一個或多個終端[1],并且遠程被控端的桌面界面圖像可以顯示于本地的控制端。使用本地控制端的設備對遠程被控端設備進行操控時,如同直接操控遠程設備,屏幕上顯示的是被控端的桌面圖像,并且可以操控鼠標打開被控端的應用程序,瀏覽被控端設備中的文件資料等。

在不同的平臺之上有著各自獨立的遠程桌面系統,并且采用了不同的技術手段來實現,例如微軟Windows系統常用的RDP(remote desktop protocol)遠程桌面協議,蘋果Mac系統采用的ARD(apple remote desktop)蘋果遠程桌面,而在Linux系統之上,各類VNC程序例如Tight VNC、Real VNC、Ultra VNC等較為常用。各類VNC程序主要框架基本一致,都包括了服務器端VNC Server、客戶端VNC Client以及用來連接服務器端與客戶端的RFB協議,本文研究了主流VNC遠程桌面軟件的工作流程及原理,分析VNC遠程桌面軟件存在的主要問題,并提出了對該程序進行優化改進的建議。

遠程桌面軟件的流程分為初始化握手階段以及正常交互階段兩部分。在正常交互階段中,遠程桌面軟件主要實現兩個功能,一個是遠端系統桌面圖像的顯示,另一個是本地端對遠端系統的控制。其中遠端系統桌面圖像的顯示又涉及到圖像消息的傳輸、屏幕變化的檢測與圖像消息的壓縮編碼這3個重要組成部分,對遠端系統的控制涉及到對鍵盤及鼠標事件的模擬輸入。

1 遠程桌面軟件工作流程

基于RFB協議的遠程桌面軟件工作流程分為兩個階段:初始化握手階段和正常交互階段。初始化握手階段主要進行客戶端連接服務器時的認證以及雙方協商服務器向客戶端發送圖像畫面消息時所采用的像素格式以及編碼方式。在正常交互階段中,服務器將根據初始化握手階段所協商的像素格式以及編碼方式,將圖像發送給客戶端,實現遠程畫面的顯示;同時客戶端將鼠標、鍵盤事件發送給服務器,實現對服務器的遠程控制。

1.1 初始化握手階段

初始化握手階段主要分為協商版本號、協商認證方法、雙方交換初始化消息、協商像素格式和編碼方式這4個步驟。

首先,服務器與客戶端雙方進行握手,服務器將其所能支持的最高RFB協議版本號發送給客戶端,客戶端回復其所要使用的版本號,其所使用的版本必須小于或者等于服務器的版本號,目前主流的協議版本主要有3.3、3.7和3.8。

接著雙方協商所要進行安全認證的方式,主要分為兩種:NONE與VNC認證,采用NONE方式則不需要驗證,采用VNC認證方式時,則使用挑戰/應答機制身份認證方法,服務器向客戶端發送一個16字節的隨機數,客戶端使用DES加密算法對其進行加密處理,秘鑰采用用戶的密碼,將加密后的結果發送給服務器,服務器使用自己保存的密碼以同樣的方法對隨機數進行處理,若處理得到的結果與客戶端發送過來的結果一致,則說明客戶端輸入了正確的密碼,此時服務器將認證成功的結果發送給客戶端,否則服務器則返回給客戶端認證失敗的結果。

雙方認證成功后,客戶端向服務器發送一個字節的客戶端初始化消息,該消息包含是否允許服務器共享屏幕的標志位,如果該標志位為真,則允許其它客戶端同時連入該服務器,否則只允許當前客戶端連接服務器。之后服務器向客戶端發送服務器初始化消息,其中含有服務器的各種配置信息,包括:幀緩存的寬度和高度、像素格式以及桌面相關的名稱。其中像素格式包含了每個像素需要的位數、像素值中有用的位數和是否為真彩色等相關參數,該像素格式為服務器原本的像素格式,并且在之后的發送圖像畫面消息中會沿用此格式,除非客戶端發送了設置像素格式消息,請求了另外一種像素格式。

客戶端如果要使用自己的像素格式,則向服務器發送設置像素格式消息,之后發送設置編碼格式的消息,該消息包括了客戶端所支持的所有編碼類型,先后次序按所期望使用的優先級進行排列,首位具有最高優先級,而后服務器對所使用的編碼類型進行選擇。在此之后,服務器與客戶端雙方便進入了正常的協議交互階段。

1.2 正常交互階段

在服務器與客戶端進行的正常交互過程中,客戶端不斷發送鼠標、鍵盤以及請求屏幕畫面更新的消息,服務器則不斷發送屏幕畫面更新的數據,從而實現遠程顯示畫面以及遠程操控的功能。

2 圖像傳輸方式

在VNC中,屏幕更新推送策略主要有兩種分別是客戶端主動拉取更新策略(Poll機制)和服務端主動推送的更新策略(Push機制)[2]。其中Push方式為服務器端每隔10 ms檢測是否有圖像的更新,若有則主動把更新的畫面推送到客戶端。而Poll方式則需要客戶端主動發送幀緩存更新請求消息來對服務器畫面的更新進行一個請求,服務器端收到該消息后,檢測屏幕畫面更新情況,若有更新,則向客戶端發送畫面的更新。VNC默認情況下采用惰性更新的Poll方式[3],因此其具有一定的自調節可適應性,根據客戶端的處理速度以及當前的網絡帶寬情況進行相應傳輸速率的調整,保證了遠程桌面不會因網絡的延遲等因素造成畫面更新錯誤的發生。

2.1 圖像消息的傳輸

當程序進入正常交互階段后,客戶端需要不斷發送幀緩存更新請求消息以獲取服務器的畫面更新。該消息包含消息的類型(默認為3)、是否為增量更新、所請求需要更新畫面左上角的(x,y)坐標以及畫面的寬高。在通常情況下客戶端所請求的為服務器端的全屏信息[3],因此該消息中所請求需要更新畫面左上角的(x,y)坐標默認為 (0,0),寬高默認為服務器畫面的寬高。增量更新代表著是否需要服務器發送客戶端所請求畫面的全部內容還是只需要發送變化的部分,因為通常情況下,客戶端都保留著服務器幀緩存的副本,服務器只需要每次發送變化部分的更新即可保持客戶端與服務器的同步。但是某些情況下客戶端會丟失某一區域的內容,那么它便需要服務器將該區域的全部內容發送過來,此時發送幀緩存更新請求消息時,需要將其中的增量更新標志位設為false。而在通常情況下,客戶端不會丟失任何內容,因此每次發送幀緩存更新請求消息時,都將其中的增量更新標志位設為true,服務器收到該消息后,會將其變化的內容發送給客戶端。

當服務器收到客戶端發送過來的幀緩存更新請求消息時,會記錄這一消息,同時調用PollingManager類的對象的函數進行屏幕變化的檢測,若檢測到屏幕自上一次發送更新之后,又產生了新的變化,則向客戶端發送幀緩存圖像更新消息,若畫面沒有任何變化則不發送。同時服務器有一個計時器,每隔30 ms也會對屏幕的變化進行一次檢測,若檢測到屏幕的變化,同時還有客戶端的更新請求未處理時,則會向客戶端發送最新的屏幕變化消息。該流程如圖1所示。

圖1 圖像更新流程

幀緩存更新圖像更新消息包含一系列像素數據矩形,客戶端接收這些消息并解碼,而后顯示在自己的幀緩存中。其格式如下:首先為屏幕圖像更新消息的頭部,其中包含了消息的類型(默認為0)、一字節的填充與所要發送的矩形塊的個數。接下來是所要發送的各個矩形塊的像素信息,包含了矩形塊像素信息的頭部和數據部分。其中頭部包含了矩形塊的左上角坐標、寬、高以及所使用的編碼方式。數據部分為所使用指定編碼方式進行編碼的圖像數據。

當客戶端收到服務器發送過來的幀緩存更新圖像更新消息之后,會將其解碼,得到需要進行更新的矩形塊的原始像素信息,根據像素信息填充到相應的坐標位置,便完成了一次屏幕圖像的更新。同時客戶端完成一次畫面更新后,會再次向服務器發送幀緩存更新請求消息對服務器進行畫面更新的請求,循環往復,這樣便實現了客戶端與服務器的同步顯示。

2.2 屏幕變化的檢測

在Windows操作系統中,屏幕的變化通常可以通過系統鉤子(Hook)來獲取[4],因為在windows系統中的應用程序是基于消息驅動的,所有的應用程序通過對各種消息做出響應進而實現各種功能,而桌面的改變同樣也會產生相應的消息,因此便可以通過系統鉤子獲取到屏幕的變化。

而在Linux中,RFB協議則基于幀緩存的掃描來實現屏幕變化的檢測,即通過新舊幀緩存的對比,找出屏幕變化的部分,具體實現方法如下:

首先對屏幕進行分塊,將屏幕分為一個個寬高均為32pixel的小塊,用m_changeFlags[]數組記錄改變標志位,即記錄哪一個小塊發生了變化,另外用一個數據結構保存舊的屏幕圖像。接下來便開始按照從上到下從左到右的順序,對每一個小塊分別進行掃描。對小塊的新舊圖像進行對比時,并不是對小塊的每一個像素點都進行比較,而是只選取了其中的某一個橫排(即32個像素點)作為代表,只掃描這一橫排,對比判定是否一致,若一致,則未發生變化,若不一致,則說明該小塊的圖像發生了改變,之后將相應的標志位置為true記錄這一改變,這樣便減少了比較的次數,極大地提高了程序的效率。而具體取哪一行作為小塊的代表,RFB協議的作者經過測試,得出了以下的順序:m_pollingOrder[32]={0,16,8,24,4,20,12,28,10,26,18,2,22,6,30,14,1,17,9,25,7,23,15,31,19,3,27,11,29,13,5,21}, 即當第一次掃描時,每一次只比較每個小塊第0行的數據,第二次比較時,則比較每個小塊第16行的數據,以此類推,如圖2所示。通過對每個小塊的掃描,便得到了屏幕變化的塊,服務器將這些變化的塊進行編碼發送,客戶端便得到了最新的畫面。

圖2 屏幕變化的檢測流程

2.3 圖像的壓縮編碼

當獲取到屏幕變化的圖像數據后,需要采取一定的壓縮編碼方法進行處理后傳輸;在客戶端展現圖像時,需用相應的算法對其進行譯碼便得到了服務器的圖像。而圖像的壓縮編碼方法是RFB協議的核心[5],關系著遠程桌面傳輸所占的帶寬以及畫面的質量。圖像的壓縮方法大體上分為如下兩類:①有損壓縮,即經過相應方法壓縮處理之后,無論采用何種算法進行譯碼處理,所獲得的圖像與原始的圖像相比總會產生一部分失真,因為其允許一些數據的流失,因此此種壓縮方法通常有著比較高的壓縮比率;②無損壓縮,經過壓縮處理后,采用一定的算法進行譯碼處理,得到的圖像與原始的圖像數據完全一致,不產生任何失真,還原度高,但由于其保留著所有的圖像數據,通常這類壓縮方法的壓縮比率會比較低[6]。目前RFB協議支持許多圖像壓縮處理方法,包含Raw編碼、CopyRect編碼、RRE編碼、CoRRE編碼、Hextile編碼、ZRLE編碼以及偽編碼等,下文將對其中幾種具有代表性的編碼進行簡單介紹。

2.3.1 Raw編碼

Raw編碼,即原始編碼,該編碼不進行任何的數據壓縮,保留原始的圖像數據。此方法在同等條件下傳輸所占用的帶寬最大,傳輸效率最低,但是因其不進行任何的編碼處理,所以對CPU處理的負荷比較小。所有RFB服務器都必須支持Raw編碼方式,通常情況下,如果客戶端不特別請求使用別的編碼方式,則服務器則默認使用Raw編碼方式進行處理。

Raw編碼的處理方法如下:對于要進行編碼處理的矩形圖像塊,從其左上角開始,從左到右,逐行對每一個像素點進行掃描,并按照其像素數據格式依次放入內存的編碼區域。假設像素的格式為32位真彩色,則一個像素占4個字節,若所要發送的矩形區域高為height、寬為width,則這個矩形區域采用Raw編碼所占總大小為4*height*width個字節。Raw編碼是最為簡單的一種編碼方式,在內存中編碼后的數據與矩形內的像素點一一對應,此編碼方法為其它編碼方法的設計基礎。

2.3.2 CopyRect編碼

CopyRect編碼,對于在客戶端緩存中已有某些相同的圖像數據區域,但是其位置發生改變的情況下十分有效,該編碼僅包含待更新圖像數據區域的坐標,客戶端將已有的圖像數據直接復制到指定坐標即完成了一次圖像的更新。也就是說,算法只需要在第一次將矩形的所有像素數據發送,而后在服務器端該矩形的位置可能發生變化,但其矩形內的像素內容并沒有發生改變,因此接下來只需要發送該矩形當前左上角的坐標即可完成客戶端畫面的更新。而對于矩形的第一次發送時所采用的編碼方式并沒有加以限定,所以該編碼方法可以和其它編碼方式結合使用,以達到更好的效果。該算法可以應用于許多種情形,其中最明顯的就是當用戶在屏幕上移動程序窗口的時候,采用該編碼方法會極大地減少帶寬的使用,提高傳輸效率。

2.3.3 RRE編碼

RRE編碼(rise-and-run-length encoding),正如它的名字所示,它的本質是RLE編碼(run-length encoding),為其在二維空間上的實現。該編碼的主要思想是將要傳送的圖像區域劃分為一些子塊,其中每個子塊的像素點顏色都一致,將這些子塊作為整體進行傳輸,可以極大程度上減少數據的重復表示。該編碼主要利用了圖像空間關聯的特性,也就是空間中相鄰像素的值通常一致或近似,因此該編碼方法在一些圖像較為簡單的情況下十分有效,在復雜的桌面環境下效果差強人意。

該編碼的具體方法如下:首先在所要發送的像素矩形中找到一個出現頻率最高的像素值Vb,將該像素值作為該矩形的背景色進行傳送。然后將矩形分為一個個顏色一致的子塊,子塊個數記為N,將子塊的個數發送給客戶端。接下來便要發送所有小子塊的像素信息,格式為 , 其中v代表子塊的像素值,并且v≠Vb, 也就是和背景色像素值不相同。(x,y)為子塊左上角的坐標,(w,h)分別為子塊的寬度和高度。在進行分塊處理時,該算法會分別對行與列都進行分塊,然后判斷這兩種分塊方法的壓縮率,選擇壓縮率高的分塊方法進行分塊并發送。在接收到服務器發送過來的該編碼消息后,客戶端首先將背景色填充到指定的區域,接下來再分別把每個子塊繪制到相應的位置即可完成圖像的傳遞工作。

2.3.4 Hextile編碼

Hextile編碼[7]為RRE編碼的變種,該編碼會將所要進行編碼處理的圖像細分為16*16的小塊,這樣可以壓縮控制參數所占的空間,可以僅僅用4 bits分別表示塊的長度或寬度,也就是說塊的左上角坐標(x,y)可以用一個字節來表示,塊的寬度及高度(w,h)也可以只用一個字節來表示。排列順序按照從左到右、從上到下依次進行編碼,若圖像的寬度非16的整數倍,則每行最右側的塊的寬度會進行相應地減少,同樣地如果高度非16的整數倍,每列最下側的塊的高度也會相應減少。

對于每一個小塊的圖像數據的編碼方式,可以采用Raw編碼,也可以采用RRE編碼的變種,該變種同樣要選擇出現頻率最高的像素顏色作為背景色,之后要將小塊再分成一系列的小矩形,其中小矩形中的每個像素都含有相同的顏色,然后便是將背景色與這些小矩形的數據發送即可。而與RRE編碼不同的是,其中的背景色與前景色可以不用明確地寫出,當不寫明時,便會沿用上一個小矩形所使用的數據信息,節省了數據空間,提高傳輸效率。

2.3.5 幾種編碼的測試

通過在Linux系統下使用VNC軟件,對幾種主流編碼方式所占用的帶寬進行測試后發現:當進行一些簡單操作并且圖像變化不大時,使用各種算法效果均令人滿意。但是當服務器的桌面分辨率較高,并且圖像快速變化時,則會出現畫面殘影現象,并且流暢度不夠高。使用Raw原始編碼雖然可以提高流暢度,但會顯著提高帶寬的消耗,經測試,使用Raw編碼在正常使用中平均占用帶寬10 Mb/s,若讓屏幕圖像快速變化,最高占用帶寬60 Mb/s。使用RRE等壓縮編碼雖然可以顯著降低帶寬,在實際使用中大約占用帶寬2 Mb/s,但是由于需要利用CPU對圖像編碼數據進行額外的處理,因此圖像的快速變化又會導致電腦的流暢度降低。

3 鼠標、鍵盤操作處理

3.1 鼠標消息的傳遞

客戶端不斷檢測鼠標的移動、按鍵的點擊與釋放等事件,當此類事件發生時,便會向服務器發送相應鼠標事件的消息,從而對服務器進行控制。鼠標消息的格式見表1。

表1 鼠標消息格式

鼠標消息的第一項為消息類型,這里默認值為5。接著是按鍵掩碼,由1字節表示,也就是8 bit,鼠標的每個按鈕分別對應其中的每一位,例如0號位為true代表著沒有任何按鍵被按下,1、2和3號位分別對應著鼠標的左中右鍵被按下,4號位表示鼠標滾輪往上滑,5號位表示鼠標滾輪往下滑。(x,y)坐標代表了當前鼠標所在的位置。

3.2 鍵盤消息的傳遞

同樣地,客戶端也要對鍵盤的事件進行監測,當監測到鍵盤按鍵的按下與釋放時,都要發送鍵盤的消息給服務器,其中鍵盤消息格式見表2。

表2 鍵盤消息格式

其中消息類型的值這里默認為4。當鍵盤上某一按鍵被按下時,按下標志位為true,釋放時為false。然后發送2字節的填充,之后發送鍵號。在X Window中按鍵被賦值為keysym(鍵號),對于大多數按鍵來說,比如abcd等等,它們的鍵號與ASCII碼是相對應的,而其它按鍵例如Delete、Insert等功能鍵則有另外的鍵號表示,具體參考Linux系統下的文件。

3.3 鼠標、鍵盤消息的處理

Linux輸入子系統是Linux內核用來管理各種輸入設備的,一般情況下,鼠標和鍵盤設備分別對應著/dev/input/event0和/dev/input/event1[8]。通過Input子系統可以實現對鼠標以及鍵盤操作的模擬,例如假設當前鍵盤設備為/dev/input/event1,可以向/dev/input/event1設備文件寫入一個字符“A”,這樣便相當于通過鍵盤按下了A鍵,模擬了鍵盤的操作。

基于此種方式,客戶端向服務器發送鼠標與鍵盤事件的消息后,服務器解析消息,并向相應的鼠標或鍵盤設備節點寫入數據,模擬服務器的鼠標或鍵盤操作,進而實現了客戶端對服務器的遠程操控。

4 展 望

基于RFB協議的遠程桌面程序工作流程分為兩個階段:初始化握手階段和正常交互階段。初始化握手階段分為協商版本號、協商認證方法、雙方交換初始化消息、協商像素格式和編碼方式這4個步驟。正常交互階段中,服務器通過將自己幀緩存中的內容發送給客戶端實現了畫面的同步顯示,同時采用了只傳輸變化的部分以及運用了多種編碼方式降低了畫面傳輸過程中的帶寬占用率。并且采用了Poll方式,屏幕的畫面刷新完全由客戶機驅動,通過客戶端不斷發送幀緩存請求消息來請求畫面的更新,收到該請求后服務器處理該消息并向客戶端發送畫面的更新,這樣使得VNC程序具有了相當的自適應性,其畫面更新的快慢取決于當前客戶端的處理能力以及當前的網絡質量,保證了傳輸的穩定性。同時客戶端將其鼠標與鍵盤的操作通過消息發送給服務器,服務器將其解析,并按照一定的格式向自己的鼠標或鍵盤設備節點寫入相應的數據,模擬服務器端鼠標或鍵盤的操作,實現了客戶端對服務器端的操控。

使用RFB協議的VNC程序,實現了遠程桌面同步顯示與控制的功能,針對目前國產化發展應用需求以及現狀,現有的VNC技術已經不能滿足應用需求,特別是在當前國產處理器性能較低的情況下,為了進一步提升VNC程序的性能,以滿足國產信息系統的新需求,筆者認為其下一步的改進優化重點在于:

(1)圖像壓縮編碼的優化:通過使用幾種主流的編碼方式進行圖像傳輸測試后發現:當進行一些簡單操作并且圖像變化不大時,使用各種算法效果均令人滿意。但是當服務器的桌面分辨率較高,并且圖像快速變化時,則會出現畫面殘影現象,并且流暢度不夠高。雖然隨著計算機技術的不斷進步,網速以及CPU處理速度會不斷提高,二者均會使遠程桌面軟件有著更好的體驗,但是依賴于硬件革新的同時,也需要對軟件進行不斷地優化,研究如何保證畫面質量的前提下進一步減少帶寬的占用,同時在圖像快速變化時保證畫面的流暢度,另外現階段國產平臺CPU處理速度與國外主流CPU相比還有著些許差距,因此對于畫面的傳輸,需要對其圖像的壓縮編碼方式進行進一步的研究優化,以達到更好的使用效果。

(2)安全性的提高:在VNC的連接認證中,采用了基于挑戰/應答機制身份認證的方法[9],比起傳統的靜態口令身份認證,增加了隨機數,通過隨機數的唯一性和多變性,增加了安全性,可以有效抵抗多種攻擊,但是其仍然存在著一些不足:例如服務器用于驗證身份的密碼保存在服務器中,雖然其采用了Des進行加密后存儲,但是通過對幾個VNC程序的源碼進行研究后發現,其所使用的Des加密秘鑰都為 {23,82,107,6,35,78,88,7}, 因此黑客可以入侵服務器獲取密碼的密文,并通過此秘鑰解密獲得密碼的明文,從而可以連接到服務器對服務器進行控制。另外在挑戰/應答機制中的挑戰隨機數在網絡中是以明文的形式發送的,無任何保護,易被黑客截取,而后可能采取離線密碼猜測攻擊獲得秘鑰的值[10]。同時RFB協議中服務器與客戶端正常交互的過程中,服務器畫面圖像的傳送以及鼠標鍵盤消息的傳送都為明文傳送,同樣易被不法分子截獲,還原圖像從而使服務器上的隱私一覽無余。因此為了提升國產信息系統安全性,助力國家安全,基于國產平臺的遠程桌面軟件需要使用更安全的認證手段,比如智能卡、數字證書、USB KEY、生物認證等多技術結合的多因素認證方法,同時對RFB協議的正常交互階段均采用密文形式發送。

5 結束語

針對基于RFB協議的Linux遠程桌面VNC程序,本文研究了其基本框架及流程,重點研究了圖像消息的傳輸、屏幕變化的檢測以及圖像的壓縮編碼方式,并對幾種編碼方式的效率進行了測試。最后針對目前國產化發展應用需求以及現狀,為了滿足全面國產信息系統的新需求,基于目前VNC所存在的問題,提出了更進一步的改進優化重點,包括圖像壓縮編碼的優化,以及安全性的提高,以實現基于國產平臺的安全遠程桌面軟件。

主站蜘蛛池模板: 久久伊人色| 在线观看无码a∨| 91久久精品日日躁夜夜躁欧美| 青青草欧美| 亚洲日韩精品综合在线一区二区| 国产精品视频系列专区| 亚洲an第二区国产精品| 香蕉网久久| 亚洲欧美激情小说另类| 色婷婷在线播放| 美女免费黄网站| 日韩国产综合精选| 真实国产精品vr专区| 亚洲福利网址| 亚洲IV视频免费在线光看| 综合五月天网| 真人高潮娇喘嗯啊在线观看| 91福利免费视频| 亚洲人成高清| 亚洲成人在线免费| 无码精品一区二区久久久| 久久婷婷国产综合尤物精品| 青青草91视频| 中国一级特黄视频| 成人国产精品2021| 成人免费午间影院在线观看| 亚洲日韩AV无码一区二区三区人| 99久久精品国产精品亚洲| 99999久久久久久亚洲| 色综合天天娱乐综合网| 18禁高潮出水呻吟娇喘蜜芽| 好吊色妇女免费视频免费| 国产成人亚洲精品蜜芽影院| 国产福利2021最新在线观看| 四虎亚洲国产成人久久精品| 国产女人18毛片水真多1| 久久青草免费91观看| 久久夜色精品| 国产成人精品一区二区| 9cao视频精品| 亚洲无码91视频| 2021国产乱人伦在线播放| 免费中文字幕在在线不卡| 99re视频在线| 欧美日韩国产精品va| 免费全部高H视频无码无遮掩| 国产成人乱无码视频| 97视频在线精品国自产拍| 亚洲免费播放| 欧美综合一区二区三区| 欧美日一级片| 青草午夜精品视频在线观看| 亚洲高清在线天堂精品| 午夜限制老子影院888| 666精品国产精品亚洲| 精品少妇人妻无码久久| 中字无码精油按摩中出视频| 久久永久免费人妻精品| 午夜啪啪福利| 99久久精品视香蕉蕉| 亚洲一区第一页| 亚洲成人动漫在线| 亚洲欧美日韩综合二区三区| 国产色伊人| 视频一区亚洲| 国产理论精品| 久久五月天国产自| 九九久久精品免费观看| 亚洲伦理一区二区| 99久久精品国产精品亚洲| 欧美成人午夜影院| 亚洲全网成人资源在线观看| 91麻豆国产视频| 国产欧美视频在线观看| 在线免费亚洲无码视频| 亚洲中文字幕国产av| 国产精品高清国产三级囯产AV| 久久综合亚洲色一区二区三区| 国产av剧情无码精品色午夜| 欧美精品一区在线看| 91精品福利自产拍在线观看| 亚洲无线一二三四区男男|