func NewSegmentWriter(writer io.Writer, mtu uint32) *BufferedSegmentWriter { return &BufferedSegmentWriter{ mtu: mtu, writer: writer, buffer: buf.NewSmall(), } }
func (v *UDPHub) start() { v.cancel.WaitThread() defer v.cancel.FinishThread() oobBytes := make([]byte, 256) for v.Running() { buffer := buf.NewSmall() var noob int var addr *net.UDPAddr err := buffer.AppendSupplier(func(b []byte) (int, error) { n, nb, _, a, e := ReadUDPMsg(v.conn, b, oobBytes) noob = nb addr = a return n, e }) if err != nil { log.Info("UDP|Hub: Failed to read UDP msg: ", err) buffer.Release() continue } session := new(proxy.SessionInfo) session.Source = v2net.UDPDestination(v2net.IPAddress(addr.IP), v2net.Port(addr.Port)) if v.option.ReceiveOriginalDest && noob > 0 { session.Destination = RetrieveOriginalDest(oobBytes[:noob]) } v.queue.Enqueue(UDPPayload{ payload: buffer, session: session, }) } }
func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) *buf.Buffer { b := buf.NewSmall() b.AppendBytes(0, 0, 0 /* Fragment */) appendAddress(b, request.Address, request.Port) b.Append(data) return b }
func NewWriter(rawWriter io.Writer) *BufferedWriter { return &BufferedWriter{ writer: rawWriter, buffer: buf.NewSmall(), cached: true, } }
func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) { buffer := buf.NewSmall() totalBytes := 0 endingDetected := false for totalBytes < maxHeaderLength { err := buffer.AppendSupplier(buf.ReadFrom(reader)) if err != nil { return nil, err } if n := bytes.Index(buffer.Bytes(), []byte(ENDING)); n != -1 { buffer.SliceFrom(n + len(ENDING)) endingDetected = true break } if buffer.Len() >= len(ENDING) { totalBytes += buffer.Len() - len(ENDING) leftover := buffer.BytesFrom(-len(ENDING)) buffer.Reset(func(b []byte) (int, error) { return copy(b, leftover), nil }) } } if buffer.IsEmpty() { buffer.Release() return nil, nil } if !endingDetected { buffer.Release() return nil, ErrHeaderToLong } return buffer, nil }
func (v *DataSegment) SetData(b []byte) { if v.Data == nil { v.Data = buf.NewSmall() } v.Data.Clear() v.Data.Append(b) }
func (r *UDPReader) Read() (*buf.Buffer, error) { b := buf.NewSmall() if err := b.AppendSupplier(buf.ReadFrom(r.reader)); err != nil { return nil, err } _, data, err := DecodeUDPPacket(b.Bytes()) if err != nil { return nil, err } b.Clear() b.Append(data) return b, nil }
func (v *UDPReader) Read() (*buf.Buffer, error) { buffer := buf.NewSmall() err := buffer.AppendSupplier(buf.ReadFrom(v.Reader)) if err != nil { buffer.Release() return nil, err } _, payload, err := DecodeUDPPacket(v.User, buffer) if err != nil { buffer.Release() return nil, err } return payload, nil }
func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) { if len(packet) < 5 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } request := new(Socks5UDPRequest) // packet[0] and packet[1] are reserved request.Fragment = packet[2] addrType := packet[3] var dataBegin int switch addrType { case AddrTypeIPv4: if len(packet) < 10 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } ip := packet[4:8] request.Port = v2net.PortFromBytes(packet[8:10]) request.Address = v2net.IPAddress(ip) dataBegin = 10 case AddrTypeIPv6: if len(packet) < 22 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } ip := packet[4:20] request.Port = v2net.PortFromBytes(packet[20:22]) request.Address = v2net.IPAddress(ip) dataBegin = 22 case AddrTypeDomain: domainLength := int(packet[4]) if len(packet) < 5+domainLength+2 { return nil, errors.New("Socks|UDP: Insufficient length of packet.") } domain := string(packet[5 : 5+domainLength]) request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2]) request.Address = v2net.ParseAddress(domain) dataBegin = 5 + domainLength + 2 default: return nil, errors.Format("Socks|UDP: Unknown address type %d", addrType) } if len(packet) > dataBegin { b := buf.NewSmall() b.Append(packet[dataBegin:]) request.Data = b } return request, nil }
func (v HttpAuthenticator) GetClientWriter() *HeaderWriter { header := buf.NewSmall() config := v.config.Request header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickUri(), config.GetFullVersion()}, " "))) header.AppendSupplier(writeCRLF) headers := config.PickHeaders() for _, h := range headers { header.AppendSupplier(serial.WriteString(h)) header.AppendSupplier(writeCRLF) } header.AppendSupplier(writeCRLF) return &HeaderWriter{ header: header, } }
func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf.Buffer, error) { user := request.User rawAccount, err := user.GetTypedAccount() if err != nil { return nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to parse account.") } account := rawAccount.(*ShadowsocksAccount) buffer := buf.NewSmall() ivLen := account.Cipher.IVSize() buffer.AppendSupplier(buf.ReadFullFrom(rand.Reader, ivLen)) iv := buffer.Bytes() switch request.Address.Family() { case v2net.AddressFamilyIPv4: buffer.AppendBytes(AddrTypeIPv4) buffer.Append([]byte(request.Address.IP())) case v2net.AddressFamilyIPv6: buffer.AppendBytes(AddrTypeIPv6) buffer.Append([]byte(request.Address.IP())) case v2net.AddressFamilyDomain: buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))) buffer.Append([]byte(request.Address.Domain())) default: return nil, errors.New("Shadowsocks|UDP: Unsupported address type: ", request.Address.Family()) } buffer.AppendSupplier(serial.WriteUint16(uint16(request.Port))) buffer.Append(payload.Bytes()) if request.Option.Has(RequestOptionOneTimeAuth) { authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv)) buffer.SetByte(ivLen, buffer.Byte(ivLen)|0x10) buffer.AppendSupplier(authenticator.Authenticate(buffer.BytesFrom(ivLen))) } stream, err := account.Cipher.NewEncodingStream(account.Key, iv) if err != nil { return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.") } stream.XORKeyStream(buffer.BytesFrom(ivLen), buffer.BytesFrom(ivLen)) return buffer, nil }
func (o *ClientConnection) Run() { payload := buf.NewSmall() defer payload.Release() for { err := payload.Reset(buf.ReadFrom(o.Conn)) if err != nil { payload.Release() return } o.RLock() if o.input != nil { segments := o.reader.Read(payload.Bytes()) if len(segments) > 0 { o.input(segments) } } o.RUnlock() } }
func formResponseHeader(config *ResponseConfig) *HeaderWriter { header := buf.NewSmall() header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.GetStatusValue().Code, config.GetStatusValue().Reason}, " "))) header.AppendSupplier(writeCRLF) headers := config.PickHeaders() for _, h := range headers { header.AppendSupplier(serial.WriteString(h)) header.AppendSupplier(writeCRLF) } if !config.HasHeader("Date") { header.AppendSupplier(serial.WriteString("Date: ")) header.AppendSupplier(serial.WriteString(time.Now().Format(http.TimeFormat))) header.AppendSupplier(writeCRLF) } header.AppendSupplier(writeCRLF) return &HeaderWriter{ header: header, } }
func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection) error { source := proxy.SourceFromContext(ctx) log.Info("Socks|Server: Client UDP connection from ", source) reader := buf.NewReader(conn) for { payload, err := reader.Read() if err != nil { return err } request, data, err := DecodeUDPPacket(payload.Bytes()) if err != nil { log.Info("Socks|Server: Failed to parse UDP request: ", err) continue } if len(data) == 0 { continue } log.Info("Socks: Send packet to ", request.Destination(), " with ", len(data), " bytes") log.Access(source, request.Destination, log.AccessAccepted, "") dataBuf := buf.NewSmall() dataBuf.Append(data) v.udpServer.Dispatch(ctx, request.Destination(), dataBuf, func(payload *buf.Buffer) { defer payload.Release() log.Info("Socks|Server: Writing back UDP response with ", payload.Len(), " bytes") udpMessage := EncodeUDPPacket(request, payload.Bytes()) defer udpMessage.Release() conn.Write(udpMessage.Bytes()) }) } }
func NewSegmentWriter(writer io.Writer) SegmentWriter { return &SimpleSegmentWriter{ writer: writer, buffer: buf.NewSmall(), } }