blob: 4f5fe683d5deef8f14297f14fbd8f6a2ed4d51a3 [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -07001// 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 ipv6
8
9import (
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// A Message represents an IO message.
21//
22// type Message struct {
23// Buffers [][]byte
24// OOB []byte
25// Addr net.Addr
26// N int
27// NN int
28// Flags int
29// }
30//
31// The Buffers fields represents a list of contiguous buffers, which
32// can be used for vectored IO, for example, putting a header and a
33// payload in each slice.
34// When writing, the Buffers field must contain at least one byte to
35// write.
36// When reading, the Buffers field will always contain a byte to read.
37//
38// The OOB field contains protocol-specific control or miscellaneous
39// ancillary data known as out-of-band data.
40// It can be nil when not required.
41//
42// The Addr field specifies a destination address when writing.
43// It can be nil when the underlying protocol of the endpoint uses
44// connection-oriented communication.
45// After a successful read, it may contain the source address on the
46// received packet.
47//
48// The N field indicates the number of bytes read or written from/to
49// Buffers.
50//
51// The NN field indicates the number of bytes read or written from/to
52// OOB.
53//
54// The Flags field contains protocol-specific information on the
55// received message.
56type Message = socket.Message
57
58// ReadBatch reads a batch of messages.
59//
60// The provided flags is a set of platform-dependent flags, such as
61// syscall.MSG_PEEK.
62//
63// On a successful read it returns the number of messages received, up
64// to len(ms).
65//
66// On Linux, a batch read will be optimized.
67// On other platforms, this method will read only a single message.
68func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
69 if !c.ok() {
70 return 0, syscall.EINVAL
71 }
72 switch runtime.GOOS {
73 case "linux":
74 n, err := c.RecvMsgs([]socket.Message(ms), flags)
75 if err != nil {
76 err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
77 }
78 return n, err
79 default:
80 n := 1
81 err := c.RecvMsg(&ms[0], flags)
82 if err != nil {
83 n = 0
84 err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
85 }
86 return n, err
87 }
88}
89
90// WriteBatch writes a batch of messages.
91//
92// The provided flags is a set of platform-dependent flags, such as
93// syscall.MSG_DONTROUTE.
94//
95// It returns the number of messages written on a successful write.
96//
97// On Linux, a batch write will be optimized.
98// On other platforms, this method will write only a single message.
99func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
100 if !c.ok() {
101 return 0, syscall.EINVAL
102 }
103 switch runtime.GOOS {
104 case "linux":
105 n, err := c.SendMsgs([]socket.Message(ms), flags)
106 if err != nil {
107 err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
108 }
109 return n, err
110 default:
111 n := 1
112 err := c.SendMsg(&ms[0], flags)
113 if err != nil {
114 n = 0
115 err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
116 }
117 return n, err
118 }
119}