github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/vless/encoding/addons.go (about)

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