Beispiel #1
0
func PacketToBytes(pkt ResponsePacket) ([]byte, error) {
	now := time.Now().UnixNano()
	marker := pkt.Marker()
	echotime, recvtime, stmptime := pkt.EchoTime()
	if echotime {
		if recvtime+30*int64(time.Second) < now {
			echotime = false
		} else {
			marker += 0x04
		}
	}
	w := xio.NewPacketWriter(nil)
	if err := w.SetOffset(6); err != nil {
		return nil, errors.New("packet.skip header")
	}
	if err := w.Write8(marker); err != nil {
		return nil, errors.New("packet.write marker")
	}
	const div = int64(time.Millisecond)
	if err := w.Write16(uint16(now / div)); err != nil {
		return nil, errors.New("packet.write time.now")
	}
	if echotime {
		if err := w.Write16(stmptime + uint16((now-recvtime)/div)); err != nil {
			return nil, errors.New("packet.write time.ping")
		}
	}
	for _, rsp := range pkt.Messages() {
		if err := w.Write8(rsp.Code()); err != nil {
			return nil, errors.New("message.write code")
		}
		pos := w.Offset()
		if err := w.Skip(2); err != nil {
			return nil, errors.New("message.skip size")
		}
		if err := rsp.WriteTo(w); err != nil {
			return nil, errors.New("message.write content")
		}
		beg, end := pos+2, w.Offset()
		if err := w.SetOffset(pos); err != nil {
			return nil, errors.New("message.skip back")
		}
		if end < beg || end > beg+0xffff {
			return nil, errors.New("message.bad content length")
		} else if err := w.Write16(uint16(end - beg)); err != nil {
			return nil, errors.New("message.write size")
		}
		if err := w.SetOffset(end); err != nil {
			return nil, errors.New("message.skip to end")
		}
	}
	return w.Bytes(), nil
}
Beispiel #2
0
func newAmfBytesWriter(name string) (*amf0.Writer, error) {
	w := amf0.NewWriter(xio.NewPacketWriter(nil))
	if err := w.Write8(0x0f); err != nil {
		return nil, errors.New("message.amf.write code")
	}
	if err := w.Write8(0); err != nil {
		return nil, errors.New("message.amf.write useless1")
	}
	if err := w.Write32(0); err != nil {
		return nil, errors.New("message.amf.write useless2")
	}
	if err := w.WriteString(name); err != nil {
		return nil, errors.New("message.amf.write name")
	}
	return w, nil
}
Beispiel #3
0
func (h *connHandler) newSetBufferTime(sid uint32) error {
	w := xio.NewPacketWriter(nil)
	if err := w.Write8(0x04); err != nil {
		return err
	}
	if err := w.Write32(0); err != nil {
		return err
	}
	if err := w.Write16(0); err != nil {
		return err
	}
	if err := w.Write32(sid); err != nil {
		return err
	}
	h.fw.AddFragments(true, split(w.Bytes())...)
	return nil
}
Beispiel #4
0
func EncodePacket(engine AESEngine, yid uint32, data []byte) ([]byte, error) {
	if len(data) < 6 {
		return nil, errors.New("packet.too small")
	}
	w := xio.NewPacketWriter(data)
	if n := (w.Len() - 4) % AESBlockSize; n != 0 {
		if err := w.WriteBytes(paddings[n]); err != nil {
			return nil, err
		}
	}
	sum := checksum(w.Bytes()[6:])
	if err := w.SetOffset(4); err != nil {
		return nil, err
	}
	if err := w.Write8(uint8(sum >> 8)); err != nil {
		return nil, err
	}
	if err := w.Write8(uint8(sum)); err != nil {
		return nil, err
	}
	data = w.Bytes()
	if err := engine.Encode(data[4:]); err != nil {
		return nil, err
	}
	r := xio.NewPacketReader(data)
	if err := r.SetOffset(4); err != nil {
		return nil, err
	}
	for i := 0; i < 2; i++ {
		if v, err := r.Read32(); err != nil {
			return nil, err
		} else {
			yid ^= v
		}
	}
	w.SetBytes(data)
	if err := w.SetOffset(0); err != nil {
		return nil, err
	}
	if err := w.Write32(yid); err != nil {
		return nil, err
	}
	return w.Bytes(), nil
}
Beispiel #5
0
func newAmfMessageWriter(name string, callback float64) (*amf0.Writer, error) {
	w := amf0.NewWriter(xio.NewPacketWriter(nil))
	if err := w.Write8(0x14); err != nil {
		return nil, errors.New("message.amf.write code")
	}
	if err := w.Write32(0); err != nil {
		return nil, errors.New("message.amf.write useless")
	}
	if err := w.WriteString(name); err != nil {
		return nil, errors.New("message.amf.write name")
	}
	if err := w.WriteNumber(callback); err != nil {
		return nil, errors.New("message.amf.write callback")
	}
	if err := w.WriteNull(); err != nil {
		return nil, errors.New("message.amf.write null")
	}
	return w, nil
}
Beispiel #6
0
func (h *streamHandler) newPlayBoundResponse(bound uint32) error {
	w := xio.NewPacketWriter(nil)
	if err := w.Write8(0x04); err != nil {
		return err
	}
	if err := w.Write32(0); err != nil {
		return err
	}
	if err := w.Write16(0x22); err != nil {
		return err
	}
	if err := w.Write32(bound); err != nil {
		return err
	}
	if err := w.Write32(1); err != nil {
		return err
	}
	h.fw.AddFragments(true, split(w.Bytes())...)
	return nil
}
Beispiel #7
0
func (h *connHandler) newKeepAliveResponse(keepAliveServer, keepAlivePeer uint32) error {
	w := xio.NewPacketWriter(nil)
	if err := w.Write8(0x04); err != nil {
		return err
	}
	if err := w.Write32(0); err != nil {
		return err
	}
	if err := w.Write16(0x29); err != nil {
		return err
	}
	if err := w.Write32(keepAliveServer); err != nil {
		return err
	}
	if err := w.Write32(keepAlivePeer); err != nil {
		return err
	}
	h.fw.AddFragments(true, split(w.Bytes())...)
	return nil
}