github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/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 //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 }