github.com/ooni/psiphon/tunnel-core@v0.0.0-20230105123940-fe12a24c96ee/oovendor/quic-go/internal/wire/frame_parser.go (about)

     1  package wire
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"reflect"
     8  
     9  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/protocol"
    10  	"github.com/ooni/psiphon/tunnel-core/oovendor/quic-go/internal/qerr"
    11  )
    12  
    13  type frameParser struct {
    14  	ackDelayExponent uint8
    15  
    16  	supportsDatagrams bool
    17  
    18  	version protocol.VersionNumber
    19  }
    20  
    21  // NewFrameParser creates a new frame parser.
    22  func NewFrameParser(supportsDatagrams bool, v protocol.VersionNumber) FrameParser {
    23  	return &frameParser{
    24  		supportsDatagrams: supportsDatagrams,
    25  		version:           v,
    26  	}
    27  }
    28  
    29  // ParseNext parses the next frame.
    30  // It skips PADDING frames.
    31  func (p *frameParser) ParseNext(r *bytes.Reader, encLevel protocol.EncryptionLevel) (Frame, error) {
    32  	for r.Len() != 0 {
    33  		typeByte, _ := r.ReadByte()
    34  		if typeByte == 0x0 { // PADDING frame
    35  			continue
    36  		}
    37  		r.UnreadByte()
    38  
    39  		f, err := p.parseFrame(r, typeByte, encLevel)
    40  		if err != nil {
    41  			return nil, &qerr.TransportError{
    42  				FrameType:    uint64(typeByte),
    43  				ErrorCode:    qerr.FrameEncodingError,
    44  				ErrorMessage: err.Error(),
    45  			}
    46  		}
    47  		return f, nil
    48  	}
    49  	return nil, nil
    50  }
    51  
    52  func (p *frameParser) parseFrame(r *bytes.Reader, typeByte byte, encLevel protocol.EncryptionLevel) (Frame, error) {
    53  	var frame Frame
    54  	var err error
    55  	if typeByte&0xf8 == 0x8 {
    56  		frame, err = parseStreamFrame(r, p.version)
    57  	} else {
    58  		switch typeByte {
    59  		case 0x1:
    60  			frame, err = parsePingFrame(r, p.version)
    61  		case 0x2, 0x3:
    62  			ackDelayExponent := p.ackDelayExponent
    63  			if encLevel != protocol.Encryption1RTT {
    64  				ackDelayExponent = protocol.DefaultAckDelayExponent
    65  			}
    66  			frame, err = parseAckFrame(r, ackDelayExponent, p.version)
    67  		case 0x4:
    68  			frame, err = parseResetStreamFrame(r, p.version)
    69  		case 0x5:
    70  			frame, err = parseStopSendingFrame(r, p.version)
    71  		case 0x6:
    72  			frame, err = parseCryptoFrame(r, p.version)
    73  		case 0x7:
    74  			frame, err = parseNewTokenFrame(r, p.version)
    75  		case 0x10:
    76  			frame, err = parseMaxDataFrame(r, p.version)
    77  		case 0x11:
    78  			frame, err = parseMaxStreamDataFrame(r, p.version)
    79  		case 0x12, 0x13:
    80  			frame, err = parseMaxStreamsFrame(r, p.version)
    81  		case 0x14:
    82  			frame, err = parseDataBlockedFrame(r, p.version)
    83  		case 0x15:
    84  			frame, err = parseStreamDataBlockedFrame(r, p.version)
    85  		case 0x16, 0x17:
    86  			frame, err = parseStreamsBlockedFrame(r, p.version)
    87  		case 0x18:
    88  			frame, err = parseNewConnectionIDFrame(r, p.version)
    89  		case 0x19:
    90  			frame, err = parseRetireConnectionIDFrame(r, p.version)
    91  		case 0x1a:
    92  			frame, err = parsePathChallengeFrame(r, p.version)
    93  		case 0x1b:
    94  			frame, err = parsePathResponseFrame(r, p.version)
    95  		case 0x1c, 0x1d:
    96  			frame, err = parseConnectionCloseFrame(r, p.version)
    97  		case 0x1e:
    98  			frame, err = parseHandshakeDoneFrame(r, p.version)
    99  		case 0x30, 0x31:
   100  			if p.supportsDatagrams {
   101  				frame, err = parseDatagramFrame(r, p.version)
   102  				break
   103  			}
   104  			fallthrough
   105  		default:
   106  			err = errors.New("unknown frame type")
   107  		}
   108  	}
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  	if !p.isAllowedAtEncLevel(frame, encLevel) {
   113  		return nil, fmt.Errorf("%s not allowed at encryption level %s", reflect.TypeOf(frame).Elem().Name(), encLevel)
   114  	}
   115  	return frame, nil
   116  }
   117  
   118  func (p *frameParser) isAllowedAtEncLevel(f Frame, encLevel protocol.EncryptionLevel) bool {
   119  	switch encLevel {
   120  	case protocol.EncryptionInitial, protocol.EncryptionHandshake:
   121  		switch f.(type) {
   122  		case *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *PingFrame:
   123  			return true
   124  		default:
   125  			return false
   126  		}
   127  	case protocol.Encryption0RTT:
   128  		switch f.(type) {
   129  		case *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *NewTokenFrame, *PathResponseFrame, *RetireConnectionIDFrame:
   130  			return false
   131  		default:
   132  			return true
   133  		}
   134  	case protocol.Encryption1RTT:
   135  		return true
   136  	default:
   137  		panic("unknown encryption level")
   138  	}
   139  }
   140  
   141  func (p *frameParser) SetAckDelayExponent(exp uint8) {
   142  	p.ackDelayExponent = exp
   143  }