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

Convert to a library #35

Closed
jkcoxson opened this issue Jun 23, 2022 · 8 comments
Closed

Convert to a library #35

jkcoxson opened this issue Jun 23, 2022 · 8 comments

Comments

@jkcoxson
Copy link
Contributor

Hello, thank you for your work on this project. It is very helpful.

I would love to incorporate this into other projects, specifically on iOS where it must be incorporated into a Swift application through a library. Onetun's uses can be expanded for a variety of use-cases as a library.

The SideStore team and I are willing to put in the development time to convert the core parts of onetun into a callable library, while adding a binary option to maintain onetun's current use-case. If this is something that you would be willing to merge, I'll create a PR once we have something to show. Otherwise we will maintain our own fork.

@aramperes
Copy link
Owner

Would it just be a matter of splitting the main method so you can execute it within your application by passing a Config instance?

Otherwise I'm not sure I see how onetun can be useful as a library, given that it's mainly a runtime combining smoltcp, boringtun, and tokio TCP/UDP.

@jkcoxson
Copy link
Contributor Author

jkcoxson commented Jun 24, 2022

I see your point, but I have thought of a few more reasons why this could be useful as a library.

  • Hot loading/removing routes without killing the whole thing
  • Monitoring packet transfer

I guess that's it

@aramperes
Copy link
Owner

I see, yeah that could be an option.

Ideally would be able to pass such instructions through the Bus interface to add/remove routes, and use the existing events to monitor packets (see src/pcap.rs). That would require minimal changes to onetun's architecture, which I'm not interested in refactoring at this time.

@aramperes
Copy link
Owner

aramperes commented Jun 24, 2022

I would also gate some portions of the code and dependencies behind features, such as:

  • src/pcap.rs
  • src/config.rs (the clap portion)

edit: f856929

@jkcoxson
Copy link
Contributor Author

So is this a PR that you would accept if done right? If so I’ll keep my changes focused on merging upstream.

@aramperes
Copy link
Owner

Could you test importing onetun as a library with the latest release, 0.3.2?

Note, I bumped the MSRV to 1.56 and Rust edition 2021.

I'm willing to build this over time and adding more customization through the Bus interface.

@jkcoxson
Copy link
Contributor Author

jkcoxson commented Jun 25, 2022

Looks great! I have a few suggestions after trying it out. I've created an example here

#[tokio::main]
async fn main() {
    println!("Starting env logger");
    env_logger::init();

    println!("Creating config...");

    let port_forward = onetun::config::PortForwardConfig {
        source: std::net::SocketAddr::V4(SocketAddrV4::from_str("127.0.0.1:2222").unwrap()),
        destination: std::net::SocketAddr::V4(SocketAddrV4::from_str("10.7.0.10:2222").unwrap()),
        protocol: onetun::config::PortProtocol::Tcp,
        remote: false,
    };

    let private_key =
        X25519SecretKey::from_str("secret key here").unwrap();

    let public_key =
        X25519PublicKey::from_str("public key here").unwrap();

    let endpoint_addr =
        std::net::SocketAddr::V4(SocketAddrV4::from_str("192.168.1.16:12345").unwrap());

    let endpoint_bind_addr =
        std::net::SocketAddr::V4(SocketAddrV4::from_str("0.0.0.0:51820").unwrap());

    let source_peer_ip = std::net::Ipv4Addr::from_str("10.7.0.1").unwrap();

    let config = onetun::config::Config {
        port_forwards: vec![port_forward],
        remote_port_forwards: vec![],
        private_key: Arc::new(private_key),
        endpoint_public_key: Arc::new(public_key),
        endpoint_addr,
        endpoint_bind_addr,
        source_peer_ip: std::net::IpAddr::V4(source_peer_ip),
        keepalive_seconds: None,
        max_transmission_unit: 1420,
        log: "TRACE".to_string(),
        warnings: vec![],
        pcap_file: None,
    };

    println!("Creating bus...");

    let bus = onetun::events::Bus::new();

    println!("Creating tun...");

    match onetun::start_tunnels(config, bus).await {
        Ok(tun) => tun,
        Err(e) => {
            println!("Error creating tun: {}", e);
            return;
        }
    };

    // Insert your own way to not kill the program
    loop {
        tokio::time::sleep(std::time::Duration::from_secs(10)).await;
    }
}
  • onetun should re-export boringtun's X25519*Key, or create functions to create them. That way the user of the lib doesn't have to include boringtun as a dependency. fixed
  • If there isn't a way to hotload/remove routes, another easy workaround would to be to just kill the tunnel altogether so the user can create a new one.

Thanks a lot for looking into this!

@aramperes
Copy link
Owner

X25519 primitives are now exported in 8cee210.

In terms of hot-loading/removing routes, I would prefer to tackle this once remote port-forwardig is implemented (#6), as it will alter onetun's architecture a bit, and may affect the feasibility of this feature.

Since I believe this goes beyond the scope of this ticket, I opened #36 and will close this one unless you have other suggestions for improving library support.


    // Insert your own way to not kill the program
    loop {
        tokio::time::sleep(std::time::Duration::from_secs(10)).await;
    }

btw, you can create an infinite future that doesn't complete using futures::future::pending().await

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

No branches or pull requests

2 participants