Black Lives Matter. Support the Equal Justice Initiative.

Source file src/net/sockopt_posix.go

Documentation: net

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

View as plain text