Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
mf
go-multiaddr
Commits
31e031dc
Unverified
Commit
31e031dc
authored
Jun 22, 2018
by
Steven Allen
Committed by
GitHub
Jun 22, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #43 from multiformats/feat/expose-half-close
expose methods from underlying connection types
parents
8792ba0a
a109f8da
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
68 additions
and
24 deletions
+68
-24
net.go
net.go
+64
-24
net_test.go
net_test.go
+4
-0
No files found.
net.go
View file @
31e031dc
...
...
@@ -28,8 +28,64 @@ type Conn interface {
RemoteMultiaddr
()
ma
.
Multiaddr
}
// WrapNetConn wraps a net.Conn object with a Multiaddr
// friendly Conn.
type
halfOpen
interface
{
net
.
Conn
CloseRead
()
error
CloseWrite
()
error
}
func
wrap
(
nconn
net
.
Conn
,
laddr
,
raddr
ma
.
Multiaddr
)
Conn
{
endpts
:=
maEndpoints
{
laddr
:
laddr
,
raddr
:
raddr
,
}
// This sucks. However, it's the only way to reliably expose the
// underlying methods. This way, users that need access to, e.g.,
// CloseRead and CloseWrite, can do so via type assertions.
switch
nconn
:=
nconn
.
(
type
)
{
case
*
net
.
TCPConn
:
return
&
struct
{
*
net
.
TCPConn
maEndpoints
}{
nconn
,
endpts
}
case
*
net
.
UDPConn
:
return
&
struct
{
*
net
.
UDPConn
maEndpoints
}{
nconn
,
endpts
}
case
*
net
.
IPConn
:
return
&
struct
{
*
net
.
IPConn
maEndpoints
}{
nconn
,
endpts
}
case
*
net
.
UnixConn
:
return
&
struct
{
*
net
.
UnixConn
maEndpoints
}{
nconn
,
endpts
}
case
halfOpen
:
return
&
struct
{
halfOpen
maEndpoints
}{
nconn
,
endpts
}
default
:
return
&
struct
{
net
.
Conn
maEndpoints
}{
nconn
,
endpts
}
}
}
// WrapNetConn wraps a net.Conn object with a Multiaddr friendly Conn.
//
// This function does it's best to avoid "hiding" methods exposed by the wrapped
// type. Guarantees:
//
// * If the wrapped connection exposes the "half-open" closer methods
// (CloseWrite, CloseRead), these will be available on the wrapped connection
// via type assertions.
// * If the wrapped connection is a UnixConn, IPConn, TCPConn, or UDPConn, all
// methods on these wrapped connections will be available via type assertions.
func
WrapNetConn
(
nconn
net
.
Conn
)
(
Conn
,
error
)
{
if
nconn
==
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to convert nconn.LocalAddr: nil"
)
...
...
@@ -45,30 +101,23 @@ func WrapNetConn(nconn net.Conn) (Conn, error) {
return
nil
,
fmt
.
Errorf
(
"failed to convert nconn.RemoteAddr: %s"
,
err
)
}
return
&
maConn
{
Conn
:
nconn
,
laddr
:
laddr
,
raddr
:
raddr
,
},
nil
return
wrap
(
nconn
,
laddr
,
raddr
),
nil
}
// maConn implements the Conn interface. It's a thin wrapper
// around a net.Conn
type
maConn
struct
{
net
.
Conn
type
maEndpoints
struct
{
laddr
ma
.
Multiaddr
raddr
ma
.
Multiaddr
}
// LocalMultiaddr returns the local address associated with
// this connection
func
(
c
*
ma
Conn
)
LocalMultiaddr
()
ma
.
Multiaddr
{
func
(
c
*
ma
Endpoints
)
LocalMultiaddr
()
ma
.
Multiaddr
{
return
c
.
laddr
}
// RemoteMultiaddr returns the remote address associated with
// this connection
func
(
c
*
ma
Conn
)
RemoteMultiaddr
()
ma
.
Multiaddr
{
func
(
c
*
ma
Endpoints
)
RemoteMultiaddr
()
ma
.
Multiaddr
{
return
c
.
raddr
}
...
...
@@ -135,12 +184,7 @@ func (d *Dialer) DialContext(ctx context.Context, remote ma.Multiaddr) (Conn, er
return
nil
,
err
}
}
return
&
maConn
{
Conn
:
nconn
,
laddr
:
local
,
raddr
:
remote
,
},
nil
return
wrap
(
nconn
,
local
,
remote
),
nil
}
// Dial connects to a remote address. It uses an underlying net.Conn,
...
...
@@ -204,11 +248,7 @@ func (l *maListener) Accept() (Conn, error) {
return
nil
,
fmt
.
Errorf
(
"failed to convert connn.RemoteAddr: %s"
,
err
)
}
return
&
maConn
{
Conn
:
nconn
,
laddr
:
l
.
laddr
,
raddr
:
raddr
,
},
nil
return
wrap
(
nconn
,
l
.
laddr
,
raddr
),
nil
}
// Multiaddr returns the listener's (local) Multiaddr.
...
...
net_test.go
View file @
31e031dc
...
...
@@ -407,12 +407,14 @@ func TestWrapNetConn(t *testing.T) {
defer
wg
.
Done
()
cB
,
err
:=
listener
.
Accept
()
checkErr
(
err
,
"failed to accept"
)
_
=
cB
.
(
halfOpen
)
cB
.
Close
()
}()
cA
,
err
:=
net
.
Dial
(
"tcp"
,
listener
.
Addr
()
.
String
())
checkErr
(
err
,
"failed to dial"
)
defer
cA
.
Close
()
_
=
cA
.
(
halfOpen
)
lmaddr
,
err
:=
FromNetAddr
(
cA
.
LocalAddr
())
checkErr
(
err
,
"failed to get local addr"
)
...
...
@@ -422,6 +424,8 @@ func TestWrapNetConn(t *testing.T) {
mcA
,
err
:=
WrapNetConn
(
cA
)
checkErr
(
err
,
"failed to wrap conn"
)
_
=
mcA
.
(
halfOpen
)
if
mcA
.
LocalAddr
()
.
String
()
!=
cA
.
LocalAddr
()
.
String
()
{
t
.
Error
(
"wrapped conn local addr differs"
)
}
...
...
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