From: Mikio Hara Date: Wed, 1 Feb 2012 05:14:04 +0000 (+0900) Subject: net, syscall: add IPv4 multicast helpers for windows X-Git-Tag: weekly.2012-02-07~152 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=804f1882c582f05d55db812964ebe41a986b5eb1;p=gostls13.git net, syscall: add IPv4 multicast helpers for windows Also re-enable simple IPv4 multicast testing on windows. R=alex.brainman, rsc CC=golang-dev https://golang.org/cl/5605048 --- diff --git a/src/pkg/net/multicast_test.go b/src/pkg/net/multicast_test.go index 4112f47cb2..bf0fe4d8d0 100644 --- a/src/pkg/net/multicast_test.go +++ b/src/pkg/net/multicast_test.go @@ -86,7 +86,7 @@ func TestListenMulticastUDP(t *testing.T) { func TestSimpleListenMulticastUDP(t *testing.T) { switch runtime.GOOS { - case "plan9", "windows": + case "plan9": return } diff --git a/src/pkg/net/sockoptip_windows.go b/src/pkg/net/sockoptip_windows.go index 3320e76bda..a8a9d1c2bf 100644 --- a/src/pkg/net/sockoptip_windows.go +++ b/src/pkg/net/sockoptip_windows.go @@ -7,6 +7,7 @@ package net import ( + "os" "syscall" ) @@ -16,8 +17,19 @@ func ipv4MulticastInterface(fd *netFD) (*Interface, error) { } func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error { - // TODO: Implement this - return syscall.EWINDOWS + ip, err := interfaceToIPv4Addr(ifi) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } + var x [4]byte + copy(x[:], ip.To4()) + fd.incref() + defer fd.decref() + err = syscall.SetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, x) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } + return nil } func ipv4MulticastTTL(fd *netFD) (int, error) { @@ -26,8 +38,14 @@ func ipv4MulticastTTL(fd *netFD) (int, error) { } func setIPv4MulticastTTL(fd *netFD, v int) error { - // TODO: Implement this - return syscall.EWINDOWS + fd.incref() + defer fd.decref() + err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, v) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } + return nil + } func ipv4MulticastLoopback(fd *netFD) (bool, error) { @@ -36,8 +54,14 @@ func ipv4MulticastLoopback(fd *netFD) (bool, error) { } func setIPv4MulticastLoopback(fd *netFD, v bool) error { - // TODO: Implement this - return syscall.EWINDOWS + fd.incref() + defer fd.decref() + err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, boolint(v)) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } + return nil + } func ipv4ReceiveInterface(fd *netFD) (bool, error) { diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go index 45e2994f15..21bdd46d1a 100644 --- a/src/pkg/syscall/syscall_windows.go +++ b/src/pkg/syscall/syscall_windows.go @@ -657,6 +657,9 @@ type IPv6Mreq struct { func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS } func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) { return EWINDOWS } +func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) { + return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4) +} func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) { return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) } diff --git a/src/pkg/syscall/ztypes_windows.go b/src/pkg/syscall/ztypes_windows.go index 1ebcab70f7..ac41f8aa13 100644 --- a/src/pkg/syscall/ztypes_windows.go +++ b/src/pkg/syscall/ztypes_windows.go @@ -389,8 +389,13 @@ const ( SO_SNDBUF = 0x1001 SO_UPDATE_ACCEPT_CONTEXT = 0x700b + // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 + IP_TOS = 0x3 IP_TTL = 0x4 + IP_MULTICAST_IF = 0x9 + IP_MULTICAST_TTL = 0xa + IP_MULTICAST_LOOP = 0xb IP_ADD_MEMBERSHIP = 0xc IP_DROP_MEMBERSHIP = 0xd