...
Source file
src/net/sockopt_posix.go
Documentation: net
1
2
3
4
5
6
7
8 package net
9
10 import (
11 "internal/bytealg"
12 "runtime"
13 "syscall"
14 )
15
16
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