github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/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 solaris windows 6 7 package net 8 9 import ( 10 "runtime" 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 err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes) 105 runtime.KeepAlive(fd) 106 return wrapSyscallError("setsockopt", err) 107 } 108 109 func setWriteBuffer(fd *netFD, bytes int) error { 110 err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes) 111 runtime.KeepAlive(fd) 112 return wrapSyscallError("setsockopt", err) 113 } 114 115 func setKeepAlive(fd *netFD, keepalive bool) error { 116 err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)) 117 runtime.KeepAlive(fd) 118 return wrapSyscallError("setsockopt", err) 119 } 120 121 func setLinger(fd *netFD, sec int) error { 122 var l syscall.Linger 123 if sec >= 0 { 124 l.Onoff = 1 125 l.Linger = int32(sec) 126 } else { 127 l.Onoff = 0 128 l.Linger = 0 129 } 130 err := fd.pfd.SetsockoptLinger(syscall.SOL_SOCKET, syscall.SO_LINGER, &l) 131 runtime.KeepAlive(fd) 132 return wrapSyscallError("setsockopt", err) 133 }