Skip to content

Commit

Permalink
update: final edits to v1 spec
Browse files Browse the repository at this point in the history
Signed-off-by: Gaukas Wang <[email protected]>
  • Loading branch information
gaukas committed Jul 18, 2024
1 parent 235bb15 commit a951f79
Show file tree
Hide file tree
Showing 23 changed files with 581 additions and 488 deletions.
81 changes: 41 additions & 40 deletions tinygo/v1/dialer.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,66 @@
package v1

import v1net "github.com/refraction-networking/watm/tinygo/v1/net"

type dialer struct {
// outbound: pick one
wt WrappingTransport
dt DialingTransport

locked bool
}

func (d *dialer) ConfigurableTransport() ConfigurableTransport {
func (d *dialer) Configurable() Configurable {
if d.wt != nil {
if wt, ok := d.wt.(ConfigurableTransport); ok {
if wt, ok := d.wt.(Configurable); ok {
return wt
}
}

if d.dt != nil {
if dt, ok := d.dt.(ConfigurableTransport); ok {
} else if d.dt != nil {
if dt, ok := d.dt.(Configurable); ok {
return dt
}
}

return nil
}

func (d *dialer) Initialize() {
// TODO: allow initialization on dialer
}

var globalDialer dialer

// BuildDialerWithOutboundTransport arms the dialer with a
// [WrappingTransport] or [DialingTransport] that is used to wrap
// a [v1net.Conn] into another [net.Conn] by providing some
// high-level application layer protocol or dial a remote address
// and provide high-level application layer protocol over the dialed
// connection.
func BuildDialerWithOutboundTransport(anyTransport any) {
switch t := anyTransport.(type) {
case WrappingTransport:
BuildDialerWithWrappingTransport(t)
case DialingTransport:
BuildDialerWithDialingTransport(t)
default:
panic("transport type not supported")
}
}

// BuildDialerWithWrappingTransport arms the dialer with a
// [WrappingTransport] that is used to wrap a [v1net.Conn] into
// another [net.Conn] by providing some high-level application
// layer protocol.
//
// The caller MUST keep in mind that the [WrappingTransport] is
// used to wrap the outbound connection (to the remote address), not the
// connection from the caller (the client).
//
// Mutually exclusive with [BuildDialerWithDialingTransport].
func BuildDialerWithWrappingTransport(wt WrappingTransport) {
if globalDialer.locked {
panic("dialer is locked")
}

globalDialer.wt = wt
globalDialer.dt = nil
globalDialer.locked = true
}

// BuildDialerWithDialingTransport arms the dialer with a
Expand All @@ -45,36 +70,12 @@ func BuildDialerWithWrappingTransport(wt WrappingTransport) {
//
// Mutually exclusive with [BuildDialerWithWrappingTransport].
func BuildDialerWithDialingTransport(dt DialingTransport) {
panic("not implemented until Runtime start passing remote access into WATM")
// globalDialer.dt = dt
// globalDialer.wt = nil
}

type fixedDialer struct {
fdt FixedDialingTransport
}

// ConfigurableTransport returns the ConfigurableTransport of the
// underlying DialingTransport if it implements the interface.
func (f *fixedDialer) ConfigurableTransport() ConfigurableTransport {
if f.fdt != nil {
if dt, ok := f.fdt.(ConfigurableTransport); ok {
return dt
}
if globalDialer.locked {
panic("dialer is locked")
}

return nil
}

func (f *fixedDialer) Initialize() {
// TODO: allow initialization on dialer
}

var globalFixedDialer fixedDialer

// BuildFixedDialerWithFixedDialingTransport arms the fixedDialer with a
// [FixedDialingTransport] that provide high-level application layer protocol
// over the dialed connection.
func BuildFixedDialerWithFixedDialingTransport(fdt FixedDialingTransport) {
globalFixedDialer.fdt = fdt
globalDialer.dt = dt
dt.SetDialer(v1net.Dial)
globalDialer.wt = nil
globalDialer.locked = true
}
18 changes: 12 additions & 6 deletions tinygo/v1/examples/plain/dialing_transport.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package main

import v1net "github.com/refraction-networking/watm/tinygo/v1/net"
import (
v1 "github.com/refraction-networking/watm/tinygo/v1"
v1net "github.com/refraction-networking/watm/tinygo/v1/net"
)

type PlainFixedDialingTransport struct {
// type guard
var _ v1.DialingTransport = (*PlainDialingTransport)(nil)

type PlainDialingTransport struct {
dialer func(network, address string) (v1net.Conn, error)
}

func (fdt *PlainFixedDialingTransport) SetDialer(dialer func(network, address string) (v1net.Conn, error)) {
fdt.dialer = dialer
func (dt *PlainDialingTransport) SetDialer(dialer func(network, address string) (v1net.Conn, error)) {
dt.dialer = dialer
}

func (fdt *PlainFixedDialingTransport) DialFixed() (v1net.Conn, error) {
conn, err := fdt.dialer("tcp", "localhost:7700") // TODO: hardcoded address, any better idea?
func (dt *PlainDialingTransport) Dial(network, address string) (v1net.Conn, error) {
conn, err := dt.dialer(network, address) // dial the passed address
if err != nil {
return nil, err
}
Expand Down
26 changes: 26 additions & 0 deletions tinygo/v1/examples/plain/listening_transport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
v1 "github.com/refraction-networking/watm/tinygo/v1"
v1net "github.com/refraction-networking/watm/tinygo/v1/net"
)

// type guard
var _ v1.ListeningTransport = (*PlainListeningTransport)(nil)

type PlainListeningTransport struct {
listener v1net.Listener
}

func (lt *PlainListeningTransport) SetListener(listener v1net.Listener) {
lt.listener = listener
}

func (lt *PlainListeningTransport) Accept() (v1net.Conn, error) {
conn, err := lt.listener.Accept() // accept the connection
if err != nil {
return nil, err
}

return &PlainConn{conn}, conn.SetNonBlock(true) // must set non-block, otherwise will block on read and lose fairness
}
7 changes: 3 additions & 4 deletions tinygo/v1/examples/plain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import (
func init() {
v1.WorkerFairness(false)
v1.SetReadBufferSize(1024) // 1024B buffer for copying data
v1.BuildDialerWithWrappingTransport(&PlainWrappingTransport{})
v1.BuildListenerWithWrappingTransport(&PlainWrappingTransport{})
v1.BuildRelayWithWrappingTransport(&PlainWrappingTransport{}, v1.RelayWrapRemote)
v1.BuildFixedDialerWithFixedDialingTransport(&PlainFixedDialingTransport{})
v1.BuildDialerWithDialingTransport(&PlainDialingTransport{})
v1.BuildListenerWithListeningTransport(&PlainListeningTransport{})
v1.BuildRelayWithOutboundWrappingTransport(&PlainWrappingTransport{})
}

func main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var _ v1.WrappingTransport = (*PlainWrappingTransport)(nil)
type PlainWrappingTransport struct {
}

func (rwt *PlainWrappingTransport) Wrap(conn v1net.Conn) (v1net.Conn, error) {
func (*PlainWrappingTransport) Wrap(conn v1net.Conn) (v1net.Conn, error) {
return &PlainConn{conn}, conn.SetNonBlock(true) // must set non-block, otherwise will block on read and lose fairness
}

Expand Down
10 changes: 5 additions & 5 deletions tinygo/v1/examples/reverse/dialing_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package main

import v1net "github.com/refraction-networking/watm/tinygo/v1/net"

type ReverseFixedDialingTransport struct {
type ReverseDialingTransport struct {
dialer func(network, address string) (v1net.Conn, error)
}

func (fdt *ReverseFixedDialingTransport) SetDialer(dialer func(network, address string) (v1net.Conn, error)) {
fdt.dialer = dialer
func (dt *ReverseDialingTransport) SetDialer(dialer func(network, address string) (v1net.Conn, error)) {
dt.dialer = dialer
}

func (fdt *ReverseFixedDialingTransport) DialFixed() (v1net.Conn, error) {
conn, err := fdt.dialer("tcp", "localhost:7700") // TODO: hardcoded address, any better idea?
func (dt *ReverseDialingTransport) Dial(network, address string) (v1net.Conn, error) {
conn, err := dt.dialer(network, address) // dial the passed address
if err != nil {
return nil, err
}
Expand Down
26 changes: 26 additions & 0 deletions tinygo/v1/examples/reverse/listening_transport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
v1 "github.com/refraction-networking/watm/tinygo/v1"
v1net "github.com/refraction-networking/watm/tinygo/v1/net"
)

// type guard
var _ v1.ListeningTransport = (*ReverseListeningTransport)(nil)

type ReverseListeningTransport struct {
listener v1net.Listener
}

func (lt *ReverseListeningTransport) SetListener(listener v1net.Listener) {
lt.listener = listener
}

func (lt *ReverseListeningTransport) Accept() (v1net.Conn, error) {
conn, err := lt.listener.Accept() // accept the connection
if err != nil {
return nil, err
}

return &ReverseConn{conn}, conn.SetNonBlock(true) // must set non-block, otherwise will block on read and lose fairness
}
7 changes: 3 additions & 4 deletions tinygo/v1/examples/reverse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package main
import v1 "github.com/refraction-networking/watm/tinygo/v1"

func init() {
v1.BuildDialerWithWrappingTransport(&ReverseWrappingTransport{})
v1.BuildListenerWithWrappingTransport(&ReverseWrappingTransport{})
v1.BuildRelayWithWrappingTransport(&ReverseWrappingTransport{}, v1.RelayWrapRemote)
v1.BuildFixedDialerWithFixedDialingTransport(&ReverseFixedDialingTransport{})
v1.BuildDialerWithDialingTransport(&ReverseDialingTransport{})
v1.BuildListenerWithListeningTransport(&ReverseListeningTransport{})
v1.BuildRelayWithOutboundWrappingTransport(&ReverseWrappingTransport{})
}

func main() {}
35 changes: 35 additions & 0 deletions tinygo/v1/examples/reverse/reverse_conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
v1net "github.com/refraction-networking/watm/tinygo/v1/net"
)

type ReverseConn struct {
v1net.Conn // embedded Conn
}

func (rc *ReverseConn) Read(b []byte) (n int, err error) {
tmpBuf := make([]byte, len(b))
n, err = rc.Conn.Read(tmpBuf)
if err != nil {
return 0, err
}

// reverse all bytes read successfully so far
for i := 0; i < n; i++ {
b[i] = tmpBuf[n-i-1]
}

return n, err
}

func (rc *ReverseConn) Write(b []byte) (n int, err error) {
tmpBuf := make([]byte, len(b))

// reverse the bytes to be written
for i := 0; i < len(b); i++ {
tmpBuf[i] = b[len(b)-i-1]
}

return rc.Conn.Write(tmpBuf[:len(b)])
}
30 changes: 0 additions & 30 deletions tinygo/v1/examples/reverse/wrapper_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,3 @@ type ReverseWrappingTransport struct {
func (rwt *ReverseWrappingTransport) Wrap(conn v1net.Conn) (v1net.Conn, error) {
return &ReverseConn{conn}, conn.SetNonBlock(true) // must set non-block, otherwise will block on read and lose fairness
}

type ReverseConn struct {
v1net.Conn // embedded Conn
}

func (rc *ReverseConn) Read(b []byte) (n int, err error) {
tmpBuf := make([]byte, len(b))
n, err = rc.Conn.Read(tmpBuf)
if err != nil {
return 0, err
}

// reverse all bytes read successfully so far
for i := 0; i < n; i++ {
b[i] = tmpBuf[n-i-1]
}

return n, err
}

func (rc *ReverseConn) Write(b []byte) (n int, err error) {
tmpBuf := make([]byte, len(b))

// reverse the bytes to be written
for i := 0; i < len(b); i++ {
tmpBuf[i] = b[len(b)-i-1]
}

return rc.Conn.Write(tmpBuf[:len(b)])
}
2 changes: 1 addition & 1 deletion tinygo/v1/examples/utls/wrapper_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (uwt *UTLSClientWrappingTransport) Wrap(conn v1net.Conn) (v1net.Conn, error
}, nil
}

var _ v1.ConfigurableTransport = (*UTLSClientWrappingTransport)(nil)
var _ v1.Configurable = (*UTLSClientWrappingTransport)(nil)

func (uwt *UTLSClientWrappingTransport) Configure(config []byte) error {
configurables := &lib.Configurables{}
Expand Down
Loading

0 comments on commit a951f79

Please sign in to comment.