func (this *SimpleAuthenticator) Open(buffer *alloc.Buffer) bool { len := buffer.Len() xtra := 4 - len%4 if xtra != 0 { buffer.Slice(0, len+xtra) } xorbkd(buffer.Value) if xtra != 0 { buffer.Slice(0, len) } fnvHash := fnv.New32a() fnvHash.Write(buffer.Value[4:]) if serial.BytesToUint32(buffer.Value[:4]) != fnvHash.Sum32() { return false } length := serial.BytesToUint16(buffer.Value[4:6]) if buffer.Len()-6 != int(length) { return false } buffer.SliceFrom(6) return true }
func (this *ChunkReader) Read() (*alloc.Buffer, error) { buffer := alloc.NewLargeBuffer() if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil { buffer.Release() return nil, err } // There is a potential buffer overflow here. Large buffer is 64K bytes, // while uin16 + 10 will be more than that length := serial.BytesToUint16(buffer.Value[:2]) + AuthSize if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil { buffer.Release() return nil, err } buffer.Slice(0, int(length)) authBytes := buffer.Value[:AuthSize] payload := buffer.Value[AuthSize:] actualAuthBytes := this.auth.Authenticate(nil, payload) if !bytes.Equal(authBytes, actualAuthBytes) { buffer.Release() log.Debug("AuthenticationReader: Unexpected auth: ", authBytes) return nil, transport.ErrorCorruptedPacket } buffer.Value = payload return buffer, nil }
func (this *Listener) OnReceive(payload *alloc.Buffer, src v2net.Destination) { defer payload.Release() if valid := this.block.Open(payload); !valid { log.Info("KCP|Listener: discarding invalid payload from ", src) return } if !this.running { return } this.Lock() defer this.Unlock() if !this.running { return } if payload.Len() < 4 { return } conv := serial.BytesToUint16(payload.Value) cmd := Command(payload.Value[2]) sourceId := src.NetAddr() + "|" + serial.Uint16ToString(conv) conn, found := this.sessions[sourceId] if !found { if cmd == CommandTerminate { return } log.Debug("KCP|Listener: Creating session with id(", sourceId, ") from ", src) writer := &Writer{ id: sourceId, hub: this.hub, dest: src, listener: this, } srcAddr := &net.UDPAddr{ IP: src.Address().IP(), Port: int(src.Port()), } conn = NewConnection(conv, writer, this.localAddr, srcAddr, this.block) select { case this.awaitingConns <- conn: case <-time.After(time.Second * 5): conn.Close() return } this.sessions[sourceId] = conn } conn.Input(payload.Value) }
func (this *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) { cmd := new(protocol.CommandSwitchAccount) if len(data) == 0 { return nil, transport.ErrCorruptedPacket } lenHost := int(data[0]) if len(data) < lenHost+1 { return nil, transport.ErrCorruptedPacket } if lenHost > 0 { cmd.Host = v2net.ParseAddress(string(data[1 : 1+lenHost])) } portStart := 1 + lenHost if len(data) < portStart+2 { return nil, transport.ErrCorruptedPacket } cmd.Port = v2net.PortFromBytes(data[portStart : portStart+2]) idStart := portStart + 2 if len(data) < idStart+16 { return nil, transport.ErrCorruptedPacket } cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16]) alterIdStart := idStart + 16 if len(data) < alterIdStart+2 { return nil, transport.ErrCorruptedPacket } cmd.AlterIds = serial.BytesToUint16(data[alterIdStart : alterIdStart+2]) levelStart := alterIdStart + 2 if len(data) < levelStart+1 { return nil, transport.ErrCorruptedPacket } cmd.Level = protocol.UserLevel(data[levelStart]) timeStart := levelStart + 1 if len(data) < timeStart { return nil, transport.ErrCorruptedPacket } cmd.ValidMin = data[timeStart] return cmd, nil }
func (this *AuthChunkReader) Read() (*alloc.Buffer, error) { var buffer *alloc.Buffer if this.last != nil { buffer = this.last this.last = nil } else { buffer = alloc.NewBufferWithSize(4096).Clear() } if this.chunkLength == -1 { for buffer.Len() < 6 { _, err := buffer.FillFrom(this.reader) if err != nil { buffer.Release() return nil, io.ErrUnexpectedEOF } } length := serial.BytesToUint16(buffer.Value[:2]) this.chunkLength = int(length) - 4 this.validator = NewValidator(serial.BytesToUint32(buffer.Value[2:6])) buffer.SliceFrom(6) if buffer.Len() < this.chunkLength && this.chunkLength <= 2048 { _, err := buffer.FillFrom(this.reader) if err != nil { buffer.Release() return nil, io.ErrUnexpectedEOF } } } else if buffer.Len() < this.chunkLength { _, err := buffer.FillFrom(this.reader) if err != nil { buffer.Release() return nil, io.ErrUnexpectedEOF } } if this.chunkLength == 0 { buffer.Release() return nil, io.EOF } if buffer.Len() < this.chunkLength { this.validator.Consume(buffer.Value) this.chunkLength -= buffer.Len() } else { this.validator.Consume(buffer.Value[:this.chunkLength]) if !this.validator.Validate() { buffer.Release() return nil, transport.ErrCorruptedPacket } leftLength := buffer.Len() - this.chunkLength if leftLength > 0 { this.last = alloc.NewBufferWithSize(leftLength + 4096).Clear() this.last.Append(buffer.Value[this.chunkLength:]) buffer.Slice(0, this.chunkLength) } this.chunkLength = -1 this.validator = nil } return buffer, nil }
// PortFromBytes converts a byte array to a Port, assuming bytes are in big endian order. // @unsafe Caller must ensure that the byte array has at least 2 elements. func PortFromBytes(port []byte) Port { return Port(serial.BytesToUint16(port)) }
func ReadSegment(buf []byte) (Segment, []byte) { if len(buf) <= 4 { return nil, nil } conv := serial.BytesToUint16(buf) buf = buf[2:] cmd := Command(buf[0]) opt := SegmentOption(buf[1]) buf = buf[2:] if cmd == CommandData { seg := NewDataSegment() seg.Conv = conv seg.Option = opt if len(buf) < 16 { return nil, nil } seg.Timestamp = serial.BytesToUint32(buf) buf = buf[4:] seg.Number = serial.BytesToUint32(buf) buf = buf[4:] seg.SendingNext = serial.BytesToUint32(buf) buf = buf[4:] dataLen := int(serial.BytesToUint16(buf)) buf = buf[2:] if len(buf) < dataLen { return nil, nil } seg.Data = alloc.NewSmallBuffer().Clear().Append(buf[:dataLen]) buf = buf[dataLen:] return seg, buf } if cmd == CommandACK { seg := NewAckSegment() seg.Conv = conv seg.Option = opt if len(buf) < 9 { return nil, nil } seg.ReceivingWindow = serial.BytesToUint32(buf) buf = buf[4:] seg.ReceivingNext = serial.BytesToUint32(buf) buf = buf[4:] count := int(buf[0]) buf = buf[1:] if len(buf) < count*8 { return nil, nil } for i := 0; i < count; i++ { seg.PutNumber(serial.BytesToUint32(buf), serial.BytesToUint32(buf[4:])) buf = buf[8:] } return seg, buf } seg := NewCmdOnlySegment() seg.Conv = conv seg.Command = cmd seg.Option = opt if len(buf) < 8 { return nil, nil } seg.SendingNext = serial.BytesToUint32(buf) buf = buf[4:] seg.ReceivinNext = serial.BytesToUint32(buf) buf = buf[4:] return seg, buf }