func parseAssignRequest(r *xio.PacketReader) (*assignRequest, error) { var err error yid := uint32(0) if yid, err = r.Read32(); err != nil { return nil, errors.New("assign.read yid") } coolen := uint64(0) if coolen, err = r.Read7BitValue64(); err != nil { return nil, errors.New("assign.read cookie.len") } else if coolen != cookies.CookieSize { return nil, errors.New("assign.bad cookie.len") } coobuf := make([]byte, cookies.CookieSize) if err = r.ReadBytes(coobuf); err != nil { return nil, errors.New("assign.read cookie.value") } size := uint64(0) if size, err = r.Read7BitValue64(); err != nil { return nil, errors.New("assign.read pid.size") } else if size == 0 || size > uint64(r.Len()) { return nil, errors.New("assign.bad pid.size") } pid := sha256.Sum256(r.Bytes()[:size]) if len(pid) != 0x20 { return nil, errors.New("assign.bad pid.len") } if size, err = r.Read7BitValue64(); err != nil { return nil, errors.New("assign.read pubkey.len") } else if size <= 2 { return nil, errors.New("assign.too small pubkey.len") } else { size -= 2 if size > uint64(r.Len()) { return nil, errors.New("assign.too big pubkey.len") } if err := r.Skip(2); err != nil { return nil, errors.New("assign.skip useless") } } pubkey := make([]byte, int(size)) if err = r.ReadBytes(pubkey); err != nil { return nil, errors.New("assign.read pubkey") } if size, err = r.Read7BitValue64(); err != nil { return nil, errors.New("assign.read initiator.len") } else if size == 0 || size > uint64(r.Len()) { return nil, errors.New("assign.bad initiator.len") } initiator := make([]byte, int(size)) if err = r.ReadBytes(initiator); err != nil { return nil, errors.New("assign.read initiator") } return &assignRequest{yid, string(pid[:]), coobuf, pubkey, initiator}, nil }
func parseFlowRequest(r *xio.PacketReader) (*flowRequest, error) { var err error flags := uint8(0) if flags, err = r.Read8(); err != nil { return nil, errors.New("flow.read flags") } fid := uint64(0) if fid, err = r.Read7BitValue64(); err != nil { return nil, errors.New("flow.read fid") } stage, delta := uint64(0), uint64(0) if stage, err = r.Read7BitValue64(); err != nil { return nil, errors.New("flow.read stage") } if delta, err = r.Read7BitValue64(); err != nil { return nil, errors.New("flow.read delta") } signature := "" if (flags & flagsHeader) != 0 { if signature, err = r.ReadString8(); err != nil { return nil, errors.New("flow.read signature") } for { if size, err := r.Read8(); err != nil { return nil, errors.New("flow.read header content size") } else if size == 0 { break } else if n := int(size); n > r.Len() { return nil, errors.New("flows.too big header content size") } else if err = r.Skip(n); err != nil { return nil, errors.New("flows.skip header") } } } data := r.Bytes() req := &flowRequest{} req.fid = fid req.signature = signature req.stage = stage req.stageack = stage - delta req.slices = make([]*flowRequestSlice, 0, 4) req.AddSlice(&flowRequestSlice{flags, data}) return req, nil }
func handleMessage(h messageHandler, r *xio.PacketReader) error { if code, err := r.Read8(); err != nil { return errors.New("message.read code") } else { switch code { default: return h.OnRawMessage(code, r) case 0x11: if err := r.Skip(5); err != nil { return errors.New("message.skip useless") } return handleAmfMessage(h, amf0.NewReader(r), true) case 0x14: if err := r.Skip(4); err != nil { return errors.New("message.skip useless") } return handleAmfMessage(h, amf0.NewReader(r), true) case 0x0f: if err := r.Skip(5); err != nil { return errors.New("message.skip useless") } return handleAmfMessage(h, amf0.NewReader(r), false) } } }
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 } }