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