diff options
Diffstat (limited to 'pkg/tcpip/transport/udp')
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 31 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/udp_test.go | 18 |
2 files changed, 23 insertions, 26 deletions
diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index f2dd98f35..6ed805357 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -258,10 +258,10 @@ func (e *endpoint) prepareForWrite(to *tcpip.FullAddress) (retry bool, err *tcpi // Write writes data to the endpoint's peer. This method does not block // if the data cannot be written. -func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tcpip.Error) { +func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, <-chan struct{}, *tcpip.Error) { // MSG_MORE is unimplemented. (This also means that MSG_EOR is a no-op.) if opts.More { - return 0, tcpip.ErrInvalidOptionValue + return 0, nil, tcpip.ErrInvalidOptionValue } to := opts.To @@ -271,14 +271,14 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // If we've shutdown with SHUT_WR we are in an invalid state for sending. if e.shutdownFlags&tcpip.ShutdownWrite != 0 { - return 0, tcpip.ErrClosedForSend + return 0, nil, tcpip.ErrClosedForSend } // Prepare for write. for { retry, err := e.prepareForWrite(to) if err != nil { - return 0, err + return 0, nil, err } if !retry { @@ -303,7 +303,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc // Recheck state after lock was re-acquired. if e.state != stateConnected { - return 0, tcpip.ErrInvalidEndpointState + return 0, nil, tcpip.ErrInvalidEndpointState } } } else { @@ -312,7 +312,7 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc nicid := to.NIC if e.bindNICID != 0 { if nicid != 0 && nicid != e.bindNICID { - return 0, tcpip.ErrNoRoute + return 0, nil, tcpip.ErrNoRoute } nicid = e.bindNICID @@ -322,13 +322,13 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc to = &toCopy netProto, err := e.checkV4Mapped(to, false) if err != nil { - return 0, err + return 0, nil, err } // Find the enpoint. r, err := e.stack.FindRoute(nicid, e.id.LocalAddress, to.Addr, netProto) if err != nil { - return 0, err + return 0, nil, err } defer r.Release() @@ -338,23 +338,20 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc if route.IsResolutionRequired() { waker := &sleep.Waker{} - if err := route.Resolve(waker); err != nil { + if ch, err := route.Resolve(waker); err != nil { if err == tcpip.ErrWouldBlock { // Link address needs to be resolved. Resolution was triggered the background. // Better luck next time. - // - // TODO: queue up the request and send after link address - // is resolved. route.RemoveWaker(waker) - return 0, tcpip.ErrNoLinkAddress + return 0, ch, tcpip.ErrNoLinkAddress } - return 0, err + return 0, nil, err } } v, err := p.Get(p.Size()) if err != nil { - return 0, err + return 0, nil, err } ttl := route.DefaultTTL() @@ -363,9 +360,9 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc } if err := sendUDP(route, buffer.View(v).ToVectorisedView(), e.id.LocalPort, dstPort, ttl); err != nil { - return 0, err + return 0, nil, err } - return uintptr(len(v)), nil + return uintptr(len(v)), nil, nil } // Peek only returns data from a single datagram, so do nothing here. diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 46110c8ff..c3f592bd4 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -482,7 +482,7 @@ func TestV4ReadOnV4(t *testing.T) { func testV4Write(c *testContext) uint16 { // Write to V4 mapped address. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}, }) if err != nil { @@ -512,7 +512,7 @@ func testV4Write(c *testContext) uint16 { func testV6Write(c *testContext) uint16 { // Write to v6 address. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV6Addr, Port: testPort}, }) if err != nil { @@ -590,7 +590,7 @@ func TestDualWriteConnectedToV6(t *testing.T) { // Write to V4 mapped address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}, }) if err != tcpip.ErrNetworkUnreachable { @@ -613,7 +613,7 @@ func TestDualWriteConnectedToV4Mapped(t *testing.T) { // Write to v6 address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV6Addr, Port: testPort}, }) if err != tcpip.ErrInvalidEndpointState { @@ -629,7 +629,7 @@ func TestV4WriteOnV6Only(t *testing.T) { // Write to V4 mapped address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV4MappedAddr, Port: testPort}, }) if err != tcpip.ErrNoRoute { @@ -650,7 +650,7 @@ func TestV6WriteOnBoundToV4Mapped(t *testing.T) { // Write to v6 address. payload := buffer.View(newPayload()) - _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ + _, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: testV6Addr, Port: testPort}, }) if err != tcpip.ErrInvalidEndpointState { @@ -671,7 +671,7 @@ func TestV6WriteOnConnected(t *testing.T) { // Write without destination. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) if err != nil { c.t.Fatalf("Write failed: %v", err) } @@ -707,7 +707,7 @@ func TestV4WriteOnConnected(t *testing.T) { // Write without destination. payload := buffer.View(newPayload()) - n, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) + n, _, err := c.ep.Write(tcpip.SlicePayload(payload), tcpip.WriteOptions{}) if err != nil { c.t.Fatalf("Write failed: %v", err) } @@ -856,7 +856,7 @@ func TestTTL(t *testing.T) { c.t.Fatalf("SetSockOpt failed: %v", err) } - n, err := c.ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{Addr: addr, Port: port}}) + n, _, err := c.ep.Write(payload, tcpip.WriteOptions{To: &tcpip.FullAddress{Addr: addr, Port: port}}) if err != nil { c.t.Fatalf("Write failed: %v", err) } |