func (fr *flowReader) deliver() { if fr.ready.Len() != 0 { bs := fr.merge() fr.ready.Init() if len(bs) != 0 { if err := handleMessage(fr.handler, xio.NewPacketReader(bs)); err != nil { xlog.OutLog.Printf("[flows]: xid = %d, reader.fid = %d, deliver error = '%v'\n", fr.session.xid, fr.fid, err) } } } }
func PacketXid(data []byte) (uint32, error) { if len(data) < 12 { return 0, errors.New("too small packet") } xid := uint32(0) r := xio.NewPacketReader(data) for i := 0; i < 3; i++ { if v, err := r.Read32(); err != nil { return 0, err } else { xid ^= v } } return xid, nil }
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 }
func HandlePacket(lport uint16, raddr *net.UDPAddr, data []byte) { h := getHandshake() if h == nil { return } defer putHandshake(h) var err error if data, err = rtmfp.DecodePacket(h, data); err != nil { counts.Count("handshake.decode.error", 1) xlog.ErrLog.Printf("[handshake]: decode error = '%v'\n", err) return } xlog.OutLog.Printf("[handshake]: recv addr = [%s], data.len = %d\n%s\n", raddr, len(data), utils.Formatted(data)) h.lport, h.raddr = lport, raddr var pkt *packet if pkt, err = h.handle(xio.NewPacketReader(data[6:])); err != nil { counts.Count("handshake.handle.error", 1) xlog.ErrLog.Printf("[handshake]: handle error = '%v'\n", err) return } else if pkt == nil { xlog.OutLog.Printf("[handshake]: response packet is empty\n") return } if data, err = rtmfp.PacketToBytes(pkt); err != nil { counts.Count("handshake.tobytes.error", 1) xlog.ErrLog.Printf("[handshake]: packet to bytes error = '%v'\n", err) return } xlog.OutLog.Printf("[handshake]: send addr = [%s], data.len = %d\n%s\n", raddr, len(data), utils.Formatted(data)) if data, err = rtmfp.EncodePacket(h, pkt.yid, data); err != nil { counts.Count("handshake.encode.error", 1) xlog.ErrLog.Printf("[handshake]: encode packet error = '%v'\n", err) return } udp.Send(lport, raddr, data) }
func HandlePacket(lport uint16, raddr *net.UDPAddr, xid uint32, data []byte) { s := FindByXid(xid) if s == nil { counts.Count("session.notfound", 1) return } s.Lock() defer s.Unlock() if s.closed { counts.Count("session.hasclosed", 1) return } defer s.flush() var err error if data, err = rtmfp.DecodePacket(s, data); err != nil { counts.Count("session.decode.error", 1) xlog.ErrLog.Printf("[session]: decode error = '%v'\n", err) return } xlog.OutLog.Printf("[session]: recv addr = [%s], data.len = %d\n%s\n", raddr, len(data), utils.Formatted(data)) s.lport, s.raddr = lport, raddr if len(s.cookie) != 0 { cookies.Commit(s.cookie) s.cookie = "" rpc.Join(s.xid, s.raddr) } s.manage.cnt, s.manage.lasttime = 0, time.Now().UnixNano() if err = s.handle(xio.NewPacketReader(data[6:])); err != nil { counts.Count("session.handle.error", 1) xlog.ErrLog.Printf("[session]: handle error = '%v'\n", err) } }
func ParseRequestMessage(r *xio.PacketReader) (*RequestMessage, error) { var err error code := uint8(0) if code, err = r.Read8(); err != nil { return nil, errors.New("message.read code") } else if code == 0xff { return nil, EOP } var size uint16 if size, err = r.Read16(); err != nil { return nil, errors.New("message.read size") } rlen := r.Len() mlen := int(size) if rlen < mlen { return nil, errors.New("message.bad content length") } else { data := r.Bytes()[:mlen] if err := r.Skip(mlen); err != nil { return nil, errors.New("message.skip forward") } return &RequestMessage{code, xio.NewPacketReader(data)}, nil } }