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