blob: 4a6d7a85ee67b06819afe8eba9f4df804850a531 [file] [log] [blame]
Dmitri Shuralyov5d997792016-11-07 15:05:57 -08001// Copyright 2012 The Go Authors. All rights reserved.
Mikio Harad2e5a122012-09-26 21:03:09 +09002// 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"
Mikio Harad2e5a122012-09-26 21:03:09 +09009 "time"
Mikio Hara76252772016-08-25 06:13:12 +090010
Mikio Harac4fa6e02017-02-15 06:52:17 +090011 "golang.org/x/net/internal/socket"
Mikio Harad2e5a122012-09-26 21:03:09 +090012)
13
Mikio Hara0cc88842016-12-15 07:16:17 +090014// BUG(mikio): On Windows, the JoinSourceSpecificGroup,
15// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
16// IncludeSourceSpecificGroup methods of PacketConn and RawConn are
17// not implemented.
18
Mikio Harad2e5a122012-09-26 21:03:09 +090019// 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.
22type Conn struct {
23 genericOpt
24}
25
26type genericOpt struct {
Mikio Harac4fa6e02017-02-15 06:52:17 +090027 *socket.Conn
Mikio Harad2e5a122012-09-26 21:03:09 +090028}
29
Mikio Hara9d071032013-06-17 00:37:19 +090030func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
Mikio Harad2e5a122012-09-26 21:03:09 +090031
32// NewConn returns a new Conn.
33func NewConn(c net.Conn) *Conn {
Mikio Harac4fa6e02017-02-15 06:52:17 +090034 cc, _ := socket.NewConn(c)
Mikio Harad2e5a122012-09-26 21:03:09 +090035 return &Conn{
Mikio Harac4fa6e02017-02-15 06:52:17 +090036 genericOpt: genericOpt{Conn: cc},
Mikio Harad2e5a122012-09-26 21:03:09 +090037 }
38}
39
40// A PacketConn represents a packet network endpoint that uses the
Dmitri Shuralyov357296a2016-11-07 15:02:51 -080041// IPv4 transport. It is used to control several IP-level socket
42// options including multicasting. It also provides datagram based
Mikio Harad2e5a122012-09-26 21:03:09 +090043// network I/O methods specific to the IPv4 and higher layer protocols
44// such as UDP.
45type PacketConn struct {
46 genericOpt
47 dgramOpt
48 payloadHandler
49}
50
51type dgramOpt struct {
Mikio Harac4fa6e02017-02-15 06:52:17 +090052 *socket.Conn
Mikio Harad2e5a122012-09-26 21:03:09 +090053}
54
Mikio Harac4fa6e02017-02-15 06:52:17 +090055func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
Mikio Harad2e5a122012-09-26 21:03:09 +090056
57// SetControlMessage sets the per packet IP-level socket options.
58func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
59 if !c.payloadHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +090060 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +090061 }
Mikio Harac4fa6e02017-02-15 06:52:17 +090062 return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
Mikio Harad2e5a122012-09-26 21:03:09 +090063}
64
65// SetDeadline sets the read and write deadlines associated with the
66// endpoint.
67func (c *PacketConn) SetDeadline(t time.Time) error {
68 if !c.payloadHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +090069 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +090070 }
Mikio Hara9d071032013-06-17 00:37:19 +090071 return c.payloadHandler.PacketConn.SetDeadline(t)
Mikio Harad2e5a122012-09-26 21:03:09 +090072}
73
74// SetReadDeadline sets the read deadline associated with the
75// endpoint.
76func (c *PacketConn) SetReadDeadline(t time.Time) error {
77 if !c.payloadHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +090078 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +090079 }
Mikio Hara9d071032013-06-17 00:37:19 +090080 return c.payloadHandler.PacketConn.SetReadDeadline(t)
Mikio Harad2e5a122012-09-26 21:03:09 +090081}
82
83// SetWriteDeadline sets the write deadline associated with the
84// endpoint.
85func (c *PacketConn) SetWriteDeadline(t time.Time) error {
86 if !c.payloadHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +090087 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +090088 }
Mikio Hara9d071032013-06-17 00:37:19 +090089 return c.payloadHandler.PacketConn.SetWriteDeadline(t)
Mikio Harad2e5a122012-09-26 21:03:09 +090090}
91
92// Close closes the endpoint.
93func (c *PacketConn) Close() error {
94 if !c.payloadHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +090095 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +090096 }
Mikio Hara9d071032013-06-17 00:37:19 +090097 return c.payloadHandler.PacketConn.Close()
Mikio Harad2e5a122012-09-26 21:03:09 +090098}
99
100// NewPacketConn returns a new PacketConn using c as its underlying
101// transport.
102func NewPacketConn(c net.PacketConn) *PacketConn {
Mikio Harac4fa6e02017-02-15 06:52:17 +0900103 cc, _ := socket.NewConn(c.(net.Conn))
Mikio Hara5c9495a2014-11-29 10:17:57 +0900104 p := &PacketConn{
Mikio Harac4fa6e02017-02-15 06:52:17 +0900105 genericOpt: genericOpt{Conn: cc},
106 dgramOpt: dgramOpt{Conn: cc},
Mikio Harab7a1f622017-03-18 18:28:25 +0900107 payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
Mikio Hara5c9495a2014-11-29 10:17:57 +0900108 }
109 return p
Mikio Harad2e5a122012-09-26 21:03:09 +0900110}
111
112// A RawConn represents a packet network endpoint that uses the IPv4
Dmitri Shuralyov357296a2016-11-07 15:02:51 -0800113// transport. It is used to control several IP-level socket options
114// including IPv4 header manipulation. It also provides datagram
Mikio Harad2e5a122012-09-26 21:03:09 +0900115// based network I/O methods specific to the IPv4 and higher layer
116// protocols that handle IPv4 datagram directly such as OSPF, GRE.
117type RawConn struct {
118 genericOpt
119 dgramOpt
120 packetHandler
121}
122
123// SetControlMessage sets the per packet IP-level socket options.
124func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
125 if !c.packetHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900126 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +0900127 }
Mikio Harac4fa6e02017-02-15 06:52:17 +0900128 return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
Mikio Harad2e5a122012-09-26 21:03:09 +0900129}
130
131// SetDeadline sets the read and write deadlines associated with the
132// endpoint.
133func (c *RawConn) SetDeadline(t time.Time) error {
134 if !c.packetHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900135 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +0900136 }
Mikio Harab7a1f622017-03-18 18:28:25 +0900137 return c.packetHandler.IPConn.SetDeadline(t)
Mikio Harad2e5a122012-09-26 21:03:09 +0900138}
139
140// SetReadDeadline sets the read deadline associated with the
141// endpoint.
142func (c *RawConn) SetReadDeadline(t time.Time) error {
143 if !c.packetHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900144 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +0900145 }
Mikio Harab7a1f622017-03-18 18:28:25 +0900146 return c.packetHandler.IPConn.SetReadDeadline(t)
Mikio Harad2e5a122012-09-26 21:03:09 +0900147}
148
149// SetWriteDeadline sets the write deadline associated with the
150// endpoint.
151func (c *RawConn) SetWriteDeadline(t time.Time) error {
152 if !c.packetHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900153 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +0900154 }
Mikio Harab7a1f622017-03-18 18:28:25 +0900155 return c.packetHandler.IPConn.SetWriteDeadline(t)
Mikio Harad2e5a122012-09-26 21:03:09 +0900156}
157
158// Close closes the endpoint.
159func (c *RawConn) Close() error {
160 if !c.packetHandler.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900161 return errInvalidConn
Mikio Harad2e5a122012-09-26 21:03:09 +0900162 }
Mikio Harab7a1f622017-03-18 18:28:25 +0900163 return c.packetHandler.IPConn.Close()
Mikio Harad2e5a122012-09-26 21:03:09 +0900164}
165
Mikio Haracb3df7e2013-05-30 20:22:16 +0900166// NewRawConn returns a new RawConn using c as its underlying
Mikio Harad2e5a122012-09-26 21:03:09 +0900167// transport.
168func NewRawConn(c net.PacketConn) (*RawConn, error) {
Mikio Harac4fa6e02017-02-15 06:52:17 +0900169 cc, err := socket.NewConn(c.(net.Conn))
Mikio Harad2e5a122012-09-26 21:03:09 +0900170 if err != nil {
171 return nil, err
172 }
Mikio Harac4fa6e02017-02-15 06:52:17 +0900173 r := &RawConn{
174 genericOpt: genericOpt{Conn: cc},
175 dgramOpt: dgramOpt{Conn: cc},
Mikio Harab7a1f622017-03-18 18:28:25 +0900176 packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},
Mikio Harac4fa6e02017-02-15 06:52:17 +0900177 }
178 so, ok := sockOpts[ssoHeaderPrepend]
179 if !ok {
Mikio Hara511f7942019-03-13 15:30:34 +0900180 return nil, errNotImplemented
Mikio Harac4fa6e02017-02-15 06:52:17 +0900181 }
182 if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
Mikio Harad2e5a122012-09-26 21:03:09 +0900183 return nil, err
184 }
185 return r, nil
186}