github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/net/sockopt_posix.go (about)

     1  // Copyright 2009 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux netbsd openbsd windows
     6  
     7  package net
     8  
     9  import (
    10  	"os"
    11  	"syscall"
    12  )
    13  
    14  // Boolean to int.
    15  func boolint(b bool) int {
    16  	if b {
    17  		return 1
    18  	}
    19  	return 0
    20  }
    21  
    22  func ipv4AddrToInterface(ip IP) (*Interface, error) {
    23  	ift, err := Interfaces()
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  	for _, ifi := range ift {
    28  		ifat, err := ifi.Addrs()
    29  		if err != nil {
    30  			return nil, err
    31  		}
    32  		for _, ifa := range ifat {
    33  			switch v := ifa.(type) {
    34  			case *IPAddr:
    35  				if ip.Equal(v.IP) {
    36  					return &ifi, nil
    37  				}
    38  			case *IPNet:
    39  				if ip.Equal(v.IP) {
    40  					return &ifi, nil
    41  				}
    42  			}
    43  		}
    44  	}
    45  	if ip.Equal(IPv4zero) {
    46  		return nil, nil
    47  	}
    48  	return nil, errNoSuchInterface
    49  }
    50  
    51  func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
    52  	if ifi == nil {
    53  		return IPv4zero, nil
    54  	}
    55  	ifat, err := ifi.Addrs()
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	for _, ifa := range ifat {
    60  		switch v := ifa.(type) {
    61  		case *IPAddr:
    62  			if v.IP.To4() != nil {
    63  				return v.IP, nil
    64  			}
    65  		case *IPNet:
    66  			if v.IP.To4() != nil {
    67  				return v.IP, nil
    68  			}
    69  		}
    70  	}
    71  	return nil, errNoSuchInterface
    72  }
    73  
    74  func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
    75  	if ifi == nil {
    76  		return nil
    77  	}
    78  	ifat, err := ifi.Addrs()
    79  	if err != nil {
    80  		return err
    81  	}
    82  	for _, ifa := range ifat {
    83  		switch v := ifa.(type) {
    84  		case *IPAddr:
    85  			if a := v.IP.To4(); a != nil {
    86  				copy(mreq.Interface[:], a)
    87  				goto done
    88  			}
    89  		case *IPNet:
    90  			if a := v.IP.To4(); a != nil {
    91  				copy(mreq.Interface[:], a)
    92  				goto done
    93  			}
    94  		}
    95  	}
    96  done:
    97  	if bytesEqual(mreq.Multiaddr[:], IPv4zero.To4()) {
    98  		return errNoSuchMulticastInterface
    99  	}
   100  	return nil
   101  }
   102  
   103  func setReadBuffer(fd *netFD, bytes int) error {
   104  	if err := fd.incref(); err != nil {
   105  		return err
   106  	}
   107  	defer fd.decref()
   108  	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes))
   109  }
   110  
   111  func setWriteBuffer(fd *netFD, bytes int) error {
   112  	if err := fd.incref(); err != nil {
   113  		return err
   114  	}
   115  	defer fd.decref()
   116  	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes))
   117  }
   118  
   119  func setKeepAlive(fd *netFD, keepalive bool) error {
   120  	if err := fd.incref(); err != nil {
   121  		return err
   122  	}
   123  	defer fd.decref()
   124  	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)))
   125  }
   126  
   127  func setLinger(fd *netFD, sec int) error {
   128  	var l syscall.Linger
   129  	if sec >= 0 {
   130  		l.Onoff = 1
   131  		l.Linger = int32(sec)
   132  	} else {
   133  		l.Onoff = 0
   134  		l.Linger = 0
   135  	}
   136  	if err := fd.incref(); err != nil {
   137  		return err
   138  	}
   139  	defer fd.decref()
   140  	return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
   141  }