Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
go-libp2p-quic-transport
Commits
9d8055d4
Unverified
Commit
9d8055d4
authored
Aug 01, 2018
by
Marten Seemann
Committed by
GitHub
Aug 01, 2018
Browse files
Merge pull request #27 from libp2p/fix-ip-version
obey the multiaddr's IP version
parents
43da075e
bd2c36a8
Changes
5
Hide whitespace changes
Inline
Side-by-side
.travis.yml
View file @
9d8055d4
...
...
@@ -18,6 +18,10 @@ before_install:
-
export GOARCH=$TRAVIS_GOARCH
-
go env
# for debugging
# see https://github.com/travis-ci/travis-ci/issues/8361#issuecomment-350090030
before_script
:
-
sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'
script
:
-
ginkgo -r -v --cover --randomizeAllSpecs --randomizeSuites --trace --progress
...
...
conn_test.go
View file @
9d8055d4
...
...
@@ -35,12 +35,12 @@ var _ = Describe("Connection", func() {
return
id
,
priv
}
runServer
:=
func
(
tr
tpt
.
Transport
)
(
ma
.
Multiaddr
,
<-
chan
tpt
.
Conn
)
{
runServer
:=
func
(
tr
tpt
.
Transport
,
multiaddr
string
)
(
ma
.
Multiaddr
,
<-
chan
tpt
.
Conn
)
{
addrChan
:=
make
(
chan
ma
.
Multiaddr
)
connChan
:=
make
(
chan
tpt
.
Conn
)
go
func
()
{
defer
GinkgoRecover
()
addr
,
err
:=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/udp/0/quic"
)
addr
,
err
:=
ma
.
NewMultiaddr
(
multiaddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
ln
,
err
:=
tr
.
Listen
(
addr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
...
...
@@ -62,10 +62,30 @@ var _ = Describe("Connection", func() {
clientID
,
clientKey
=
createPeer
()
})
It
(
"handshakes"
,
func
()
{
It
(
"handshakes
on IPv4
"
,
func
()
{
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
clientTransport
,
err
:=
NewTransport
(
clientKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
conn
,
err
:=
clientTransport
.
Dial
(
context
.
Background
(),
serverAddr
,
serverID
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverConn
:=
<-
serverConnChan
Expect
(
conn
.
LocalPeer
())
.
To
(
Equal
(
clientID
))
Expect
(
conn
.
LocalPrivateKey
())
.
To
(
Equal
(
clientKey
))
Expect
(
conn
.
RemotePeer
())
.
To
(
Equal
(
serverID
))
Expect
(
conn
.
RemotePublicKey
())
.
To
(
Equal
(
serverKey
.
GetPublic
()))
Expect
(
serverConn
.
LocalPeer
())
.
To
(
Equal
(
serverID
))
Expect
(
serverConn
.
LocalPrivateKey
())
.
To
(
Equal
(
serverKey
))
Expect
(
serverConn
.
RemotePeer
())
.
To
(
Equal
(
clientID
))
Expect
(
serverConn
.
RemotePublicKey
())
.
To
(
Equal
(
clientKey
.
GetPublic
()))
})
It
(
"handshakes on IPv6"
,
func
()
{
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip6/::1/udp/0/quic"
)
clientTransport
,
err
:=
NewTransport
(
clientKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
...
...
@@ -85,7 +105,7 @@ var _ = Describe("Connection", func() {
It
(
"opens and accepts streams"
,
func
()
{
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
clientTransport
,
err
:=
NewTransport
(
clientKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
...
...
@@ -110,7 +130,7 @@ var _ = Describe("Connection", func() {
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
clientTransport
,
err
:=
NewTransport
(
clientKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
...
...
@@ -124,7 +144,7 @@ var _ = Describe("Connection", func() {
It
(
"fails if the client presents an invalid cert chain"
,
func
()
{
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
clientTransport
,
err
:=
NewTransport
(
clientKey
)
invalidateCertChain
(
clientTransport
.
(
*
transport
)
.
tlsConf
)
...
...
@@ -139,7 +159,7 @@ var _ = Describe("Connection", func() {
serverTransport
,
err
:=
NewTransport
(
serverKey
)
invalidateCertChain
(
serverTransport
.
(
*
transport
)
.
tlsConf
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
clientTransport
,
err
:=
NewTransport
(
clientKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
...
...
@@ -152,7 +172,7 @@ var _ = Describe("Connection", func() {
It
(
"keeps accepting connections after a failed connection attempt"
,
func
()
{
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
// first dial with an invalid cert chain
clientTransport1
,
err
:=
NewTransport
(
clientKey
)
...
...
@@ -175,10 +195,10 @@ var _ = Describe("Connection", func() {
serverTransport
,
err
:=
NewTransport
(
serverKey
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
)
serverAddr
,
serverConnChan
:=
runServer
(
serverTransport
,
"/ip4/127.0.0.1/udp/0/quic"
)
serverTransport2
,
err
:=
NewTransport
(
serverKey2
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
serverAddr2
,
serverConnChan2
:=
runServer
(
serverTransport2
)
serverAddr2
,
serverConnChan2
:=
runServer
(
serverTransport2
,
"/ip4/127.0.0.1/udp/0/quic"
)
data
:=
bytes
.
Repeat
([]
byte
{
'a'
},
5
*
1
<<
20
)
// 5 MB
// wait for both servers to accept a connection
...
...
listener.go
View file @
9d8055d4
...
...
@@ -27,11 +27,19 @@ type listener struct {
var
_
tpt
.
Listener
=
&
listener
{}
func
newListener
(
addr
ma
.
Multiaddr
,
transport
tpt
.
Transport
,
localPeer
peer
.
ID
,
key
ic
.
PrivKey
,
tlsConf
*
tls
.
Config
)
(
tpt
.
Listener
,
error
)
{
_
,
host
,
err
:=
manet
.
DialArgs
(
addr
)
lnet
,
host
,
err
:=
manet
.
DialArgs
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
ln
,
err
:=
quicListenAddr
(
host
,
tlsConf
,
quicConfig
)
laddr
,
err
:=
net
.
ResolveUDPAddr
(
lnet
,
host
)
if
err
!=
nil
{
return
nil
,
err
}
conn
,
err
:=
net
.
ListenUDP
(
lnet
,
laddr
)
if
err
!=
nil
{
return
nil
,
err
}
ln
,
err
:=
quic
.
Listen
(
conn
,
tlsConf
,
quicConfig
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
listener_test.go
View file @
9d8055d4
...
...
@@ -15,10 +15,7 @@ import (
)
var
_
=
Describe
(
"Listener"
,
func
()
{
var
(
t
tpt
.
Transport
localAddr
ma
.
Multiaddr
)
var
t
tpt
.
Transport
BeforeEach
(
func
()
{
rsaKey
,
err
:=
rsa
.
GenerateKey
(
rand
.
Reader
,
1024
)
...
...
@@ -27,41 +24,76 @@ var _ = Describe("Listener", func() {
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
t
,
err
=
NewTransport
(
key
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
localAddr
,
err
=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/udp/0/quic"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
})
It
(
"returns the address it is listening on"
,
func
()
{
ln
,
err
:=
t
.
Listen
(
localAddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
netAddr
:=
ln
.
Addr
()
Expect
(
netAddr
)
.
To
(
BeAssignableToTypeOf
(
&
net
.
UDPAddr
{}))
port
:=
netAddr
.
(
*
net
.
UDPAddr
)
.
Port
Expect
(
port
)
.
ToNot
(
BeZero
())
Expect
(
ln
.
Multiaddr
()
.
String
())
.
To
(
Equal
(
fmt
.
Sprintf
(
"/ip4/127.0.0.1/udp/%d/quic"
,
port
)))
})
Context
(
"listening on the right address"
,
func
()
{
It
(
"returns the address it is listening on"
,
func
()
{
localAddr
,
err
:=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/udp/0/quic"
)
ln
,
err
:=
t
.
Listen
(
localAddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
netAddr
:=
ln
.
Addr
()
Expect
(
netAddr
)
.
To
(
BeAssignableToTypeOf
(
&
net
.
UDPAddr
{}))
port
:=
netAddr
.
(
*
net
.
UDPAddr
)
.
Port
Expect
(
port
)
.
ToNot
(
BeZero
())
Expect
(
ln
.
Multiaddr
()
.
String
())
.
To
(
Equal
(
fmt
.
Sprintf
(
"/ip4/127.0.0.1/udp/%d/quic"
,
port
)))
})
It
(
"returns Accept when it is closed"
,
func
()
{
addr
,
err
:=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/udp/0/quic"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
ln
,
err
:=
t
.
Listen
(
addr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
done
:=
make
(
chan
struct
{})
go
func
()
{
defer
GinkgoRecover
()
ln
.
Accept
()
close
(
done
)
}()
Consistently
(
done
)
.
ShouldNot
(
BeClosed
())
Expect
(
ln
.
Close
())
.
To
(
Succeed
())
Eventually
(
done
)
.
Should
(
BeClosed
())
It
(
"returns the address it is listening on, for listening on IPv4"
,
func
()
{
localAddr
,
err
:=
ma
.
NewMultiaddr
(
"/ip4/0.0.0.0/udp/0/quic"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
ln
,
err
:=
t
.
Listen
(
localAddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
netAddr
:=
ln
.
Addr
()
Expect
(
netAddr
)
.
To
(
BeAssignableToTypeOf
(
&
net
.
UDPAddr
{}))
port
:=
netAddr
.
(
*
net
.
UDPAddr
)
.
Port
Expect
(
port
)
.
ToNot
(
BeZero
())
Expect
(
ln
.
Multiaddr
()
.
String
())
.
To
(
Equal
(
fmt
.
Sprintf
(
"/ip4/0.0.0.0/udp/%d/quic"
,
port
)))
})
It
(
"returns the address it is listening on, for listening on IPv6"
,
func
()
{
localAddr
,
err
:=
ma
.
NewMultiaddr
(
"/ip6/::/udp/0/quic"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
ln
,
err
:=
t
.
Listen
(
localAddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
netAddr
:=
ln
.
Addr
()
Expect
(
netAddr
)
.
To
(
BeAssignableToTypeOf
(
&
net
.
UDPAddr
{}))
port
:=
netAddr
.
(
*
net
.
UDPAddr
)
.
Port
Expect
(
port
)
.
ToNot
(
BeZero
())
Expect
(
ln
.
Multiaddr
()
.
String
())
.
To
(
Equal
(
fmt
.
Sprintf
(
"/ip6/::/udp/%d/quic"
,
port
)))
})
})
It
(
"doesn't accept Accept calls after it is closed"
,
func
()
{
ln
,
err
:=
t
.
Listen
(
localAddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
Expect
(
ln
.
Close
())
.
To
(
Succeed
())
_
,
err
=
ln
.
Accept
()
Expect
(
err
)
.
To
(
HaveOccurred
())
Context
(
"accepting connections"
,
func
()
{
var
localAddr
ma
.
Multiaddr
BeforeEach
(
func
()
{
var
err
error
localAddr
,
err
=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/udp/0/quic"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
})
It
(
"returns Accept when it is closed"
,
func
()
{
addr
,
err
:=
ma
.
NewMultiaddr
(
"/ip4/127.0.0.1/udp/0/quic"
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
ln
,
err
:=
t
.
Listen
(
addr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
done
:=
make
(
chan
struct
{})
go
func
()
{
defer
GinkgoRecover
()
ln
.
Accept
()
close
(
done
)
}()
Consistently
(
done
)
.
ShouldNot
(
BeClosed
())
Expect
(
ln
.
Close
())
.
To
(
Succeed
())
Eventually
(
done
)
.
Should
(
BeClosed
())
})
It
(
"doesn't accept Accept calls after it is closed"
,
func
()
{
ln
,
err
:=
t
.
Listen
(
localAddr
)
Expect
(
err
)
.
ToNot
(
HaveOccurred
())
Expect
(
ln
.
Close
())
.
To
(
Succeed
())
_
,
err
=
ln
.
Accept
()
Expect
(
err
)
.
To
(
HaveOccurred
())
})
})
})
transport.go
View file @
9d8055d4
...
...
@@ -5,7 +5,9 @@ import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net"
"sync"
ic
"github.com/libp2p/go-libp2p-crypto"
peer
"github.com/libp2p/go-libp2p-peer"
...
...
@@ -27,12 +29,47 @@ var quicConfig = &quic.Config{
KeepAlive
:
true
,
}
type
connManager
struct
{
connIPv4Once
sync
.
Once
connIPv4
net
.
PacketConn
connIPv6Once
sync
.
Once
connIPv6
net
.
PacketConn
}
func
(
c
*
connManager
)
GetConnForAddr
(
network
string
)
(
net
.
PacketConn
,
error
)
{
switch
network
{
case
"udp4"
:
var
err
error
c
.
connIPv4Once
.
Do
(
func
()
{
c
.
connIPv4
,
err
=
c
.
createConn
(
network
,
"0.0.0.0:0"
)
})
return
c
.
connIPv4
,
err
case
"udp6"
:
var
err
error
c
.
connIPv6Once
.
Do
(
func
()
{
c
.
connIPv6
,
err
=
c
.
createConn
(
network
,
":0"
)
})
return
c
.
connIPv6
,
err
default
:
return
nil
,
fmt
.
Errorf
(
"unsupported network: %s"
,
network
)
}
}
func
(
c
*
connManager
)
createConn
(
network
,
host
string
)
(
net
.
PacketConn
,
error
)
{
addr
,
err
:=
net
.
ResolveUDPAddr
(
network
,
host
)
if
err
!=
nil
{
return
nil
,
err
}
return
net
.
ListenUDP
(
network
,
addr
)
}
// The Transport implements the tpt.Transport interface for QUIC connections.
type
transport
struct
{
privKey
ic
.
PrivKey
localPeer
peer
.
ID
tlsConf
*
tls
.
Config
p
conn
net
.
PacketConn
privKey
ic
.
PrivKey
localPeer
peer
.
ID
tlsConf
*
tls
.
Config
conn
Manager
*
connManager
}
var
_
tpt
.
Transport
=
&
transport
{}
...
...
@@ -48,27 +85,21 @@ func NewTransport(key ic.PrivKey) (tpt.Transport, error) {
return
nil
,
err
}
// create a packet conn for outgoing connections
addr
,
err
:=
net
.
ResolveUDPAddr
(
"udp"
,
"localhost:0"
)
if
err
!=
nil
{
return
nil
,
err
}
conn
,
err
:=
net
.
ListenUDP
(
"udp"
,
addr
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
transport
{
privKey
:
key
,
localPeer
:
localPeer
,
tlsConf
:
tlsConf
,
p
conn
:
conn
,
privKey
:
key
,
localPeer
:
localPeer
,
tlsConf
:
tlsConf
,
conn
Manager
:
&
connManager
{}
,
},
nil
}
// Dial dials a new QUIC connection
func
(
t
*
transport
)
Dial
(
ctx
context
.
Context
,
raddr
ma
.
Multiaddr
,
p
peer
.
ID
)
(
tpt
.
Conn
,
error
)
{
_
,
host
,
err
:=
manet
.
DialArgs
(
raddr
)
network
,
host
,
err
:=
manet
.
DialArgs
(
raddr
)
if
err
!=
nil
{
return
nil
,
err
}
pconn
,
err
:=
t
.
connManager
.
GetConnForAddr
(
network
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -100,7 +131,7 @@ func (t *transport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tp
}
return
nil
}
sess
,
err
:=
quic
.
DialContext
(
ctx
,
t
.
pconn
,
addr
,
host
,
tlsConf
,
quicConfig
)
sess
,
err
:=
quic
.
DialContext
(
ctx
,
pconn
,
addr
,
host
,
tlsConf
,
quicConfig
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
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