From 276b2e01aa0c02333ced641a9848a28fa4f7d13c Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Sun, 24 Apr 2016 20:19:48 +1000 Subject: [PATCH] Conn.Write should fail if Socket is destroyed https://github.com/ipfs/go-ipfs/issues/2566 --- conn.go | 10 +++++++--- utp_test.go | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/conn.go b/conn.go index acb454e..240086e 100644 --- a/conn.go +++ b/conn.go @@ -337,7 +337,7 @@ func (c *Conn) deliveryProcessor() { func (c *Conn) lazyDestroy() { if c.wroteFin && len(c.unackedSends) <= 1 && (c.gotFin || c.closed) { - c.destroy(nil) + c.destroy(errors.New("lazily destroyed")) } } @@ -550,8 +550,12 @@ func (c *Conn) Write(p []byte) (n int, err error) { defer mu.Unlock() for len(p) != 0 { for { - if c.wroteFin || c.gotFin { - err = io.ErrClosedPipe + if c.wroteFin || c.closed { + err = errClosed + return + } + if c.destroyed { + err = c.err return } if c.connDeadlines.write.deadlineExceeded() { diff --git a/utp_test.go b/utp_test.go index 5036578..d283520 100644 --- a/utp_test.go +++ b/utp_test.go @@ -571,3 +571,22 @@ func TestWriteClose(t *testing.T) { require.EqualValues(t, "hiho", c) b.Close() } + +func TestWriteUnderlyingPacketConnClosed(t *testing.T) { + // writeTimeout = time.Hour + // packetReadTimeout = time.Hour + pc, err := listenPacket("udp", "localhost:0") + require.NoError(t, err) + s, err := NewSocketFromPacketConn(pc) + require.NoError(t, err) + log.Println("pc closed") + dc, ac := connPairSocket(s) + defer dc.Close() + defer ac.Close() + pc.Close() + n, err := ac.Write([]byte("hello")) + require.Equal(t, 0, n) + require.EqualError(t, err, "error sending packet: closed") + _, err = dc.Read(nil) + require.EqualError(t, err, "Socket destroyed") +}