Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
export qlogs when the QLOGDIR env variable is set
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Mar 26, 2020
1 parent 506057f commit 88546e0
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.qlog
*.qlog.gz
25 changes: 25 additions & 0 deletions buffered_write_closer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package libp2pquic

import (
"bufio"
"io"
)

type bufferedWriteCloser struct {
*bufio.Writer
io.Closer
}

func newBufferedWriteCloser(writer *bufio.Writer, closer io.Closer) io.WriteCloser {
return &bufferedWriteCloser{
Writer: writer,
Closer: closer,
}
}

func (h bufferedWriteCloser) Close() error {
if err := h.Writer.Flush(); err != nil {
return err
}
return h.Closer.Close()
}
26 changes: 26 additions & 0 deletions buffered_write_closer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package libp2pquic

import (
"bufio"
"bytes"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

type nopCloser struct{}

func (nopCloser) Close() error { return nil }

var _ = Describe("buffered io.WriteCloser", func() {
It("flushes before closing", func() {
buf := &bytes.Buffer{}

w := bufio.NewWriter(buf)
wc := newBufferedWriteCloser(w, &nopCloser{})
wc.Write([]byte("foobar"))
Expect(buf.Len()).To(BeZero())
Expect(wc.Close()).To(Succeed())
Expect(buf.String()).To(Equal("foobar"))
})
})
4 changes: 2 additions & 2 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,13 @@ var _ = Describe("Connection", func() {
Expect(err).ToNot(HaveOccurred())

// make sure that connection attempts fails
clientTransport.(*transport).config.HandshakeTimeout = 250 * time.Millisecond
clientTransport.(*transport).clientConfig.HandshakeTimeout = 250 * time.Millisecond
_, err = clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID)
Expect(err).To(HaveOccurred())
Expect(err.(net.Error).Timeout()).To(BeTrue())

// now allow the address and make sure the connection goes through
clientTransport.(*transport).config.HandshakeTimeout = 2 * time.Second
clientTransport.(*transport).clientConfig.HandshakeTimeout = 2 * time.Second
filters.AddFilter(ipNet, filter.ActionAccept)
conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID)
Expect(err).ToNot(HaveOccurred())
Expand Down
2 changes: 1 addition & 1 deletion listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func newListener(rconn *reuseConn, t *transport, localPeer peer.ID, key ic.PrivK
conf, _ := identity.ConfigForAny()
return conf, nil
}
ln, err := quic.Listen(rconn, &tlsConf, t.config)
ln, err := quic.Listen(rconn, &tlsConf, t.serverConfig)
if err != nil {
return nil, err
}
Expand Down
62 changes: 49 additions & 13 deletions transport.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package libp2pquic

import (
"bufio"
"compress/gzip"
"context"
"errors"
"fmt"
"io"
"net"
"os"
"time"

"github.com/minio/sha256-simd"
"golang.org/x/crypto/hkdf"
Expand Down Expand Up @@ -87,11 +92,12 @@ func (c *connManager) Dial(network string, raddr *net.UDPAddr) (*reuseConn, erro

// The Transport implements the tpt.Transport interface for QUIC connections.
type transport struct {
privKey ic.PrivKey
localPeer peer.ID
identity *p2ptls.Identity
connManager *connManager
config *quic.Config
privKey ic.PrivKey
localPeer peer.ID
identity *p2ptls.Identity
connManager *connManager
serverConfig *quic.Config
clientConfig *quic.Config
}

var _ tpt.Transport = &transport{}
Expand Down Expand Up @@ -125,13 +131,17 @@ func NewTransport(key ic.PrivKey, psk pnet.PSK, filters *filter.Filters) (tpt.Tr
return nil, err
}

return &transport{
privKey: key,
localPeer: localPeer,
identity: identity,
connManager: connManager,
config: config,
}, nil
t := &transport{
privKey: key,
localPeer: localPeer,
identity: identity,
connManager: connManager,
serverConfig: config,
clientConfig: config.Clone(),
}
t.serverConfig.GetLogWriter = t.GetLogWriterFor("server")
t.clientConfig.GetLogWriter = t.GetLogWriterFor("client")
return t, nil
}

// Dial dials a new QUIC connection
Expand All @@ -153,7 +163,7 @@ func (t *transport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tp
if err != nil {
return nil, err
}
sess, err := quic.DialContext(ctx, pconn, addr, host, tlsConf, t.config)
sess, err := quic.DialContext(ctx, pconn, addr, host, tlsConf, t.clientConfig)
if err != nil {
pconn.DecreaseCount()
return nil, err
Expand Down Expand Up @@ -190,6 +200,32 @@ func (t *transport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (tp
}, nil
}

func (t *transport) GetLogWriterFor(role string) func([]byte) io.WriteCloser {
qlogDir := os.Getenv("QLOGDIR")
if len(qlogDir) == 0 {
return nil
}
return func(connID []byte) io.WriteCloser {
// create the QLOGDIR, if it doesn't exist
if _, err := os.Stat(qlogDir); os.IsNotExist(err) {
if err := os.MkdirAll(qlogDir, 0777); err != nil {
log.Errorf("creating the QLOGDIR failed: %s", err)
return nil
}
}
now := time.Now()
t := fmt.Sprintf("%d-%02d-%02dT%02d-%02d-%02d-%06d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond()/1000)
filename := fmt.Sprintf("%s/log_%s_%s_%x.qlog.gz", qlogDir, t, role, connID)
f, err := os.Create(filename)
if err != nil {
log.Errorf("unable to create qlog file %s: %s", filename, err)
return nil
}
gz := gzip.NewWriter(f)
return newBufferedWriteCloser(bufio.NewWriter(gz), gz)
}
}

// CanDial determines if we can dial to an address
func (t *transport) CanDial(addr ma.Multiaddr) bool {
return mafmt.QUIC.Matches(addr)
Expand Down

0 comments on commit 88546e0

Please sign in to comment.