Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split library in separated crates #326

Closed
2 of 19 tasks
zonyitoo opened this issue Nov 26, 2020 · 18 comments
Closed
2 of 19 tasks

Split library in separated crates #326

zonyitoo opened this issue Nov 26, 2020 · 18 comments
Assignees

Comments

@zonyitoo
Copy link
Collaborator

zonyitoo commented Nov 26, 2020

Moved from #199 . Work to do:

  • Take ownership of shadowsocks
  • Separate crates into
    • shadowsocks-core (will be released as shadowsocks crate), which contains:

      • TCP Relay: a Stream like interface for communicating with remote servers (Local + Server)
        • Extra API, connects without Context:
          ProxyTcpStream::connect(server_addr, method, password).await
      • UDP Relay, an Association Manager, for building a NAT to remote servers (Local + Server)
      • Plugin
      • ACL, including libev's ACL list, and other possible implementations, like GeoIP
      • Config, including basic format parsing, SIP002 URL parsing facilities
    • shadowsocks binaries (will be released as shadowsocks-rust crate), which contains:

      • Logging facilities, currently uses log4rs, could be customized
      • sslocal
        • socks5, socks4/4a, or universal socks
        • http/https
        • tunnel
        • tun/tap
        • redir
        • dns
      • ssserver
      • ssmanager
      • ssurl
    • Crypto Library, shadowsocks-crypto

@zonyitoo zonyitoo self-assigned this Nov 26, 2020
@gfreezy
Copy link

gfreezy commented Nov 26, 2020

这个是在哪个分支上? shadowsocks-crypto 是已经拆出来了吗?

@zonyitoo
Copy link
Collaborator Author

这个是在哪个分支上? shadowsocks-crypto 是已经拆出来了吗?

Yes. shadowsocks-crypto.

@gfreezy
Copy link

gfreezy commented Nov 26, 2020

感觉下面每个独立成一个 crate,方便复用

协议相关:

  • socks5
  • socks4/4a
  • http/https
  • shadowsocks

接入方式:

  • tunnel
  • redir

@zonyitoo
Copy link
Collaborator Author

zonyitoo commented Nov 26, 2020

So if I want to make a release, I will have to release at least 7 crates.

http/https are implemented with hyper, anyone who wants to write a HTTP proxy could use hyper from scratch.

shadowsocks-local is good enough, because shadowsocks' socks5 / http / https doesn't have any authentication mechanism. All of these "protocol"s could be controlled by features.

@zonyitoo
Copy link
Collaborator Author

zonyitoo commented Nov 26, 2020

I think it is not recommended to try to be compatible with all available async runtime, because tokio's AsyncRead and AsyncWrite are different with others.

@gfreezy
Copy link

gfreezy commented Nov 26, 2020

So if I want to make a release, I will have to release at least 7 crates.

http/https are implemented with hyper, anyone who wants to write a HTTP proxy could use hyper from scratch.

shadowsocks-local is good enough, because shadowsocks' socks5 / http / https doesn't have any authentication mechanism. All of these "protocol"s could be controlled by features.

 socks5
 socks4/4a
 http/https
 shadowsocks

These protocol related crates should be very stable. We don't release them often. Most of time, we just need to release ss-local.

@zonyitoo
Copy link
Collaborator Author

So, each protocol crate only need to implement its own run function? Then why not just controll it with feature?

@gfreezy
Copy link

gfreezy commented Nov 26, 2020

Protocol don't need to implement the run function. The protocol interface can just be like TcpStream and UdpSocket.
Take socks5, for example, we can implement Socks5TcpStream which impls AsyncRead and AsyncWrite and UdpSocket which provides send and recv.

@zonyitoo
Copy link
Collaborator Author

If Socks5TcpStream is for general usage, then it has to support socks5's authentication mechanism, which means that it cannot read or write before tunnel established.

@gfreezy
Copy link

gfreezy commented Nov 27, 2020

If Socks5TcpStream is for general usage, then it has to support socks5's authentication mechanism, which means that it cannot read or write before tunnel established.

The new function can be like this. The connection is not considiered connected until authentication is passed and the connection between the proxy server and dest address is established.

impl Socks5TcpStream {
    pub async fn new(socks_server_addr: SocketAddr, remote_addr: &str, user_name: Option<String>, password: Option<String>)
}

@zonyitoo
Copy link
Collaborator Author

zonyitoo commented Nov 27, 2020

Your Socks5TcpStream is for client use cases, but sslocal is working as a socks5 server.

So it there must be a struct Socks5Server, which have a run function that drives the server and user should provide a handler for accepted TcpStream.

let mut server = Socks5Server::builder()
    .authenticate_handler(...)
    .connect_handler(...)
    .udp_associate_handler(...)
    .bind_handler(...);
server.run().await?;

which will envolve too many things that won't be used in this project. I suggest it should have lower priority.

For the shadowsocks-core crate, it could provide a TCP stream (which is called ProxyStream in the current master branch), and a UDP association manager for users to define their own version of sslocal.

  • TCP: ProxyStream, or TcpStream in public API which implements AsyncRead and AsyncWrite.
  • UDP:
    • UDP Association manager, implements a UDP NAT manager (port forwarding)
    • UdpSocket, a plain UDP socket that send/recv packets to/from shadowsocks' server

@zonyitoo
Copy link
Collaborator Author

Step 1: Splits binaries and the library into 2 crates, shadowsocks and shadowsocks-core.

zonyitoo added a commit that referenced this issue Nov 28, 2020
- shadowsocks-core is a library contains all necessary functions for
running shadowsocks

- shadowsocks is a binary crate that ships end-user products

ref #326
@LuoZijun
Copy link
Contributor

LuoZijun commented Nov 29, 2020

这样拆分你们看如何:

  1. shadowsocks (原始的 socks2socks , 含 client 和 server 以及 ACL 组件 )
  2. tun2socks (client)
  3. https2socks (client)

至于终端 App,如果他只需要一个 socks2socks 的话,那么只依赖一个就行了。

至于我,可以帮忙做 tun2socks 和 ACL 这两部分。

@IceCodeNew
Copy link

个人建议这部分的动作先放到 PR 里,实现完了再合并。
看提交记录从 4a4576b 开始 CI 就一直编译出错了。

@zonyitoo
Copy link
Collaborator Author

看提交记录从 4a4576b 开始 CI 就一直编译出错了。

That is a compiler bug, which will be fixed in the next nightly build.

@zonyitoo
Copy link
Collaborator Author

zonyitoo commented Nov 30, 2020

We should keep 2 crates:

  1. shadowsocks-core (will be released as shadowsocks crate), which contains:

    • TCP Relay: a Stream like interface for communicating with remote servers (Local + Server)
    • UDP Relay, an Association Manager, for building a NAT to remote servers (Local + Server)
    • Plugin
    • ACL, including libev's ACL list, and other possible implementations, like GeoIP
    • Config, including basic format parsing, SIP002 URL parsing facilities
  2. shadowsocks binaries (will be released as shadowsocks-rust crate), which contains:

    • Logging facilities, currently uses log4rs, could be customized
    • sslocal
      • socks5, socks4/4a, or universal socks
      • http/https
      • tunnel
      • tun/tap
      • redir
      • dns
    • ssserver
    • ssmanager
    • ssurl

zonyitoo added a commit that referenced this issue Dec 1, 2020
- ref #326
- Binary crate will keep shadowsocks-rust's name
zonyitoo added a commit that referenced this issue Dec 1, 2020
- ref #326
- Binary crate will keep shadowsocks-rust's name
@zonyitoo
Copy link
Collaborator Author

Already finished library refactor in branch feature-separate-crates.

@zonyitoo
Copy link
Collaborator Author

merged to master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants