net: permit WriteMsgUDP to connected UDP sockets

The sanity checks at the beginning of WriteMsgUDP were too
strict, and did not allow a case sendmsg(2) suppports: sending
to a connected UDP socket.

This fixes the sanity checks. Either the socket is unconnected,
and a destination addresses is required (what all existing callers
must have been doing), or the socket is connected and an explicit
destination address must not be used.

Fixes #9807

Change-Id: I08d4ec3c2bf830335c402acfc0680c841cfcec71
Reviewed-on: https://go-review.googlesource.com/3951
Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com>
diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go
index a053336..0770b7c 100644
--- a/src/net/udpsock_posix.go
+++ b/src/net/udpsock_posix.go
@@ -139,17 +139,19 @@
 	return c.WriteToUDP(b, a)
 }
 
-// WriteMsgUDP writes a packet to addr via c, copying the payload from
-// b and the associated out-of-band data from oob.  It returns the
-// number of payload and out-of-band bytes written.
+// WriteMsgUDP writes a packet to addr via c if c isn't connected, or
+// to c's remote destination address if c is connected (in which case
+// addr must be nil).  The payload is copied from b and the associated
+// out-of-band data is copied from oob.  It returns the number of
+// payload and out-of-band bytes written.
 func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
 	if !c.ok() {
 		return 0, 0, syscall.EINVAL
 	}
-	if c.fd.isConnected {
+	if c.fd.isConnected && addr != nil {
 		return 0, 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
 	}
-	if addr == nil {
+	if !c.fd.isConnected && addr == nil {
 		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
 	}
 	sa, err := addr.sockaddr(c.fd.family)