Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefane Fermigier
neo
Commits
341b2124
Commit
341b2124
authored
Jun 14, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
b78c529a
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
192 additions
and
131 deletions
+192
-131
go/neo/server/cluster_test.go
go/neo/server/cluster_test.go
+10
-2
go/xcommon/xnet/net.go
go/xcommon/xnet/net.go
+3
-1
go/xcommon/xnet/pipenet/pipenet.go
go/xcommon/xnet/pipenet/pipenet.go
+177
-128
go/xcommon/xnet/trace.go
go/xcommon/xnet/trace.go
+2
-0
No files found.
go/neo/server/cluster_test.go
View file @
341b2124
...
@@ -117,7 +117,12 @@ func (tc *TraceChecker) ExpectNetTx(src, dst string, pkt string) {
...
@@ -117,7 +117,12 @@ func (tc *TraceChecker) ExpectNetTx(src, dst string, pkt string) {
func
TestMasterStorage
(
t
*
testing
.
T
)
{
func
TestMasterStorage
(
t
*
testing
.
T
)
{
tracer
:=
&
MyTracer
{
xtesting
.
NewSyncTracer
()}
tracer
:=
&
MyTracer
{
xtesting
.
NewSyncTracer
()}
tc
:=
xtesting
.
NewTraceChecker
(
t
,
tracer
.
SyncTracer
)
tc
:=
xtesting
.
NewTraceChecker
(
t
,
tracer
.
SyncTracer
)
net
:=
xnet
.
NetTrace
(
pipenet
.
New
(
""
),
tracer
)
// test network
//net := xnet.NetTrace(pipenet.New(""), tracer) // test network
net
:=
pipenet
.
New
(
"testnet"
)
// test network
Mhost
:=
xnet
.
NetTrace
(
net
.
Host
(
"m"
),
tracer
)
Shost
:=
xnet
.
NetTrace
(
net
.
Host
(
"s"
),
tracer
)
Maddr
:=
"0"
Maddr
:=
"0"
Saddr
:=
"1"
Saddr
:=
"1"
...
@@ -125,7 +130,7 @@ func TestMasterStorage(t *testing.T) {
...
@@ -125,7 +130,7 @@ func TestMasterStorage(t *testing.T) {
wg
:=
&
xsync
.
WorkGroup
{}
wg
:=
&
xsync
.
WorkGroup
{}
// start master
// start master
M
:=
NewMaster
(
"abc1"
,
Maddr
,
ne
t
)
M
:=
NewMaster
(
"abc1"
,
Maddr
,
Mhos
t
)
Mctx
,
Mcancel
:=
context
.
WithCancel
(
context
.
Background
())
Mctx
,
Mcancel
:=
context
.
WithCancel
(
context
.
Background
())
wg
.
Gox
(
func
()
{
wg
.
Gox
(
func
()
{
err
:=
M
.
Run
(
Mctx
)
err
:=
M
.
Run
(
Mctx
)
...
@@ -158,6 +163,9 @@ func TestMasterStorage(t *testing.T) {
...
@@ -158,6 +163,9 @@ func TestMasterStorage(t *testing.T) {
//tc.Expect(nettx("2c", "2s", "\x00\x00\x00\x01"))
//tc.Expect(nettx("2c", "2s", "\x00\x00\x00\x01"))
// handshake
// handshake
tc
.
Expect
(
nettx
(
"s:1"
,
"m:1"
,
"
\x00\x00\x00\x01
"
))
tc
.
Expect
(
nettx
(
"m:1"
,
"s:1"
,
"
\x00\x00\x00\x01
"
))
//tc.ExpectNetTx("2c", "2s", "\x00\x00\x00\x01") // handshake
//tc.ExpectNetTx("2c", "2s", "\x00\x00\x00\x01") // handshake
//tc.ExpectNetTx("2s", "2c", "\x00\x00\x00\x01")
//tc.ExpectNetTx("2s", "2c", "\x00\x00\x00\x01")
tc
.
ExpectPar
(
tc
.
ExpectPar
(
...
...
go/xcommon/xnet/net.go
View file @
341b2124
...
@@ -30,11 +30,13 @@ type Networker interface {
...
@@ -30,11 +30,13 @@ type Networker interface {
// Network returns name of the network XXX recheck
// Network returns name of the network XXX recheck
Network
()
string
Network
()
string
// XXX +Addr() net.Addr -> address of this access-point on underlying network ?
// Dial connects to addr on underlying network
// Dial connects to addr on underlying network
// see net.Dial for semantic details
// see net.Dial for semantic details
Dial
(
ctx
context
.
Context
,
addr
string
)
(
net
.
Conn
,
error
)
Dial
(
ctx
context
.
Context
,
addr
string
)
(
net
.
Conn
,
error
)
// Listen starts listening on local address laddr on underlying network
// Listen starts listening on local address laddr on underlying network
access-point
// see net.Listen for semantic details
// see net.Listen for semantic details
//
//
// XXX also introduce xnet.Listener in which Accept() accepts also ctx?
// XXX also introduce xnet.Listener in which Accept() accepts also ctx?
...
...
go/xcommon/xnet/pipenet/pipenet.go
View file @
341b2124
...
@@ -15,26 +15,23 @@
...
@@ -15,26 +15,23 @@
//
//
// See COPYING file for full licensing terms.
// See COPYING file for full licensing terms.
// Package pipenet provides synchronous in-memory network of net.Pipes
// Package pipenet provides
TCP-like
synchronous in-memory network of net.Pipes
//
//
// It can be worked with the same way a regular TCP network is used with
// Addresses on pipenet are host:port pairs. A host is xnet.Networker and so
// Dial/Listen/Accept/...
// can be worked with similarly to regular TCP network with Dial/Listen/Accept/...
//
// Addresses on pipenet are numbers, indicating serial number of a pipe
// used, plus "c"/"s" suffix depending on whether pipe endpoint was created via
// Dial or Accept.
//
// Address of a listener is just number, which will be in turn used for
// corresponding Dial/Accept as prefix.
//
//
// Example:
// Example:
//
//
// XXX adjust
// net := pipenet.New("")
// net := pipenet.New("")
// l, err := net.Listen("10") // starts listening on address "10"
// h1 := net.Host("abc")
// h2 := net.Host("def")
//
// l, err := h1.Listen(":10") // starts listening on address "abc:10"
// go func() {
// go func() {
// csrv, err := l.Accept() // csrv will have LocalAddr "
10s
"
// csrv, err := l.Accept() // csrv will have LocalAddr "
abc:10
"
// }()
// }()
// ccli, err :=
net.Dial("10") // ccli will have LocalAddr "10c
"
// ccli, err :=
h2.Dial("abc:10") // ccli will have RemoteAddr "def:10
"
//
//
// Pipenet might be handy for testing interaction of networked applications in 1
// Pipenet might be handy for testing interaction of networked applications in 1
// process without going to OS networking stack.
// process without going to OS networking stack.
...
@@ -54,42 +51,53 @@ const NetPrefix = "pipe" // pipenet package creates only "pipe*" networks
...
@@ -54,42 +51,53 @@ const NetPrefix = "pipe" // pipenet package creates only "pipe*" networks
var
(
var
(
errNetClosed
=
errors
.
New
(
"network connection closed"
)
errNetClosed
=
errors
.
New
(
"network connection closed"
)
errAddrAlreadyUsed
=
errors
.
New
(
"address already in use"
)
errAddrAlreadyUsed
=
errors
.
New
(
"address already in use"
)
errAddrNoListen
=
errors
.
New
(
"cannot listen on requested address"
)
errConnRefused
=
errors
.
New
(
"connection refused"
)
errConnRefused
=
errors
.
New
(
"connection refused"
)
)
)
// Addr represents address of a pipenet endpoint
// Addr represents address of a pipenet endpoint
type
Addr
struct
{
type
Addr
struct
{
Net
string
// full network name, e.g. "pipe"
Net
string
// full network name, e.g. "pipe"
Port
int
// -1, if anonymous
Host
string
// name of host access point on the network
Endpoint
int
// 0 (client) | 1 (server) | -1 (listening)
Port
int
// port on host XXX -1, if anonymous ?
//Addr string // port + c/s depending on connection endpoint
}
}
// Network implements synchronous in-memory network of pipes
// Network implements synchronous in-memory network of pipes
// XXX text about hosts & ports and routing logic
type
Network
struct
{
type
Network
struct
{
// name of this network under "pipe" namespace -> e.g. ""
// name of this network under "pipe" namespace -> e.g. ""
// full network name will be reported as "pipe"+name
// full network name will be reported as "pipe"+name
name
string
name
string
// big network lock for everything dynamic under Network
// (e.g. Host.socketv too)
mu
sync
.
Mutex
mu
sync
.
Mutex
entryv
[]
*
entry
// port -> listener | (conn, conn)
hostMap
map
[
string
]
*
Host
}
}
// entry represents one Network entry
// Host represents named access point on Network
// it can be either already connected (2 endpoints) or only listening (1 endpoint)
type
Host
struct
{
// anything from the above becomes nil when closed
type
entry
struct
{
network
*
Network
network
*
Network
name
string
// NOTE protected by Network.mu
socketv
[]
*
socket
// port -> listener | conn
}
// socket represents one endpoint entry on Network
// it can be either already connected or listening
type
socket
struct
{
host
*
Host
// host/port this socket is binded to
port
int
port
int
pipev
[
2
]
*
conn
// connection endpoints are t
here if != nil
conn
*
conn
// connection endpoint is
here if != nil
listener
*
listener
// listener is waiting here if != nil
listener
*
listener
// listener is waiting here if != nil
}
}
// conn represents one endpoint of connection created under Network
// conn represents one endpoint of connection created under Network
type
conn
struct
{
type
conn
struct
{
entry
*
entry
socket
*
socket
endpoint
int
// 0 | 1 -> entry.pipev
net
.
Conn
net
.
Conn
...
@@ -98,15 +106,21 @@ type conn struct {
...
@@ -98,15 +106,21 @@ type conn struct {
// listener implements net.Listener for piped network
// listener implements net.Listener for piped network
type
listener
struct
{
type
listener
struct
{
// network/port we are listening on
// network/
host/
port we are listening on
entry
*
entry
socket
*
socket
dialq
chan
chan
net
.
Conn
// Dial requests to our port go here
dialq
chan
dialReq
// Dial requests to our port go here
down
chan
struct
{}
// Close -> down=ready
down
chan
struct
{}
// Close -> down=ready
closeOnce
sync
.
Once
closeOnce
sync
.
Once
}
}
// dialReq represents one dial request to listener
type
dialReq
struct
{
from
*
Host
resp
chan
net
.
Conn
}
// ----------------------------------------
// ----------------------------------------
// New creates new pipenet Network
// New creates new pipenet Network
...
@@ -117,58 +131,97 @@ func New(name string) *Network {
...
@@ -117,58 +131,97 @@ func New(name string) *Network {
return
&
Network
{
name
:
name
}
return
&
Network
{
name
:
name
}
}
}
// Host returns network access point by name
// if there was no such host it creates new one
func
(
n
*
Network
)
Host
(
name
string
)
*
Host
{
n
.
mu
.
Lock
()
defer
n
.
mu
.
Unlock
()
host
:=
n
.
hostMap
[
name
]
if
host
==
nil
{
host
=
&
Host
{
network
:
n
,
name
:
name
}
n
.
hostMap
[
name
]
=
host
}
return
host
}
// resolveAddr resolved addr on the network from the host point of view
// must be called with Network.mu held
func
(
h
*
Host
)
resolveAddr
(
addr
string
)
(
host
*
Host
,
port
int
,
err
error
)
{
hoststr
,
portstr
,
err
:=
net
.
SplitHostPort
(
addr
)
if
err
!=
nil
{
return
nil
,
0
,
err
}
port
,
err
=
strconv
.
Atoi
(
portstr
)
if
err
!=
nil
||
port
<
0
{
return
nil
,
0
,
&
net
.
AddrError
{
Err
:
"invalid"
,
Addr
:
addr
}
}
if
hoststr
==
""
{
hoststr
=
h
.
name
}
host
=
h
.
network
.
hostMap
[
hoststr
]
if
host
==
nil
{
return
nil
,
0
,
&
net
.
AddrError
{
Err
:
"no such host"
,
Addr
:
addr
}
}
return
host
,
port
,
nil
}
// Listen starts new listener
// Listen starts new listener
// It either allocates free port if laddr is "", or binds to laddr.
// It either allocates free port if laddr is "", or binds to laddr.
// Once listener is started, Dials could connect to listening address.
// Once listener is started, Dials could connect to listening address.
// Connection requests created by Dials could be accepted via Accept.
// Connection requests created by Dials could be accepted via Accept.
func
(
n
*
Network
)
Listen
(
laddr
string
)
(
net
.
Listener
,
error
)
{
func
(
h
*
Host
)
Listen
(
laddr
string
)
(
net
.
Listener
,
error
)
{
h
.
network
.
mu
.
Lock
()
defer
h
.
network
.
mu
.
Unlock
()
var
sk
*
socket
// find first free port if autobind requested
if
laddr
==
""
{
sk
=
h
.
allocFreeSocket
()
// else we resolve/checr address, whether it is already used and if not allocate socket in-place
}
else
{
var
netladdr
net
.
Addr
var
netladdr
net
.
Addr
lerr
:=
func
(
err
error
)
error
{
lerr
:=
func
(
err
error
)
error
{
return
&
net
.
OpError
{
Op
:
"listen"
,
Net
:
n
.
Network
(),
Addr
:
netladdr
,
Err
:
err
}
return
&
net
.
OpError
{
Op
:
"listen"
,
Net
:
h
.
Network
(),
Addr
:
netladdr
,
Err
:
err
}
}
}
// laddr must be empty or int >= 0
host
,
port
,
err
:=
h
.
resolveAddr
(
laddr
)
port
:=
-
1
if
err
!=
nil
{
if
laddr
!=
""
{
return
nil
,
lerr
(
err
)
port
,
err
:=
strconv
.
Atoi
(
laddr
)
if
err
!=
nil
||
port
<
0
{
return
nil
,
lerr
(
&
net
.
AddrError
{
Err
:
"invalid"
,
Addr
:
laddr
})
}
}
}
netladdr
=
&
Addr
{
n
.
Network
(),
port
,
-
1
}
netladdr
=
&
Addr
{
Net
:
h
.
Network
(),
Host
:
host
.
name
,
Port
:
port
}
n
.
mu
.
Lock
()
defer
n
.
mu
.
Unlock
()
var
e
*
entry
// find first free port if it was not specified
if
host
!=
h
{
if
port
<
0
{
return
nil
,
lerr
(
errAddrNoListen
)
e
=
n
.
allocFreeEntry
()
}
// else we check whether address is already used and if not allocate entry in-place
}
else
{
// grow if needed
// grow if needed
for
port
>=
len
(
n
.
entry
v
)
{
for
port
>=
len
(
h
.
socket
v
)
{
n
.
entryv
=
append
(
n
.
entry
v
,
nil
)
h
.
socketv
=
append
(
h
.
socket
v
,
nil
)
}
}
if
n
.
entry
v
[
port
]
!=
nil
{
if
h
.
socket
v
[
port
]
!=
nil
{
return
nil
,
lerr
(
errAddrAlreadyUsed
)
return
nil
,
lerr
(
errAddrAlreadyUsed
)
}
}
e
=
&
entry
{
network
:
n
,
port
:
port
}
sk
=
&
socket
{
host
:
h
,
port
:
port
}
n
.
entryv
[
port
]
=
e
h
.
socketv
[
port
]
=
sk
}
}
// create listener under
entry
// create listener under
socket
l
:=
&
listener
{
l
:=
&
listener
{
entry
:
e
,
socket
:
sk
,
dialq
:
make
(
chan
chan
net
.
Conn
),
dialq
:
make
(
chan
dialReq
),
down
:
make
(
chan
struct
{}),
down
:
make
(
chan
struct
{}),
}
}
e
.
listener
=
l
sk
.
listener
=
l
return
l
,
nil
return
l
,
nil
}
}
...
@@ -179,15 +232,16 @@ func (l *listener) Close() error {
...
@@ -179,15 +232,16 @@ func (l *listener) Close() error {
l
.
closeOnce
.
Do
(
func
()
{
l
.
closeOnce
.
Do
(
func
()
{
close
(
l
.
down
)
close
(
l
.
down
)
e
:=
l
.
entry
sk
:=
l
.
socket
n
:=
e
.
network
h
:=
sk
.
host
n
:=
h
.
network
n
.
mu
.
Lock
()
n
.
mu
.
Lock
()
defer
n
.
mu
.
Unlock
()
defer
n
.
mu
.
Unlock
()
e
.
listener
=
nil
sk
.
listener
=
nil
if
e
.
empty
()
{
if
sk
.
empty
()
{
n
.
entryv
[
e
.
port
]
=
nil
h
.
socketv
[
sk
.
port
]
=
nil
}
}
})
})
return
nil
return
nil
...
@@ -195,58 +249,62 @@ func (l *listener) Close() error {
...
@@ -195,58 +249,62 @@ func (l *listener) Close() error {
// Accept tries to connect to Dial called with addr corresponding to our listener
// Accept tries to connect to Dial called with addr corresponding to our listener
func
(
l
*
listener
)
Accept
()
(
net
.
Conn
,
error
)
{
func
(
l
*
listener
)
Accept
()
(
net
.
Conn
,
error
)
{
n
:=
l
.
entry
.
network
h
:=
l
.
socket
.
host
n
:=
h
.
network
select
{
select
{
case
<-
l
.
down
:
case
<-
l
.
down
:
return
nil
,
&
net
.
OpError
{
Op
:
"accept"
,
Net
:
n
.
Network
(),
Addr
:
l
.
Addr
(),
Err
:
errNetClosed
}
return
nil
,
&
net
.
OpError
{
Op
:
"accept"
,
Net
:
h
.
Network
(),
Addr
:
l
.
Addr
(),
Err
:
errNetClosed
}
case
re
sp
:=
<-
l
.
dialq
:
case
re
q
:=
<-
l
.
dialq
:
// someone dialed us - let's connect
// someone dialed us - let's connect
pc
,
ps
:=
net
.
Pipe
()
pc
,
ps
:=
net
.
Pipe
()
// allocate
entry and register conns to Network under it
// allocate
sockets and register conns to Network under them
n
.
mu
.
Lock
()
n
.
mu
.
Lock
()
e
:=
n
.
allocFreeEntry
()
skc
:=
req
.
from
.
allocFreeSocket
()
e
.
pipev
[
0
]
=
&
conn
{
entry
:
e
,
endpoint
:
0
,
Conn
:
pc
}
sks
:=
h
.
allocFreeSocket
()
e
.
pipev
[
1
]
=
&
conn
{
entry
:
e
,
endpoint
:
1
,
Conn
:
ps
}
skc
.
conn
=
&
conn
{
socket
:
skc
,
Conn
:
pc
}
sks
.
conn
=
&
conn
{
socket
:
sks
,
Conn
:
ps
}
n
.
mu
.
Unlock
()
n
.
mu
.
Unlock
()
re
sp
<-
e
.
pipev
[
0
]
re
q
.
resp
<-
skc
.
conn
return
e
.
pipev
[
1
]
,
nil
return
sks
.
conn
,
nil
}
}
}
}
// Dial dials address on the network
// Dial dials address on the network
// It tries to connect to Accept called on listener corresponding to addr.
// It tries to connect to Accept called on listener corresponding to addr.
func
(
n
*
Network
)
Dial
(
ctx
context
.
Context
,
addr
string
)
(
net
.
Conn
,
error
)
{
func
(
h
*
Host
)
Dial
(
ctx
context
.
Context
,
addr
string
)
(
net
.
Conn
,
error
)
{
var
netaddr
net
.
Addr
var
netaddr
net
.
Addr
derr
:=
func
(
err
error
)
error
{
derr
:=
func
(
err
error
)
error
{
return
&
net
.
OpError
{
Op
:
"dial"
,
Net
:
n
.
Network
(),
Addr
:
netaddr
,
Err
:
err
}
return
&
net
.
OpError
{
Op
:
"dial"
,
Net
:
h
.
Network
(),
Addr
:
netaddr
,
Err
:
err
}
}
}
port
,
err
:=
strconv
.
Atoi
(
addr
)
n
:=
h
.
network
if
err
!=
nil
||
port
<
0
{
n
.
mu
.
Lock
()
return
nil
,
derr
(
&
net
.
AddrError
{
Err
:
"invalid"
,
Addr
:
addr
})
}
netaddr
=
&
Addr
{
n
.
Network
(),
port
,
-
1
}
host
,
port
,
err
:=
h
.
resolveAddr
(
addr
)
if
err
!=
nil
{
n
.
mu
.
Unlock
()
return
nil
,
derr
(
err
)
}
n
.
mu
.
Lock
()
n
etaddr
=
&
Addr
{
Net
:
h
.
Network
(),
Host
:
host
.
name
,
Port
:
port
}
if
port
>=
len
(
n
.
entry
v
)
{
if
port
>=
len
(
host
.
socket
v
)
{
n
.
mu
.
Unlock
()
n
.
mu
.
Unlock
()
return
nil
,
derr
(
errConnRefused
)
return
nil
,
derr
(
errConnRefused
)
}
}
e
:=
n
.
entry
v
[
port
]
sks
:=
host
.
socket
v
[
port
]
if
e
==
nil
||
e
.
listener
==
nil
{
if
sks
==
nil
||
sks
.
listener
==
nil
{
n
.
mu
.
Unlock
()
n
.
mu
.
Unlock
()
return
nil
,
derr
(
errConnRefused
)
return
nil
,
derr
(
errConnRefused
)
}
}
l
:=
e
.
listener
l
:=
sks
.
listener
// NOTE Accept is locking n.mu -> we must release n.mu before sending dial request
// NOTE Accept is locking n.mu -> we must release n.mu before sending dial request
n
.
mu
.
Unlock
()
n
.
mu
.
Unlock
()
...
@@ -259,7 +317,7 @@ func (n *Network) Dial(ctx context.Context, addr string) (net.Conn, error) {
...
@@ -259,7 +317,7 @@ func (n *Network) Dial(ctx context.Context, addr string) (net.Conn, error) {
case
<-
l
.
down
:
case
<-
l
.
down
:
return
nil
,
derr
(
errConnRefused
)
return
nil
,
derr
(
errConnRefused
)
case
l
.
dialq
<-
resp
:
case
l
.
dialq
<-
dialReq
{
from
:
h
,
resp
:
resp
}
:
return
<-
resp
,
nil
return
<-
resp
,
nil
}
}
}
}
...
@@ -270,16 +328,17 @@ func (c *conn) Close() (err error) {
...
@@ -270,16 +328,17 @@ func (c *conn) Close() (err error) {
c
.
closeOnce
.
Do
(
func
()
{
c
.
closeOnce
.
Do
(
func
()
{
err
=
c
.
Conn
.
Close
()
err
=
c
.
Conn
.
Close
()
e
:=
c
.
entry
sk
:=
c
.
socket
n
:=
e
.
network
h
:=
sk
.
host
n
:=
h
.
network
n
.
mu
.
Lock
()
n
.
mu
.
Lock
()
defer
n
.
mu
.
Unlock
()
defer
n
.
mu
.
Unlock
()
e
.
pipev
[
c
.
endpoin
t
]
=
nil
h
.
socketv
[
sk
.
por
t
]
=
nil
if
e
.
empty
()
{
if
sk
.
empty
()
{
n
.
entryv
[
e
.
port
]
=
nil
h
.
socketv
[
sk
.
port
]
=
nil
}
}
})
})
...
@@ -287,71 +346,61 @@ func (c *conn) Close() (err error) {
...
@@ -287,71 +346,61 @@ func (c *conn) Close() (err error) {
}
}
// LocalAddr returns address of local end of connection
// LocalAddr returns address of local end of connection
// it is entry address + "c" (client) or "s" (server) suffix depending on
// whether pipe endpoint was created via Dial or Accept.
func
(
c
*
conn
)
LocalAddr
()
net
.
Addr
{
func
(
c
*
conn
)
LocalAddr
()
net
.
Addr
{
addr
:=
c
.
entry
.
addr
()
return
c
.
socket
.
addr
()
addr
.
Endpoint
=
c
.
endpoint
return
addr
}
}
// RemoteAddr returns address of remote end of connection
// RemoteAddr returns address of remote end of connection
// it is entry address + "c" or "s" suffix -- see LocalAddr for details
func
(
c
*
conn
)
RemoteAddr
()
net
.
Addr
{
func
(
c
*
conn
)
RemoteAddr
()
net
.
Addr
{
addr
:=
c
.
entry
.
addr
()
return
c
.
socket
.
addr
()
// FIXME -> must be addr of remote socket
addr
.
Endpoint
=
(
c
.
endpoint
+
1
)
%
2
return
addr
}
}
// ----------------------------------------
// ----------------------------------------
// allocFree
Entry finds first free port and allocates network
entry for it
// allocFree
Socket finds first free port and allocates socket
entry for it
// must be called with .mu held
// must be called with
Network
.mu held
func
(
n
*
Network
)
allocFreeEntry
()
*
entry
{
func
(
h
*
Host
)
allocFreeSocket
()
*
socket
{
// find first free port
if it was not specified
// find first free port
port
:=
0
port
:=
0
for
;
port
<
len
(
n
.
entry
v
);
port
++
{
for
;
port
<
len
(
h
.
socket
v
);
port
++
{
if
n
.
entry
v
[
port
]
==
nil
{
if
h
.
socket
v
[
port
]
==
nil
{
break
break
}
}
}
}
// if all busy it exits with port == len(
n.entry
v)
// if all busy it exits with port == len(
h.socket
v)
// grow if needed
// grow if needed
for
port
>=
len
(
n
.
entry
v
)
{
for
port
>=
len
(
h
.
socket
v
)
{
n
.
entryv
=
append
(
n
.
entry
v
,
nil
)
h
.
socketv
=
append
(
h
.
socket
v
,
nil
)
}
}
e
:=
&
entry
{
network
:
n
,
port
:
port
}
sk
:=
&
socket
{
host
:
h
,
port
:
port
}
n
.
entryv
[
port
]
=
e
h
.
socketv
[
port
]
=
sk
return
e
return
sk
}
}
// empty checks whether
entry's both 2 pipe endpoints
and listener are all nil
// empty checks whether
sockets's both pipe endpoint
and listener are all nil
func
(
e
*
entry
)
empty
()
bool
{
func
(
sk
*
socket
)
empty
()
bool
{
return
e
.
pipev
[
0
]
==
nil
&&
e
.
pipev
[
1
]
==
nil
&&
e
.
listener
==
nil
return
sk
.
conn
==
nil
&&
sk
.
listener
==
nil
}
}
// addr returns address corresponding to entry
// addr returns address corresponding to entry
func
(
e
*
entry
)
addr
()
*
Addr
{
func
(
sk
*
socket
)
addr
()
*
Addr
{
return
&
Addr
{
Net
:
e
.
network
.
Network
(),
Port
:
e
.
port
,
Endpoint
:
-
1
}
h
:=
sk
.
host
return
&
Addr
{
Net
:
h
.
Network
(),
Host
:
h
.
name
,
Port
:
sk
.
port
}
}
}
func
(
a
*
Addr
)
Network
()
string
{
return
a
.
Net
}
func
(
a
*
Addr
)
Network
()
string
{
return
a
.
Net
}
func
(
a
*
Addr
)
String
()
string
{
func
(
a
*
Addr
)
String
()
string
{
return
net
.
JoinHostPort
(
a
.
Host
,
strconv
.
Itoa
(
a
.
Port
))
}
addr
:=
strconv
.
Itoa
(
a
.
Port
)
if
a
.
Endpoint
>=
0
{
addr
+=
string
(
"cs"
[
a
.
Endpoint
])
}
return
addr
}
// Addr returns address where listener is accepting incoming connections
// Addr returns address where listener is accepting incoming connections
func
(
l
*
listener
)
Addr
()
net
.
Addr
{
func
(
l
*
listener
)
Addr
()
net
.
Addr
{
// NOTE no +"l" suffix e.g. because Dial(l.Addr()) must work
return
l
.
socket
.
addr
()
return
l
.
entry
.
addr
()
}
}
// Network returns full network name of this network
// Network returns full network name of this network
func
(
n
*
Network
)
Network
()
string
{
return
NetPrefix
+
n
.
name
}
func
(
n
*
Network
)
Network
()
string
{
return
NetPrefix
+
n
.
name
}
// Network returns full network name of underllying network
func
(
h
*
Host
)
Network
()
string
{
return
h
.
network
.
Network
()
}
go/xcommon/xnet/trace.go
View file @
341b2124
...
@@ -34,6 +34,8 @@ import (
...
@@ -34,6 +34,8 @@ import (
// only Tx events are traced:
// only Tx events are traced:
// - because Write, contrary to Read, never writes partial data on non-error
// - because Write, contrary to Read, never writes partial data on non-error
// - because in case of pipenet tracing writes only is enough to get whole network exchange picture
// - because in case of pipenet tracing writes only is enough to get whole network exchange picture
//
// XXX Dial/Listen are also traced
func
NetTrace
(
inner
Networker
,
tracer
Tracer
)
Networker
{
func
NetTrace
(
inner
Networker
,
tracer
Tracer
)
Networker
{
return
&
netTrace
{
inner
,
tracer
}
return
&
netTrace
{
inner
,
tracer
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment