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

Issues encountered while setting up masquerade for HTTP/3 to HTTP/1.1 proxying, and a question about using existing SOCKS5 proxies #2

Open
kaykyr opened this issue Apr 9, 2023 · 2 comments
Assignees

Comments

@kaykyr
Copy link

kaykyr commented Apr 9, 2023

Hi,

I was looking for a way to proxy my connection with Instagram using a proxy that sends requests over HTTP/3 and returns responses in HTTP/1.1. Is this project intended to serve a similar purpose?

While trying to set up and execute the project, I encountered some issues with the provided code. Here's what happened:

Initially, I executed the server with the following command:

cargo run --bin server -- 127.0.0.1:4433

Then, I executed the client using this command:

cargo run --bin client -- 127.0.0.1:4433 127.0.0.1:8989 http

However, I received an error message that stated:

thread 'main' panicked at 'UDP socket send_to() failed: Os { code: 56, kind: Uncategorized, message: "Socket is already connected" }'

To resolve this issue, I made the following changes to the code:

At line 155 in client.rs:

        let (write, send_info) = conn.send(&mut out).expect("initial send failed"); 
        // while let Err(e) = socket.send_to(&out[..write], send_info.to).await {
        while let Err(e) = socket.send(&out[..write]).await {
            if e.kind() == std::io::ErrorKind::WouldBlock {
                debug!("send_to() would block");
                continue;
            }
            panic!("UDP socket send_to() failed: {:?}", e);
        }
        debug!("written {}", write);

At line 476 in client.rs:

                // match socket.send_to(&out[..write], send_info.to).await {
                match socket.send(&out[..write]).await {
                    Ok(written) => debug!("{} written {} bytes out of {}", conn.trace_id(), written, write),
                    Err(e) => panic!("UDP socket send_to() failed: {:?}", e),
                }

After making this change, the code executed without any errors. Is this approach correct?

Finally, I would like to ask if it's possible to use an existing TCP/SOCKS5 proxy hosted on a remote server as a way to establish a QUIC-encapsulated connection, or if it's only possible to do this using pre-existing interfaces on localhost?

Thank you for your help!

@jromwu
Copy link
Owner

jromwu commented Apr 14, 2023

Hi!

I am not too sure what does it mean by to send requests in HTTP/3 and receive responses in HTTP/1.1. What happens here is we proxy a connection with Instagram (whatever protocol Instagram is using, HTTP/3 or HTTP/1.1), you establish a tunnel:

Instagram client <-HTTP/1.1 or SOCKS5> masquerade client <-HTTP/3-> masquerade server <-> Instagram server
                 <---------------------any protocol Instagram uses---------------------->

where the packets reaching the Instagram server and client are unmodified, so it stays HTTP/1.1 if it uses HTTP/1.1.

The code change looks okay to me. It might be that I tested on a different platform and the socket did let me connect.. I will review and change the code later.

It is definitely possible to host it on a remote server. You would need to replace corresponding the 127.0.0.1 in the command to the IP for the network interface you would like to host it on.

Cheers!

@jromwu jromwu self-assigned this Apr 14, 2023
@DavidWittman
Copy link

After making this change, the code executed without any errors. Is this approach correct?

Yes, it is correct. From the Tokio docs:

UDP is "connectionless", unlike TCP. Meaning, regardless of what address you've bound to, a UdpSocket is free to communicate with many different remotes. In tokio there are basically two main ways to use UdpSocket:

one to many: bind and use send_to and recv_from to communicate with many different addresses
one to one: connect and associate with a single address, using send and recv to communicate only with that remote address

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

3 participants