| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 | 
							- package shadowsocks
 
- import (
 
- 	"io"
 
- 	"github.com/v2ray/v2ray-core/common/alloc"
 
- 	"github.com/v2ray/v2ray-core/common/log"
 
- 	v2net "github.com/v2ray/v2ray-core/common/net"
 
- 	"github.com/v2ray/v2ray-core/common/serial"
 
- 	"github.com/v2ray/v2ray-core/transport"
 
- )
 
- const (
 
- 	AddrTypeIPv4   = 1
 
- 	AddrTypeIPv6   = 4
 
- 	AddrTypeDomain = 3
 
- )
 
- type Request struct {
 
- 	Address    v2net.Address
 
- 	Port       v2net.Port
 
- 	OTA        bool
 
- 	UDPPayload *alloc.Buffer
 
- }
 
- func ReadRequest(reader io.Reader, auth *Authenticator, udp bool) (*Request, error) {
 
- 	buffer := alloc.NewSmallBuffer()
 
- 	defer buffer.Release()
 
- 	_, err := io.ReadFull(reader, buffer.Value[:1])
 
- 	if err != nil {
 
- 		log.Error("Shadowsocks: Failed to read address type: ", err)
 
- 		return nil, transport.ErrorCorruptedPacket
 
- 	}
 
- 	lenBuffer := 1
 
- 	request := new(Request)
 
- 	addrType := (buffer.Value[0] & 0x0F)
 
- 	if (buffer.Value[0] & 0x10) == 0x10 {
 
- 		request.OTA = true
 
- 	}
 
- 	switch addrType {
 
- 	case AddrTypeIPv4:
 
- 		_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4])
 
- 		if err != nil {
 
- 			log.Error("Shadowsocks: Failed to read IPv4 address: ", err)
 
- 			return nil, transport.ErrorCorruptedPacket
 
- 		}
 
- 		request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4])
 
- 		lenBuffer += 4
 
- 	case AddrTypeIPv6:
 
- 		_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16])
 
- 		if err != nil {
 
- 			log.Error("Shadowsocks: Failed to read IPv6 address: ", err)
 
- 			return nil, transport.ErrorCorruptedPacket
 
- 		}
 
- 		request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16])
 
- 		lenBuffer += 16
 
- 	case AddrTypeDomain:
 
- 		_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1])
 
- 		if err != nil {
 
- 			log.Error("Shadowsocks: Failed to read domain lenth: ", err)
 
- 			return nil, transport.ErrorCorruptedPacket
 
- 		}
 
- 		domainLength := int(buffer.Value[lenBuffer])
 
- 		lenBuffer++
 
- 		_, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength])
 
- 		if err != nil {
 
- 			log.Error("Shadowsocks: Failed to read domain: ", err)
 
- 			return nil, transport.ErrorCorruptedPacket
 
- 		}
 
- 		request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength]))
 
- 		lenBuffer += domainLength
 
- 	default:
 
- 		log.Error("Shadowsocks: Unknown address type: ", addrType)
 
- 		return nil, transport.ErrorCorruptedPacket
 
- 	}
 
- 	_, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2])
 
- 	if err != nil {
 
- 		log.Error("Shadowsocks: Failed to read port: ", err)
 
- 		return nil, transport.ErrorCorruptedPacket
 
- 	}
 
- 	request.Port = v2net.PortFromBytes(buffer.Value[lenBuffer : lenBuffer+2])
 
- 	lenBuffer += 2
 
- 	var authBytes []byte
 
- 	if udp {
 
- 		nBytes, err := reader.Read(buffer.Value[lenBuffer:])
 
- 		if err != nil {
 
- 			log.Error("Shadowsocks: Failed to read UDP payload: ", err)
 
- 			return nil, transport.ErrorCorruptedPacket
 
- 		}
 
- 		buffer.Slice(0, lenBuffer+nBytes)
 
- 		if request.OTA {
 
- 			authBytes = buffer.Value[lenBuffer+nBytes-AuthSize:]
 
- 			request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer : lenBuffer+nBytes-AuthSize])
 
- 			lenBuffer = lenBuffer + nBytes - AuthSize
 
- 		} else {
 
- 			request.UDPPayload = alloc.NewSmallBuffer().Clear().Append(buffer.Value[lenBuffer:])
 
- 		}
 
- 	} else {
 
- 		if request.OTA {
 
- 			authBytes = buffer.Value[lenBuffer : lenBuffer+AuthSize]
 
- 			_, err = io.ReadFull(reader, authBytes)
 
- 			if err != nil {
 
- 				log.Error("Shadowsocks: Failed to read OTA: ", err)
 
- 				return nil, transport.ErrorCorruptedPacket
 
- 			}
 
- 		}
 
- 	}
 
- 	if request.OTA {
 
- 		actualAuth := auth.Authenticate(nil, buffer.Value[0:lenBuffer])
 
- 		if !serial.BytesLiteral(actualAuth).Equals(serial.BytesLiteral(authBytes)) {
 
- 			log.Error("Shadowsocks: Invalid OTA: ", actualAuth)
 
- 			return nil, transport.ErrorCorruptedPacket
 
- 		}
 
- 	}
 
- 	return request, nil
 
- }
 
 
  |