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