OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv4 / endpoint.go
1 // Copyright 2012 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 package ipv4
6
7 import (
8         "net"
9         "syscall"
10         "time"
11
12         "golang.org/x/net/internal/socket"
13 )
14
15 // BUG(mikio): On Windows, the JoinSourceSpecificGroup,
16 // LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
17 // IncludeSourceSpecificGroup methods of PacketConn and RawConn are
18 // not implemented.
19
20 // A Conn represents a network endpoint that uses the IPv4 transport.
21 // It is used to control basic IP-level socket options such as TOS and
22 // TTL.
23 type Conn struct {
24         genericOpt
25 }
26
27 type genericOpt struct {
28         *socket.Conn
29 }
30
31 func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
32
33 // NewConn returns a new Conn.
34 func NewConn(c net.Conn) *Conn {
35         cc, _ := socket.NewConn(c)
36         return &Conn{
37                 genericOpt: genericOpt{Conn: cc},
38         }
39 }
40
41 // A PacketConn represents a packet network endpoint that uses the
42 // IPv4 transport. It is used to control several IP-level socket
43 // options including multicasting. It also provides datagram based
44 // network I/O methods specific to the IPv4 and higher layer protocols
45 // such as UDP.
46 type PacketConn struct {
47         genericOpt
48         dgramOpt
49         payloadHandler
50 }
51
52 type dgramOpt struct {
53         *socket.Conn
54 }
55
56 func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
57
58 // SetControlMessage sets the per packet IP-level socket options.
59 func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
60         if !c.payloadHandler.ok() {
61                 return syscall.EINVAL
62         }
63         return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
64 }
65
66 // SetDeadline sets the read and write deadlines associated with the
67 // endpoint.
68 func (c *PacketConn) SetDeadline(t time.Time) error {
69         if !c.payloadHandler.ok() {
70                 return syscall.EINVAL
71         }
72         return c.payloadHandler.PacketConn.SetDeadline(t)
73 }
74
75 // SetReadDeadline sets the read deadline associated with the
76 // endpoint.
77 func (c *PacketConn) SetReadDeadline(t time.Time) error {
78         if !c.payloadHandler.ok() {
79                 return syscall.EINVAL
80         }
81         return c.payloadHandler.PacketConn.SetReadDeadline(t)
82 }
83
84 // SetWriteDeadline sets the write deadline associated with the
85 // endpoint.
86 func (c *PacketConn) SetWriteDeadline(t time.Time) error {
87         if !c.payloadHandler.ok() {
88                 return syscall.EINVAL
89         }
90         return c.payloadHandler.PacketConn.SetWriteDeadline(t)
91 }
92
93 // Close closes the endpoint.
94 func (c *PacketConn) Close() error {
95         if !c.payloadHandler.ok() {
96                 return syscall.EINVAL
97         }
98         return c.payloadHandler.PacketConn.Close()
99 }
100
101 // NewPacketConn returns a new PacketConn using c as its underlying
102 // transport.
103 func NewPacketConn(c net.PacketConn) *PacketConn {
104         cc, _ := socket.NewConn(c.(net.Conn))
105         p := &PacketConn{
106                 genericOpt:     genericOpt{Conn: cc},
107                 dgramOpt:       dgramOpt{Conn: cc},
108                 payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
109         }
110         return p
111 }
112
113 // A RawConn represents a packet network endpoint that uses the IPv4
114 // transport. It is used to control several IP-level socket options
115 // including IPv4 header manipulation. It also provides datagram
116 // based network I/O methods specific to the IPv4 and higher layer
117 // protocols that handle IPv4 datagram directly such as OSPF, GRE.
118 type RawConn struct {
119         genericOpt
120         dgramOpt
121         packetHandler
122 }
123
124 // SetControlMessage sets the per packet IP-level socket options.
125 func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
126         if !c.packetHandler.ok() {
127                 return syscall.EINVAL
128         }
129         return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
130 }
131
132 // SetDeadline sets the read and write deadlines associated with the
133 // endpoint.
134 func (c *RawConn) SetDeadline(t time.Time) error {
135         if !c.packetHandler.ok() {
136                 return syscall.EINVAL
137         }
138         return c.packetHandler.IPConn.SetDeadline(t)
139 }
140
141 // SetReadDeadline sets the read deadline associated with the
142 // endpoint.
143 func (c *RawConn) SetReadDeadline(t time.Time) error {
144         if !c.packetHandler.ok() {
145                 return syscall.EINVAL
146         }
147         return c.packetHandler.IPConn.SetReadDeadline(t)
148 }
149
150 // SetWriteDeadline sets the write deadline associated with the
151 // endpoint.
152 func (c *RawConn) SetWriteDeadline(t time.Time) error {
153         if !c.packetHandler.ok() {
154                 return syscall.EINVAL
155         }
156         return c.packetHandler.IPConn.SetWriteDeadline(t)
157 }
158
159 // Close closes the endpoint.
160 func (c *RawConn) Close() error {
161         if !c.packetHandler.ok() {
162                 return syscall.EINVAL
163         }
164         return c.packetHandler.IPConn.Close()
165 }
166
167 // NewRawConn returns a new RawConn using c as its underlying
168 // transport.
169 func NewRawConn(c net.PacketConn) (*RawConn, error) {
170         cc, err := socket.NewConn(c.(net.Conn))
171         if err != nil {
172                 return nil, err
173         }
174         r := &RawConn{
175                 genericOpt:    genericOpt{Conn: cc},
176                 dgramOpt:      dgramOpt{Conn: cc},
177                 packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},
178         }
179         so, ok := sockOpts[ssoHeaderPrepend]
180         if !ok {
181                 return nil, errOpNoSupport
182         }
183         if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
184                 return nil, err
185         }
186         return r, nil
187 }