From 000fa84a3bb1aebeda235c56545c942d7c29003d Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Thu, 6 Dec 2018 11:40:39 -0800 Subject: Fix tcpip.Endpoint.Write contract regarding short writes * Clarify tcpip.Endpoint.Write contract regarding short writes. * Enforce tcpip.Endpoint.Write contract regarding short writes. * Update relevant users of tcpip.Endpoint.Write. PiperOrigin-RevId: 224377586 Change-Id: I24299ecce902eb11317ee13dae3b8d8a7c5b097d --- pkg/tcpip/tcpip.go | 5 ++++- pkg/tcpip/transport/ping/endpoint.go | 6 +++++- pkg/tcpip/transport/tcp/endpoint.go | 6 +----- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'pkg/tcpip') diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index 8e2fe70ee..dc6339173 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -312,7 +312,10 @@ type Endpoint interface { // the caller should not use data[:n] after Write returns. // // Note that unlike io.Writer.Write, it is not an error for Write to - // perform a partial write. + // perform a partial write (if n > 0, no error may be returned). Only + // stream (TCP) Endpoints may return partial writes, and even then only + // in the case where writing additional data would block. Other Endpoints + // will either write the entire message or return an error. // // For UDP and Ping sockets if address resolution is required, // ErrNoLinkAddress and a notification channel is returned for the caller to diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go index b3f54cfe0..10d4d138e 100644 --- a/pkg/tcpip/transport/ping/endpoint.go +++ b/pkg/tcpip/transport/ping/endpoint.go @@ -299,7 +299,11 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c err = sendPing6(route, e.id.LocalPort, v) } - return uintptr(len(v)), nil, err + if err != nil { + return 0, nil, err + } + + return uintptr(len(v)), nil, nil } // Peek only returns data from a single datagram, so do nothing here. diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 1649dbc97..6034ba90b 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -554,10 +554,6 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c return 0, nil, perr } - var err *tcpip.Error - if p.Size() > avail { - err = tcpip.ErrWouldBlock - } l := len(v) s := newSegmentFromView(&e.route, e.id, v) @@ -576,7 +572,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-c // Let the protocol goroutine do the work. e.sndWaker.Assert() } - return uintptr(l), nil, err + return uintptr(l), nil, nil } // Peek reads data without consuming it from the endpoint. -- cgit v1.2.3