mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-15 03:40:56 +08:00
91 lines
2.8 KiB
Go
91 lines
2.8 KiB
Go
/*
|
|
* Copyright (c) 2014 by Farsight Security, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package framestream
|
|
|
|
import (
|
|
"io"
|
|
"time"
|
|
)
|
|
|
|
// DecoderOptions specifies configuration for a framestream Decoder.
|
|
type DecoderOptions struct {
|
|
// MaxPayloadSize is the largest frame size accepted by the Decoder.
|
|
//
|
|
// If the Frame Streams Writer sends a frame in excess of this size,
|
|
// Decode() will return the error ErrDataFrameTooLarge. The Decoder
|
|
// attempts to recover from this error, so calls to Decode() after
|
|
// receiving this error may succeed.
|
|
MaxPayloadSize uint32
|
|
// The ContentType expected by the Decoder. May be left unset for no
|
|
// content negotiation. If the Writer requests a different content type,
|
|
// NewDecoder() will return ErrContentTypeMismatch.
|
|
ContentType []byte
|
|
// If Bidirectional is true, the underlying io.Reader must be an
|
|
// io.ReadWriter, and the Decoder will engage in a bidirectional
|
|
// handshake with its peer to establish content type and communicate
|
|
// shutdown.
|
|
Bidirectional bool
|
|
// Timeout gives the timeout for reading the initial handshake messages
|
|
// from the peer and writing response messages if Bidirectional. It is
|
|
// only effective for underlying Readers satisfying net.Conn.
|
|
Timeout time.Duration
|
|
}
|
|
|
|
// A Decoder decodes Frame Streams frames read from an underlying io.Reader.
|
|
//
|
|
// It is provided for compatibility. Use Reader instead.
|
|
type Decoder struct {
|
|
buf []byte
|
|
r *Reader
|
|
}
|
|
|
|
// NewDecoder returns a Decoder using the given io.Reader and options.
|
|
func NewDecoder(r io.Reader, opt *DecoderOptions) (*Decoder, error) {
|
|
if opt == nil {
|
|
opt = &DecoderOptions{}
|
|
}
|
|
if opt.MaxPayloadSize == 0 {
|
|
opt.MaxPayloadSize = DEFAULT_MAX_PAYLOAD_SIZE
|
|
}
|
|
ropt := &ReaderOptions{
|
|
Bidirectional: opt.Bidirectional,
|
|
Timeout: opt.Timeout,
|
|
}
|
|
if opt.ContentType != nil {
|
|
ropt.ContentTypes = append(ropt.ContentTypes, opt.ContentType)
|
|
}
|
|
dr, err := NewReader(r, ropt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dec := &Decoder{
|
|
buf: make([]byte, opt.MaxPayloadSize),
|
|
r: dr,
|
|
}
|
|
return dec, nil
|
|
}
|
|
|
|
// Decode returns the data from a Frame Streams data frame. The slice returned
|
|
// is valid until the next call to Decode.
|
|
func (dec *Decoder) Decode() (frameData []byte, err error) {
|
|
n, err := dec.r.ReadFrame(dec.buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return dec.buf[:n], nil
|
|
}
|