Skip to content

Commit

Permalink
improvement: v0 enhancement and fix (#11)
Browse files Browse the repository at this point in the history
* example: make sure version is v0

v0plus is an internal developer code reference and should keep internal.

* fix: README code indentation

* update: type guard for three net objects

* update: require Addr() for Relay interface

Plus optimize the workflow for v0/relay

* update: move v0 testdata to subdirectory

* update: remove deprecated build tags

Since v0 is optionally imported, it is pointless to assign a special build tag to explicitly disable it.

* new: dialer-oriented test coverage

* fix: minor relay/listener adjustment

* test: test suites for v0

* fix: allow complex testsuites

* fix: ignoring err is unsafe

* fix: allow this complex test suite

* test: overengineered benchmark

water benchmark bested std tcp... wut?

* fix: listener implements net.Listener

Add `AcceptWATER()` in case it is useful to directly get `water.Conn` without unsafe type assertion.

* test: remove redundant defer

Remove a few redundant defer calls.

* test: consistently use localhost:0

* test: use new data for every write

Read from crypto/rand after each Write, which introduces "reasonable" latency as well.

* fix: unsafe usage missed before
  • Loading branch information
gaukas authored Oct 28, 2023
1 parent 06599f5 commit eb43f3b
Show file tree
Hide file tree
Showing 22 changed files with 1,047 additions and 292 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ endpoint with the WebAssembly module wrapping / encrypting / transforming the tr
connection.

```go
wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm")
wasm, err := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TMBin: wasm,
}

dialer, err := water.NewDialer(config)
conn, err := dialer.Dial("tcp", remoteAddr)
// ...
// ...
```

### Listener
Expand All @@ -65,7 +65,7 @@ client.
managing the tunnel obfuscation once a connection is established.

```go
wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm")
wasm, err := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TMBin: wasm,
Expand All @@ -78,8 +78,8 @@ managing the tunnel obfuscation once a connection is established.
clientCntr := 0
for {
conn, err := lis.Accept()
// ...
}
// ...
}
```

### Relay
Expand All @@ -94,15 +94,15 @@ connections as well as the associated outgoing connectons.
to tunnel traffic.

```go
wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm")
wasm, err := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TMBin: wasm,
}

relay, err := water.NewRelay(config)

err = relay.ListenAndRelayTo("tcp", localAddr, "tcp", remoteAddr)
err = relay.ListenAndRelayTo("tcp", localAddr, "tcp", remoteAddr) // blocking
```

## Example
Expand Down
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (c *Config) WASIConfig() *wasm.WASIConfigFactory {
return c.wasiConfigFactory
}

func (c *Config) Listen(network, address string) (net.Listener, error) {
func (c *Config) Listen(network, address string) (Listener, error) {
lis, err := net.Listen(network, address)
if err != nil {
return nil, err
Expand Down
2 changes: 2 additions & 0 deletions dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var (
ErrDialerAlreadyRegistered = errors.New("water: dialer already registered")
ErrDialerVersionNotFound = errors.New("water: dialer version not found")
ErrUnimplementedDialer = errors.New("water: unimplemented dialer")

_ Dialer = (*UnimplementedDialer)(nil) // type guard
)

// UnimplementedDialer is a Dialer that always returns errors.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func main() {
}
var remoteAddr string = os.Args[1]

wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm")
wasm, err := os.ReadFile("./examples/v0/plain/plain.wasm")
if err != nil {
panic(fmt.Sprintf("failed to read wasm file: %v", err))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func main() {
}
var localAddr string = os.Args[1]

wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm")
wasm, err := os.ReadFile("./examples/v0/plain/plain.wasm")
if err != nil {
panic(fmt.Sprintf("failed to read wasm file: %v", err))
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func main() {
var localAddr string = os.Args[1]
var remoteAddr string = os.Args[2]

wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm")
wasm, err := os.ReadFile("./examples/v0/plain/plain.wasm")
if err != nil {
panic(fmt.Sprintf("failed to read wasm file: %v", err))
}
Expand Down
22 changes: 17 additions & 5 deletions listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ import (
//
// As shown above, a Listener consists of a net.Listener to accept
// incoming connections and a WATM to handle the incoming connections
// from an external source. Accept() returns a net.Conn that caller
// can Read()-from or Write()-to.
// from an external source. Accept() returns a net.Conn that caller may
// Read()-from or Write()-to.
type Listener interface {
// Listener implements net.Listener
net.Listener

// AcceptWATER waits for and returns the next connection to the listener
// as a water.Conn.
AcceptWATER() (Conn, error)

mustEmbedUnimplementedListener()
}

Expand All @@ -38,28 +43,35 @@ var (
ErrListenerAlreadyRegistered = errors.New("water: listener already registered")
ErrListenerVersionNotFound = errors.New("water: listener version not found")
ErrUnimplementedListener = errors.New("water: unimplemented Listener")

_ Listener = (*UnimplementedListener)(nil) // type guard
)

// UnimplementedListener is a Listener that always returns errors.
//
// It is used to ensure forward compatibility of the Listener interface.
type UnimplementedListener struct{}

// Accept implements Listener.Accept().
// Accept implements net.Listener.Accept().
func (*UnimplementedListener) Accept() (net.Conn, error) {
return nil, ErrUnimplementedListener
}

// Close implements Listener.Close().
// Close implements net.Listener.Close().
func (*UnimplementedListener) Close() error {
return ErrUnimplementedListener
}

// Addr implements Listener.Addr().
// Addr implements net.Listener.Addr().
func (*UnimplementedListener) Addr() net.Addr {
return nil
}

// AcceptWATER implements water.Listener.AcceptWATER().
func (*UnimplementedListener) AcceptWATER() (Conn, error) {
return nil, ErrUnimplementedListener
}

// mustEmbedUnimplementedListener is a function that developers cannot
func (*UnimplementedListener) mustEmbedUnimplementedListener() {}

Expand Down
18 changes: 16 additions & 2 deletions relay.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package water

import "errors"
import (
"errors"
"net"
)

// Relay listens on a local network address and handles requests
// on incoming connections by passing the incoming connection to
Expand Down Expand Up @@ -32,6 +35,11 @@ type Relay interface {
// does not close the established connections.
Close() error

// Addr returns the local address the relay is listening on.
//
// If no address is available, instead of panicking it returns nil.
Addr() net.Addr

mustEmbedUnimplementedRelay()
}

Expand All @@ -43,8 +51,9 @@ var (
ErrRelayAlreadyRegistered = errors.New("water: relay already registered")
ErrRelayVersionNotFound = errors.New("water: relay version not found")
ErrUnimplementedRelay = errors.New("water: unimplemented relay")
ErrRelayAlreadyStarted = errors.New("water: relay already started") // RelayTo and ListenAndRelayTo may return this error if a relay was reused.

ErrRelayAlreadyStarted = errors.New("water: relay already started") // RelayTo and ListenAndRelayTo may return this error if a relay was reused.
_ Relay = (*UnimplementedRelay)(nil) // type guard
)

// UnimplementedRelay is a Relay that always returns errors.
Expand All @@ -67,6 +76,11 @@ func (*UnimplementedRelay) Close() error {
return ErrUnimplementedRelay
}

// Addr implements Relay.Addr().
func (*UnimplementedRelay) Addr() net.Addr {
return nil
}

// mustEmbedUnimplementedRelay is a function that developers cannot
// manually implement. It is used to ensure forward compatibility of
// the Relay interface.
Expand Down
File renamed without changes.
Binary file added testdata/v0/reverse.wasm
Binary file not shown.
2 changes: 0 additions & 2 deletions transport/v0/conn.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build !exclude_v0

package v0

import (
Expand Down
Loading

0 comments on commit eb43f3b

Please sign in to comment.