Repository: go
Issue: x/net: Implement PacketConn.JoinSourceSpecificGroup() and PacketConn.LeaveSourceSpecificGroup for Windows
Labels: OS-Windows,NeedsInvestigation

### What version of Go are you using (`go version`)?

<pre>
go1.12.6 windows/amd64

</pre>

### Does this issue reproduce with the latest release?

Yes

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Administrator\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Administrator\go
set GOPROXY=
set GORACE=
set GOROOT=c:\go
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=0
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\ADMINI~1\AppData\Local\Temp\go-build729998322=/tmp/go-build -gno-record-gcc-switches

</pre></details>

### What did you do?
Following this documentation https://godoc.org/golang.org/x/net/ipv4 we wanted to join a multicast group and receive packets from a specified source on **Windows** :
 
``` golang
func (m *MCastSource) joinMulticastSourceGroup() error {
	var err error

	m.iface, err = net.InterfaceByName(m.ifaceName)
	if err != nil {
		return err
	}

	// Listens on any interfaces
	m.netPacketConn, err = net.ListenPacket("udp4", "0.0.0.0:5050")
	if err != nil {
		return err
	}
	m.ipv4PacketConn = ipv4.NewPacketConn(m.netPacketConn)

	groupIP := net.ParseIP(m.groupIp)
	sourceIP := net.ParseIP(m.sourceIp)
	m.ssmgroup = &net.UDPAddr{IP: net.IPv4(groupIP[12], groupIP[13], groupIP[14], groupIP[15])}
	m.ssmsource = &net.UDPAddr{IP: net.IPv4(sourceIP[12], sourceIP[13], sourceIP[14], sourceIP[15])}

	// Join source-specific multicast group
	if err := m.ipv4PacketConn.JoinSourceSpecificGroup(m.iface, m.ssmgroup, m.ssmsource); err != nil {
		return err
	}

	return nil
}
```

### What did you expect to see?

We expected to join a multicast group with a specified source.


### What did you see instead?

An error message explaining that PacketConn.JoinSourceSpecificGroup() from `/net/ipv4` is not implemented on Windows.

### What's next?

A pull request will quickly follow this issue. This PR aims to add the support of JoinSourceSpecificGroup() and LeaveSourceSpecificGroup() to Windows OSes.
We plan on doing so by adding the IP_ADD_SOURCE_MEMBERSHIP and the IP_DROP_SOURCE_MEMBERSHIP options to the list of sockopts supported on Windows.
https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options

We do know that there's a more recent API (https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-group_source_req) that we could use to implement these two methods on Windows but we chose to use the IPProto socket options for the following reasons:
- these socket options are part of the same group of options that is currently used by the net/ipv4 package to implement the JoinGroup() and LeaveGroup() methods on Windows (IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP). We find it more consistent to use the same API for both joining/leaving groups and source specific groups.
- these socket options are available on a wider range of OSes (it was first added on Windows XP)