github.com/xraypb/Xray-core@v1.8.1/proxy/vless/encoding/addons.go (about)

     1  package encoding
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/golang/protobuf/proto"
     7  	"github.com/xraypb/Xray-core/common/buf"
     8  	"github.com/xraypb/Xray-core/common/protocol"
     9  	"github.com/xraypb/Xray-core/proxy/vless"
    10  )
    11  
    12  func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error {
    13  	switch addons.Flow {
    14  	case vless.XRV:
    15  		bytes, err := proto.Marshal(addons)
    16  		if err != nil {
    17  			return newError("failed to marshal addons protobuf value").Base(err)
    18  		}
    19  		if err := buffer.WriteByte(byte(len(bytes))); err != nil {
    20  			return newError("failed to write addons protobuf length").Base(err)
    21  		}
    22  		if _, err := buffer.Write(bytes); err != nil {
    23  			return newError("failed to write addons protobuf value").Base(err)
    24  		}
    25  	default:
    26  		if err := buffer.WriteByte(0); err != nil {
    27  			return newError("failed to write addons protobuf length").Base(err)
    28  		}
    29  	}
    30  
    31  	return nil
    32  }
    33  
    34  func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) {
    35  	addons := new(Addons)
    36  	buffer.Clear()
    37  	if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
    38  		return nil, newError("failed to read addons protobuf length").Base(err)
    39  	}
    40  
    41  	if length := int32(buffer.Byte(0)); length != 0 {
    42  		buffer.Clear()
    43  		if _, err := buffer.ReadFullFrom(reader, length); err != nil {
    44  			return nil, newError("failed to read addons protobuf value").Base(err)
    45  		}
    46  
    47  		if err := proto.Unmarshal(buffer.Bytes(), addons); err != nil {
    48  			return nil, newError("failed to unmarshal addons protobuf value").Base(err)
    49  		}
    50  
    51  		// Verification.
    52  		switch addons.Flow {
    53  		default:
    54  		}
    55  	}
    56  
    57  	return addons, nil
    58  }
    59  
    60  // EncodeBodyAddons returns a Writer that auto-encrypt content written by caller.
    61  func EncodeBodyAddons(writer io.Writer, request *protocol.RequestHeader, addons *Addons) buf.Writer {
    62  	switch addons.Flow {
    63  	default:
    64  		if request.Command == protocol.RequestCommandUDP {
    65  			return NewMultiLengthPacketWriter(writer.(buf.Writer))
    66  		}
    67  	}
    68  	return buf.NewWriter(writer)
    69  }
    70  
    71  // DecodeBodyAddons returns a Reader from which caller can fetch decrypted body.
    72  func DecodeBodyAddons(reader io.Reader, request *protocol.RequestHeader, addons *Addons) buf.Reader {
    73  	switch addons.Flow {
    74  	default:
    75  		if request.Command == protocol.RequestCommandUDP {
    76  			return NewLengthPacketReader(reader)
    77  		}
    78  	}
    79  	return buf.NewReader(reader)
    80  }
    81  
    82  func NewMultiLengthPacketWriter(writer buf.Writer) *MultiLengthPacketWriter {
    83  	return &MultiLengthPacketWriter{
    84  		Writer: writer,
    85  	}
    86  }
    87  
    88  type MultiLengthPacketWriter struct {
    89  	buf.Writer
    90  }
    91  
    92  func (w *MultiLengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
    93  	defer buf.ReleaseMulti(mb)
    94  	mb2Write := make(buf.MultiBuffer, 0, len(mb)+1)
    95  	for _, b := range mb {
    96  		length := b.Len()
    97  		if length == 0 || length+2 > buf.Size {
    98  			continue
    99  		}
   100  		eb := buf.New()
   101  		if err := eb.WriteByte(byte(length >> 8)); err != nil {
   102  			eb.Release()
   103  			continue
   104  		}
   105  		if err := eb.WriteByte(byte(length)); err != nil {
   106  			eb.Release()
   107  			continue
   108  		}
   109  		if _, err := eb.Write(b.Bytes()); err != nil {
   110  			eb.Release()
   111  			continue
   112  		}
   113  		mb2Write = append(mb2Write, eb)
   114  	}
   115  	if mb2Write.IsEmpty() {
   116  		return nil
   117  	}
   118  	return w.Writer.WriteMultiBuffer(mb2Write)
   119  }
   120  
   121  func NewLengthPacketWriter(writer io.Writer) *LengthPacketWriter {
   122  	return &LengthPacketWriter{
   123  		Writer: writer,
   124  		cache:  make([]byte, 0, 65536),
   125  	}
   126  }
   127  
   128  type LengthPacketWriter struct {
   129  	io.Writer
   130  	cache []byte
   131  }
   132  
   133  func (w *LengthPacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
   134  	length := mb.Len() // none of mb is nil
   135  	// fmt.Println("Write", length)
   136  	if length == 0 {
   137  		return nil
   138  	}
   139  	defer func() {
   140  		w.cache = w.cache[:0]
   141  	}()
   142  	w.cache = append(w.cache, byte(length>>8), byte(length))
   143  	for i, b := range mb {
   144  		w.cache = append(w.cache, b.Bytes()...)
   145  		b.Release()
   146  		mb[i] = nil
   147  	}
   148  	if _, err := w.Write(w.cache); err != nil {
   149  		return newError("failed to write a packet").Base(err)
   150  	}
   151  	return nil
   152  }
   153  
   154  func NewLengthPacketReader(reader io.Reader) *LengthPacketReader {
   155  	return &LengthPacketReader{
   156  		Reader: reader,
   157  		cache:  make([]byte, 2),
   158  	}
   159  }
   160  
   161  type LengthPacketReader struct {
   162  	io.Reader
   163  	cache []byte
   164  }
   165  
   166  func (r *LengthPacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
   167  	if _, err := io.ReadFull(r.Reader, r.cache); err != nil { // maybe EOF
   168  		return nil, newError("failed to read packet length").Base(err)
   169  	}
   170  	length := int32(r.cache[0])<<8 | int32(r.cache[1])
   171  	// fmt.Println("Read", length)
   172  	mb := make(buf.MultiBuffer, 0, length/buf.Size+1)
   173  	for length > 0 {
   174  		size := length
   175  		if size > buf.Size {
   176  			size = buf.Size
   177  		}
   178  		length -= size
   179  		b := buf.New()
   180  		if _, err := b.ReadFullFrom(r.Reader, size); err != nil {
   181  			return nil, newError("failed to read packet payload").Base(err)
   182  		}
   183  		mb = append(mb, b)
   184  	}
   185  	return mb, nil
   186  }