435c0d9fc8
This PR switches the Nomad repository from using govendor to Go modules for managing dependencies. Aspects of the Nomad workflow remain pretty much the same. The usual Makefile targets should continue to work as they always did. The API submodule simply defers to the parent Nomad version on the repository, keeping the semantics of API versioning that currently exists.
265 lines
6.6 KiB
Go
265 lines
6.6 KiB
Go
// Copyright 2012 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package ipv4
|
|
|
|
import (
|
|
"net"
|
|
|
|
"golang.org/x/net/bpf"
|
|
)
|
|
|
|
// MulticastTTL returns the time-to-live field value for outgoing
|
|
// multicast packets.
|
|
func (c *dgramOpt) MulticastTTL() (int, error) {
|
|
if !c.ok() {
|
|
return 0, errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoMulticastTTL]
|
|
if !ok {
|
|
return 0, errNotImplemented
|
|
}
|
|
return so.GetInt(c.Conn)
|
|
}
|
|
|
|
// SetMulticastTTL sets the time-to-live field value for future
|
|
// outgoing multicast packets.
|
|
func (c *dgramOpt) SetMulticastTTL(ttl int) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoMulticastTTL]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
return so.SetInt(c.Conn, ttl)
|
|
}
|
|
|
|
// MulticastInterface returns the default interface for multicast
|
|
// packet transmissions.
|
|
func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
|
|
if !c.ok() {
|
|
return nil, errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoMulticastInterface]
|
|
if !ok {
|
|
return nil, errNotImplemented
|
|
}
|
|
return so.getMulticastInterface(c.Conn)
|
|
}
|
|
|
|
// SetMulticastInterface sets the default interface for future
|
|
// multicast packet transmissions.
|
|
func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoMulticastInterface]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
return so.setMulticastInterface(c.Conn, ifi)
|
|
}
|
|
|
|
// MulticastLoopback reports whether transmitted multicast packets
|
|
// should be copied and send back to the originator.
|
|
func (c *dgramOpt) MulticastLoopback() (bool, error) {
|
|
if !c.ok() {
|
|
return false, errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoMulticastLoopback]
|
|
if !ok {
|
|
return false, errNotImplemented
|
|
}
|
|
on, err := so.GetInt(c.Conn)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return on == 1, nil
|
|
}
|
|
|
|
// SetMulticastLoopback sets whether transmitted multicast packets
|
|
// should be copied and send back to the originator.
|
|
func (c *dgramOpt) SetMulticastLoopback(on bool) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoMulticastLoopback]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
return so.SetInt(c.Conn, boolint(on))
|
|
}
|
|
|
|
// 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.
|
|
// JoinGroup 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) JoinGroup(ifi *net.Interface, group net.Addr) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoJoinGroup]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
grp := netAddrToIP4(group)
|
|
if grp == nil {
|
|
return errMissingAddress
|
|
}
|
|
return so.setGroup(c.Conn, ifi, grp)
|
|
}
|
|
|
|
// LeaveGroup leaves the group address group on the interface ifi
|
|
// regardless of whether the group is any-source group or
|
|
// source-specific group.
|
|
func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoLeaveGroup]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
grp := netAddrToIP4(group)
|
|
if grp == nil {
|
|
return errMissingAddress
|
|
}
|
|
return so.setGroup(c.Conn, ifi, grp)
|
|
}
|
|
|
|
// JoinSourceSpecificGroup joins the source-specific group comprising
|
|
// group and source on the interface ifi.
|
|
// JoinSourceSpecificGroup 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 errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoJoinSourceGroup]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
grp := netAddrToIP4(group)
|
|
if grp == nil {
|
|
return errMissingAddress
|
|
}
|
|
src := netAddrToIP4(source)
|
|
if src == nil {
|
|
return errMissingAddress
|
|
}
|
|
return so.setSourceGroup(c.Conn, 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 errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoLeaveSourceGroup]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
grp := netAddrToIP4(group)
|
|
if grp == nil {
|
|
return errMissingAddress
|
|
}
|
|
src := netAddrToIP4(source)
|
|
if src == nil {
|
|
return errMissingAddress
|
|
}
|
|
return so.setSourceGroup(c.Conn, ifi, grp, src)
|
|
}
|
|
|
|
// ExcludeSourceSpecificGroup excludes the source-specific group from
|
|
// the already joined any-source groups by JoinGroup on the interface
|
|
// ifi.
|
|
func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoBlockSourceGroup]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
grp := netAddrToIP4(group)
|
|
if grp == nil {
|
|
return errMissingAddress
|
|
}
|
|
src := netAddrToIP4(source)
|
|
if src == nil {
|
|
return errMissingAddress
|
|
}
|
|
return so.setSourceGroup(c.Conn, 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 errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoUnblockSourceGroup]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
grp := netAddrToIP4(group)
|
|
if grp == nil {
|
|
return errMissingAddress
|
|
}
|
|
src := netAddrToIP4(source)
|
|
if src == nil {
|
|
return errMissingAddress
|
|
}
|
|
return so.setSourceGroup(c.Conn, ifi, grp, src)
|
|
}
|
|
|
|
// ICMPFilter returns an ICMP filter.
|
|
// Currently only Linux supports this.
|
|
func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
|
|
if !c.ok() {
|
|
return nil, errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoICMPFilter]
|
|
if !ok {
|
|
return nil, errNotImplemented
|
|
}
|
|
return so.getICMPFilter(c.Conn)
|
|
}
|
|
|
|
// SetICMPFilter deploys the ICMP filter.
|
|
// Currently only Linux supports this.
|
|
func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoICMPFilter]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
return so.setICMPFilter(c.Conn, f)
|
|
}
|
|
|
|
// SetBPF attaches a BPF program to the connection.
|
|
//
|
|
// Only supported on Linux.
|
|
func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
|
|
if !c.ok() {
|
|
return errInvalidConn
|
|
}
|
|
so, ok := sockOpts[ssoAttachFilter]
|
|
if !ok {
|
|
return errNotImplemented
|
|
}
|
|
return so.setBPF(c.Conn, filter)
|
|
}
|