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

[M2] app2 implementation #543

Merged
merged 44 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
790571e
Add basic structures
Darkren Aug 30, 2019
5299283
Add methods for HSFrame
Darkren Aug 30, 2019
7deb42b
Fix PR queries
Darkren Aug 31, 2019
95a0d28
Add HSFrame tests
Darkren Aug 31, 2019
804b770
Add more work
Darkren Sep 1, 2019
5029589
Add yamux conn multiplexing
Darkren Sep 6, 2019
972fa99
Add some shape to the client
Darkren Sep 8, 2019
0a6506d
Add some work on server
Darkren Sep 9, 2019
67ab801
More work on app2
Darkren Sep 9, 2019
a07d8a0
Move `listen` to lm, add `Close` to lm
Darkren Sep 10, 2019
8dc1513
`acceptedConn` -> `clientConn`, `clientConn` -> `serverConn`
Darkren Sep 10, 2019
a282c5a
More work on app2
Darkren Sep 10, 2019
e2afc9e
Add RPC server for server
Darkren Sep 12, 2019
f374c39
Finish RPC communication
Darkren Sep 15, 2019
7bcafc9
Add comments
Darkren Sep 16, 2019
cf5e105
Impement `net` interfaces
Darkren Sep 16, 2019
f68b3e0
Add proper port handling
Darkren Sep 16, 2019
a161a2d
Remove `freeLocalPort` from `Conn`
Darkren Sep 16, 2019
a790f2c
Start to merge managers
Darkren Sep 16, 2019
3e295fd
Add more comments, finish manager
Darkren Sep 17, 2019
ca7fcae
Start implementing `manager` tests
Darkren Sep 17, 2019
1daf6c0
Almost finish `manager` tests
Darkren Sep 17, 2019
8b8ad33
Add client tests
Darkren Sep 18, 2019
0e4a24a
Add conn tests
Darkren Sep 18, 2019
f43c6bf
Add `Listener` tests
Darkren Sep 18, 2019
7ef6861
Refactor tests a bit
Darkren Sep 18, 2019
946a3dc
Merge branch 'mainnet-milestone2' of https://github.com/skycoin/skywi…
Darkren Sep 18, 2019
f5986d5
Add networker stuff
Darkren Sep 20, 2019
25489ef
Adjust code to the `Networker` usage
Darkren Sep 20, 2019
eb42bca
Refactor a bit
Darkren Sep 21, 2019
0714e55
Add more tests
Darkren Sep 21, 2019
3491994
Add even more tests
Darkren Sep 21, 2019
07d5b80
And more tests
Darkren Sep 22, 2019
b2dcbbb
Fix some queries
Darkren Sep 23, 2019
e243192
Finish RPC gateway tests
Darkren Sep 23, 2019
f9c933f
Add `WrappedConn`
Darkren Sep 24, 2019
34c6e29
Pass assigned local port from the server
Darkren Sep 24, 2019
677fb24
Add conn/listener tracking
Darkren Sep 24, 2019
3a9fdba
Fix client tests
Darkren Sep 24, 2019
8c02d73
Partially fix `idManager` tests
Darkren Sep 24, 2019
d7e140b
Get rid of porter
Darkren Sep 25, 2019
17ba146
Fix PR queries
Darkren Sep 25, 2019
d560351
Fix tests
Darkren Sep 25, 2019
662c229
Add rpcClient tests
Darkren Sep 26, 2019
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
14 changes: 5 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ module github.com/skycoin/skywire
go 1.12

require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/creack/pty v1.1.7
github.com/go-chi/chi v4.0.2+incompatible
Expand All @@ -15,18 +13,16 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/pkg/errors v0.8.1
github.com/pkg/profile v1.3.0
github.com/prometheus/client_golang v1.1.0
github.com/prometheus/common v0.6.0
github.com/prometheus/common v0.7.0
github.com/sirupsen/logrus v1.4.2
github.com/skycoin/dmsg v0.0.0-20190904181013-b781e3cbebc6
github.com/skycoin/dmsg v0.0.0-20190805065636-70f4c32a994f
github.com/skycoin/skycoin v0.26.0
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.4.0
go.etcd.io/bbolt v1.3.3
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7
golang.org/x/net v0.0.0-20190916140828-c8589233b77d
)

// Uncomment for tests with alternate branches of 'dmsg'
//replace github.com/skycoin/dmsg => ../dmsg
19 changes: 12 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
Expand Down Expand Up @@ -77,6 +78,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.3.0 h1:OQIvuDgm00gWVWGTf4m4mCt6W1/0YqU7Ntg0mySWgaI=
github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -89,8 +92,9 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
Expand All @@ -99,8 +103,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/skycoin/dmsg v0.0.0-20190904181013-b781e3cbebc6 h1:YwSyQXUyG/EFp3xCGMkOldgQNpw8XLfmocQND4/Y3aw=
github.com/skycoin/dmsg v0.0.0-20190904181013-b781e3cbebc6/go.mod h1:obZYZp8eKR7Xqz+KNhJdUE6Gvp6rEXbDO8YTlW2YXgU=
github.com/skycoin/dmsg v0.0.0-20190805065636-70f4c32a994f h1:WWjaxOXoj6oYelm67MNtJbg51HQALjKAyhs2WAHgpZs=
github.com/skycoin/dmsg v0.0.0-20190805065636-70f4c32a994f/go.mod h1:obZYZp8eKR7Xqz+KNhJdUE6Gvp6rEXbDO8YTlW2YXgU=
github.com/skycoin/skycoin v0.26.0 h1:xDxe2r8AclMntZ550Y/vUQgwgLtwrf9Wu5UYiYcN5/o=
github.com/skycoin/skycoin v0.26.0/go.mod h1:78nHjQzd8KG0jJJVL/j0xMmrihXi70ti63fh8vXScJw=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
Expand All @@ -112,6 +116,7 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand All @@ -125,15 +130,15 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190916140828-c8589233b77d h1:mCMDWKhNO37A7GAhOpHPbIw1cjd0V86kX1/WA9c7FZ8=
golang.org/x/net v0.0.0-20190916140828-c8589233b77d/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
87 changes: 87 additions & 0 deletions pkg/app2/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package app2

import (
"context"
"net"

"github.com/skycoin/dmsg/cipher"
"github.com/skycoin/dmsg/netutil"
"github.com/skycoin/skywire/pkg/routing"
)

// Client is used by skywire apps.
type Client struct {
pk cipher.PubKey
pid ProcID
rpc ServerRPCClient
porter *netutil.Porter
Darkren marked this conversation as resolved.
Show resolved Hide resolved
}

// NewClient creates a new `Client`. The `Client` needs to be provided with:
// - log: Logger instance.
// - localPK: The local public key of the parent skywire visor.
// - pid: The procID assigned for the process that Client is being used by.
// - rpc: RPC client to communicate with the server.
func NewClient(localPK cipher.PubKey, pid ProcID, rpc ServerRPCClient, porter *netutil.Porter) *Client {
Darkren marked this conversation as resolved.
Show resolved Hide resolved
return &Client{
pk: localPK,
pid: pid,
rpc: rpc,
porter: porter,
}
}

// Dial dials the remote node using `remote`.
func (c *Client) Dial(remote routing.Addr) (net.Conn, error) {
Darkren marked this conversation as resolved.
Show resolved Hide resolved
localPort, free, err := c.porter.ReserveEphemeral(context.TODO(), nil)
if err != nil {
return nil, err
}

connID, err := c.rpc.Dial(remote)
if err != nil {
free()
return nil, err
}

conn := &Conn{
id: connID,
rpc: c.rpc,
local: routing.Addr{
PubKey: c.pk,
Port: routing.Port(localPort),
},
remote: remote,
freeLocalPort: free,
}

return conn, nil
}

// Listen listens on the specified `port` for the incoming connections.
func (c *Client) Listen(port routing.Port) (net.Listener, error) {
Darkren marked this conversation as resolved.
Show resolved Hide resolved
ok, free := c.porter.Reserve(uint16(port), nil)
if !ok {
return nil, ErrPortAlreadyBound
}

local := routing.Addr{
PubKey: c.pk,
Port: port,
}

lisID, err := c.rpc.Listen(local)
if err != nil {
free()
return nil, err
}

listener := &Listener{
id: lisID,
rpc: c.rpc,
addr: local,
freePort: free,
}

return listener, nil
}
142 changes: 142 additions & 0 deletions pkg/app2/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package app2

import (
"testing"

"github.com/pkg/errors"
"github.com/stretchr/testify/require"

"github.com/skycoin/skywire/pkg/routing"

"github.com/skycoin/dmsg/cipher"

"github.com/skycoin/dmsg/netutil"
)

func TestClient_Dial(t *testing.T) {
localPK, _ := cipher.GenerateKeyPair()
pid := ProcID(1)

remotePK, _ := cipher.GenerateKeyPair()
remotePort := routing.Port(120)
remote := routing.Addr{
PubKey: remotePK,
Port: remotePort,
}

t.Run("ok", func(t *testing.T) {
dialConnID := uint16(1)
var dialErr error

rpc := &MockServerRPCClient{}
rpc.On("Dial", remote).Return(dialConnID, dialErr)

cl := NewClient(localPK, pid, rpc, netutil.NewPorter(netutil.PorterMinEphemeral))

wantConn := &Conn{
id: dialConnID,
rpc: rpc,
local: routing.Addr{
PubKey: localPK,
},
remote: remote,
}

conn, err := cl.Dial(remote)
appConn, ok := conn.(*Conn)
require.True(t, ok)

require.NoError(t, err)
require.Equal(t, wantConn.id, appConn.id)
require.Equal(t, wantConn.rpc, appConn.rpc)
require.Equal(t, wantConn.local.PubKey, appConn.local.PubKey)
require.Equal(t, wantConn.remote, appConn.remote)
require.NotNil(t, appConn.freeLocalPort)
portVal, ok := cl.porter.PortValue(uint16(appConn.local.Port))
require.True(t, ok)
require.Nil(t, portVal)
})

t.Run("dial error", func(t *testing.T) {
dialErr := errors.New("dial error")

rpc := &MockServerRPCClient{}
rpc.On("Dial", remote).Return(uint16(0), dialErr)

cl := NewClient(localPK, pid, rpc, netutil.NewPorter(netutil.PorterMinEphemeral))

conn, err := cl.Dial(remote)
require.Equal(t, dialErr, err)
require.Nil(t, conn)
})
}

func TestClient_Listen(t *testing.T) {
localPK, _ := cipher.GenerateKeyPair()
pid := ProcID(1)

port := routing.Port(1)
local := routing.Addr{
PubKey: localPK,
Port: port,
}

t.Run("ok", func(t *testing.T) {
listenLisID := uint16(1)
var listenErr error

rpc := &MockServerRPCClient{}
rpc.On("Listen", local).Return(listenLisID, listenErr)

cl := NewClient(localPK, pid, rpc, netutil.NewPorter(netutil.PorterMinEphemeral))

wantListener := &Listener{
id: listenLisID,
rpc: rpc,
addr: local,
}

listener, err := cl.Listen(port)
require.Nil(t, err)
appListener, ok := listener.(*Listener)
require.True(t, ok)
require.Equal(t, wantListener.id, appListener.id)
require.Equal(t, wantListener.rpc, appListener.rpc)
require.Equal(t, wantListener.addr, appListener.addr)
require.NotNil(t, appListener.freePort)
portVal, ok := cl.porter.PortValue(uint16(port))
require.True(t, ok)
require.Nil(t, portVal)
})

t.Run("port is already bound", func(t *testing.T) {
porter := netutil.NewPorter(netutil.PorterMinEphemeral)
ok, _ := porter.Reserve(uint16(port), nil)
require.True(t, ok)

rpc := &MockServerRPCClient{}

cl := NewClient(localPK, pid, rpc, porter)

wantErr := ErrPortAlreadyBound

listener, err := cl.Listen(port)
require.Equal(t, wantErr, err)
require.Nil(t, listener)
})

t.Run("listen error", func(t *testing.T) {
listenErr := errors.New("listen error")

rpc := &MockServerRPCClient{}
rpc.On("Listen", local).Return(uint16(0), listenErr)

cl := NewClient(localPK, pid, rpc, netutil.NewPorter(netutil.PorterMinEphemeral))

listener, err := cl.Listen(port)
require.Equal(t, listenErr, err)
require.Nil(t, listener)
_, ok := cl.porter.PortValue(uint16(port))
require.False(t, ok)
})
}
64 changes: 64 additions & 0 deletions pkg/app2/conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package app2

import (
"net"
"time"

"github.com/skycoin/skywire/pkg/routing"
)

// Conn is a connection from app client to the server.
// Implements `net.Conn`.
type Conn struct {
Darkren marked this conversation as resolved.
Show resolved Hide resolved
id uint16
rpc ServerRPCClient
local routing.Addr
remote routing.Addr
freeLocalPort func()
}

func (c *Conn) Read(b []byte) (int, error) {
n, readBytes, err := c.rpc.Read(c.id, b)
if err != nil {
return 0, err
}

// TODO: check for slice border
copy(b[:n], readBytes[:n])

return n, err
}

func (c *Conn) Write(b []byte) (int, error) {
return c.rpc.Write(c.id, b)
}

func (c *Conn) Close() error {
defer func() {
if c.freeLocalPort != nil {
c.freeLocalPort()
}
}()

return c.rpc.CloseConn(c.id)
}

func (c *Conn) LocalAddr() net.Addr {
return c.local
}

func (c *Conn) RemoteAddr() net.Addr {
return c.remote
}

func (c *Conn) SetDeadline(t time.Time) error {
return errMethodNotImplemented
}

func (c *Conn) SetReadDeadline(t time.Time) error {
return errMethodNotImplemented
}

func (c *Conn) SetWriteDeadline(t time.Time) error {
return errMethodNotImplemented
}
Loading