-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update: final v0 (plus) API and spec (#7)
* new: moving runtime towards v0+ * new: v0+ spec * fix: SetReadDeadline otherwise may block too long * update: v0 finalized spec with namespace * style: format code with Gofumpt This commit fixes the style issues introduced in 70401cf according to the output from Gofumpt. Details: #7 * fix: remove benchmark result benchmark result should be ignored. * update: .gitignore ignore bench.txt * fix: UnixConn and TCPConn failing on macOS * fix: deepsource detected bugs and issues * docs: update README * update: ci and readme - Update CI to fail fast. Add `golangci-lint` to CI. - Update full name WebAssembly Transport Executables Runtime. Update badges. * satisfy the linting gods * style: format code with Gofumpt This commit fixes the style issues introduced in 0422575 according to the output from Gofumpt. Details: #7 * readme pass --------- Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com> Co-authored-by: Jack Wampler <[email protected]>
- Loading branch information
1 parent
baa9b44
commit ec4b9f1
Showing
54 changed files
with
2,421 additions
and
1,803 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,4 +35,7 @@ Cargo.lock | |
# vendor/ | ||
|
||
# Go workspace file | ||
go.work | ||
go.work | ||
|
||
# Benchmark file | ||
bench.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,110 @@ | ||
# W.A.T.E.R.: WebAssembly Transport Executable Reactor | ||
[![License](https://img.shields.io/badge/License-Apache_2.0-yellowgreen.svg)](https://opensource.org/licenses/Apache-2.0) [![Build Status](https://github.com/gaukas/water/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/gaukas/water/actions/workflows/go.yml) | ||
# W.A.T.E.R.: WebAssembly Transport Executables Runtime | ||
[![License](https://img.shields.io/badge/License-Apache_2.0-yellowgreen.svg)](https://opensource.org/licenses/Apache-2.0) | ||
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgaukas%2Fwater.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgaukas%2Fwater?ref=badge_shield&issueType=license) | ||
[![Build Status](https://github.com/gaukas/water/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/gaukas/water/actions/workflows/go.yml) | ||
[![Go Reference](https://pkg.go.dev/badge/github.com/gaukas/water.svg)](https://pkg.go.dev/github.com/gaukas/water) | ||
[![DeepSource](https://app.deepsource.com/gh/gaukas/water.svg/?label=resolved+issues&show_trend=true&token=SonUOOtyjJHnPuIdEBGZp4zx)](https://app.deepsource.com/gh/gaukas/water/) | ||
|
||
W.A.T.E.R. provides a runtime environment for WebAssembly modules to run in and work as a application-layer transport protocol. It is designed to be highly portable and lightweight, and can be used as a replacement for pluggable transports. | ||
<div style="width: 100%; height = 160px"> | ||
<div style="width: 75%; height: 150px; float: left;"> | ||
WATER-go provides a golang runtime for WebAssembly Transport Modules(WATM) as a pluggable | ||
application-layer transport protocol provider. It is designed to be highly portable and | ||
lightweight, allowing for rapidly deployable pluggable transports. While other pluggable | ||
transport implementations require a fresh client deployment (and app-store review) to update | ||
their protocol WATER allows <b><u>dynamic delivery of new transports</u></b> in real time | ||
over the network.<br /> | ||
<br /> | ||
</div> | ||
<div style="margin-left: 80%; height: 150px;"> | ||
<img src=".github/assets/logo_v0.svg" alt="WATER wasm transport" align="right"> | ||
</div> | ||
</div> | ||
|
||
## API | ||
Information about writing, buiding, and sharing WebAssembly Transport Modules can be found in the | ||
[water-rs](https://github.com/erikziyunchi/water-rs/tree/main/crates/wasm) library. | ||
|
||
Currently, W.A.T.E.R. provides a set of APIs based on **WASI Preview 1 (wasip1)** snapshot. | ||
# Usage | ||
|
||
### Config | ||
A `Config` is a struct that contains the configuration for a WASI instance. It is used to configure the WASI reactor before starting it. | ||
<!-- ## API --> | ||
Based on **WASI Preview 1 (wasip1)** snapshot, currently W.A.T.E.R. provides a set of | ||
`net`-like APIs, including `Dialer`, `Listener` and `Relay`. | ||
|
||
### Dialer | ||
### Dialer | ||
|
||
A `Dialer` could be used to dial a remote address upon `Dial()` and return a `net.Conn` back to the caller once the connection is established. Caller could use the `net.Conn` to read and write data to the remote address and the data will be processed by a WebAssembly instance. | ||
A `Dialer` connects to a remote address and returns a `net.Conn` to the caller if the connection can | ||
be successfully established. The `net.Conn` then provides tunnelled read and write to the remote | ||
endpoint with the WebAssembly module wrapping / encrypting / transforming the traffic. | ||
|
||
`Dialer` is used to encapsulate the caller's connection into an outbound, transport-wrapped | ||
connection. | ||
|
||
```go | ||
wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm") | ||
|
||
config := &water.Config{ | ||
TMBin: wasm, | ||
} | ||
|
||
dialer, err := water.NewDialer(config) | ||
conn, err := dialer.Dial("tcp", remoteAddr) | ||
// ... | ||
``` | ||
|
||
### Listener | ||
|
||
A `Listener` could be used to listen on a local address. Upon `Accept()`, it returns a `net.Conn` back once an incoming connection is accepted from the wrapped listener. Caller could use the `net.Conn` to read and write data to the remote address and the data will be processed by a WebAssembly instance. | ||
A `Listener` listens on a local address for incoming connections which it `Accept()`s, returning | ||
a `net.Conn` for the caller to handle. The WebAssembly Module is responsible for the initial | ||
accpt allowing it to implement both the server side handshake as well as any unwrap / decrypt | ||
/reform operations required to validate and re-assemble the stream. The `net.Conn` returned provides | ||
the normalized stream, and allows the caller to write back to the client with the WebAssembly module | ||
encoding / encrypting / transforming traffic to be obfuscated on the wire on the way to the remote | ||
client. | ||
|
||
|
||
`Listener` is used to decapsulate incoming transport-wrapped connections for the caller to handle, | ||
managing the tunnel obfuscation once a connection is established. | ||
|
||
```go | ||
wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm") | ||
|
||
config := &water.Config{ | ||
TMBin: wasm, | ||
} | ||
|
||
lis, err := config.Listen("tcp", localAddr) | ||
defer lis.Close() | ||
log.Infof("Listening on %s", lis.Addr().String()) | ||
|
||
clientCntr := 0 | ||
for { | ||
conn, err := lis.Accept() | ||
// ... | ||
} | ||
``` | ||
|
||
### Relay | ||
|
||
A `Relay` combines the role of `Dialer` and `Listener`. It listens on a local address `Accept()`-ing | ||
incoming connections and `Dial()`-ing the remote endpoints on establishment. The connecions are | ||
tunneled through the WebAssembly Transport Module allowing the module to handshake, encode, | ||
transform, pad, etc. without any caller interaction. The internal `Relay` manages the incoming | ||
connections as well as the associated outgoing connectons. | ||
|
||
`Relay` is a managed many-to-many handler for incoming connections that uses the WebAssemble module | ||
to tunnel traffic. | ||
|
||
```go | ||
wasm, err := os.ReadFile("./examples/v0plus/plain/plain.wasm") | ||
|
||
config := &water.Config{ | ||
TMBin: wasm, | ||
} | ||
|
||
relay, err := water.NewRelay(config) | ||
|
||
### Server | ||
err = relay.ListenAndRelayTo("tcp", localAddr, "tcp", remoteAddr) | ||
``` | ||
|
||
A `Server` somewhat combines the role of `Dialer` and `Listener`. It could be used to listen on a local address and dial a remote address and automatically `Accept()` the incoming connections, feed them into the WebAssembly instance and `Dial()` the pre-defined remote address. Without any caller interaction, the `Server` will automatically* handle the data transmission between the two ends. | ||
## Example | ||
|
||
***TODO: Server could not be realistic until WASI multi-threading or blocking mainloop is supported** | ||
See [examples](./examples) for example usecase of W.A.T.E.R. API, including `Dialer`, `Listener` and `Relay`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package water_test | ||
|
||
import ( | ||
"crypto/rand" | ||
"net" | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/gaukas/water" | ||
) | ||
|
||
func TestConfigClone(t *testing.T) { | ||
c := &water.Config{ | ||
TMBin: make([]byte, 256), | ||
NetworkDialerFunc: nil, // functions aren't deeply equal unless nil | ||
NetworkListener: &net.TCPListener{}, | ||
TMConfig: water.TMConfig{ | ||
FilePath: "/tmp/watm.toml", | ||
}, | ||
} | ||
|
||
_, err := rand.Read(c.TMBin) | ||
if err != nil { | ||
t.Fatalf("rand.Read error: %v", err) | ||
} | ||
|
||
ccloned := c.Clone() | ||
|
||
if !reflect.DeepEqual(c, ccloned) { | ||
t.Errorf("Clone() = %v, want %v", ccloned, c) | ||
} | ||
} |
Oops, something went wrong.