ipv4,ipv6: retry ENOBUFS in TestPacketConnReadWriteUnicastUDP

This ports CL 402059 to the non-concurrent UDP and ICMP variants of
the test.

(It isn't obvious to me whether the ENOBUFS retry loop is strictly
needed for the ICMP variants, but I'm getting kind of tired of porting
this CL to different tests and would rather minimize the number of
times it has to be done again. 😩)

Fixes golang/go#53402.

Change-Id: I8dc385fbce121c364efafd988ccf08eebe3fef28
Reviewed-on: https://go-review.googlesource.com/c/net/+/416556
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/ipv4/unicast_test.go b/ipv4/unicast_test.go
index a2b0338..44d4f28 100644
--- a/ipv4/unicast_test.go
+++ b/ipv4/unicast_test.go
@@ -53,11 +53,24 @@
 		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)
 		}
-		if n, err := p.WriteTo(wb, nil, dst); err != nil {
-			t.Fatal(err)
-		} else if n != len(wb) {
-			t.Fatalf("got %v; want %v", n, len(wb))
+
+		backoff := time.Millisecond
+		for {
+			n, err := p.WriteTo(wb, nil, dst)
+			if err != nil {
+				if n == 0 && isENOBUFS(err) {
+					time.Sleep(backoff)
+					backoff *= 2
+					continue
+				}
+				t.Fatal(err)
+			}
+			if n != len(wb) {
+				t.Fatalf("got %d; want %d", n, len(wb))
+			}
+			break
 		}
+
 		rb := make([]byte, 128)
 		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)
@@ -124,11 +137,24 @@
 		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)
 		}
-		if n, err := p.WriteTo(wb, nil, dst); err != nil {
-			t.Fatal(err)
-		} else if n != len(wb) {
-			t.Fatalf("got %v; want %v", n, len(wb))
+
+		backoff := time.Millisecond
+		for {
+			n, err := p.WriteTo(wb, nil, dst)
+			if err != nil {
+				if n == 0 && isENOBUFS(err) {
+					time.Sleep(backoff)
+					backoff *= 2
+					continue
+				}
+				t.Fatal(err)
+			}
+			if n != len(wb) {
+				t.Fatalf("got %d; want %d", n, len(wb))
+			}
+			break
 		}
+
 		rb := make([]byte, 128)
 	loop:
 		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
diff --git a/ipv6/unicast_test.go b/ipv6/unicast_test.go
index 32c42c9..be45a5d 100644
--- a/ipv6/unicast_test.go
+++ b/ipv6/unicast_test.go
@@ -59,11 +59,24 @@
 		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)
 		}
-		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
-			t.Fatal(err)
-		} else if n != len(wb) {
-			t.Fatalf("got %v; want %v", n, len(wb))
+
+		backoff := time.Millisecond
+		for {
+			n, err := p.WriteTo(wb, &cm, dst)
+			if err != nil {
+				if n == 0 && isENOBUFS(err) {
+					time.Sleep(backoff)
+					backoff *= 2
+					continue
+				}
+				t.Fatal(err)
+			}
+			if n != len(wb) {
+				t.Fatalf("got %d; want %d", n, len(wb))
+			}
+			break
 		}
+
 		rb := make([]byte, 128)
 		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)
@@ -159,11 +172,24 @@
 		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)
 		}
-		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
-			t.Fatal(err)
-		} else if n != len(wb) {
-			t.Fatalf("got %v; want %v", n, len(wb))
+
+		backoff := time.Millisecond
+		for {
+			n, err := p.WriteTo(wb, &cm, dst)
+			if err != nil {
+				if n == 0 && isENOBUFS(err) {
+					time.Sleep(backoff)
+					backoff *= 2
+					continue
+				}
+				t.Fatal(err)
+			}
+			if n != len(wb) {
+				t.Fatalf("got %d; want %d", n, len(wb))
+			}
+			break
 		}
+
 		rb := make([]byte, 128)
 		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatal(err)