Imported Upstream version 4.7.2
[platform/upstream/gcc48.git] / libgo / go / net / sockopt.go
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 freebsd linux netbsd openbsd windows
6
7 // Socket options
8
9 package net
10
11 import (
12         "os"
13         "syscall"
14         "time"
15 )
16
17 // Boolean to int.
18 func boolint(b bool) int {
19         if b {
20                 return 1
21         }
22         return 0
23 }
24
25 func ipv4AddrToInterface(ip IP) (*Interface, error) {
26         ift, err := Interfaces()
27         if err != nil {
28                 return nil, err
29         }
30         for _, ifi := range ift {
31                 ifat, err := ifi.Addrs()
32                 if err != nil {
33                         return nil, err
34                 }
35                 for _, ifa := range ifat {
36                         switch v := ifa.(type) {
37                         case *IPAddr:
38                                 if ip.Equal(v.IP) {
39                                         return &ifi, nil
40                                 }
41                         case *IPNet:
42                                 if ip.Equal(v.IP) {
43                                         return &ifi, nil
44                                 }
45                         }
46                 }
47         }
48         if ip.Equal(IPv4zero) {
49                 return nil, nil
50         }
51         return nil, errNoSuchInterface
52 }
53
54 func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
55         if ifi == nil {
56                 return IPv4zero, nil
57         }
58         ifat, err := ifi.Addrs()
59         if err != nil {
60                 return nil, err
61         }
62         for _, ifa := range ifat {
63                 switch v := ifa.(type) {
64                 case *IPAddr:
65                         if v.IP.To4() != nil {
66                                 return v.IP, nil
67                         }
68                 case *IPNet:
69                         if v.IP.To4() != nil {
70                                 return v.IP, nil
71                         }
72                 }
73         }
74         return nil, errNoSuchInterface
75 }
76
77 func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
78         if ifi == nil {
79                 return nil
80         }
81         ifat, err := ifi.Addrs()
82         if err != nil {
83                 return err
84         }
85         for _, ifa := range ifat {
86                 switch v := ifa.(type) {
87                 case *IPAddr:
88                         if a := v.IP.To4(); a != nil {
89                                 copy(mreq.Interface[:], a)
90                                 goto done
91                         }
92                 case *IPNet:
93                         if a := v.IP.To4(); a != nil {
94                                 copy(mreq.Interface[:], a)
95                                 goto done
96                         }
97                 }
98         }
99 done:
100         if bytesEqual(mreq.Multiaddr[:], IPv4zero.To4()) {
101                 return errNoSuchMulticastInterface
102         }
103         return nil
104 }
105
106 func setReadBuffer(fd *netFD, bytes int) error {
107         if err := fd.incref(false); err != nil {
108                 return err
109         }
110         defer fd.decref()
111         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes))
112 }
113
114 func setWriteBuffer(fd *netFD, bytes int) error {
115         if err := fd.incref(false); err != nil {
116                 return err
117         }
118         defer fd.decref()
119         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes))
120 }
121
122 func setReadDeadline(fd *netFD, t time.Time) error {
123         if t.IsZero() {
124                 fd.rdeadline = 0
125         } else {
126                 fd.rdeadline = t.UnixNano()
127         }
128         return nil
129 }
130
131 func setWriteDeadline(fd *netFD, t time.Time) error {
132         if t.IsZero() {
133                 fd.wdeadline = 0
134         } else {
135                 fd.wdeadline = t.UnixNano()
136         }
137         return nil
138 }
139
140 func setDeadline(fd *netFD, t time.Time) error {
141         if err := setReadDeadline(fd, t); err != nil {
142                 return err
143         }
144         return setWriteDeadline(fd, t)
145 }
146
147 func setReuseAddr(fd *netFD, reuse bool) error {
148         if err := fd.incref(false); err != nil {
149                 return err
150         }
151         defer fd.decref()
152         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse)))
153 }
154
155 func setDontRoute(fd *netFD, dontroute bool) error {
156         if err := fd.incref(false); err != nil {
157                 return err
158         }
159         defer fd.decref()
160         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute)))
161 }
162
163 func setKeepAlive(fd *netFD, keepalive bool) error {
164         if err := fd.incref(false); err != nil {
165                 return err
166         }
167         defer fd.decref()
168         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)))
169 }
170
171 func setNoDelay(fd *netFD, noDelay bool) error {
172         if err := fd.incref(false); err != nil {
173                 return err
174         }
175         defer fd.decref()
176         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)))
177 }
178
179 func setLinger(fd *netFD, sec int) error {
180         var l syscall.Linger
181         if sec >= 0 {
182                 l.Onoff = 1
183                 l.Linger = int32(sec)
184         } else {
185                 l.Onoff = 0
186                 l.Linger = 0
187         }
188         if err := fd.incref(false); err != nil {
189                 return err
190         }
191         defer fd.decref()
192         return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
193 }