OSDN Git Service

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