blob: 2ab8773630e5dc02ea9740baf09752e4e5e4e97f [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -07001// 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
5package ipv4
6
7import (
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.
23type Conn struct {
24 genericOpt
25}
26
27type genericOpt struct {
28 *socket.Conn
29}
30
31func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
32
33// NewConn returns a new Conn.
34func 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.
46type PacketConn struct {
47 genericOpt
48 dgramOpt
49 payloadHandler
50}
51
52type dgramOpt struct {
53 *socket.Conn
54}
55
56func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
57
58// SetControlMessage sets the per packet IP-level socket options.
59func (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.
68func (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.
77func (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.
86func (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.
94func (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.
103func 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.
118type RawConn struct {
119 genericOpt
120 dgramOpt
121 packetHandler
122}
123
124// SetControlMessage sets the per packet IP-level socket options.
125func (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.
134func (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.
143func (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.
152func (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.
160func (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.
169func 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}