Commit 653fbe64 authored by Marten Seemann's avatar Marten Seemann

close the underlying connection when the context is canceled

parent 29d15e5b
...@@ -43,8 +43,20 @@ var _ cs.Transport = &Transport{} ...@@ -43,8 +43,20 @@ var _ cs.Transport = &Transport{}
// SecureInbound runs the TLS handshake as a server. // SecureInbound runs the TLS handshake as a server.
func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (cs.Conn, error) { func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (cs.Conn, error) {
serv := tls.Server(insecure, t.identity.Config) serv := tls.Server(insecure, t.identity.Config)
// TODO: use the ctx
// see https://github.com/golang/go/issues/18482 // There's no way to pass a context to tls.Conn.Handshake().
// See https://github.com/golang/go/issues/18482.
// Close the connection instead.
done := make(chan struct{})
defer close(done)
go func() {
select {
case <-done:
case <-ctx.Done():
insecure.Close()
}
}()
if err := serv.Handshake(); err != nil { if err := serv.Handshake(); err != nil {
return nil, err return nil, err
} }
...@@ -54,8 +66,20 @@ func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (cs.Co ...@@ -54,8 +66,20 @@ func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (cs.Co
// SecureOutbound runs the TLS handshake as a client. // SecureOutbound runs the TLS handshake as a client.
func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (cs.Conn, error) { func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (cs.Conn, error) {
cl := tls.Client(insecure, t.identity.ConfigForPeer(p)) cl := tls.Client(insecure, t.identity.ConfigForPeer(p))
// TODO: use the ctx
// see https://github.com/golang/go/issues/18482 // There's no way to pass a context to tls.Conn.Handshake().
// See https://github.com/golang/go/issues/18482.
// Close the connection instead.
done := make(chan struct{})
defer close(done)
go func() {
select {
case <-done:
case <-ctx.Done():
insecure.Close()
}
}()
if err := cl.Handshake(); err != nil { if err := cl.Handshake(); err != nil {
return nil, err return nil, err
} }
......
...@@ -96,6 +96,46 @@ var _ = Describe("Transport", func() { ...@@ -96,6 +96,46 @@ var _ = Describe("Transport", func() {
Expect(string(b)).To(Equal("foobar")) Expect(string(b)).To(Equal("foobar"))
}) })
It("fails when the context of the outgoing connection is canceled", func() {
clientTransport, err := New(clientKey)
Expect(err).ToNot(HaveOccurred())
serverTransport, err := New(serverKey)
Expect(err).ToNot(HaveOccurred())
clientInsecureConn, serverInsecureConn := connect()
go func() {
defer GinkgoRecover()
_, err := serverTransport.SecureInbound(context.Background(), serverInsecureConn)
Expect(err).To(HaveOccurred())
}()
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err = clientTransport.SecureOutbound(ctx, clientInsecureConn, serverID)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("use of closed network connection"))
})
It("fails when the context of the incoming connection is canceled", func() {
clientTransport, err := New(clientKey)
Expect(err).ToNot(HaveOccurred())
serverTransport, err := New(serverKey)
Expect(err).ToNot(HaveOccurred())
clientInsecureConn, serverInsecureConn := connect()
go func() {
defer GinkgoRecover()
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := serverTransport.SecureInbound(ctx, serverInsecureConn)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("use of closed network connection"))
}()
_, err = clientTransport.SecureOutbound(context.Background(), clientInsecureConn, serverID)
Expect(err).To(HaveOccurred())
})
It("fails if the peer ID doesn't match", func() { It("fails if the peer ID doesn't match", func() {
thirdPartyID, _ := createPeer() thirdPartyID, _ := createPeer()
......
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