Skip to content

support setting IP_TRANSPARENT on sockets #226

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

Closed
pepinns opened this issue Apr 29, 2021 · 6 comments
Closed

support setting IP_TRANSPARENT on sockets #226

pepinns opened this issue Apr 29, 2021 · 6 comments

Comments

@pepinns
Copy link
Contributor

pepinns commented Apr 29, 2021

This socket option allows you to setup a transparent proxy on linux.

Testing this is somewhat difficult to do in an automated fashion as it requires at least CAP_NET_ADMIN permissions to bind the socket, as well as iptables rules to make the traffic flow.

I have the code ready to set the socket option, and verified it works, but need some guidance on how it should be documented and tested to be accepted in the project. https://github.com/rust-lang/socket2/compare/master...pepinns:tproxy?expand=1

I've written a test in the get/set style, but it requires root to pass, so it has to be ignored during test runs. I also encountered other test failures.

`[vagrant@polarisdev03]~/pjs/socket2 (tproxy ✘)✹ --ᐅ make test
cargo test --all-features
...
Running tests/socket.rs (target/debug/deps/socket-7ade8124568b7805)

running 48 tests
test ip_transparent ... FAILED
...
failures:

---- ip_transparent stdout ----
thread 'ip_transparent' panicked at 'failed to set option: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }', tests/socket.rs:1044:1
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

---- connect_timeout_unrouteable stdout ----
thread 'connect_timeout_unrouteable' panicked at 'unexpected success', tests/socket.rs:347:18

---- recv_from_vectored_truncated stdout ----
thread 'recv_from_vectored_truncated' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- recv_vectored_truncated stdout ----
thread 'recv_vectored_truncated' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- send_from_recv_to_vectored stdout ----
thread 'send_from_recv_to_vectored' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- send_recv_vectored stdout ----
thread 'send_recv_vectored' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- unix stdout ----
thread 'unix' panicked at 'called Result::unwrap() on an Err value: Os { code: 98, kind: AddrInUse, message: "Address already in use" }', tests/socket.rs:411:26
...
[vagrant@polarisdev03]~/pjs/socket2 (tproxy ✘)✹ --ᐅ sudo target/debug/deps/socket-7ade8124568b7805

running 48 tests
test broadcast ... ok
test device ... ignored
test connect_timeout_unbound ... ok
test cpu_affinity ... ok
test connect_timeout_valid ... ok
test domain ... ok
test domain_fmt_debug ... ok
test domain_for_address ... ok
test default_flags ... ok
test connect_timeout_unrouteable ... FAILED
test ip_transparent ... ok
...
failures:

---- connect_timeout_unrouteable stdout ----
thread 'connect_timeout_unrouteable' panicked at 'unexpected success', tests/socket.rs:347:18
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

---- recv_from_vectored_truncated stdout ----
thread 'recv_from_vectored_truncated' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- recv_vectored_truncated stdout ----
thread 'recv_vectored_truncated' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- send_from_recv_to_vectored stdout ----
thread 'send_from_recv_to_vectored' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

---- send_recv_vectored stdout ----
thread 'send_recv_vectored' panicked at 'called Result::unwrap() on an Err value: Os { code: 99, kind: AddrNotAvailable, message: "Cannot assign requested address" }', tests/socket.rs:628:45

failures:
connect_timeout_unrouteable
recv_from_vectored_truncated
recv_vectored_truncated
send_from_recv_to_vectored
send_recv_vectored
`

Are the failures I'm seeing expected? I get the same 6 failures on the master branch.
Do I have missing dependencies?

@pepinns
Copy link
Contributor Author

pepinns commented Apr 29, 2021

opened #227

@Thomasdezeeuw
Copy link
Collaborator

You're 90% there I've reviewed #227.

@pepinns
Copy link
Contributor Author

pepinns commented Apr 29, 2021

Thanks for the review. I believe I've addressed everything.

I'm new to rust so curious about the 'all' feature here.

Is it the intention that the 'standard' or 'default' featureset has only things that are available on ALL supported operating systems? And if you wanted OS-specific features you'd have to ask for the 'all' feature from this crate?

@Thomasdezeeuw
Copy link
Collaborator

Closed by #227.

@Thomasdezeeuw
Copy link
Collaborator

Thanks for the review. I believe I've addressed everything.

I'm new to rust so curious about the 'all' feature here.

Is it the intention that the 'standard' or 'default' featureset has only things that are available on ALL supported operating systems? And if you wanted OS-specific features you'd have to ask for the 'all' feature from this crate?

The "all" feature is for function/options, such as this one, that isn't support on on the three major OSs (Linux, macOS and Widnows). When you disable the "all" feature (the default) you know that your application will work on at least the those three OSs (bar any different in same-named options etc.). Enabling the "all" feature enables more options, but it requires the user of the crate to ensure cross-platform support, usually by using a bunch of cfg attributes.

@pepinns
Copy link
Contributor Author

pepinns commented Apr 30, 2021

Thanks for your time, I appreciate the feedback and explanation.

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