Skip to content

Commit

Permalink
x/net/ipv6: add support for source-specific multicast
Browse files Browse the repository at this point in the history
This CL introduces methods for the manipulation of source-specifc
group into PacketConn as follows:

JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error

Fixes golang/go#8752.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/169510043
  • Loading branch information
cixtor committed Nov 14, 2014
1 parent 53bb751 commit 40ad15c
Show file tree
Hide file tree
Showing 6 changed files with 430 additions and 178 deletions.
4 changes: 4 additions & 0 deletions ipv6/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ var (
// http://tools.ietf.org/html/rfc3493.html
// RFC 3542 Advanced Sockets Application Program Interface (API) for IPv6
// http://tools.ietf.org/html/rfc3542
// RFC 3678 Socket Interface Extensions for Multicast Source Filters
// http://tools.ietf.org/html/rfc3678
// RFC 4607 Source-Specific Multicast for IP
// http://tools.ietf.org/html/rfc4607
//
// Note that RFC 3542 obsoletes RFC 2292 but OS X Snow Leopard and the
// former still support RFC 2292 only. Please be aware that almost
Expand Down
96 changes: 95 additions & 1 deletion ipv6/dgramopt_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error {
return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on))
}

// JoinGroup joins the group address group on the interface ifi.
// JoinGroup joins the group address group on the interface ifi. By
// default all sources that can cast data to group are accepted. It's
// possible to mute and unmute data transmission from a specific
// source by using ExcludeSourceSpecificGroup and
// IncludeSourceSpecificGroup.
// It uses the system assigned multicast interface when ifi is nil,
// although this is not recommended because the assignment depends on
// platforms and sometimes it might require routing configuration.
Expand All @@ -113,6 +117,8 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
}

// LeaveGroup leaves the group address group on the interface ifi.
// It's allowed to leave the group which is formed by
// JoinSourceSpecificGroup for convenience.
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
if !c.ok() {
return syscall.EINVAL
Expand All @@ -128,6 +134,94 @@ func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp)
}

// JoinSourceSpecificGroup joins the source-specific group consisting
// group and source on the interface ifi. It uses the system assigned
// multicast interface when ifi is nil, although this is not
// recommended because the assignment depends on platforms and
// sometimes it might require routing configuration.
func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() {
return syscall.EINVAL
}
fd, err := c.sysfd()
if err != nil {
return err
}
grp := netAddrToIP16(group)
if grp == nil {
return errMissingAddress
}
src := netAddrToIP16(source)
if src == nil {
return errMissingAddress
}
return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src)
}

// LeaveSourceSpecificGroup leaves the source-specific group on the
// interface ifi.
func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() {
return syscall.EINVAL
}
fd, err := c.sysfd()
if err != nil {
return err
}
grp := netAddrToIP16(group)
if grp == nil {
return errMissingAddress
}
src := netAddrToIP16(source)
if src == nil {
return errMissingAddress
}
return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src)
}

// ExcludeSourceSpecificGroup excludes the source-specific group from
// the already joined groups by either JoinGroup or
// JoinSourceSpecificGroup on the interface ifi.
func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() {
return syscall.EINVAL
}
fd, err := c.sysfd()
if err != nil {
return err
}
grp := netAddrToIP16(group)
if grp == nil {
return errMissingAddress
}
src := netAddrToIP16(source)
if src == nil {
return errMissingAddress
}
return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src)
}

// IncludeSourceSpecificGroup includes the excluded source-specific
// group by ExcludeSourceSpecificGroup again on the interface ifi.
func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
if !c.ok() {
return syscall.EINVAL
}
fd, err := c.sysfd()
if err != nil {
return err
}
grp := netAddrToIP16(group)
if grp == nil {
return errMissingAddress
}
src := netAddrToIP16(source)
if src == nil {
return errMissingAddress
}
return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src)
}

// Checksum reports whether the kernel will compute, store or verify a
// checksum for both incoming and outgoing packets. If on is true, it
// returns an offset in bytes into the data of where the checksum
Expand Down
36 changes: 35 additions & 1 deletion ipv6/dgramopt_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ func (c *dgramOpt) SetMulticastLoopback(on bool) error {
return errOpNoSupport
}

// JoinGroup joins the group address group on the interface ifi.
// JoinGroup joins the group address group on the interface ifi. By
// default all sources that can cast data to group are accepted. It's
// possible to mute and unmute data transmission from a specific
// source by using ExcludeSourceSpecificGroup and
// IncludeSourceSpecificGroup.
// It uses the system assigned multicast interface when ifi is nil,
// although this is not recommended because the assignment depends on
// platforms and sometimes it might require routing configuration.
Expand All @@ -53,10 +57,40 @@ func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
}

// LeaveGroup leaves the group address group on the interface ifi.
// It's allowed to leave the group which is formed by
// JoinSourceSpecificGroup for convenience.
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
return errOpNoSupport
}

// JoinSourceSpecificGroup joins the source-specific group consisting
// group and source on the interface ifi. It uses the system assigned
// multicast interface when ifi is nil, although this is not
// recommended because the assignment depends on platforms and
// sometimes it might require routing configuration.
func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
return errOpNoSupport
}

// LeaveSourceSpecificGroup leaves the source-specific group on the
// interface ifi.
func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
return errOpNoSupport
}

// ExcludeSourceSpecificGroup excludes the source-specific group from
// the already joined groups by either JoinGroup or
// JoinSourceSpecificGroup on the interface ifi.
func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
return errOpNoSupport
}

// IncludeSourceSpecificGroup includes the excluded source-specific
// group by ExcludeSourceSpecificGroup again on the interface ifi.
func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
return errOpNoSupport
}

// Checksum reports whether the kernel will compute, store or verify a
// checksum for both incoming and outgoing packets. If on is true, it
// returns an offset in bytes into the data of where the checksum
Expand Down
3 changes: 2 additions & 1 deletion ipv6/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
//
// The package provides IP-level socket options that allow
// manipulation of IPv6 facilities. The IPv6 and socket options for
// IPv6 are defined in RFC 2460, RFC 3493 and RFC 3542.
// IPv6 are defined in RFC 2460, RFC 3493, RFC 3542, RFC 3678 and RFC
// 4607.
//
//
// Unicasting
Expand Down

0 comments on commit 40ad15c

Please sign in to comment.