internal/socket: properly reset Iov and Control on the msghdr

A sync.Pool is used to reduce allocations of the msghdr struct. When using a
struct obtained from the pool, the fields need to be cleared.

Fixes golang/go#54693.

Change-Id: Ie693979abf3aa6bc3c834b9558c5029b376326e6
Reviewed-on: https://go-review.googlesource.com/c/net/+/425915
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
diff --git a/internal/socket/mmsghdr_unix.go b/internal/socket/mmsghdr_unix.go
index 0bfcf7a..41883c5 100644
--- a/internal/socket/mmsghdr_unix.go
+++ b/internal/socket/mmsghdr_unix.go
@@ -172,7 +172,23 @@
 }
 
 func (p *mmsgTmpsPool) Get() *mmsgTmps {
-	return p.p.Get().(*mmsgTmps)
+	m := p.p.Get().(*mmsgTmps)
+	// Clear fields up to the len (not the cap) of the slice,
+	// assuming that the previous caller only used that many elements.
+	for i := range m.packer.sockaddrs {
+		m.packer.sockaddrs[i] = 0
+	}
+	m.packer.sockaddrs = m.packer.sockaddrs[:0]
+	for i := range m.packer.vs {
+		m.packer.vs[i] = iovec{}
+	}
+	m.packer.vs = m.packer.vs[:0]
+	for i := range m.packer.hs {
+		m.packer.hs[i].Len = 0
+		m.packer.hs[i].Hdr = msghdr{}
+	}
+	m.packer.hs = m.packer.hs[:0]
+	return m
 }
 
 func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
diff --git a/internal/socket/msghdr_linux.go b/internal/socket/msghdr_linux.go
index c3c7cc4..5a38798 100644
--- a/internal/socket/msghdr_linux.go
+++ b/internal/socket/msghdr_linux.go
@@ -17,9 +17,6 @@
 	if sa != nil {
 		h.Name = (*byte)(unsafe.Pointer(&sa[0]))
 		h.Namelen = uint32(len(sa))
-	} else {
-		h.Name = nil
-		h.Namelen = 0
 	}
 }