Unverified Commit f992fe7d authored by Marten Seemann's avatar Marten Seemann
Browse files

implement a dialer

parent aa803f3d
......@@ -2,23 +2,54 @@ package libp2pquic
import (
"context"
"crypto/tls"
tpt "github.com/libp2p/go-libp2p-transport"
quicconn "github.com/marten-seemann/quic-conn"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr-net"
"github.com/whyrusleeping/mafmt"
)
type dialer struct{}
type dialer struct {
transport tpt.Transport
}
func newDialer(transport tpt.Transport) (*dialer, error) {
return &dialer{
transport: transport,
}, nil
}
func (d *dialer) Dial(raddr ma.Multiaddr) (tpt.Conn, error) {
panic("not implemented")
// TODO: check that raddr is a QUIC address
tlsConf := &tls.Config{InsecureSkipVerify: true}
_, host, err := manet.DialArgs(raddr)
if err != nil {
return nil, err
}
c, err := quicconn.Dial(host, tlsConf)
if err != nil {
return nil, err
}
mnc, err := manet.WrapNetConn(c)
if err != nil {
return nil, err
}
return &tpt.ConnWrap{
Conn: mnc,
Tpt: d.transport,
}, nil
}
func (d *dialer) DialContext(ctx context.Context, raddr ma.Multiaddr) (tpt.Conn, error) {
panic("not implemented")
return d.Dial(raddr)
}
func (d *dialer) Matches(ma.Multiaddr) bool {
panic("not implemented")
func (d *dialer) Matches(a ma.Multiaddr) bool {
return mafmt.QUIC.Matches(a)
}
var _ tpt.Dialer = &dialer{}
package libp2pquic
import (
tpt "github.com/libp2p/go-libp2p-transport"
ma "github.com/multiformats/go-multiaddr"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Listener", func() {
var (
d *dialer
transport tpt.Transport
)
BeforeEach(func() {
var err error
transport = &QuicTransport{}
d, err = newDialer(transport)
Expect(err).ToNot(HaveOccurred())
})
It("dials", func() {
addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/8888")
Expect(err).ToNot(HaveOccurred())
// start a listener to connect to
var ln *listener
go func() {
defer GinkgoRecover()
ln, err = newListener(addr, nil, transport)
Expect(err).ToNot(HaveOccurred())
_, err = ln.Accept()
Expect(err).ToNot(HaveOccurred())
}()
Eventually(func() *listener { return ln }).ShouldNot(BeNil())
conn, err := d.Dial(addr)
Expect(err).ToNot(HaveOccurred())
Expect(conn.Transport()).To(Equal(d.transport))
})
It("matches", func() {
invalidAddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
Expect(err).ToNot(HaveOccurred())
validAddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234/quic")
Expect(err).ToNot(HaveOccurred())
Expect(d.Matches(invalidAddr)).To(BeFalse())
Expect(d.Matches(validAddr)).To(BeTrue())
})
})
......@@ -12,24 +12,47 @@ import (
// QuicTransport implements a QUIC Transport
type QuicTransport struct {
mutex sync.Mutex
peers pstore.Peerstore
lmutex sync.Mutex
listeners map[string]tpt.Listener
dmutex sync.Mutex
dialers map[string]tpt.Dialer
}
// NewQuicTransport creates a new QUIC Transport
// it tracks dialers and listeners created
func NewQuicTransport(peers pstore.Peerstore) *QuicTransport {
// utils.SetLogLevel(utils.LogLevelDebug)
return &QuicTransport{
peers: peers,
listeners: make(map[string]tpt.Listener),
dialers: make(map[string]tpt.Dialer),
}
}
func (t *QuicTransport) Dialer(laddr ma.Multiaddr, opts ...tpt.DialOpt) (tpt.Dialer, error) {
panic("not implemented")
if !t.Matches(laddr) {
return nil, fmt.Errorf("quic transport cannot dial %q", laddr)
}
t.dmutex.Lock()
defer t.dmutex.Unlock()
s := laddr.String()
d, ok := t.dialers[s]
if ok {
return d, nil
}
// TODO: read opts
quicd, err := newDialer(t)
if err != nil {
return nil, err
}
t.dialers[s] = quicd
return quicd, nil
}
// Listen starts listening on laddr
......@@ -38,8 +61,8 @@ func (t *QuicTransport) Listen(laddr ma.Multiaddr) (tpt.Listener, error) {
return nil, fmt.Errorf("quic transport cannot listen on %q", laddr)
}
t.mutex.Lock()
defer t.mutex.Unlock()
t.lmutex.Lock()
defer t.lmutex.Unlock()
l, ok := t.listeners[laddr.String()]
if ok {
......
......@@ -43,6 +43,34 @@ var _ = Describe("Transport", func() {
})
})
Context("dialing", func() {
It("creates a new dialer", func() {
maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234/quic")
Expect(err).ToNot(HaveOccurred())
d, err := t.Dialer(maddr)
Expect(err).ToNot(HaveOccurred())
Expect(d).ToNot(BeNil())
})
It("returns an existing dialer", func() {
maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1235/quic")
Expect(err).ToNot(HaveOccurred())
d, err := t.Dialer(maddr)
Expect(err).ToNot(HaveOccurred())
d2, err := t.Dialer(maddr)
Expect(err).ToNot(HaveOccurred())
Expect(d2).To(Equal(d))
Expect(t.dialers).To(HaveLen(1))
})
It("errors if the address is not a QUIC address", func() {
maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1235/utp")
Expect(err).ToNot(HaveOccurred())
_, err = t.Dialer(maddr)
Expect(err).To(MatchError("quic transport cannot dial \"/ip4/127.0.0.1/udp/1235/utp\""))
})
})
It("matches", func() {
invalidAddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
Expect(err).ToNot(HaveOccurred())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment