Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / net / sockopt_posix.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 // TODO(dfc) these unused error returns could be removed
123
124 func setReadDeadline(fd *netFD, t time.Time) error {
125         fd.rdeadline.setTime(t)
126         return nil
127 }
128
129 func setWriteDeadline(fd *netFD, t time.Time) error {
130         fd.wdeadline.setTime(t)
131         return nil
132 }
133
134 func setDeadline(fd *netFD, t time.Time) error {
135         setReadDeadline(fd, t)
136         setWriteDeadline(fd, t)
137         return nil
138 }
139
140 func setKeepAlive(fd *netFD, keepalive bool) error {
141         if err := fd.incref(false); err != nil {
142                 return err
143         }
144         defer fd.decref()
145         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)))
146 }
147
148 func setNoDelay(fd *netFD, noDelay bool) error {
149         if err := fd.incref(false); err != nil {
150                 return err
151         }
152         defer fd.decref()
153         return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)))
154 }
155
156 func setLinger(fd *netFD, sec int) error {
157         var l syscall.Linger
158         if sec >= 0 {
159                 l.Onoff = 1
160                 l.Linger = int32(sec)
161         } else {
162                 l.Onoff = 0
163                 l.Linger = 0
164         }
165         if err := fd.incref(false); err != nil {
166                 return err
167         }
168         defer fd.decref()
169         return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
170 }