公交车上荫蒂添的好舒服的电影-公用玩物(np双xing总受)-公用小荡货芊芊-公与妇仑乱hd-攻把受做哭边走边肉楼梯play-古装一级淫片a免费播放口

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#構(gòu)建具有用戶認(rèn)證與管理的socks5代理服務(wù)端

freeflydom
2025年5月12日 9:31 本文熱度 109

Socks 協(xié)議是一種代理 (Proxy) 協(xié)議, 例如我們所熟知的 Shdowsocks 便是 Socks 協(xié)議的一個(gè)典型應(yīng)用程序, Socks 協(xié)議有多個(gè)版本, 目前最新的版本為 5, 其協(xié)議標(biāo)準(zhǔn)文檔為 RFC 1928。
我們一起來(lái)使用.net 7 構(gòu)建一個(gè)支持用戶管理的高性能socks5代理服務(wù)端。

協(xié)議流程

1 client -> server 客戶端與服務(wù)端握手
VERSIONMETHODS_COUNTMETHODS
1字節(jié)1字節(jié)1到255字節(jié),長(zhǎng)度zMETHODS_COUNT
0x050x030x00 0x01
0x02
  1. VERSION SOCKS協(xié)議版本,目前固定0x05
  2. METHODS_COUNT 客戶端支持的認(rèn)證方法數(shù)量
  3. METHODS 客戶端支持的認(rèn)證方法,每個(gè)方法占用1個(gè)字節(jié)

METHODS列表(其他的認(rèn)證方法可以自行上網(wǎng)了解)

  1. 0x00 不需要認(rèn)證(常用)
  2. 0x02 賬號(hào)密碼認(rèn)證(常用)
2.1 server -> client 無(wú)需認(rèn)證,直接進(jìn)入第3步,命令過(guò)程
VERSIONMETHOD
1字節(jié)1字節(jié)
0x050x00
2.2、server -> client 密碼認(rèn)證
VERSIONMETHOD
1字節(jié)1字節(jié)
0x050x02
2.2.1、client -> server 客戶端發(fā)送賬號(hào)密碼
VERSIONUSERNAME_LENGTHUSERNAMEPASSWORD_LENGTHPASSWORD
1字節(jié)1字節(jié)1到255字節(jié)1字節(jié)1到255字節(jié)
0x010x010x0a0x010x0a
  1. VERSION 認(rèn)證子協(xié)商版本(與SOCKS協(xié)議版本的0x05無(wú)關(guān)系)
  2. USERNAME_LENGTH 用戶名長(zhǎng)度
  3. USERNAME 用戶名字節(jié)數(shù)組,長(zhǎng)度為USERNAME_LENGTH
  4. PASSWORD_LENGTH 密碼長(zhǎng)度
  5. PASSWORD 密碼字節(jié)數(shù)組,長(zhǎng)度為PASSWORD_LENGTH
2.2.2、server -> client 返回認(rèn)證結(jié)果
VERSIONSTATUS
1字節(jié)1字節(jié)
0x010x00
  1. VERSION 認(rèn)證子協(xié)商版本
  2. STATUS 認(rèn)證結(jié)果,0x00認(rèn)證成功,大于0x00認(rèn)證失敗
3.1 client -> server 發(fā)送連接請(qǐng)求
VERSIONCOMMANDRSVADDRESS_TYPEDST.ADDRDST.PORT
1字節(jié)1字節(jié)1字節(jié)1字節(jié)1-255字節(jié)2字節(jié)
  1. VERSION SOCKS協(xié)議版本,固定0x05
  2. COMMAND 命令
    1. 0x01 CONNECT 連接上游服務(wù)器
    2. 0x02 BIND 綁定,客戶端會(huì)接收來(lái)自代理服務(wù)器的鏈接,著名的FTP被動(dòng)模式
    3. 0x03 UDP ASSOCIATE UDP中繼
  3. RSV 保留字段
  4. ADDRESS_TYPE 目標(biāo)服務(wù)器地址類(lèi)型
    1. 0x01 IP V4地址
    2. 0x03 域名地址(沒(méi)有打錯(cuò),就是沒(méi)有0x02),域名地址的第1個(gè)字節(jié)為域名長(zhǎng)度,剩下字節(jié)為域名名稱(chēng)字節(jié)數(shù)組
    3. 0x04 IP V6地址
  5. DST.ADDR 目標(biāo)服務(wù)器地址(如果COMMAND是0x03,即UDP模式,此處為客戶端啟動(dòng)UDP發(fā)送消息的主機(jī)地址)
  6. DST.PORT 目標(biāo)服務(wù)器端口(如果COMMAND是0x03,即UDP模式,此處為客戶端啟動(dòng)UDP發(fā)送消息的端口)
3.2 server -> client 服務(wù)端響應(yīng)連接結(jié)果
VERSIONRESPONSERSVADDRESS_TYPEDST.ADDRDST.PORT
1字節(jié)1字節(jié)1字節(jié)1字節(jié)1-255字節(jié)2字節(jié)
  1. VERSION SOCKS協(xié)議版本,固定0x05
  2. RESPONSE 響應(yīng)命令,除0x00外,其它響應(yīng)都應(yīng)該直接斷開(kāi)連接
    1. 0x00 代理服務(wù)器連接目標(biāo)服務(wù)器成功
    2. 0x01 代理服務(wù)器故障
    3. 0x02 代理服務(wù)器規(guī)則集不允許連接
    4. 0x03 網(wǎng)絡(luò)無(wú)法訪問(wèn)
    5. 0x04 目標(biāo)服務(wù)器無(wú)法訪問(wèn)(主機(jī)名無(wú)效)
    6. 0x05 連接目標(biāo)服務(wù)器被拒絕
    7. 0x06 TTL已過(guò)期
    8. 0x07 不支持的命令
    9. 0x08 不支持的目標(biāo)服務(wù)器地址類(lèi)型
    10. 0x09 - 0xFF 未分配
  3. RSV 保留字段
  4. BND.ADDR 代理服務(wù)器連接目標(biāo)服務(wù)器成功后的代理服務(wù)器IP
  5. BND.PORT 代理服務(wù)器連接目標(biāo)服務(wù)器成功后的代理服務(wù)器端口
4、數(shù)據(jù)轉(zhuǎn)發(fā)

第3步成功后,進(jìn)入數(shù)據(jù)轉(zhuǎn)發(fā)階段

  1. CONNECT 則將client過(guò)來(lái)的數(shù)據(jù)原樣轉(zhuǎn)發(fā)到目標(biāo),接著再將目標(biāo)回來(lái)的數(shù)據(jù)原樣返回給client
  2. BIND
  3. UDP ASSOCIATE
udp轉(zhuǎn)發(fā)的數(shù)據(jù)包
  1. 收到客戶端udp數(shù)據(jù)包后,解析出目標(biāo)地址,數(shù)據(jù),然后把數(shù)據(jù)發(fā)送過(guò)去
  2. 收到服務(wù)端回來(lái)的udp數(shù)據(jù)后,根據(jù)相同格式,打包,然后發(fā)回客戶端
RSVFRAGADDRESS_TYPEDST.ADDRDST.PORTDATA
2字節(jié)1字節(jié)1字節(jié)可變長(zhǎng)2字節(jié)可變長(zhǎng)
  1. RSV 保留為
  2. FRAG 分片位
  3. ATYP 地址類(lèi)型
    1. 0x01 IP V4地址
    2. 0x03 域名地址(沒(méi)有打錯(cuò),就是沒(méi)有0x02),域名地址的第1個(gè)字節(jié)為域名長(zhǎng)度,剩下字節(jié)為域名名稱(chēng)字節(jié)數(shù)組
    3. 0x04 IP V6地址
  4. DST.ADDR 目標(biāo)地址
  5. DST.PORT 目標(biāo)端口
  6. DATA 數(shù)據(jù)

狀態(tài)機(jī)控制每個(gè)連接狀態(tài)

從協(xié)議中我們可以看出,一個(gè)Socks5協(xié)議的連接需要經(jīng)過(guò)握手,認(rèn)證(可選),建立連接三個(gè)流程。那么這是典型的符合狀態(tài)機(jī)模型的業(yè)務(wù)流程。

創(chuàng)建狀態(tài)和事件枚舉

public enum ClientState
    {
        Normal,
        ToBeCertified,
        Certified,
        Connected,
        Death
    }
    public enum ClientStateEvents
    {
        OnRevAuthenticationNegotiation, //當(dāng)收到客戶端認(rèn)證協(xié)商
        OnRevClientProfile, //收到客戶端的認(rèn)證信息
        OnRevRequestProxy, //收到客戶端的命令請(qǐng)求請(qǐng)求代理
        OnException,
        OnDeath
    }

根據(jù)服務(wù)器是否配置需要用戶名密碼登錄,從而建立正確的狀態(tài)流程。

if (clientStatehandler.NeedAuth)
            {
                builder.In(ClientState.Normal)
                    .On(ClientStateEvents.OnRevAuthenticationNegotiation)
                    .Goto(ClientState.ToBeCertified)
                    .Execute<UserToken>(clientStatehandler.HandleAuthenticationNegotiationRequestAsync)
                    .On(ClientStateEvents.OnException)
                    .Goto(ClientState.Death);
            }
            else 
            {
                builder.In(ClientState.Normal)
                        .On(ClientStateEvents.OnRevAuthenticationNegotiation)
                        .Goto(ClientState.Certified)
                        .Execute<UserToken>(clientStatehandler.HandleAuthenticationNegotiationRequestAsync)
                        .On(ClientStateEvents.OnException)
                        .Goto(ClientState.Death);
            }
            builder.In(ClientState.ToBeCertified)
                .On(ClientStateEvents.OnRevClientProfile)
                .Goto(ClientState.Certified)
                .Execute<UserToken>(clientStatehandler.HandleClientProfileAsync)
                .On(ClientStateEvents.OnException)
                .Goto(ClientState.Death); ;
            builder.In(ClientState.Certified)
                .On(ClientStateEvents.OnRevRequestProxy)
                .Goto(ClientState.Connected)
                .Execute<UserToken>(clientStatehandler.HandleRequestProxyAsync)
                .On(ClientStateEvents.OnException)
                .Goto(ClientState.Death);
            builder.In(ClientState.Connected).On(ClientStateEvents.OnException).Goto(ClientState.Death);

在狀態(tài)扭轉(zhuǎn)中如果出現(xiàn)異常,則直接跳轉(zhuǎn)狀態(tài)到“Death”,

_machine.TransitionExceptionThrown += async (obj, e) =>
            {
                _logger.LogError(e.Exception.ToString());
                await _machine.Fire(ClientStateEvents.OnException);
            };

對(duì)應(yīng)狀態(tài)扭轉(zhuǎn)創(chuàng)建相應(yīng)的處理方法, 基本都是解析客戶端發(fā)來(lái)的數(shù)據(jù)包,判斷是否合理,最后返回一個(gè)響應(yīng)。

/// <summary>
        /// 處理認(rèn)證協(xié)商
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task HandleAuthenticationNegotiationRequestAsync(UserToken token)
        {
            if (token.ClientData.Length < 3)
            {
                await token.ClientSocket.SendAsync(new byte[] { 0x05, _exceptionCode });
                throw new ArgumentException("Error request format from client.");
            }
            if (token.ClientData.Span[0] != 0x05) //socks5默認(rèn)頭為5
            {
                await token.ClientSocket.SendAsync(new byte[] { 0x05, _exceptionCode });
                throw new ArgumentException("Error request format from client.");
            }
            int methodCount = token.ClientData.Span[1];
            if (token.ClientData.Length < 2 + methodCount) //校驗(yàn)報(bào)文
            {
                await token.ClientSocket.SendAsync(new byte[] { 0x05, _exceptionCode });
                throw new ArgumentException("Error request format from client.");
            }
            bool supprtAuth = false;
            for (int i = 0; i < methodCount; i++)
            {
                if (token.ClientData.Span[2 + i] == 0x02)
                {
                    supprtAuth = true;
                    break;
                }
            }
            if (_serverConfiguration.NeedAuth && !supprtAuth) //是否支持賬號(hào)密碼認(rèn)證
            {
                await token.ClientSocket.SendAsync(new byte[] { 0x05, _exceptionCode });
                throw new InvalidOperationException("Can't support password authentication!");
            }
            await token.ClientSocket.SendAsync(new byte[] { 0x05, (byte)(_serverConfiguration.NeedAuth ? 0x02 : 0x00) });
        }
        /// <summary>
        /// 接收到客戶端認(rèn)證
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task HandleClientProfileAsync(UserToken token)
        {
            var version = token.ClientData.Span[0];
            //if (version != _serverConfiguration.AuthVersion)
            //{
            //    await token.ClientSocket.SendAsync(new byte[] { 0x05, _exceptionCode });
            //    throw new ArgumentException("The certification version is inconsistent");
            //}
            var userNameLength = token.ClientData.Span[1];
            var passwordLength = token.ClientData.Span[2 + userNameLength];
            if (token.ClientData.Length < 3 + userNameLength + passwordLength)
            {
                await token.ClientSocket.SendAsync(new byte[] { 0x05, _exceptionCode });
                throw new ArgumentException("Error authentication format from client.");
            }
            var userName = Encoding.UTF8.GetString(token.ClientData.Span.Slice(2, userNameLength));
            var password = Encoding.UTF8.GetString(token.ClientData.Span.Slice(3 + userNameLength, passwordLength));
            var user = await _userService.FindSingleUserByUserNameAndPasswordAsync(userName, password);
            if (user == null || user.ExpireTime < DateTime.Now) 
            {
                await token.ClientSocket.SendAsync(new byte[] { version, _exceptionCode });
                throw new ArgumentException($"User{userName}嘗試非法登錄");
            }
            token.UserName = user.UserName;
            token.Password = user.Password;
            token.ExpireTime = user.ExpireTime;
            await token.ClientSocket.SendAsync(new byte[] { version, 0x00 });
        }
        /// <summary>
        /// 客戶端請(qǐng)求連接
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task HandleRequestProxyAsync(UserToken token)
        {
            var data = token.ClientData.Slice(3);
            Socks5CommandType socks5CommandType = (Socks5CommandType)token.ClientData.Span[1];
            var proxyInfo = _byteUtil.GetProxyInfo(data);
            var serverPort = BitConverter.GetBytes(_serverConfiguration.Port);
            if (socks5CommandType == Socks5CommandType.Connect) //tcp
            {
                //返回連接成功
                IPEndPoint targetEP = new IPEndPoint(proxyInfo.Item2, proxyInfo.Item3);//目標(biāo)服務(wù)器的終結(jié)點(diǎn)
                token.ServerSocket = new Socket(targetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                token.ServerSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
                var e = new SocketAsyncEventArgs
                {
                    RemoteEndPoint = new IPEndPoint(targetEP.Address, targetEP.Port)
                };
                token.ServerSocket.ConnectAsync(e);
                e.Completed += async (e, a) =>
                {
                    try
                    {
                        token.ServerBuffer = new byte[800 * 1024];//800kb
                        token.StartTcpProxy();
                        var datas = new List<byte> { 0x05, 0x0, 0, (byte)Socks5AddressType.IPV4 };
                        foreach (var add in (token.ServerSocket.LocalEndPoint as IPEndPoint).Address.GetAddressBytes())
                        {
                            datas.Add(add);
                        }
                        //代理端啟動(dòng)的端口信息回復(fù)給客戶端
                        datas.AddRange(BitConverter.GetBytes((token.ServerSocket.LocalEndPoint as IPEndPoint).Port).Take(2).Reverse());
                        await token.ClientSocket.SendAsync(datas.ToArray());
                    }
                    catch (Exception) 
                    {
                        token.Dispose();
                    }
                };
            }
            else if (socks5CommandType == Socks5CommandType.Udp)//udp
            {
                token.ClientUdpEndPoint = new IPEndPoint(proxyInfo.Item2, proxyInfo.Item3);//客戶端發(fā)起代理的udp終結(jié)點(diǎn)
                token.IsSupportUdp = true;
                token.ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                token.ServerSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
                token.ServerBuffer = new byte[800 * 1024];//800kb
                token.StartUdpProxy(_byteUtil);
                var addressBytes = (token.ServerSocket.LocalEndPoint as IPEndPoint).Address.GetAddressBytes();
                var portBytes = BitConverter.GetBytes((token.ServerSocket.LocalEndPoint as IPEndPoint).Port).Take(2).Reverse().ToArray();
                await token.ClientSocket.SendAsync(new byte[] { 0x05, 0x0, 0, (byte)Socks5AddressType.IPV4, addressBytes[0], addressBytes[1], addressBytes[2], addressBytes[3], portBytes[0], portBytes[1] });
            }
            else
            {
                await token.ClientSocket.SendAsync(new byte[] { 0x05, 0x1, 0, (byte)Socks5AddressType.IPV4, 0, 0, 0, 0, 0, 0 });
                throw new Exception("Unsupport proxy type.");
            }
        }

連接與用戶管理

當(dāng)服務(wù)器采用需要認(rèn)證的配置時(shí),我們會(huì)返回給客戶端0x02的認(rèn)證方式,此時(shí),客戶端需要上傳用戶名和密碼,如果認(rèn)證成功我們就可以將用戶信息與連接對(duì)象做綁定,方便后續(xù)管理。

在客戶端通過(guò)tcp或者udp上傳數(shù)據(jù)包,需要代理服務(wù)器轉(zhuǎn)發(fā)時(shí),我們記錄數(shù)據(jù)包的大小作為上傳數(shù)據(jù)包流量記錄下來(lái),反之亦然。
示例:記錄tcp代理客戶端的下載流量

public void StartTcpProxy()
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    var data = await ServerSocket.ReceiveAsync(ServerBuffer);
                    if (data == 0)
                    {
                        Dispose();
                    }
                    await ClientSocket.SendAsync(ServerBuffer.AsMemory(0, data));
                    if (!string.IsNullOrEmpty(UserName))
                        ExcuteAfterDownloadBytes?.Invoke(UserName, data);
                }
            }, CancellationTokenSource.Token);
        }

當(dāng)管理界面修改某用戶的密碼或者過(guò)期時(shí)間的時(shí)候
1.修改密碼,強(qiáng)制目前所有使用該用戶名密碼的連接斷開(kāi)
2.我們每個(gè)連接會(huì)有一個(gè)定時(shí)服務(wù),判斷是否過(guò)期
從而實(shí)現(xiàn)用戶下線。

//更新密碼或者過(guò)期時(shí)間后
public void UpdateUserPasswordAndExpireTime(string password, DateTime dateTime)
        {
            if (password != Password)
            {
                Dispose();
            }
            if (DateTime.Now > ExpireTime)
            {
                Dispose();
            }
        }
/// <summary>
        /// 過(guò)期自動(dòng)下線
        /// </summary>
        public void WhenExpireAutoOffline()
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    if (DateTime.Now > ExpireTime)
                    {
                        Dispose();
                    }
                    await Task.Delay(1000);
                }
            }, CancellationTokenSource.Token);
        }

持久化

用戶數(shù)據(jù)包括,用戶名密碼,使用流量,過(guò)期時(shí)間等存儲(chǔ)在server端的sqlite數(shù)據(jù)庫(kù)中。通過(guò)EFcore來(lái)增刪改查。
如下定期更新用戶流量到數(shù)據(jù)庫(kù)

private void LoopUpdateUserFlowrate()
        {
            Task.Run(async () =>
            {
                while (true)
                {
                    var datas = _uploadBytes.Select(x =>
                    {
                        return new
                        {
                            UserName = x.Key,
                            AddUploadBytes = x.Value,
                            AddDownloadBytes = _downloadBytes.ContainsKey(x.Key) ? _downloadBytes[x.Key] : 0
                        };
                    });
                    if (datas.Count() <= 0
                        || (datas.All(x => x.AddUploadBytes == 0)
                        && datas.All(x => x.AddDownloadBytes == 0)))
                    {
                        await Task.Delay(5000);
                        continue;
                    }
                    var users = await _userService.Value.GetUsersInNamesAsync(datas.Select(x => x.UserName));
                    foreach (var item in datas)
                    {
                        users.FirstOrDefault(x => x.UserName == item.UserName).UploadBytes += item.AddUploadBytes;
                        users.FirstOrDefault(x => x.UserName == item.UserName).DownloadBytes += item.AddDownloadBytes;
                    }
                    await _userService.Value.BatchUpdateUserAsync(users);
                    _uploadBytes.Clear();
                    _downloadBytes.Clear();
                    await Task.Delay(5000);
                }
            });
        }
//批量更新用戶信息到sqlite
        public async Task BatchUpdateUserFlowrateAsync(IEnumerable<User> users)
        {
            using (var context = _dbContextFactory.CreateDbContext())
            {
                context.Users.UpdateRange(users);
                await context.SaveChangesAsync();
            }
        }

效果示例

打開(kāi)服務(wù)

打開(kāi)Proxifier配置到我們的服務(wù)

查看Proxifier已經(jīng)流量走到我們的服務(wù)

服務(wù)端管理器

源碼以及如何使用

https://github.com/BruceQiu1996/Socks5Server

轉(zhuǎn)自https://www.cnblogs.com/qwqwQAQ/p/17410319.html

?


該文章在 2025/5/12 9:31:27 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 国产午夜福利一级福利短片 | 91天堂一区二区在线观看 | 动漫3d精品一区二区三区乱码 | 精品无码久久久久国产动漫3 | 成人无码电影一区二区三区 | 国产一区二区草草影 | 成人无码h免费动漫在线观看 | 国产动漫av一二三区 | 国产69无码一区 | 国产成人一区二区三区在线观看 | 国产成人一区二区三区影院动漫 | 国产免费无码午夜福利电影 | 国产一区二区三区精品欧 | 国产午夜a一级毛片 | 99国产午夜精品一区二区色戒 | 国产精品国产精品专区不卡 | 精品国产91久久久久久黄无码 | 白嫩一区二区在线视频 | 成人免费在线视频一区二区 | 国精产品一品二品国在线 | 成人播放日韩在线观看视频 | 2025国产精品极品在线 | 国产成人无码国产亚 | 成人无码精品1 | 国产成人手机高清在线观看网站 | 国产一区二区精品久久91 | 99久久夜色精品国产网站 | 91视频国产精品免费观看 | 国产精品丝袜无码不卡一区 | 高潮久久久久久久久不 | 国产午夜精品理论片 | 国产一区二区三区免费观看在线 | 韩国精品一区二区 | 国产精品日韩欧美在线第3页 | 囯产精品不卡无码av在线播放 | 成人精品视频在线观看 | 国产古装又黄a片在 | 国产精品无码卡 | 国产极品精品无码在线播出 | 国产91成人在在线播放 | heyzo专区无码综合久久 |