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

Add and update documentation for stack. #9

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[![PkgGoDev](https://pkg.go.dev/badge/github.com/invisv-privacy/masque)](https://pkg.go.dev/github.com/invisv-privacy/masque)
![Build Status](https://github.com/invisv-privacy/masque/actions/workflows/build.yaml/badge.svg?branch=main)
[![godocs.io](https://godocs.io/github.com/invisv-privacy/masque?status.svg)](https://godocs.io/github.com/invisv-privacy/masque)

## What is INVISV masque?

Expand Down Expand Up @@ -52,6 +53,10 @@ $ curl -v --proxy http://localhost:32190 ipinfo.io/ip
146.75.153.247
```

## Example application: Preproxy

In addition to the Relay HTTP Proxy sample application, we have included an application we call the "preproxy". This performs a combination of functions: reverse proxying of inbound traffic and tunneling of that traffic via a (multi-hop) MASQUE tunnel to a given destination. This enables use of unmodified applications with MASQUE tunnels, where the remote client network stack is potentially unaware of the MASQUE tunnel yet wishes to use a MASQUE to reach a destination. See the documentation of preproxy for details.

## Testing

We have automated tests which utilize an h2o container that we can leverage as the MASQUE target.
Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package masque implements a client-side IETF MASQUE protocol stack.
package masque

import "time"
Expand Down
18 changes: 12 additions & 6 deletions example/preproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
)

// A port list to be used as a default if one is not provided via a file.
// These are the ports that preproxy should listen on.
var PortListBase = []int{
80, 443, 5349, 7880,
}
Expand All @@ -33,6 +34,7 @@ var PortListBaseUdp = []int{
var insecure *bool

// This port range is to allow a large number of UDP ports to be added.
// This is useful when a client may use an unknown high port number.
const PortRangeUdpMin = 50000
const PortRangeUdpMax = 60000

Expand All @@ -53,8 +55,10 @@ func defaultPortList() ([]int, []int) {
return portListTCP, portListUDP
}

// Load the provided port file. Returns a list of TCP and UDP ports to forward.
// The format of the file is tcp:port_number or udp:port_number on individual lines.
// loadPortFile loads the provided port file. It returns a list of TCP and UDP
// ports to forward. The format of the file is tcp:port_number or
// udp:port_number on individual lines.
//
// TODO: Support port ranges in the form of udp:port_start-port_end
func loadPortFile(portFile string) ([]int, []int, error) {
portList, err := os.ReadFile(portFile)
Expand Down Expand Up @@ -91,10 +95,10 @@ func loadPortFile(portFile string) ([]int, []int, error) {
return portListTCP, portListUDP, nil
}

// Preproxy executable. Starts running the preproxy on localaddr by tunneling connections thru the given proxyaddr
// Starts running the preproxy on localaddr by tunneling connections thru the given proxyaddr
// to the final destination targetServer for the ports configured (either by default or via the portconf file).
func main() {
invisvRelay := flag.String("invisvRelay", "fastest.pgpp.stations.invisv.com", "Invisv Relay Server")
invisvRelay := flag.String("invisvRelay", "", "Invisv Relay Server")
invisvRelayPort := flag.String("invisvRelayPort", "443", "Invisv Relay Server Port")
targetServer := flag.String("targetServer", "", "Target server to proxy all connections to")

Expand Down Expand Up @@ -294,10 +298,12 @@ func Transfer(dst io.WriteCloser, src io.ReadCloser) {
}
}

// A connFailFunc is called when a Relay stream creation fails. It is given the connection being proxied so it can reply to the client if needed.
// A connFailFunc is called when a Relay stream creation fails. It is given the
// connection being proxied so it can reply to the client if needed.
type connFailFunc func(c net.Conn)

// HandleConnectMasque creates a new TCP or UDP stream via the relayClient and returns the connected stream upon success.
// HandleConnectMasque creates a new TCP or UDP stream via the relayClient and
// returns the connected stream upon success.
func HandleConnectMasque(relayClient *masqueH3.Client, c net.Conn, target string, isTcp bool, fail connFailFunc) (io.ReadWriteCloser, error) {
_, port, err := net.SplitHostPort(target)
if err != nil {
Expand Down
12 changes: 5 additions & 7 deletions example/relay-http-proxy/main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/*
relay-http-proxy is a sample application that uses the INVISV IETF MASQUE
stack. It listens on a local port, presenting an ordinary HTTP proxy
interface, and sends requests it receives to the destination host via the
MASQUE relay server, such as the one run by INVISV. In effect, this tunnels
ordinary HTTP via MASQUE (which is itself an extension to HTTP).
*/
// relay-http-proxy is a sample application that uses the INVISV IETF MASQUE
// stack. It listens on a local port, presenting an ordinary HTTP proxy
// interface, and sends requests it receives to the destination host via the
// MASQUE relay server, such as the one run by INVISV. In effect, this tunnels
// ordinary HTTP via MASQUE (which is itself an extension to HTTP).
package main

import (
Expand Down
9 changes: 7 additions & 2 deletions http2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ const (
// Client is a MASQUE HTTP/2 client that supports HTTP CONNECT and CONNECT-UDP.
// All CONNECT requests are multiplexed using a HTTP/2 transport.
// Each CONNECT-UDP request is performed in HTTP/1.1 and sent individually
// via its own TLS connection. Any CONNECT or CONNECT-UDP requests that need HTTP/3 should not directly use this.
// via its own TLS connection. Any CONNECT or CONNECT-UDP requests that
// need HTTP/3 should not directly use this.
//
// The tlsTimeout setting determines the duration the client waits when
// attempting to create a new TLS connection to the proxy. An error is returned
// if the connection is not ready to use within the specified tlsTimeout.
//
// prot if not nil should be called before connect.
type Client struct {
proxyAddr string
authToken string
Expand All @@ -45,7 +48,7 @@ type Client struct {
tlsTimeout time.Duration
tcpReqs map[uint64]*Conn
udpReqs map[uint64]*Conn
prot SocketProtector // Call before connect
prot SocketProtector
certData []byte
makingSpare bool
lowLatencyAddrs map[string]bool
Expand All @@ -54,6 +57,8 @@ type Client struct {
ignoreCert bool
}

// ClientConfig is a configuration for a MASQUE client to be used to set
// the configuration of a new Client to be created.
type ClientConfig struct {
ProxyAddr string
AuthToken string
Expand Down
4 changes: 2 additions & 2 deletions http2/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ type connCleanupFunc func(bool, uint64)
// and a pair of I/O handles, namely |IoInc| and |IoOut|, designed for
// sending and receiving data via the proxied TCP/UDP connection.
//
// For CONNECT-UDP using HTTP/1.1, the |transport| field keeps track of the unique
// HTTP/1.1 TLS connection to the destination proxy server.
// For CONNECT-UDP using HTTP/1.1, the |transport| field keeps track of the
// unique HTTP/1.1 TLS connection to the destination proxy server.
//
// The |Alive| field indicates the liveness of the underlying CONNECT-UDP HTTP connection.
// Users should only send data through this proxied connection if |Alive| is true.
Expand Down
8 changes: 6 additions & 2 deletions http3/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type Client struct {
// ClientConfig is options to give when creating a new Client with NewClient().
// Note that sane defaults are used when value is not provided/initialized.
type ClientConfig struct {
// The proxy to connect to in host:port format.
ProxyAddr string

// Maximium number of incoming streams. Typically not an issue, as
Expand Down Expand Up @@ -108,8 +109,10 @@ type ClientConfig struct {
// DatagramStream is an object for Proxied UDP Streams that implements I/O functionality.
// This object contains information necessary to communicate with the Client
// message receiver loop.
//
// Read/Write on a DatagramStream works as expected, though note it will use
// Datagram framing semantics (each block is an individual UDP packet).
//
// It is important that the caller DO NOT close the quic.Stream OR the quic.Connection
// object that is given inside of the struct.
type DatagramStream struct {
Expand Down Expand Up @@ -337,7 +340,8 @@ func (c *Client) stopReceiveLoop() error {
return nil
}

// Gets a new H3_DATAGRAM Flow ID to be used with a UDP stream.
// getNewDatagramID gets a new H3_DATAGRAM Flow ID to be used with a UDP
// stream.
func (c *Client) getNewDatagramID() uint64 {
c.mutex.Lock()
defer c.mutex.Unlock()
Expand Down Expand Up @@ -573,7 +577,7 @@ func (s *DatagramStream) Read(b []byte) (int, error) {

}

// Writes to a datagram stream. May block if the stream buffer is full.
// Write writes to a datagram stream. May block if the stream buffer is full.
// Note that this function requires prepending 1 to 9 bytes to send the datagram:
// this means that the MTU size of the connection will be below what the caller
// may expect.
Expand Down
2 changes: 1 addition & 1 deletion internal/utils/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

// TLSVerifyFunc takes a cert data byte slice and returns a function that can be
// passed to the tls.Config.VerifyPeerCertificate for pinning
// passed to the tls.Config.VerifyPeerCertificate for pinning.
func TLSVerifyFunc(certData []byte) (func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error, error) {
block, _ := pem.Decode(certData)
if block == nil {
Expand Down
Loading