Repository navigation
Use same port for SOCKS5/HTTP proxy #349
Description
Activity
Accepts a
TcpStreamand then choose protocol automatically by the first byte?match first_byte { 0x05 => handle_socks5_stream 0x04 => handle_socks4_stream 'H' | 'h' => handle_http_stream }
That is quite hard to implement that with hyper. There is no API for this = =..
Reacted by MygodAccepts a
TcpStreamand then choose protocol automatically by the first byte?match first_byte { 0x05 => handle_socks5_stream 0x04 => handle_socks4_stream 'H' | 'h' => handle_http_stream }
That is quite hard to implement that with hyper. There is no API for this = =..
或许可以参考一下,clash是怎么实现?他们家好像见到能支持类似的功能
I know how to implement that, the only problem is hyper doesn't provide a API for me to customize
Server's accept process.@zonyitoo IIRC, some similar apps use pipes / channels to redirect the traffic to their HTTP modules.
BTW, I think it's a low priority request.
Reacted by tyI know how to implement that, the only problem is hyper doesn't provide a API for me to customize
Server's accept process.first_byte使用.peek(...)?I don't think the problem is how to guess which protocol going to be used,
shadowsocks-rust/crates/shadowsocks-service/src/local/socks/server/mod.rs
Lines 171 to 177 in 1d11fba
let mut version_buffer = [0u8; 1]; let n = stream.peek(&mut version_buffer).await?; if n == 0 { return Err(ErrorKind::UnexpectedEof.into()); } match version_buffer[0] { the key issue is that there is no API to feed an accepted
TcpStreaminto a hyperServerinstance.There are several ways to achieve this goal:
- Rewrite a HttpServer with the basic
httpcrate. Reinventing the whole wheel. - Customized an Acceptor and use hyper to handle all inbound connections, like a HTTPS server
shadowsocks-rust/shadowsocks/src/relay/tcprelay/http_local.rs
Lines 883 to 899 in a7c9f75
let make_service = make_service_fn(|socket: &TlsStream| { let client_addr = socket.remote_addr(); let servers = servers.clone(); let bypass_client = bypass_client.clone(); async move { Ok::<_, Infallible>(service_fn(move |req: Request<Body>| { let svr_score = servers.pick_server(); server_dispatch(req, svr_score, client_addr, bypass_client.clone()) })) } }); let acceptor = TlsAcceptor::bind(context.config(), &bind_addr)?; info!("shadowsocks HTTPS listening on {}", acceptor.local_addr()); let server = Server::builder(acceptor).http1_only(true).serve(make_service);
- Rewrite a HttpServer with the basic
I think it could be all local services use one common port, or loop all ports set in local configure file, start tcp/udp services for each port and dispatch to different workers by checking the inbound package.In this way local dns can be mixed as well.
I don't see how one could run out of ports for local services. Having multiple services over the same port adds unnecessary complexity and overhead.
Supported on master branch.
How to use SOCKS5/HTTP at the same port? I cannot find a guide on this.
shadowsocks/shadowsocks-android#2577