func (r *lz4Reader) moreBits() error { var hdr [8]byte _, err := io.ReadFull(r.rd, hdr[:]) if binary.BigEndian.Uint32(hdr[0:]) != lz4Magic { return errors.New("bad magic") } ln := int(binary.BigEndian.Uint32(hdr[4:])) if len(r.buf) < ln { r.buf = make([]byte, int(ln)) } else { r.buf = r.buf[:ln] } _, err = io.ReadFull(r.rd, r.buf) if err != nil { return err } r.ebuf, err = lz4.Decode(r.ebuf[:cap(r.ebuf)], r.buf) if err != nil { return err } if debug { l.Debugf("lz4 moreBits: %d / %d bytes", ln+8, len(r.ebuf)) } _, err = r.obuf.Write(r.ebuf) return err }
func (c *rawConnection) lz4Decompress(src []byte) ([]byte, error) { size := binary.BigEndian.Uint32(src) binary.LittleEndian.PutUint32(src, size) var err error buf := buffers.get(int(size)) buf, err = lz4.Decode(buf, src) if err != nil { return nil, err } return buf, nil }
func main() { var optCPUProfile = flag.String("cpuprofile", "", "profile") flag.Parse() if *optCPUProfile != "" { f, err := os.Create(*optCPUProfile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } args := flag.Args() var data []byte if len(args) < 2 { fmt.Print("Usage: lz4 [-d] <input> <output>\n") os.Exit(1) } input, err := os.OpenFile(args[0], os.O_RDONLY, 0644) if err != nil { fmt.Printf("Failed to open input file %s\n", args[0]) os.Exit(1) } defer input.Close() if *decompress { data, _ = ioutil.ReadAll(input) data, err = lz4.Decode(nil, data) if err != nil { fmt.Println("Failed to decode:", err) return } } else { data, _ = ioutil.ReadAll(input) data, err = lz4.Encode(nil, data) if err != nil { fmt.Println("Failed to encode:", err) return } } err = ioutil.WriteFile(args[1], data, 0644) if err != nil { fmt.Printf("Failed to open output file %s\n", args[1]) os.Exit(1) } }
func main() { verbose := flag.Bool("v", false, "verbose") flag.Parse() r := bufio.NewReader(os.Stdin) for { var header struct { PacketSize uint32 SipHash uint64 Fname []byte `binpack:"lenprefix=uint16"` UncompressedSize uint32 } err := binpack.Read(r, binary.LittleEndian, &header) if err == io.EOF { break } compressedSize := header.PacketSize - 16 - 2 - uint32(len(header.Fname)) if *verbose { log.Printf("%s: %d -> %d\n", string(header.Fname), compressedSize, header.UncompressedSize) } data := make([]byte, compressedSize) n, err := io.ReadFull(r, data) if n != len(data) || err != nil { log.Fatalf("bad read: n=%d len(data)=%d err=%s\n", n, len(data), err) } data, err = lz4.Decode(nil, data) h := siphash.Hash(0, 0, data) if err != nil || h != header.SipHash { log.Println("FAIL: err=", err) } } }
func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) { if cap(c.rdbuf0) < 8 { c.rdbuf0 = make([]byte, 8) } else { c.rdbuf0 = c.rdbuf0[:8] } _, err = io.ReadFull(c.cr, c.rdbuf0) if err != nil { return } hdr = decodeHeader(binary.BigEndian.Uint32(c.rdbuf0[0:4])) msglen := int(binary.BigEndian.Uint32(c.rdbuf0[4:8])) if debug { l.Debugf("read header %v (msglen=%d)", hdr, msglen) } if hdr.version != 0 { err = fmt.Errorf("unknown protocol version 0x%x", hdr.version) return } if cap(c.rdbuf0) < msglen { c.rdbuf0 = make([]byte, msglen) } else { c.rdbuf0 = c.rdbuf0[:msglen] } _, err = io.ReadFull(c.cr, c.rdbuf0) if err != nil { return } if debug { l.Debugf("read %d bytes", len(c.rdbuf0)) } msgBuf := c.rdbuf0 if hdr.compression { c.rdbuf1 = c.rdbuf1[:cap(c.rdbuf1)] c.rdbuf1, err = lz4.Decode(c.rdbuf1, c.rdbuf0) if err != nil { return } msgBuf = c.rdbuf1 if debug { l.Debugf("decompressed to %d bytes", len(msgBuf)) } } if debug { if len(msgBuf) > 1024 { l.Debugf("message data:\n%s", hex.Dump(msgBuf[:1024])) } else { l.Debugf("message data:\n%s", hex.Dump(msgBuf)) } } // We check each returned error for the XDRError.IsEOF() method. // IsEOF()==true here means that the message contained fewer fields than // expected. It does not signify an EOF on the socket, because we've // successfully read a size value and that many bytes already. New fields // we expected but the other peer didn't send should be interpreted as // zero/nil, and if that's not valid we'll verify it somewhere else. switch hdr.msgType { case messageTypeIndex, messageTypeIndexUpdate: var idx IndexMessage err = idx.UnmarshalXDR(msgBuf) if xdrErr, ok := err.(isEofer); ok && xdrErr.IsEOF() { err = nil } msg = idx case messageTypeRequest: var req RequestMessage err = req.UnmarshalXDR(msgBuf) if xdrErr, ok := err.(isEofer); ok && xdrErr.IsEOF() { err = nil } msg = req case messageTypeResponse: var resp ResponseMessage err = resp.UnmarshalXDR(msgBuf) if xdrErr, ok := err.(isEofer); ok && xdrErr.IsEOF() { err = nil } msg = resp case messageTypePing: msg = pingMessage{} case messageTypePong: msg = pongMessage{} case messageTypeClusterConfig: var cc ClusterConfigMessage err = cc.UnmarshalXDR(msgBuf) if xdrErr, ok := err.(isEofer); ok && xdrErr.IsEOF() { err = nil } msg = cc case messageTypeClose: var cm CloseMessage err = cm.UnmarshalXDR(msgBuf) if xdrErr, ok := err.(isEofer); ok && xdrErr.IsEOF() { err = nil } msg = cm default: err = fmt.Errorf("protocol error: %s: unknown message type %#x", c.id, hdr.msgType) } return }
func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) { hdrBuf := make([]byte, 8) _, err = io.ReadFull(c.cr, hdrBuf) if err != nil { return } hdr = decodeHeader(binary.BigEndian.Uint32(hdrBuf[:4])) msglen := int(binary.BigEndian.Uint32(hdrBuf[4:])) l.Debugf("read header %v (msglen=%d)", hdr, msglen) if msglen > MaxMessageLen { err = fmt.Errorf("message length %d exceeds maximum %d", msglen, MaxMessageLen) return } if hdr.version != 0 { err = fmt.Errorf("unknown protocol version 0x%x", hdr.version) return } // c.readerBuf contains a buffer we can reuse. But once we've unmarshalled // a message from the buffer we can't reuse it again as the unmarshalled // message refers to the contents of the buffer. The only case we a buffer // ends up in readerBuf for reuse is when the message is compressed, as we // then decompress into a new buffer instead. var msgBuf []byte if cap(c.readerBuf) >= msglen { // If we have a buffer ready in rdbuf we just use that. msgBuf = c.readerBuf[:msglen] } else { // Otherwise we allocate a new buffer. msgBuf = make([]byte, msglen) } _, err = io.ReadFull(c.cr, msgBuf) if err != nil { return } l.Debugf("read %d bytes", len(msgBuf)) if hdr.compression && msglen > 0 { // We're going to decompress msgBuf into a different newly allocated // buffer, so keep msgBuf around for reuse on the next message. c.readerBuf = msgBuf msgBuf, err = lz4.Decode(nil, msgBuf) if err != nil { return } l.Debugf("decompressed to %d bytes", len(msgBuf)) } else { c.readerBuf = nil } if shouldDebug() { if len(msgBuf) > 1024 { l.Debugf("message data:\n%s", hex.Dump(msgBuf[:1024])) } else { l.Debugf("message data:\n%s", hex.Dump(msgBuf)) } } switch hdr.msgType { case messageTypeIndex, messageTypeIndexUpdate: var idx IndexMessage err = idx.UnmarshalXDR(msgBuf) msg = idx case messageTypeRequest: var req RequestMessage err = req.UnmarshalXDR(msgBuf) msg = req case messageTypeResponse: var resp ResponseMessage err = resp.UnmarshalXDR(msgBuf) msg = resp case messageTypePing: msg = pingMessage{} case messageTypeClusterConfig: var cc ClusterConfigMessage err = cc.UnmarshalXDR(msgBuf) msg = cc case messageTypeClose: var cm CloseMessage err = cm.UnmarshalXDR(msgBuf) msg = cm default: err = fmt.Errorf("protocol error: %s: unknown message type %#x", c.id, hdr.msgType) } // We check the returned error for the XDRError.IsEOF() method. // IsEOF()==true here means that the message contained fewer fields than // expected. It does not signify an EOF on the socket, because we've // successfully read a size value and then that many bytes from the wire. // New fields we expected but the other peer didn't send should be // interpreted as zero/nil, and if that's not valid we'll verify it // somewhere else. if xdrErr, ok := err.(isEofer); ok && xdrErr.IsEOF() { err = nil } return }
func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) { if cap(c.rdbuf0) < 8 { c.rdbuf0 = make([]byte, 8) } else { c.rdbuf0 = c.rdbuf0[:8] } _, err = io.ReadFull(c.cr, c.rdbuf0) if err != nil { return } hdr = decodeHeader(binary.BigEndian.Uint32(c.rdbuf0[0:4])) msglen := int(binary.BigEndian.Uint32(c.rdbuf0[4:8])) if debug { l.Debugf("read header %v (msglen=%d)", hdr, msglen) } if cap(c.rdbuf0) < msglen { c.rdbuf0 = make([]byte, msglen) } else { c.rdbuf0 = c.rdbuf0[:msglen] } _, err = io.ReadFull(c.cr, c.rdbuf0) if err != nil { return } if debug { l.Debugf("read %d bytes", len(c.rdbuf0)) } msgBuf := c.rdbuf0 if hdr.compression { c.rdbuf1 = c.rdbuf1[:cap(c.rdbuf1)] c.rdbuf1, err = lz4.Decode(c.rdbuf1, c.rdbuf0) if err != nil { return } msgBuf = c.rdbuf1 if debug { l.Debugf("decompressed to %d bytes", len(msgBuf)) } } if debug { if len(msgBuf) > 1024 { l.Debugf("message data:\n%s", hex.Dump(msgBuf[:1024])) } else { l.Debugf("message data:\n%s", hex.Dump(msgBuf)) } } switch hdr.msgType { case messageTypeIndex, messageTypeIndexUpdate: var idx IndexMessage err = idx.UnmarshalXDR(msgBuf) msg = idx case messageTypeRequest: var req RequestMessage err = req.UnmarshalXDR(msgBuf) msg = req case messageTypeResponse: var resp ResponseMessage err = resp.UnmarshalXDR(msgBuf) msg = resp case messageTypePing, messageTypePong: msg = EmptyMessage{} case messageTypeClusterConfig: var cc ClusterConfigMessage err = cc.UnmarshalXDR(msgBuf) msg = cc case messageTypeClose: var cm CloseMessage err = cm.UnmarshalXDR(msgBuf) msg = cm default: err = fmt.Errorf("protocol error: %s: unknown message type %#x", c.id, hdr.msgType) } return }