// Extracts a usable sized symmetric key and IV for the stream cipher from the huge master key, and // creates a CTR stream cipher. func (s *Session) makeCipher() (cipher.Stream, error) { // Create the key derivation function hasher := func() hash.Hash { return s.hash.New() } hkdf := hkdf.New(hasher, s.secret.Bytes(), hkdfSalt, hkdfInfo) // Extract the symmetric key key := make([]byte, s.keybits/8) n, err := io.ReadFull(hkdf, key) if n != len(key) || err != nil { return nil, err } // Create the block cipher block, err := s.crypter(key) if err != nil { return nil, err } // Extract the IV for the counter mode iv := make([]byte, block.BlockSize()) n, err = io.ReadFull(hkdf, iv) if n != len(iv) || err != nil { return nil, err } // Create the stream cipher return cipher.NewCTR(block, iv), nil }
// ServeAgent serves the agent protocol on the given connection. It // returns when an I/O error occurs. func ServeAgent(agent Agent, c io.ReadWriter) error { s := &server{agent} var length [4]byte for { if _, err := io.ReadFull(c, length[:]); err != nil { return err } l := binary.BigEndian.Uint32(length[:]) if l > maxAgentResponseBytes { // We also cap requests. return fmt.Errorf("agent: request too large: %d", l) } req := make([]byte, l) if _, err := io.ReadFull(c, req); err != nil { return err } repData := s.processRequestBytes(req) if len(repData) > maxAgentResponseBytes { return fmt.Errorf("agent: reply too large: %d bytes", len(repData)) } binary.BigEndian.PutUint32(length[:], uint32(len(repData))) if _, err := c.Write(length[:]); err != nil { return err } if _, err := c.Write(repData); err != nil { return err } } }
func (s *Server) Handle(serial int, RpcAddr string) { conn := s.conns[serial] head := make([]byte, 2) defer s.Close(serial) for { _, err := io.ReadFull(conn, head) if err != nil { fmt.Println(err) break } var info_len uint16 buf := bytes.NewReader(head) if err := binary.Read(buf, binary.BigEndian, &info_len); err != nil { fmt.Println("binary.Read failed:", err) break } body := make([]byte, info_len) body_len, err := io.ReadFull(conn, body) if err != nil { fmt.Println(err) break } reply := CallRpc(RpcAddr, "Arith.Multiply", int(info_len), int(body_len)) fmt.Printf("reply:%d\n", reply) fmt.Println("len", info_len, body_len, string(body)) s.WriteTo(serial, body) } }
// recvMessage receives any message from the backend, or returns an error if // a problem occurred while reading the message. func (cn *conn) recvMessage() (byte, *readBuf, error) { // workaround for a QueryRow bug, see exec if cn.saveMessageType != 0 { t, r := cn.saveMessageType, cn.saveMessageBuffer cn.saveMessageType = 0 cn.saveMessageBuffer = nil return t, r, nil } x := cn.scratch[:5] _, err := io.ReadFull(cn.buf, x) if err != nil { return 0, nil, err } t := x[0] b := readBuf(x[1:]) n := b.int32() - 4 var y []byte if n <= len(cn.scratch) { y = cn.scratch[:n] } else { y = make([]byte, n) } _, err = io.ReadFull(cn.buf, y) if err != nil { return 0, nil, err } return t, (*readBuf)(&y), nil }
func TestPartialRead(t *testing.T) { f, err := os.Open("testdata/gnu.tar") if err != nil { t.Fatalf("Unexpected error: %v", err) } defer f.Close() tr := NewReader(f) // Read the first four bytes; Next() should skip the last byte. hdr, err := tr.Next() if err != nil || hdr == nil { t.Fatalf("Didn't get first file: %v", err) } buf := make([]byte, 4) if _, err := io.ReadFull(tr, buf); err != nil { t.Fatalf("Unexpected error: %v", err) } if expected := []byte("Kilt"); !bytes.Equal(buf, expected) { t.Errorf("Contents = %v, want %v", buf, expected) } // Second file hdr, err = tr.Next() if err != nil || hdr == nil { t.Fatalf("Didn't get second file: %v", err) } buf = make([]byte, 6) if _, err := io.ReadFull(tr, buf); err != nil { t.Fatalf("Unexpected error: %v", err) } if expected := []byte("Google"); !bytes.Equal(buf, expected) { t.Errorf("Contents = %v, want %v", buf, expected) } }
func (self *Session) reader() { log.Printf("session[%d] start reader...", self.id) defer func() { log.Println("reader quit...") self.ctrl <- true if self.autoReconnect { self.reconnect <- true } else { self.events <- newEvent(EVENT_DISCONNECT, self, nil) } }() header := make([]byte, 2) for { if _, err := io.ReadFull(self.conn, header); err != nil { break } size := binary.BigEndian.Uint16(header) log.Printf("size=%d", size) data := make([]byte, size) if _, err := io.ReadFull(self.conn, data); err != nil { self.events <- newEvent(EVENT_RECV_ERROR, self, err) break } log.Printf("len(data)=%d", len(data)) log.Printf("payload: %v", data) api, payload, err := self.proto.Decode(data) log.Printf("api=%v, payload=%v, err=%v", api, payload, err) if err != nil { self.events <- newEvent(EVENT_RECV_ERROR, self, err) break } msg := NewMessage(api, payload) self.events <- newEvent(EVENT_MESSAGE, self, msg) } }
func readN(r io.Reader, b []byte, n int) ([]byte, error) { if n == 0 && b == nil { return make([]byte, 0), nil } if cap(b) >= n { b = b[:n] _, err := io.ReadFull(r, b) return b, err } b = b[:cap(b)] pos := 0 for len(b) < n { diff := n - len(b) if diff > bytesAllocLimit { diff = bytesAllocLimit } b = append(b, make([]byte, diff)...) _, err := io.ReadFull(r, b[pos:]) if err != nil { return nil, err } pos = len(b) } return b, nil }
// readDirectoryHeader attempts to read a directory header from r. // It returns io.ErrUnexpectedEOF if it cannot read a complete header, // and ErrFormat if it doesn't find a valid header signature. func readDirectoryHeader(f *File, r io.Reader) error { var buf [directoryHeaderLen]byte if _, err := io.ReadFull(r, buf[:]); err != nil { return err } b := readBuf(buf[:]) if sig := b.uint32(); sig != directoryHeaderSignature { return ErrFormat } f.CreatorVersion = b.uint16() f.ReaderVersion = b.uint16() f.Flags = b.uint16() f.Method = b.uint16() f.ModifiedTime = b.uint16() f.ModifiedDate = b.uint16() f.CRC32 = b.uint32() f.CompressedSize = b.uint32() f.UncompressedSize = b.uint32() filenameLen := int(b.uint16()) extraLen := int(b.uint16()) commentLen := int(b.uint16()) b = b[4:] // skipped start disk number and internal attributes (2x uint16) f.ExternalAttrs = b.uint32() f.headerOffset = int64(b.uint32()) d := make([]byte, filenameLen+extraLen+commentLen) if _, err := io.ReadFull(r, d); err != nil { return err } f.Name = string(d[:filenameLen]) f.Extra = d[filenameLen : filenameLen+extraLen] f.Comment = string(d[filenameLen+extraLen:]) return nil }
func TestLargeMessage(t *testing.T) { server, ct := setUp(t, 0, math.MaxUint32, normal) callHdr := &CallHdr{ Host: "localhost", Method: "foo.Large", } var wg sync.WaitGroup for i := 0; i < 2; i++ { wg.Add(1) go func() { defer wg.Done() s, err := ct.NewStream(context.Background(), callHdr) if err != nil { t.Errorf("failed to open stream: %v", err) } if err := ct.Write(s, expectedRequestLarge, &Options{Last: true, Delay: false}); err != nil { t.Errorf("failed to send data: %v", err) } p := make([]byte, len(expectedResponseLarge)) _, recvErr := io.ReadFull(s, p) if recvErr != nil || !bytes.Equal(p, expectedResponseLarge) { t.Errorf("Error: %v, want <nil>; Result len: %d, want len %d", recvErr, len(p), len(expectedResponseLarge)) } _, recvErr = io.ReadFull(s, p) if recvErr != io.EOF { t.Errorf("Error: %v; want <EOF>", recvErr) } }() } wg.Wait() ct.Close() server.stop() }
func DecryptIO(reader io.Reader, writer io.Writer, passphrase string) (mac []byte, e error) { key := PassphraseToKey(passphrase) hashMac := hmac.New(sha256.New, key) block, err := aes.NewCipher(key) if err != nil { return nil, err } iv := make([]byte, aes.BlockSize) if _, err = io.ReadFull(reader, iv); err != nil { return nil, err } stream := cipher.NewOFB(block, iv) cipherReader := &cipher.StreamReader{S: stream, R: reader} pp := make([]byte, len([]byte(passphrase))) if _, err = io.ReadFull(cipherReader, pp); err != nil { return nil, err } if passphrase != string(pp) { return nil, errors.New("Incorrect passphrase") } mw := io.MultiWriter(writer, hashMac) if _, err = io.Copy(mw, cipherReader); err != nil { return nil, err } return hashMac.Sum(nil), nil }
// The initial response from the datanode: // +-----------------------------------------------------------+ // | varint length + BlockOpResponseProto | // +-----------------------------------------------------------+ func (br *BlockReader) readBlockReadResponse(r io.Reader) (*hdfs.BlockOpResponseProto, error) { varintBytes := make([]byte, binary.MaxVarintLen32) _, err := io.ReadFull(r, varintBytes) if err != nil { return nil, err } respLength, varintLength := binary.Uvarint(varintBytes) if varintLength < 1 { return nil, io.ErrUnexpectedEOF } // We may have grabbed too many bytes when reading the varint. respBytes := make([]byte, respLength) extraLength := copy(respBytes, varintBytes[varintLength:]) _, err = io.ReadFull(r, respBytes[extraLength:]) if err != nil { return nil, err } resp := &hdfs.BlockOpResponseProto{} err = proto.Unmarshal(respBytes, resp) if err != nil { return nil, err } return resp, nil }
// FromReader extracts data from a serialized DeleteOp into its concrete // structure. func (op *DeleteOp) FromReader(r io.Reader) error { var b [4]byte _, err := io.ReadFull(r, b[:]) //skip ZERO if err != nil { return err } name, err := readCStringFromReader(r) if err != nil { return err } op.Collection = string(name) _, err = io.ReadFull(r, b[:]) //Grab the flags if err != nil { return err } op.Flags = uint32(getInt32(b[:], 0)) selectorAsSlice, err := ReadDocument(r) if err != nil { return err } op.Selector = &bson.D{} err = bson.Unmarshal(selectorAsSlice, op.Selector) if err != nil { return err } return nil }
// Unmarshal parses an identity. func Unmarshal(in []byte) (*Identity, error) { buf := sbuf.NewBufferFrom(in) id := &Identity{ private: new([ed25519.PrivateKeySize]byte), public: new([ed25519.PublicKeySize]byte), } _, err := io.ReadFull(buf, id.private[:]) if err != nil { return nil, ErrInvalidIdentity } _, err = io.ReadFull(buf, id.public[:]) if err != nil { return nil, ErrInvalidIdentity } if (buf.Len() % ed25519.PublicKeySize) != 0 { return nil, ErrInvalidIdentity } for { if buf.Len() == 0 { break } peer := new([ed25519.PublicKeySize]byte) io.ReadFull(buf, peer[:]) id.peers = append(id.peers, peer) } return id, nil }
// NewReaderDict is like NewReader but uses a preset dictionary. // NewReaderDict ignores the dictionary if the compressed data does not refer to it. func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, os.Error) { z := new(reader) if fr, ok := r.(flate.Reader); ok { z.r = fr } else { z.r = bufio.NewReader(r) } _, err := io.ReadFull(z.r, z.scratch[0:2]) if err != nil { return nil, err } h := uint(z.scratch[0])<<8 | uint(z.scratch[1]) if (z.scratch[0]&0x0f != zlibDeflate) || (h%31 != 0) { return nil, HeaderError } if z.scratch[1]&0x20 != 0 { _, err = io.ReadFull(z.r, z.scratch[0:4]) if err != nil { return nil, err } checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3]) if checksum != adler32.Checksum(dict) { return nil, DictionaryError } z.decompressor = flate.NewReaderDict(z.r, dict) } else { z.decompressor = flate.NewReader(z.r) } z.digest = adler32.New() return z, nil }
func performOneRPC(ct ClientTransport) { callHdr := &CallHdr{ Host: "localhost", Method: "foo.Small", } s, err := ct.NewStream(context.Background(), callHdr) if err != nil { return } opts := Options{ Last: true, Delay: false, } if err := ct.Write(s, expectedRequest, &opts); err == nil || err == io.EOF { time.Sleep(5 * time.Millisecond) // The following s.Recv()'s could error out because the // underlying transport is gone. // // Read response p := make([]byte, len(expectedResponse)) io.ReadFull(s, p) // Read io.EOF io.ReadFull(s, p) } }
func (c *Connection) readResponse() (*Response, error) { // Read response header (token+length) _, err := io.ReadFull(c.conn, c.headerBuf[:respHeaderLen]) if err != nil { return nil, err } responseToken := int64(binary.LittleEndian.Uint64(c.headerBuf[:8])) messageLength := binary.LittleEndian.Uint32(c.headerBuf[8:]) // Read the JSON encoding of the Response itself. b := c.buf.takeBuffer(int(messageLength)) if _, err := io.ReadFull(c.conn, b[:]); err != nil { c.bad = true return nil, RqlConnectionError{err.Error()} } // Decode the response var response = newCachedResponse() if err := json.Unmarshal(b, response); err != nil { c.bad = true return nil, RqlDriverError{err.Error()} } response.Token = responseToken return response, nil }
func TestLargeMessage(t *testing.T) { server, ct := setUp(t, 0, math.MaxUint32, normal) callHdr := &CallHdr{ Host: "localhost", Method: "foo.Large", } var wg sync.WaitGroup for i := 0; i < 2; i++ { wg.Add(1) go func() { defer wg.Done() s, err := ct.NewStream(context.Background(), callHdr) if err != nil { t.Errorf("%v.NewStream(_, _) = _, %v, want _, <nil>", ct, err) } if err := ct.Write(s, expectedRequestLarge, &Options{Last: true, Delay: false}); err != nil && err != io.EOF { t.Errorf("%v.Write(_, _, _) = %v, want <nil>", ct, err) } p := make([]byte, len(expectedResponseLarge)) if _, err := io.ReadFull(s, p); err != nil || !bytes.Equal(p, expectedResponseLarge) { t.Errorf("io.ReadFull(_, %v) = _, %v, want %v, <nil>", err, p, expectedResponse) } if _, err = io.ReadFull(s, p); err != io.EOF { t.Errorf("Failed to complete the stream %v; want <EOF>", err) } }() } wg.Wait() ct.Close() server.stop() }
// decodeUintReader reads an encoded unsigned integer from an io.Reader. // Used only by the Decoder to read the message length. func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) { width = 1 n, err := io.ReadFull(r, buf[0:width]) if n == 0 { return } b := buf[0] if b <= 0x7f { return uint64(b), width, nil } n = -int(int8(b)) if n > uint64Size { err = errBadUint return } width, err = io.ReadFull(r, buf[0:n]) if err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF } return } // Could check that the high byte is zero but it's not worth it. for _, b := range buf[0:width] { x = x<<8 | uint64(b) } width++ // +1 for length byte return }
func TestHostnameInSNI(t *testing.T) { for _, tt := range hostnameInSNITests { c, s := net.Pipe() go func(host string) { Client(c, &Config{ServerName: host, InsecureSkipVerify: true}).Handshake() }(tt.in) var header [5]byte if _, err := io.ReadFull(s, header[:]); err != nil { t.Fatal(err) } recordLen := int(header[3])<<8 | int(header[4]) record := make([]byte, recordLen) if _, err := io.ReadFull(s, record[:]); err != nil { t.Fatal(err) } c.Close() s.Close() var m clientHelloMsg if !m.unmarshal(record) { t.Errorf("unmarshaling ClientHello for %q failed", tt.in) continue } if tt.in != tt.out && m.serverName == tt.in { t.Errorf("prohibited %q found in ClientHello: %x", tt.in, record) } if m.serverName != tt.out { t.Errorf("expected %q not found in ClientHello: %x", tt.out, record) } } }
func getUser(conn net.Conn) (user User, err error) { const ( idVersion = 0 // \x01 version = 1 idUser = 1 // \x02 ) buf := make([]byte, 2) if _, err = io.ReadFull(conn, buf); err != nil { return } switch buf[idVersion] { case version: break default: err = errors.New(fmt.Sprintf("version %s not supported", buf[idVersion])) return } userLen := buf[idUser] username := make([]byte, userLen) if _, err = io.ReadFull(conn, username); err != nil { return } user, err = storage.Get("user:" + string(username)) return }
// ReadTLV reads a type-length-value record from r. func ReadTLV(r io.Reader) (byte, []byte, error) { var typ [1]byte if _, err := io.ReadFull(r, typ[:]); err != nil { return 0, nil, fmt.Errorf("read message type: %s", err) } // Read the size of the message. var sz int64 if err := binary.Read(r, binary.BigEndian, &sz); err != nil { return 0, nil, fmt.Errorf("read message size: %s", err) } if sz == 0 { return 0, nil, fmt.Errorf("invalid message size: %d", sz) } if sz >= MaxMessageSize { return 0, nil, fmt.Errorf("max message size of %d exceeded: %d", MaxMessageSize, sz) } // Read the value. buf := make([]byte, sz) if _, err := io.ReadFull(r, buf); err != nil { return 0, nil, fmt.Errorf("read message value: %s", err) } return typ[0], buf, nil }
// readTxOut reads the next sequence of bytes from r as a transaction output // (TxOut). func readTxOut(r io.Reader, pver uint32, version uint32, to *TxOut) error { buf := make([]byte, 8) _, err := io.ReadFull(r, buf) if err != nil { return err } to.Value = int64(binary.LittleEndian.Uint64(buf)) count, err := readVarInt(r, pver) if err != nil { return err } // Prevent public key script larger than the max message size. It would // be possible to cause memory exhaustion and panics without a sane // upper bound on this count. if count > uint64(maxMessagePayload) { str := fmt.Sprintf("transaction output public key script is "+ "larger than max message size [count %d, max %d]", count, maxMessagePayload) return messageError("MsgTx.BtcDecode", str) } b := make([]byte, count) _, err = io.ReadFull(r, b) if err != nil { return err } to.PkScript = b return nil }
func (this *ChunkReader) Read() (*alloc.Buffer, error) { buffer := alloc.NewLargeBuffer() if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil { buffer.Release() return nil, err } // There is a potential buffer overflow here. Large buffer is 64K bytes, // while uin16 + 10 will be more than that length := serial.BytesToUint16(buffer.Value[:2]) + AuthSize if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil { buffer.Release() return nil, err } buffer.Slice(0, int(length)) authBytes := buffer.Value[:AuthSize] payload := buffer.Value[AuthSize:] actualAuthBytes := this.auth.Authenticate(nil, payload) if !bytes.Equal(authBytes, actualAuthBytes) { buffer.Release() log.Debug("AuthenticationReader: Unexpected auth: ", authBytes) return nil, transport.ErrorCorruptedPacket } buffer.Value = payload return buffer, nil }
func read(r io.Reader) (response []byte, err error) { var lenbuf [PacketLengthBytes]byte var length int if _, err = io.ReadFull(r, lenbuf[:]); err != nil { return } if lenbuf[0] != 0xce { err = errors.New("Wrong reponse header") return } length = (int(lenbuf[1]) << 24) + (int(lenbuf[2]) << 16) + (int(lenbuf[3]) << 8) + int(lenbuf[4]) if length == 0 { err = errors.New("Response should not be 0 length") return } response = make([]byte, length) _, err = io.ReadFull(r, response) return }
// recvMessage receives any message from the backend, or returns an error if // a problem occurred while reading the message. func (cn *conn) recvMessage(r *readBuf) (byte, error) { // workaround for a QueryRow bug, see exec if cn.saveMessageType != 0 { t := cn.saveMessageType *r = cn.saveMessageBuffer cn.saveMessageType = 0 cn.saveMessageBuffer = nil return t, nil } x := cn.scratch[:5] _, err := io.ReadFull(cn.buf, x) if err != nil { return 0, err } // read the type and length of the message that follows t := x[0] n := int(binary.BigEndian.Uint32(x[1:])) - 4 var y []byte if n <= len(cn.scratch) { y = cn.scratch[:n] } else { y = make([]byte, n) } _, err = io.ReadFull(cn.buf, y) if err != nil { return 0, err } *r = y return t, nil }
//----------------------------------------------- handle logical server func handleClient(conn net.Conn) { defer conn.Close() header := make([]byte, 2) ch := make(chan []byte, 8192) go protos.HubAgent(ch, conn) for { // header n, err := io.ReadFull(conn, header) if n == 0 && err == io.EOF { break } else if err != nil { log.Println("error receving header:", err) break } // data size := int(header[0])<<8 | int(header[1]) data := make([]byte, size) n, err = io.ReadFull(conn, data) if err != nil { log.Println("error receving msg:", err) break } ch <- data } close(ch) }
func init() { if interfaces, err := net.Interfaces(); err == nil { for _, i := range interfaces { if i.Flags&net.FlagLoopback == 0 && len(i.HardwareAddr) > 0 { hardwareAddr = i.HardwareAddr break } } } if hardwareAddr == nil { // If we failed to obtain the MAC address of the current computer, // we will use a randomly generated 6 byte sequence instead and set // the multicast bit as recommended in RFC 4122. hardwareAddr = make([]byte, 6) _, err := io.ReadFull(rand.Reader, hardwareAddr) if err != nil { panic(err) } hardwareAddr[0] = hardwareAddr[0] | 0x01 } // initialize the clock sequence with a random number var clockSeqRand [2]byte io.ReadFull(rand.Reader, clockSeqRand[:]) clockSeq = uint32(clockSeqRand[1])<<8 | uint32(clockSeqRand[0]) }
// Scans a file for checksum errors and returns all the corrupt ranges and // errors encountered. func groupChecksumVerify(fpr io.Reader) ([]*groupCorruptRange, []error) { header, checksumInterval, err := readGroupHeader(fpr) if err != nil { return []*groupCorruptRange{&groupCorruptRange{0, math.MaxUint32}}, []error{err} } buf := make([]byte, checksumInterval+4) copy(buf, header) if _, err := io.ReadFull(fpr, buf[len(header):]); err != nil { return []*groupCorruptRange{&groupCorruptRange{0, math.MaxUint32}}, []error{err} } start := uint32(0) stop := checksumInterval - 1 var corruptions []*groupCorruptRange var errs []error for { if murmur3.Sum32(buf[:checksumInterval]) != binary.BigEndian.Uint32(buf[checksumInterval:]) { corruptions = append(corruptions, &groupCorruptRange{start, stop}) } start = stop + 1 stop = stop + checksumInterval if _, err := io.ReadFull(fpr, buf); err != nil { corruptions = append(corruptions, &groupCorruptRange{start, math.MaxUint32}) errs = append(errs, err) break } } return corruptions, errs }
// call sends an RPC to the agent. On success, the reply is // unmarshaled into reply and replyType is set to the first byte of // the reply, which contains the type of the message. func (c *client) call(req []byte) (reply interface{}, err error) { c.mu.Lock() defer c.mu.Unlock() msg := make([]byte, 4+len(req)) binary.BigEndian.PutUint32(msg, uint32(len(req))) copy(msg[4:], req) if _, err = c.conn.Write(msg); err != nil { return nil, clientErr(err) } var respSizeBuf [4]byte if _, err = io.ReadFull(c.conn, respSizeBuf[:]); err != nil { return nil, clientErr(err) } respSize := binary.BigEndian.Uint32(respSizeBuf[:]) if respSize > maxAgentResponseBytes { return nil, clientErr(err) } buf := make([]byte, respSize) if _, err = io.ReadFull(c.conn, buf); err != nil { return nil, clientErr(err) } reply, err = unmarshal(buf) if err != nil { return nil, clientErr(err) } return reply, err }
// read response from the network connection. func (s *Session) read() ([]byte, error) { if !s.Available() { return nil, ErrCannotRead } buf := make([]byte, 4) var size int32 // first 4 bytes are always size of message if count, err := io.ReadFull(s.conn, buf); err == nil && count == 4 { sbuf := bytes.NewBuffer(buf) binary.Read(sbuf, binary.BigEndian, &size) data := make([]byte, size) // read rest of message and return it if no errors count, err := io.ReadFull(s.conn, data) if err != nil { if err == syscall.EPIPE { s.conn.Close() } s.active = false return nil, err } if count != int(size) { s.active = false return nil, errors.New(fmt.Sprintf("data length: %d, only read: %d", len(data), count)) } return data, nil } return nil, nil }