...

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