blob: 5ce9b3583cc26f960b632aa541bcc2fe9495d3e2 [file] [log] [blame]
Mikio Harab7a1f622017-03-18 18:28:25 +09001// Copyright 2017 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 go1.9
6
7package ipv4
8
9import (
10 "net"
11 "runtime"
Mikio Harab7a1f622017-03-18 18:28:25 +090012
13 "golang.org/x/net/internal/socket"
14)
15
16// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
17// PacketConn are not implemented.
18
19// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
20// RawConn are not implemented.
21
22// A Message represents an IO message.
23//
24// type Message struct {
25// Buffers [][]byte
26// OOB []byte
27// Addr net.Addr
28// N int
29// NN int
30// Flags int
31// }
32//
33// The Buffers fields represents a list of contiguous buffers, which
34// can be used for vectored IO, for example, putting a header and a
35// payload in each slice.
36// When writing, the Buffers field must contain at least one byte to
37// write.
38// When reading, the Buffers field will always contain a byte to read.
39//
40// The OOB field contains protocol-specific control or miscellaneous
41// ancillary data known as out-of-band data.
42// It can be nil when not required.
43//
44// The Addr field specifies a destination address when writing.
45// It can be nil when the underlying protocol of the endpoint uses
46// connection-oriented communication.
47// After a successful read, it may contain the source address on the
48// received packet.
49//
50// The N field indicates the number of bytes read or written from/to
51// Buffers.
52//
53// The NN field indicates the number of bytes read or written from/to
54// OOB.
55//
56// The Flags field contains protocol-specific information on the
57// received message.
58type Message = socket.Message
59
60// ReadBatch reads a batch of messages.
61//
62// The provided flags is a set of platform-dependent flags, such as
63// syscall.MSG_PEEK.
64//
65// On a successful read it returns the number of messages received, up
66// to len(ms).
67//
Mikio Haraf073e082017-12-08 07:16:59 +090068// On Linux, a batch read will be optimized.
Mikio Harab7a1f622017-03-18 18:28:25 +090069// On other platforms, this method will read only a single message.
70//
71// Unlike the ReadFrom method, it doesn't strip the IPv4 header
72// followed by option headers from the received IPv4 datagram when the
73// underlying transport is net.IPConn. Each Buffers field of Message
74// must be large enough to accommodate an IPv4 header and option
75// headers.
76func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
77 if !c.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +090078 return 0, errInvalidConn
Mikio Harab7a1f622017-03-18 18:28:25 +090079 }
80 switch runtime.GOOS {
Mikio Haraf073e082017-12-08 07:16:59 +090081 case "linux":
Mikio Harab7a1f622017-03-18 18:28:25 +090082 n, err := c.RecvMsgs([]socket.Message(ms), flags)
83 if err != nil {
84 err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
85 }
86 return n, err
87 default:
88 n := 1
89 err := c.RecvMsg(&ms[0], flags)
90 if err != nil {
91 n = 0
92 err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
93 }
94 return n, err
95 }
96}
97
98// WriteBatch writes a batch of messages.
99//
100// The provided flags is a set of platform-dependent flags, such as
101// syscall.MSG_DONTROUTE.
102//
103// It returns the number of messages written on a successful write.
104//
Mikio Haraf073e082017-12-08 07:16:59 +0900105// On Linux, a batch write will be optimized.
Mikio Harab7a1f622017-03-18 18:28:25 +0900106// On other platforms, this method will write only a single message.
107func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
108 if !c.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900109 return 0, errInvalidConn
Mikio Harab7a1f622017-03-18 18:28:25 +0900110 }
111 switch runtime.GOOS {
Mikio Haraf073e082017-12-08 07:16:59 +0900112 case "linux":
Mikio Harab7a1f622017-03-18 18:28:25 +0900113 n, err := c.SendMsgs([]socket.Message(ms), flags)
114 if err != nil {
115 err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
116 }
117 return n, err
118 default:
119 n := 1
120 err := c.SendMsg(&ms[0], flags)
121 if err != nil {
122 n = 0
123 err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
124 }
125 return n, err
126 }
127}
128
129// ReadBatch reads a batch of messages.
130//
131// The provided flags is a set of platform-dependent flags, such as
132// syscall.MSG_PEEK.
133//
134// On a successful read it returns the number of messages received, up
135// to len(ms).
136//
Mikio Haraf073e082017-12-08 07:16:59 +0900137// On Linux, a batch read will be optimized.
Mikio Harab7a1f622017-03-18 18:28:25 +0900138// On other platforms, this method will read only a single message.
139func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
140 if !c.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900141 return 0, errInvalidConn
Mikio Harab7a1f622017-03-18 18:28:25 +0900142 }
143 switch runtime.GOOS {
Mikio Haraf073e082017-12-08 07:16:59 +0900144 case "linux":
Mikio Harab7a1f622017-03-18 18:28:25 +0900145 n, err := c.RecvMsgs([]socket.Message(ms), flags)
146 if err != nil {
147 err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
148 }
149 return n, err
150 default:
151 n := 1
152 err := c.RecvMsg(&ms[0], flags)
153 if err != nil {
154 n = 0
155 err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
156 }
157 return n, err
158 }
159}
160
161// WriteBatch writes a batch of messages.
162//
163// The provided flags is a set of platform-dependent flags, such as
164// syscall.MSG_DONTROUTE.
165//
166// It returns the number of messages written on a successful write.
167//
Mikio Haraf073e082017-12-08 07:16:59 +0900168// On Linux, a batch write will be optimized.
Mikio Harab7a1f622017-03-18 18:28:25 +0900169// On other platforms, this method will write only a single message.
170func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) {
171 if !c.ok() {
Mikio Harac0ac1a52018-07-02 02:08:19 +0900172 return 0, errInvalidConn
Mikio Harab7a1f622017-03-18 18:28:25 +0900173 }
174 switch runtime.GOOS {
Mikio Haraf073e082017-12-08 07:16:59 +0900175 case "linux":
Mikio Harab7a1f622017-03-18 18:28:25 +0900176 n, err := c.SendMsgs([]socket.Message(ms), flags)
177 if err != nil {
178 err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
179 }
180 return n, err
181 default:
182 n := 1
183 err := c.SendMsg(&ms[0], flags)
184 if err != nil {
185 n = 0
186 err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
187 }
188 return n, err
189 }
190}