github.com/Cloud-Foundations/Dominator@v0.3.4/lib/net/api.go (about)

     1  package net
     2  
     3  import (
     4  	"net"
     5  	"os"
     6  	"time"
     7  
     8  	"github.com/Cloud-Foundations/Dominator/lib/log"
     9  	"github.com/Cloud-Foundations/Dominator/lib/log/nulllogger"
    10  )
    11  
    12  const (
    13  	InterfaceTypeBonding = 1 << iota
    14  	InterfaceTypeBridge
    15  	InterfaceTypeEtherNet
    16  	InterfaceTypeVlan
    17  	InterfaceTypeTunTap
    18  )
    19  
    20  // CpuSharer defines the interface for types which can be used to
    21  // co-operatively share CPUs.
    22  type CpuSharer interface {
    23  	GrabCpu()
    24  	ReleaseCpu()
    25  }
    26  
    27  // Dialer defines a dialer that can be use to create connections.
    28  type Dialer interface {
    29  	Dial(network, address string) (net.Conn, error)
    30  }
    31  
    32  type TCPConn interface {
    33  	net.Conn
    34  	SetKeepAlive(keepalive bool) error
    35  	SetKeepAlivePeriod(d time.Duration) error
    36  }
    37  
    38  // BindAndDial is similar to the net.Dial function from the standard library
    39  // except it binds the underlying network socket to a specified local address.
    40  // This gives control over the local port number of the connection, rather than
    41  // a randomly assigned port number.
    42  func BindAndDial(network, localAddr, remoteAddr string, timeout time.Duration) (
    43  	net.Conn, error) {
    44  	return bindAndDial(network, localAddr, remoteAddr, timeout)
    45  }
    46  
    47  // CreateTapDevice will create a "tap" network device with a randomly chosen
    48  // interface name. The tap device file and the interface name are returned on
    49  // success, else an error is returned. The device will be destroyed when the
    50  // file is closed.
    51  func CreateTapDevice() (*os.File, string, error) {
    52  	return createTapDevice()
    53  }
    54  
    55  // GetBridgeVlanId will get the VLAN Id associated with the uplink EtherNet
    56  // interface for the specified bridge interface. If there is no uplink then the
    57  // returned VLAN Id will be -1.
    58  func GetBridgeVlanId(bridgeIf string) (int, error) {
    59  	return getBridgeVlanId(bridgeIf)
    60  }
    61  
    62  // ListBridgePorts will return a list of names of interfaces plugged into the
    63  // specified bridge interface. An error is returned if the specified interface
    64  // does not exist or is not a bridge.
    65  func ListBridgePorts(bridge string) ([]string, error) {
    66  	return listBridgePorts(bridge)
    67  }
    68  
    69  // ListBridges will return a list of EtherNet (layer 2) bridges.
    70  func ListBridges() ([]net.Interface, error) {
    71  	bl, _, err := listBroadcastInterfaces(InterfaceTypeBridge, nulllogger.New())
    72  	return bl, err
    73  }
    74  
    75  // ListBroadcastInterfaces will return a list of broadcast (EtherNet, bridge,
    76  // vlan) interfaces. Debugging progress messages are logged to logger.
    77  func ListBroadcastInterfaces(interfaceType uint, logger log.DebugLogger) (
    78  	[]net.Interface, map[string]net.Interface, error) {
    79  	return listBroadcastInterfaces(interfaceType, logger)
    80  }
    81  
    82  // ListenWithReuse is similar to the net.Listen function from the standard
    83  // library but sets the SO_REUSEADDR and SO_REUSEPORT options on the underlying
    84  // socket. This is needed if using BindAndDial to specify the same local address
    85  // as with the listener.
    86  func ListenWithReuse(network, address string) (net.Listener, error) {
    87  	return listenWithReuse(network, address)
    88  }
    89  
    90  // NewCpuSharingDialer wraps dialer and returns a new Dialer which uses the
    91  // cpuSharer to limit concurrent CPU usage.
    92  // Whenever a blocking operation is about to commence (such a Dial or Read or
    93  // Write for the connection) the cpuSharer.ReleaseCpu method is called, allowing
    94  // the blocking operation to run concurrently.
    95  // When the blocking operation completes, the cpuSharer.GrabCpu method is
    96  // called, limiting the number of running goroutines that have to compete for
    97  // the CPU.
    98  // This helps avoid the thundering herd problem where large numbers of
    99  // goroutines processing network transactions overwhelm the CPU and affect the
   100  // responsiveness of other goroutines such as dashboards and health checks.
   101  func NewCpuSharingDialer(dialer Dialer, cpuSharer CpuSharer) Dialer {
   102  	return newCpuSharingDialer(dialer, cpuSharer)
   103  }
   104  
   105  // TestCarrier will return true if the interface has a carrier signal.
   106  func TestCarrier(name string) bool {
   107  	return testCarrier(name)
   108  }
   109  
   110  // MeasuringConnection implements the net.Conn interface. Additionally it has
   111  // methods to return the cumulative time spent blocking in the Read or Write
   112  // methods.
   113  type MeasuringConnection struct {
   114  	net.Conn
   115  	cumulativeReadTime  time.Duration
   116  	cumulativeWriteTime time.Duration
   117  }
   118  
   119  // CumulativeReadTime returns the cumulative time spent blocking on Read.
   120  func (conn *MeasuringConnection) CumulativeReadTime() time.Duration {
   121  	return conn.cumulativeReadTime
   122  }
   123  
   124  // CumulativeReadTime returns the cumulative time spent blocking on Write.
   125  func (conn *MeasuringConnection) CumulativeWriteTime() time.Duration {
   126  	return conn.cumulativeWriteTime
   127  }
   128  
   129  func (conn *MeasuringConnection) Read(b []byte) (n int, err error) {
   130  	return conn.read(b)
   131  }
   132  
   133  func (conn *MeasuringConnection) Write(b []byte) (n int, err error) {
   134  	return conn.write(b)
   135  }
   136  
   137  // MeasuringDialer implements the Dialer interface. Additionally it has
   138  // methods to return the cumulative time spent blocking in the Dial method.
   139  type MeasuringDialer struct {
   140  	dialer             Dialer
   141  	cumulativeDialTime time.Duration
   142  }
   143  
   144  // NewMeasuringDialer wraps dialer and returns a dialer that can be used to
   145  // measure the time spent in blocking operations.
   146  func NewMeasuringDialer(dialer Dialer) *MeasuringDialer {
   147  	return newMeasuringDialer(dialer)
   148  }
   149  
   150  // CumulativeDialTime returns the cumulative time spent blocking on Dial.
   151  func (d *MeasuringDialer) CumulativeDialTime() time.Duration {
   152  	return d.cumulativeDialTime
   153  }