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
}
示例#2
0
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
}
示例#3
0
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)
	}
}
示例#4
0
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)
		}
	}
}
示例#5
0
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
}
示例#6
0
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
}
示例#7
0
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
}