├── .gitignore ├── Cargo.toml ├── README.md ├── .github └── workflows │ ├── release.yml │ └── test.yml ├── src ├── main.rs ├── config.rs ├── proto.rs └── proxy.rs ├── tests └── integration.py ├── config.toml └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tunl-relay" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | tokio = { version = "1", features = ["full"] } 8 | clap = { version = "3.2", features = ["derive"] } 9 | serde = { version = "1.0", features = ["derive"] } 10 | bincode = "2.0.0-rc.3" 11 | anyhow = "1.0" 12 | pretty_env_logger = "0.5" 13 | log = "0.4" 14 | cidr = { version = "0.2", features = ["serde"] } 15 | toml = "0.8" 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tunl-relay 2 | 3 | ## Quick Start 4 | ```sh 5 | $ ./tunl-relay --config config.toml 6 | ``` 7 | 8 | ## Config 9 | ```toml 10 | version = "v1" 11 | bind = "0.0.0.0" 12 | port = 6666 13 | 14 | whitelist = [ 15 | "173.245.48.0/20", 16 | "103.21.244.0/22", 17 | "103.22.200.0/22", 18 | "103.31.4.0/22", 19 | ... 20 | ] 21 | 22 | # it blocks private networks by default 23 | # but you can add other ip addresses (such as torrent trackers) to the list 24 | blacklist = [ 25 | "93.158.213.92/32", 26 | ] 27 | ``` 28 | 29 | **protocol version**: v1 refers to [bepass-relay protocol](https://github.com/bepass-org/bepass-relay/) 30 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | permissions: 8 | contents: write 9 | packages: write 10 | 11 | jobs: 12 | build: 13 | name: build 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@master 17 | - name: Compile 18 | id: compile 19 | uses: rust-build/rust-build.action@v1.4.5 20 | env: 21 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 22 | with: 23 | RUSTTARGET: x86_64-unknown-linux-musl 24 | - name: Upload artifact 25 | uses: actions/upload-artifact@v3 26 | with: 27 | name: Binary 28 | path: | 29 | ${{ steps.compile.outputs.BUILT_ARCHIVE }} 30 | ${{ steps.compile.outputs.BUILT_CHECKSUM }} 31 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod config; 2 | mod proto; 3 | mod proxy; 4 | 5 | use config::Config; 6 | use proxy::Proxy; 7 | 8 | use anyhow::{anyhow, Result}; 9 | use clap::Parser; 10 | 11 | #[derive(Debug, Parser)] 12 | #[clap(author, version)] 13 | pub struct Args { 14 | #[clap(short, long)] 15 | pub config: String, 16 | } 17 | 18 | #[tokio::main] 19 | async fn main() -> Result<()> { 20 | pretty_env_logger::formatted_builder() 21 | .filter_level(log::LevelFilter::Info) 22 | .init(); 23 | 24 | let args = Args::parse(); 25 | 26 | let config = match std::fs::read_to_string(args.config) { 27 | Ok(c) => Config::new(&c), 28 | _ => panic!("could not find the config file"), 29 | }?; 30 | 31 | let proxy = Proxy::new(config); 32 | match proxy.run().await { 33 | Err(e) => Err(anyhow!("{e}")), 34 | _ => Ok(()), 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use crate::proto::Version; 2 | use cidr::IpCidr; 3 | 4 | use std::net::IpAddr; 5 | 6 | use anyhow::{anyhow, Result}; 7 | use serde::Deserialize; 8 | 9 | #[derive(Deserialize)] 10 | pub struct Config { 11 | pub bind: IpAddr, 12 | pub port: u16, 13 | pub version: Version, 14 | #[serde(default)] 15 | pub whitelist: Vec, 16 | #[serde(default)] 17 | pub blacklist: Vec, 18 | } 19 | 20 | impl Config { 21 | pub fn new(config: &str) -> Result { 22 | let mut config: Self = match toml::from_str(config) { 23 | Ok(c) => c, 24 | Err(e) => return Err(anyhow!("could not parse config file {}", e)), 25 | }; 26 | 27 | // block private networks by default 28 | let addrs: Vec = [ 29 | "127.0.0.0/8", 30 | "::1/128", 31 | "10.0.0.0/8", 32 | "172.16.0.0/12", 33 | "192.168.0.0/16", 34 | "fd00::/8", 35 | ] 36 | .iter() 37 | .map(|s| s.parse().unwrap()) 38 | .collect(); 39 | config.blacklist.extend_from_slice(&addrs); 40 | 41 | Ok(config) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: integration test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | integration-test: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout repository 17 | uses: actions/checkout@v3 18 | 19 | - name: preparatino 20 | run: | 21 | echo "build the program" 22 | cargo build && cp ./target/debug/tunl-relay . 23 | 24 | echo "prepare config" 25 | sed -i -e '/whitelist = \[/a\' -e ' "127.0.0.1",' config.toml 26 | sed -i -e '/whitelist = \[/a\' -e ' "216.239.38.120",' config.toml 27 | 28 | - name: test v1 header 29 | run: | 30 | ./tunl-relay --config config.toml & 31 | PID=$! 32 | echo "tunl-relay started with PID $PID" 33 | sleep 2 34 | 35 | python3 ./tests/integration.py Test.test_v1 36 | 37 | kill $PID 38 | echo "tunl-relay stopped with PID $PID" 39 | 40 | - name: test v2 header 41 | run: | 42 | echo "change config protocol version to v2" 43 | sed -i -e 's/"v1"/"v2"/' config.toml 44 | 45 | ./tunl-relay --config config.toml & 46 | PID=$! 47 | echo "tunl-relay started with PID $PID" 48 | sleep 2 49 | 50 | python3 ./tests/integration.py Test.test_v2 51 | 52 | kill $PID 53 | echo "tunl-relay stopped with PID $PID" 54 | -------------------------------------------------------------------------------- /tests/integration.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from socket import (socket, AF_INET, SOCK_STREAM) 3 | 4 | 5 | RESPONSE_CHUNK_SIZE = 4096 6 | 7 | 8 | class Proxy: 9 | def __init__(self, address, port): 10 | self.proxy = socket(AF_INET, SOCK_STREAM) 11 | self.proxy.connect((address, port)) 12 | 13 | def teardown(self): 14 | self.proxy.close() 15 | 16 | def send_v1_request(self): 17 | request = b'tcp@216.239.38.120$80\r\nGET / HTTP/1.1\r\nHost: google.com\r\nConnection: close\r\n\r\n' 18 | self.proxy.sendall(request) 19 | response = self.proxy.recv(RESPONSE_CHUNK_SIZE) 20 | return response.decode('utf-8') 21 | 22 | def send_v2_request(self): 23 | request = b'\x00\x0a\x01\x00\x00\xd8\xef\x26\x78\x50\r\nGET / HTTP/1.1\r\nHost: google.com\r\nConnection: close\r\n\r\n' 24 | self.proxy.sendall(request) 25 | response = self.proxy.recv(RESPONSE_CHUNK_SIZE) 26 | return response.decode('utf-8') 27 | 28 | 29 | class Test(unittest.TestCase): 30 | @classmethod 31 | def setUpClass(cls): 32 | cls.proxy = Proxy('127.0.0.1', 6666) 33 | 34 | @classmethod 35 | def tearDownClass(cls): 36 | cls.proxy.teardown() 37 | 38 | def test_v1(self): 39 | response = self.proxy.send_v1_request() 40 | status = response[:30] 41 | self.assertEqual(status, 'HTTP/1.1 301 Moved Permanently') 42 | 43 | def test_v2(self): 44 | response = self.proxy.send_v2_request() 45 | status = response[:30] 46 | self.assertEqual(status, 'HTTP/1.1 301 Moved Permanently') 47 | 48 | 49 | if __name__ == '__main__': 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /src/proto.rs: -------------------------------------------------------------------------------- 1 | use std::net::IpAddr; 2 | use std::str::FromStr; 3 | 4 | use bincode::{Decode, Encode}; 5 | use serde::{Deserialize, Serialize}; 6 | use tokio::io::{Error, ErrorKind, Result}; 7 | 8 | #[derive(clap::ValueEnum, Clone, Default, Debug, Decode, Encode, Serialize, Deserialize)] 9 | #[serde(rename_all = "lowercase")] 10 | pub enum Version { 11 | #[default] 12 | V1, 13 | V2, 14 | } 15 | 16 | #[derive(Debug, Decode, Encode)] 17 | pub enum Network { 18 | Tcp, 19 | Udp, 20 | } 21 | 22 | #[derive(Debug, Decode, Encode)] 23 | pub struct Header { 24 | pub ver: Version, 25 | pub net: Network, 26 | pub addr: IpAddr, 27 | pub port: u16, 28 | } 29 | 30 | impl Header { 31 | pub fn from_v2(buf: &[u8]) -> Result { 32 | let (decoded, _) = bincode::decode_from_slice(&buf, bincode::config::standard()) 33 | .map_err(|_| Error::new(ErrorKind::Other, "invalid header format"))?; 34 | Ok(decoded) 35 | } 36 | 37 | pub fn from_v1(buf: &[u8]) -> Result { 38 | let d1 = buf.iter().position(|&x| x == b'@').ok_or(Error::new( 39 | ErrorKind::Other, 40 | "could not find @ in the header", 41 | ))?; 42 | let d2 = buf.iter().position(|&x| x == b'$').ok_or(Error::new( 43 | ErrorKind::Other, 44 | "could not find $ in the header", 45 | ))?; 46 | 47 | let net = match &buf[..d1] { 48 | b"tcp" => Network::Tcp, 49 | _ => Network::Udp, 50 | }; 51 | 52 | let addr = { 53 | let ip = String::from_utf8_lossy(&buf[d1 + 1..d2]); 54 | IpAddr::from_str(&ip).map_err(|_| Error::new(ErrorKind::Other, "invalid ip address")) 55 | }?; 56 | 57 | let port = { 58 | let p = String::from_utf8_lossy(&buf[d2 + 1..buf.len() - 1]); 59 | p.parse::() 60 | .map_err(|_| Error::new(ErrorKind::Other, "invalid port number")) 61 | }?; 62 | 63 | let ver = Version::V1; 64 | 65 | Ok(Self { 66 | net, 67 | addr, 68 | port, 69 | ver, 70 | }) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | version = "v1" 2 | bind = "0.0.0.0" 3 | port = 6666 4 | 5 | whitelist = [ 6 | "173.245.48.0/20", 7 | "103.21.244.0/22", 8 | "103.22.200.0/22", 9 | "103.31.4.0/22", 10 | "104.16.0.0/12", 11 | "141.101.64.0/18", 12 | "108.162.192.0/18", 13 | "190.93.240.0/20", 14 | "188.114.96.0/20", 15 | "197.234.240.0/22", 16 | "198.41.128.0/17", 17 | "162.158.0.0/15", 18 | "104.16.0.0/13", 19 | "104.24.0.0/14", 20 | "172.64.0.0/13", 21 | "131.0.72.0/22", 22 | "2400:cb00::/32", 23 | "2606:4700::/32", 24 | "2803:f800::/32", 25 | "2405:b500::/32", 26 | "2405:8100::/32", 27 | "2a06:98c0::/29", 28 | "2c0f:f248::/32", 29 | "2c0f:f248::/32" 30 | ] 31 | 32 | blacklist = [ 33 | "93.158.213.92/32", 34 | "102.223.180.235/32", 35 | "23.134.88.6/32", 36 | "185.243.218.213/32", 37 | "208.83.20.20/32", 38 | "91.216.110.52/32", 39 | "83.146.97.90/32", 40 | "23.157.120.14/32", 41 | "185.102.219.163/32", 42 | "163.172.29.130/32", 43 | "156.234.201.18/32", 44 | "209.141.59.16/32", 45 | "34.94.213.23/32", 46 | "192.3.165.191/32", 47 | "130.61.55.93/32", 48 | "109.201.134.183/32", 49 | "95.31.11.224/32", 50 | "83.102.180.21/32", 51 | "192.95.46.115/32", 52 | "198.100.149.66/32", 53 | "95.216.74.39/32", 54 | "51.68.174.87/32", 55 | "37.187.111.136/32", 56 | "51.15.79.209/32", 57 | "45.92.156.182/32", 58 | "49.12.76.8/32", 59 | "5.196.89.204/32", 60 | "62.233.57.13/32", 61 | "45.9.60.30/32", 62 | "35.227.12.84/32", 63 | "179.43.155.30/32", 64 | "94.243.222.100/32", 65 | "207.241.231.226/32", 66 | "207.241.226.111/32", 67 | "51.159.54.68/32", 68 | "82.65.115.10/32", 69 | "95.217.167.10/32", 70 | "86.57.161.157/32", 71 | "83.31.30.230/32", 72 | "94.103.87.87/32", 73 | "160.119.252.41/32", 74 | "193.42.111.57/32", 75 | "80.240.22.46/32", 76 | "107.189.31.134/32", 77 | "104.244.79.114/32", 78 | "85.239.33.28/32", 79 | "61.222.178.254/32", 80 | "38.7.201.142/32", 81 | "51.81.222.188/32", 82 | "103.196.36.31/32", 83 | "23.153.248.2/32", 84 | "73.170.204.100/32", 85 | "176.31.250.174/32", 86 | "149.56.179.233/32", 87 | "212.237.53.230/32", 88 | "185.68.21.244/32", 89 | "82.156.24.219/32", 90 | "216.201.9.155/32", 91 | "51.15.41.46/32", 92 | "85.206.172.159/32", 93 | "104.244.77.87/32", 94 | "37.27.4.53/32", 95 | "192.3.165.198/32", 96 | "15.204.205.14/32", 97 | "103.122.21.50/32", 98 | "104.131.98.232/32", 99 | "173.249.201.201/32", 100 | "23.254.228.89/32", 101 | "5.102.159.190/32", 102 | "65.130.205.148/32", 103 | "119.28.71.45/32", 104 | "159.69.65.157/32", 105 | "160.251.78.190/32", 106 | "107.189.7.143/32", 107 | "159.65.224.91/32", 108 | "185.217.199.21/32", 109 | "91.224.92.110/32", 110 | "161.97.67.210/32", 111 | "51.15.3.74/32", 112 | "209.126.11.233/32", 113 | "37.187.95.112/32", 114 | "167.99.185.219/32", 115 | "144.91.88.22/32", 116 | "88.99.2.212/32", 117 | "37.59.48.81/32", 118 | "95.179.130.187/32", 119 | "51.15.26.25/32", 120 | "192.9.228.30/32" 121 | ] 122 | -------------------------------------------------------------------------------- /src/proxy.rs: -------------------------------------------------------------------------------- 1 | use std::net::IpAddr; 2 | use std::sync::Arc; 3 | 4 | use crate::config::Config; 5 | use crate::proto::*; 6 | 7 | use tokio::{ 8 | io::{self, copy_bidirectional, AsyncReadExt, AsyncWriteExt, BufReader, Error, ErrorKind}, 9 | net::{TcpListener, TcpStream}, 10 | }; 11 | 12 | pub struct Proxy { 13 | config: Arc, 14 | } 15 | 16 | impl Proxy { 17 | pub fn new(config: Config) -> Self { 18 | Self { 19 | config: Arc::new(config), 20 | } 21 | } 22 | 23 | pub async fn run(&self) -> io::Result<()> { 24 | let addr = format!("{}:{}", self.config.bind, self.config.port); 25 | 26 | let l = TcpListener::bind(&addr).await?; 27 | log::info!("Listening {}", &addr); 28 | 29 | loop { 30 | match self.listener(&l).await { 31 | Err(e) => log::error!("[listener]: {e}"), 32 | _ => {} 33 | }; 34 | } 35 | } 36 | 37 | async fn listener(&self, l: &TcpListener) -> io::Result<()> { 38 | let (mut stream, client_addr) = l.accept().await?; 39 | 40 | if !self 41 | .config 42 | .whitelist 43 | .iter() 44 | .any(|cidr| cidr.contains(&client_addr.ip())) 45 | { 46 | return Err(Error::new( 47 | ErrorKind::Other, 48 | format!("[blocked] source {client_addr} is not in the whitelist"), 49 | )); 50 | } 51 | 52 | let header = match &self.config.version { 53 | Version::V1 => { 54 | let mut buf = vec![]; 55 | 56 | // here we're sure the header length is at least 13 bytes 57 | let mut chunk = [0u8; 13]; 58 | stream.read_exact(&mut chunk).await?; 59 | buf.extend_from_slice(&chunk); 60 | 61 | let mut upper = 30; // 30 bytes are enough to see if we're 62 | // reading a valid header or not 63 | // continue reading the header until reach '\n' 64 | loop { 65 | if upper == 0 { 66 | return Err(Error::new(ErrorKind::Other, "invalid header")); 67 | } 68 | 69 | let b = stream.read_u8().await?; 70 | if b == b'\n' { 71 | break; 72 | } 73 | 74 | buf.push(b); 75 | upper -= 1; 76 | } 77 | 78 | Header::from_v1(&buf)? 79 | } 80 | Version::V2 => { 81 | let mut len = [0u8; 2]; 82 | stream.read(&mut len).await?; 83 | 84 | let mut buf = vec![0u8; u16::from_be_bytes(len) as _]; 85 | stream.read(&mut buf).await?; 86 | 87 | Header::from_v2(&buf)? 88 | } 89 | }; 90 | 91 | log::info!( 92 | "accepted [{:?}] {}:{}", 93 | header.net, 94 | header.addr, 95 | header.port 96 | ); 97 | tokio::spawn(handler(self.config.clone(), header, stream)); 98 | 99 | Ok(()) 100 | } 101 | } 102 | 103 | async fn handler(config: Arc, header: Header, stream: TcpStream) { 104 | // block blacklisted ip addresses 105 | if config 106 | .blacklist 107 | .iter() 108 | .any(|cidr| cidr.contains(&header.addr)) 109 | { 110 | log::error!( 111 | "[blocked] destination {}:{} is in the blacklist", 112 | header.addr, 113 | header.port 114 | ); 115 | return; 116 | } 117 | 118 | if let Err(e) = match header.net { 119 | Network::Tcp => { 120 | if !config 121 | .whitelist 122 | .iter() 123 | .any(|cidr| cidr.contains(&header.addr)) 124 | { 125 | log::error!( 126 | "[blocked] destination {}:{} is not in the whitelist", 127 | header.addr, 128 | header.port, 129 | ); 130 | return; 131 | } 132 | tcp_handler(stream, header.addr, header.port).await 133 | } 134 | Network::Udp => udp_handler(stream, header.addr, header.port).await, 135 | } { 136 | log::error!("error {e}"); 137 | } 138 | } 139 | 140 | async fn tcp_handler(mut stream: TcpStream, addr: IpAddr, port: u16) -> io::Result<()> { 141 | let mut upstream = TcpStream::connect(format!("{addr}:{port}")).await?; 142 | copy_bidirectional(&mut stream, &mut upstream).await?; 143 | 144 | Ok(()) 145 | } 146 | 147 | async fn udp_handler(mut stream: TcpStream, addr: IpAddr, port: u16) -> io::Result<()> { 148 | let (reader, mut writer) = stream.split(); 149 | let mut reader = BufReader::new(reader); 150 | 151 | let udp_stream = tokio::net::UdpSocket::bind("0.0.0.0:0").await?; 152 | udp_stream.connect(format!("{addr}:{port}")).await?; 153 | 154 | let mut tcp_buf = [0u8; 65535]; 155 | let mut udp_buf = [0u8; 65535]; 156 | 157 | loop { 158 | tokio::select! { 159 | result = reader.read(&mut tcp_buf) => { 160 | let n = result?; 161 | if n == 0 { 162 | break; 163 | } 164 | udp_stream.send(&tcp_buf[..n]).await?; 165 | } 166 | 167 | result = udp_stream.recv(&mut udp_buf) => { 168 | let n = result?; 169 | writer.write_all(&udp_buf[..n]).await?; 170 | } 171 | } 172 | } 173 | 174 | Ok(()) 175 | } 176 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.22.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anyhow" 31 | version = "1.0.86" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 34 | 35 | [[package]] 36 | name = "atty" 37 | version = "0.2.14" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 40 | dependencies = [ 41 | "hermit-abi 0.1.19", 42 | "libc", 43 | "winapi", 44 | ] 45 | 46 | [[package]] 47 | name = "autocfg" 48 | version = "1.3.0" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 51 | 52 | [[package]] 53 | name = "backtrace" 54 | version = "0.3.73" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" 57 | dependencies = [ 58 | "addr2line", 59 | "cc", 60 | "cfg-if", 61 | "libc", 62 | "miniz_oxide", 63 | "object", 64 | "rustc-demangle", 65 | ] 66 | 67 | [[package]] 68 | name = "bincode" 69 | version = "2.0.0-rc.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" 72 | dependencies = [ 73 | "bincode_derive", 74 | "serde", 75 | ] 76 | 77 | [[package]] 78 | name = "bincode_derive" 79 | version = "2.0.0-rc.3" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "7e30759b3b99a1b802a7a3aa21c85c3ded5c28e1c83170d82d70f08bbf7f3e4c" 82 | dependencies = [ 83 | "virtue", 84 | ] 85 | 86 | [[package]] 87 | name = "bitflags" 88 | version = "1.3.2" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 91 | 92 | [[package]] 93 | name = "bitflags" 94 | version = "2.5.0" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 97 | 98 | [[package]] 99 | name = "bytes" 100 | version = "1.6.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 103 | 104 | [[package]] 105 | name = "cc" 106 | version = "1.0.99" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" 109 | 110 | [[package]] 111 | name = "cfg-if" 112 | version = "1.0.0" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 115 | 116 | [[package]] 117 | name = "cidr" 118 | version = "0.2.3" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "6bdf600c45bd958cf2945c445264471cca8b6c8e67bc87b71affd6d7e5682621" 121 | dependencies = [ 122 | "serde", 123 | ] 124 | 125 | [[package]] 126 | name = "clap" 127 | version = "3.2.25" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" 130 | dependencies = [ 131 | "atty", 132 | "bitflags 1.3.2", 133 | "clap_derive", 134 | "clap_lex", 135 | "indexmap 1.9.3", 136 | "once_cell", 137 | "strsim", 138 | "termcolor", 139 | "textwrap", 140 | ] 141 | 142 | [[package]] 143 | name = "clap_derive" 144 | version = "3.2.25" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" 147 | dependencies = [ 148 | "heck", 149 | "proc-macro-error", 150 | "proc-macro2", 151 | "quote", 152 | "syn 1.0.109", 153 | ] 154 | 155 | [[package]] 156 | name = "clap_lex" 157 | version = "0.2.4" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" 160 | dependencies = [ 161 | "os_str_bytes", 162 | ] 163 | 164 | [[package]] 165 | name = "env_logger" 166 | version = "0.10.2" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" 169 | dependencies = [ 170 | "humantime", 171 | "is-terminal", 172 | "log", 173 | "regex", 174 | "termcolor", 175 | ] 176 | 177 | [[package]] 178 | name = "equivalent" 179 | version = "1.0.1" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 182 | 183 | [[package]] 184 | name = "gimli" 185 | version = "0.29.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" 188 | 189 | [[package]] 190 | name = "hashbrown" 191 | version = "0.12.3" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 194 | 195 | [[package]] 196 | name = "hashbrown" 197 | version = "0.14.5" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 200 | 201 | [[package]] 202 | name = "heck" 203 | version = "0.4.1" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 206 | 207 | [[package]] 208 | name = "hermit-abi" 209 | version = "0.1.19" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 212 | dependencies = [ 213 | "libc", 214 | ] 215 | 216 | [[package]] 217 | name = "hermit-abi" 218 | version = "0.3.9" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 221 | 222 | [[package]] 223 | name = "humantime" 224 | version = "2.1.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 227 | 228 | [[package]] 229 | name = "indexmap" 230 | version = "1.9.3" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 233 | dependencies = [ 234 | "autocfg", 235 | "hashbrown 0.12.3", 236 | ] 237 | 238 | [[package]] 239 | name = "indexmap" 240 | version = "2.2.6" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 243 | dependencies = [ 244 | "equivalent", 245 | "hashbrown 0.14.5", 246 | ] 247 | 248 | [[package]] 249 | name = "is-terminal" 250 | version = "0.4.12" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" 253 | dependencies = [ 254 | "hermit-abi 0.3.9", 255 | "libc", 256 | "windows-sys 0.52.0", 257 | ] 258 | 259 | [[package]] 260 | name = "libc" 261 | version = "0.2.155" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 264 | 265 | [[package]] 266 | name = "lock_api" 267 | version = "0.4.12" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 270 | dependencies = [ 271 | "autocfg", 272 | "scopeguard", 273 | ] 274 | 275 | [[package]] 276 | name = "log" 277 | version = "0.4.21" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 280 | 281 | [[package]] 282 | name = "memchr" 283 | version = "2.7.4" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 286 | 287 | [[package]] 288 | name = "miniz_oxide" 289 | version = "0.7.4" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" 292 | dependencies = [ 293 | "adler", 294 | ] 295 | 296 | [[package]] 297 | name = "mio" 298 | version = "0.8.11" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 301 | dependencies = [ 302 | "libc", 303 | "wasi", 304 | "windows-sys 0.48.0", 305 | ] 306 | 307 | [[package]] 308 | name = "num_cpus" 309 | version = "1.16.0" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 312 | dependencies = [ 313 | "hermit-abi 0.3.9", 314 | "libc", 315 | ] 316 | 317 | [[package]] 318 | name = "object" 319 | version = "0.36.0" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" 322 | dependencies = [ 323 | "memchr", 324 | ] 325 | 326 | [[package]] 327 | name = "once_cell" 328 | version = "1.19.0" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 331 | 332 | [[package]] 333 | name = "os_str_bytes" 334 | version = "6.6.1" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" 337 | 338 | [[package]] 339 | name = "parking_lot" 340 | version = "0.12.3" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 343 | dependencies = [ 344 | "lock_api", 345 | "parking_lot_core", 346 | ] 347 | 348 | [[package]] 349 | name = "parking_lot_core" 350 | version = "0.9.10" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 353 | dependencies = [ 354 | "cfg-if", 355 | "libc", 356 | "redox_syscall", 357 | "smallvec", 358 | "windows-targets 0.52.5", 359 | ] 360 | 361 | [[package]] 362 | name = "pin-project-lite" 363 | version = "0.2.14" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 366 | 367 | [[package]] 368 | name = "pretty_env_logger" 369 | version = "0.5.0" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" 372 | dependencies = [ 373 | "env_logger", 374 | "log", 375 | ] 376 | 377 | [[package]] 378 | name = "proc-macro-error" 379 | version = "1.0.4" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 382 | dependencies = [ 383 | "proc-macro-error-attr", 384 | "proc-macro2", 385 | "quote", 386 | "syn 1.0.109", 387 | "version_check", 388 | ] 389 | 390 | [[package]] 391 | name = "proc-macro-error-attr" 392 | version = "1.0.4" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 395 | dependencies = [ 396 | "proc-macro2", 397 | "quote", 398 | "version_check", 399 | ] 400 | 401 | [[package]] 402 | name = "proc-macro2" 403 | version = "1.0.85" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" 406 | dependencies = [ 407 | "unicode-ident", 408 | ] 409 | 410 | [[package]] 411 | name = "quote" 412 | version = "1.0.36" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 415 | dependencies = [ 416 | "proc-macro2", 417 | ] 418 | 419 | [[package]] 420 | name = "redox_syscall" 421 | version = "0.5.2" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" 424 | dependencies = [ 425 | "bitflags 2.5.0", 426 | ] 427 | 428 | [[package]] 429 | name = "regex" 430 | version = "1.10.5" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" 433 | dependencies = [ 434 | "aho-corasick", 435 | "memchr", 436 | "regex-automata", 437 | "regex-syntax", 438 | ] 439 | 440 | [[package]] 441 | name = "regex-automata" 442 | version = "0.4.7" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 445 | dependencies = [ 446 | "aho-corasick", 447 | "memchr", 448 | "regex-syntax", 449 | ] 450 | 451 | [[package]] 452 | name = "regex-syntax" 453 | version = "0.8.4" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 456 | 457 | [[package]] 458 | name = "rustc-demangle" 459 | version = "0.1.24" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 462 | 463 | [[package]] 464 | name = "scopeguard" 465 | version = "1.2.0" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 468 | 469 | [[package]] 470 | name = "serde" 471 | version = "1.0.203" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" 474 | dependencies = [ 475 | "serde_derive", 476 | ] 477 | 478 | [[package]] 479 | name = "serde_derive" 480 | version = "1.0.203" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" 483 | dependencies = [ 484 | "proc-macro2", 485 | "quote", 486 | "syn 2.0.66", 487 | ] 488 | 489 | [[package]] 490 | name = "serde_spanned" 491 | version = "0.6.6" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" 494 | dependencies = [ 495 | "serde", 496 | ] 497 | 498 | [[package]] 499 | name = "signal-hook-registry" 500 | version = "1.4.2" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 503 | dependencies = [ 504 | "libc", 505 | ] 506 | 507 | [[package]] 508 | name = "smallvec" 509 | version = "1.13.2" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 512 | 513 | [[package]] 514 | name = "socket2" 515 | version = "0.5.7" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 518 | dependencies = [ 519 | "libc", 520 | "windows-sys 0.52.0", 521 | ] 522 | 523 | [[package]] 524 | name = "strsim" 525 | version = "0.10.0" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 528 | 529 | [[package]] 530 | name = "syn" 531 | version = "1.0.109" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 534 | dependencies = [ 535 | "proc-macro2", 536 | "quote", 537 | "unicode-ident", 538 | ] 539 | 540 | [[package]] 541 | name = "syn" 542 | version = "2.0.66" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" 545 | dependencies = [ 546 | "proc-macro2", 547 | "quote", 548 | "unicode-ident", 549 | ] 550 | 551 | [[package]] 552 | name = "termcolor" 553 | version = "1.4.1" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 556 | dependencies = [ 557 | "winapi-util", 558 | ] 559 | 560 | [[package]] 561 | name = "textwrap" 562 | version = "0.16.1" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" 565 | 566 | [[package]] 567 | name = "tokio" 568 | version = "1.38.0" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" 571 | dependencies = [ 572 | "backtrace", 573 | "bytes", 574 | "libc", 575 | "mio", 576 | "num_cpus", 577 | "parking_lot", 578 | "pin-project-lite", 579 | "signal-hook-registry", 580 | "socket2", 581 | "tokio-macros", 582 | "windows-sys 0.48.0", 583 | ] 584 | 585 | [[package]] 586 | name = "tokio-macros" 587 | version = "2.3.0" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" 590 | dependencies = [ 591 | "proc-macro2", 592 | "quote", 593 | "syn 2.0.66", 594 | ] 595 | 596 | [[package]] 597 | name = "toml" 598 | version = "0.8.14" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" 601 | dependencies = [ 602 | "serde", 603 | "serde_spanned", 604 | "toml_datetime", 605 | "toml_edit", 606 | ] 607 | 608 | [[package]] 609 | name = "toml_datetime" 610 | version = "0.6.6" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" 613 | dependencies = [ 614 | "serde", 615 | ] 616 | 617 | [[package]] 618 | name = "toml_edit" 619 | version = "0.22.14" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" 622 | dependencies = [ 623 | "indexmap 2.2.6", 624 | "serde", 625 | "serde_spanned", 626 | "toml_datetime", 627 | "winnow", 628 | ] 629 | 630 | [[package]] 631 | name = "tunl-relay" 632 | version = "0.1.0" 633 | dependencies = [ 634 | "anyhow", 635 | "bincode", 636 | "cidr", 637 | "clap", 638 | "log", 639 | "pretty_env_logger", 640 | "serde", 641 | "tokio", 642 | "toml", 643 | ] 644 | 645 | [[package]] 646 | name = "unicode-ident" 647 | version = "1.0.12" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 650 | 651 | [[package]] 652 | name = "version_check" 653 | version = "0.9.4" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 656 | 657 | [[package]] 658 | name = "virtue" 659 | version = "0.0.13" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" 662 | 663 | [[package]] 664 | name = "wasi" 665 | version = "0.11.0+wasi-snapshot-preview1" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 668 | 669 | [[package]] 670 | name = "winapi" 671 | version = "0.3.9" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 674 | dependencies = [ 675 | "winapi-i686-pc-windows-gnu", 676 | "winapi-x86_64-pc-windows-gnu", 677 | ] 678 | 679 | [[package]] 680 | name = "winapi-i686-pc-windows-gnu" 681 | version = "0.4.0" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 684 | 685 | [[package]] 686 | name = "winapi-util" 687 | version = "0.1.8" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" 690 | dependencies = [ 691 | "windows-sys 0.52.0", 692 | ] 693 | 694 | [[package]] 695 | name = "winapi-x86_64-pc-windows-gnu" 696 | version = "0.4.0" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 699 | 700 | [[package]] 701 | name = "windows-sys" 702 | version = "0.48.0" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 705 | dependencies = [ 706 | "windows-targets 0.48.5", 707 | ] 708 | 709 | [[package]] 710 | name = "windows-sys" 711 | version = "0.52.0" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 714 | dependencies = [ 715 | "windows-targets 0.52.5", 716 | ] 717 | 718 | [[package]] 719 | name = "windows-targets" 720 | version = "0.48.5" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 723 | dependencies = [ 724 | "windows_aarch64_gnullvm 0.48.5", 725 | "windows_aarch64_msvc 0.48.5", 726 | "windows_i686_gnu 0.48.5", 727 | "windows_i686_msvc 0.48.5", 728 | "windows_x86_64_gnu 0.48.5", 729 | "windows_x86_64_gnullvm 0.48.5", 730 | "windows_x86_64_msvc 0.48.5", 731 | ] 732 | 733 | [[package]] 734 | name = "windows-targets" 735 | version = "0.52.5" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 738 | dependencies = [ 739 | "windows_aarch64_gnullvm 0.52.5", 740 | "windows_aarch64_msvc 0.52.5", 741 | "windows_i686_gnu 0.52.5", 742 | "windows_i686_gnullvm", 743 | "windows_i686_msvc 0.52.5", 744 | "windows_x86_64_gnu 0.52.5", 745 | "windows_x86_64_gnullvm 0.52.5", 746 | "windows_x86_64_msvc 0.52.5", 747 | ] 748 | 749 | [[package]] 750 | name = "windows_aarch64_gnullvm" 751 | version = "0.48.5" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 754 | 755 | [[package]] 756 | name = "windows_aarch64_gnullvm" 757 | version = "0.52.5" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 760 | 761 | [[package]] 762 | name = "windows_aarch64_msvc" 763 | version = "0.48.5" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 766 | 767 | [[package]] 768 | name = "windows_aarch64_msvc" 769 | version = "0.52.5" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 772 | 773 | [[package]] 774 | name = "windows_i686_gnu" 775 | version = "0.48.5" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 778 | 779 | [[package]] 780 | name = "windows_i686_gnu" 781 | version = "0.52.5" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 784 | 785 | [[package]] 786 | name = "windows_i686_gnullvm" 787 | version = "0.52.5" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 790 | 791 | [[package]] 792 | name = "windows_i686_msvc" 793 | version = "0.48.5" 794 | source = "registry+https://github.com/rust-lang/crates.io-index" 795 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 796 | 797 | [[package]] 798 | name = "windows_i686_msvc" 799 | version = "0.52.5" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 802 | 803 | [[package]] 804 | name = "windows_x86_64_gnu" 805 | version = "0.48.5" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 808 | 809 | [[package]] 810 | name = "windows_x86_64_gnu" 811 | version = "0.52.5" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 814 | 815 | [[package]] 816 | name = "windows_x86_64_gnullvm" 817 | version = "0.48.5" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 820 | 821 | [[package]] 822 | name = "windows_x86_64_gnullvm" 823 | version = "0.52.5" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 826 | 827 | [[package]] 828 | name = "windows_x86_64_msvc" 829 | version = "0.48.5" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 832 | 833 | [[package]] 834 | name = "windows_x86_64_msvc" 835 | version = "0.52.5" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 838 | 839 | [[package]] 840 | name = "winnow" 841 | version = "0.6.13" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" 844 | dependencies = [ 845 | "memchr", 846 | ] 847 | --------------------------------------------------------------------------------