コード例 #1
0
ファイル: ota_test.go プロジェクト: v2ray/v2ray-core
func TestNormalChunkWriting(t *testing.T) {
	assert := assert.On(t)

	buffer := buf.NewLocal(512)
	writer := NewChunkWriter(buffer, NewAuthenticator(ChunkKeyGenerator(
		[]byte{21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36})))

	b := buf.NewLocal(256)
	b.Append([]byte{11, 12, 13, 14, 15, 16, 17, 18})
	err := writer.Write(b)
	assert.Error(err).IsNil()
	assert.Bytes(buffer.Bytes()).Equals([]byte{0, 8, 39, 228, 69, 96, 133, 39, 254, 26, 201, 70, 11, 12, 13, 14, 15, 16, 17, 18})
}
コード例 #2
0
ファイル: default.go プロジェクト: v2ray/v2ray-core
func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
	direct := ray.NewRay()
	dispatcher := v.ohm.GetDefaultHandler()
	destination := session.Destination

	if v.router != nil {
		if tag, err := v.router.TakeDetour(session); err == nil {
			if handler := v.ohm.GetHandler(tag); handler != nil {
				log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
				dispatcher = handler
			} else {
				log.Warning("DefaultDispatcher: Nonexisting tag: ", tag)
			}
		} else {
			log.Info("DefaultDispatcher: Default route for ", destination)
		}
	}

	if session.Inbound != nil && session.Inbound.AllowPassiveConnection {
		go dispatcher.Dispatch(destination, buf.NewLocal(32), direct)
	} else {
		go v.FilterPacketAndDispatch(destination, direct, dispatcher)
	}

	return direct
}
コード例 #3
0
ファイル: socks_test.go プロジェクト: v2ray/v2ray-core
func TestResponseWrite(t *testing.T) {
	assert := assert.On(t)

	response := Socks5Response{
		socksVersion,
		ErrorSuccess,
		AddrTypeIPv4,
		[4]byte{0x72, 0x72, 0x72, 0x72},
		"",
		[16]byte{},
		v2net.Port(53),
	}
	buffer := buf.NewLocal(2048)
	defer buffer.Release()

	response.Write(buffer)
	expectedBytes := []byte{
		socksVersion,
		ErrorSuccess,
		byte(0x00),
		AddrTypeIPv4,
		0x72, 0x72, 0x72, 0x72,
		byte(0x00), byte(0x035),
	}
	assert.Bytes(buffer.Bytes()).Equals(expectedBytes)
}
コード例 #4
0
ファイル: segment_test.go プロジェクト: ylywyn/v2ray-core
func Test1ByteDataSegment(t *testing.T) {
	assert := assert.On(t)

	b := buf.NewLocal(512)
	b.AppendBytes('a')
	seg := &DataSegment{
		Conv:        1,
		Timestamp:   3,
		Number:      4,
		SendingNext: 5,
		Data:        b,
	}

	nBytes := seg.ByteSize()
	bytes := make([]byte, nBytes)
	seg.Bytes()(bytes)

	assert.Int(len(bytes)).Equals(nBytes)

	iseg, _ := ReadSegment(bytes)
	seg2 := iseg.(*DataSegment)
	assert.Uint16(seg2.Conv).Equals(seg.Conv)
	assert.Uint32(seg2.Timestamp).Equals(seg.Timestamp)
	assert.Uint32(seg2.SendingNext).Equals(seg.SendingNext)
	assert.Uint32(seg2.Number).Equals(seg.Number)
	assert.Bytes(seg2.Data.Bytes()).Equals(seg.Data.Bytes())
}
コード例 #5
0
ファイル: socks.go プロジェクト: v2ray/v2ray-core
func ReadUserPassRequest(reader io.Reader) (request Socks5UserPassRequest, err error) {
	buffer := buf.NewLocal(512)
	defer buffer.Release()

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2))
	if err != nil {
		return
	}
	request.version = buffer.Byte(0)
	nUsername := int(buffer.Byte(1))

	buffer.Clear()
	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, nUsername))
	if err != nil {
		return
	}
	request.username = buffer.String()

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
	if err != nil {
		return
	}
	nPassword := int(buffer.Byte(0))
	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, nPassword))
	if err != nil {
		return
	}
	request.password = buffer.String()
	return
}
コード例 #6
0
ファイル: ota.go プロジェクト: v2ray/v2ray-core
func (v *ChunkReader) Read() (*buf.Buffer, error) {
	buffer := buf.New()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(v.reader, 2)); err != nil {
		buffer.Release()
		return nil, err
	}
	// There is a potential buffer overflow here. Large buffer is 64K bytes,
	// while uin16 + 10 will be more than that
	length := serial.BytesToUint16(buffer.BytesTo(2)) + AuthSize
	if length > buf.Size {
		// Theoretically the size of a chunk is 64K, but most Shadowsocks implementations used <4K buffer.
		buffer.Release()
		buffer = buf.NewLocal(int(length) + 128)
	}

	buffer.Clear()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(v.reader, int(length))); err != nil {
		buffer.Release()
		return nil, err
	}

	authBytes := buffer.BytesTo(AuthSize)
	payload := buffer.BytesFrom(AuthSize)

	actualAuthBytes := make([]byte, AuthSize)
	v.auth.Authenticate(payload)(actualAuthBytes)
	if !bytes.Equal(authBytes, actualAuthBytes) {
		buffer.Release()
		return nil, errors.New("Shadowsocks|AuthenticationReader: Invalid auth.")
	}
	buffer.SliceFrom(AuthSize)

	return buffer, nil
}
コード例 #7
0
ファイル: protocol_test.go プロジェクト: v2ray/v2ray-core
func TestUDPEncoding(t *testing.T) {
	assert := assert.On(t)

	request := &protocol.RequestHeader{
		Version: Version,
		Command: protocol.RequestCommandUDP,
		Address: v2net.LocalHostIP,
		Port:    1234,
		User: &protocol.User{
			Email: "*****@*****.**",
			Account: serial.ToTypedMessage(&Account{
				Password:   "******",
				CipherType: CipherType_AES_128_CFB,
				Ota:        Account_Disabled,
			}),
		},
	}

	data := buf.NewLocal(256)
	data.AppendSupplier(serial.WriteString("test string"))
	encodedData, err := EncodeUDPPacket(request, data)
	assert.Error(err).IsNil()

	decodedRequest, decodedData, err := DecodeUDPPacket(request.User, encodedData)
	assert.Error(err).IsNil()
	assert.Bytes(decodedData.Bytes()).Equals(data.Bytes())
	assert.Address(decodedRequest.Address).Equals(request.Address)
	assert.Port(decodedRequest.Port).Equals(request.Port)
}
コード例 #8
0
ファイル: commands.go プロジェクト: ylywyn/v2ray-core
func MarshalCommand(command interface{}, writer io.Writer) error {
	if command == nil {
		return ErrUnknownCommand
	}

	var cmdID byte
	var factory CommandFactory
	switch command.(type) {
	case *protocol.CommandSwitchAccount:
		factory = new(CommandSwitchAccountFactory)
		cmdID = 1
	default:
		return ErrUnknownCommand
	}

	buffer := buf.NewLocal(512)
	defer buffer.Release()

	err := factory.Marshal(command, buffer)
	if err != nil {
		return err
	}

	auth := Authenticate(buffer.Bytes())
	len := buffer.Len() + 4
	if len > 255 {
		return ErrCommandTooLarge
	}

	writer.Write([]byte{cmdID, byte(len), byte(auth >> 24), byte(auth >> 16), byte(auth >> 8), byte(auth)})
	writer.Write(buffer.Bytes())
	return nil
}
コード例 #9
0
ファイル: reader.go プロジェクト: ylywyn/v2ray-core
// NewReader creates a new BufferedReader based on an io.Reader.
func NewReader(rawReader io.Reader) *BufferedReader {
	return &BufferedReader{
		reader:   rawReader,
		buffer:   buf.NewLocal(1024),
		buffered: true,
	}
}
コード例 #10
0
ファイル: outbound.go プロジェクト: v2ray/v2ray-core
func (v *VMessOutboundHandler) handleRequest(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, payload *buf.Buffer, input buf.Reader, finish *sync.Mutex) {
	defer finish.Unlock()

	writer := bufio.NewWriter(conn)
	defer writer.Release()
	session.EncodeRequestHeader(request, writer)

	bodyWriter := session.EncodeRequestBody(request, writer)
	defer bodyWriter.Release()

	if !payload.IsEmpty() {
		if err := bodyWriter.Write(payload); err != nil {
			log.Info("VMess|Outbound: Failed to write payload. Disabling connection reuse.", err)
			conn.SetReusable(false)
		}
		payload.Release()
	}
	writer.SetCached(false)

	if err := buf.PipeUntilEOF(input, bodyWriter); err != nil {
		conn.SetReusable(false)
	}

	if request.Option.Has(protocol.RequestOptionChunkStream) {
		err := bodyWriter.Write(buf.NewLocal(8))
		if err != nil {
			conn.SetReusable(false)
		}
	}
	return
}
コード例 #11
0
ファイル: protocol.go プロジェクト: ylywyn/v2ray-core
func readUsernamePassword(reader io.Reader) (string, string, error) {
	buffer := buf.NewLocal(512)
	defer buffer.Release()

	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
		return "", "", err
	}
	nUsername := int(buffer.Byte(1))

	buffer.Clear()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nUsername)); err != nil {
		return "", "", err
	}
	username := buffer.String()
	buffer.Clear()

	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)); err != nil {
		return "", "", err
	}
	nPassword := int(buffer.Byte(0))
	buffer.Clear()
	if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nPassword)); err != nil {
		return "", "", err
	}
	password := buffer.String()
	return username, password, nil
}
コード例 #12
0
ファイル: inbound.go プロジェクト: ylywyn/v2ray-core
func transferResponse(session *encoding.ServerSession, request *protocol.RequestHeader, response *protocol.ResponseHeader, input ray.InputStream, output io.Writer) error {
	session.EncodeResponseHeader(response, output)

	bodyWriter := session.EncodeResponseBody(request, output)

	// Optimize for small response packet
	data, err := input.Read()
	if err != nil {
		return err
	}

	if err := bodyWriter.Write(data); err != nil {
		return err
	}
	data.Release()

	if bufferedWriter, ok := output.(*bufio.BufferedWriter); ok {
		if err := bufferedWriter.SetBuffered(false); err != nil {
			return err
		}
	}

	if err := buf.PipeUntilEOF(input, bodyWriter); err != nil {
		return err
	}

	if request.Option.Has(protocol.RequestOptionChunkStream) {
		if err := bodyWriter.Write(buf.NewLocal(8)); err != nil {
			return err
		}
	}

	return nil
}
コード例 #13
0
ファイル: writer.go プロジェクト: ylywyn/v2ray-core
// NewWriter creates a new BufferedWriter.
func NewWriter(rawWriter io.Writer) *BufferedWriter {
	return &BufferedWriter{
		writer:   rawWriter,
		buffer:   buf.NewLocal(1024),
		buffered: true,
	}
}
コード例 #14
0
ファイル: auth.go プロジェクト: ylywyn/v2ray-core
func NewAuthenticationReader(auth Authenticator, reader io.Reader, aggressive bool) *AuthenticationReader {
	return &AuthenticationReader{
		auth:       auth,
		buffer:     buf.NewLocal(readerBufferSize),
		reader:     reader,
		aggressive: aggressive,
	}
}
コード例 #15
0
ファイル: protocol.go プロジェクト: ylywyn/v2ray-core
func writeSocks4Response(writer io.Writer, errCode byte, address v2net.Address, port v2net.Port) error {
	buffer := buf.NewLocal(32)
	buffer.AppendBytes(0x00, errCode)
	buffer.AppendSupplier(serial.WriteUint16(port.Value()))
	buffer.Append(address.IP())
	_, err := writer.Write(buffer.Bytes())
	return err
}
コード例 #16
0
ファイル: protocol.go プロジェクト: ylywyn/v2ray-core
func writeSocks5Response(writer io.Writer, errCode byte, address v2net.Address, port v2net.Port) error {
	buffer := buf.NewLocal(64)
	buffer.AppendBytes(socks5Version, errCode, 0x00 /* reserved */)
	appendAddress(buffer, address, port)

	_, err := writer.Write(buffer.Bytes())
	return err
}
コード例 #17
0
ファイル: wechat_test.go プロジェクト: ylywyn/v2ray-core
func TestUTPWrite(t *testing.T) {
	assert := assert.On(t)

	video := VideoChat{}

	payload := buf.NewLocal(2048)
	payload.AppendSupplier(video.Write)

	assert.Int(payload.Len()).Equals(video.Size())
}
コード例 #18
0
ファイル: auth_test.go プロジェクト: v2ray/v2ray-core
func TestAuthenticationReaderWriterPartial(t *testing.T) {
	assert := assert.On(t)

	key := make([]byte, 16)
	rand.Read(key)
	block, err := aes.NewCipher(key)
	assert.Error(err).IsNil()

	aead, err := cipher.NewGCM(block)
	assert.Error(err).IsNil()

	payload := make([]byte, 8*1024)
	rand.Read(payload)

	cache := buf.NewLocal(16 * 1024)
	iv := make([]byte, 12)
	rand.Read(iv)

	writer := NewAuthenticationWriter(&AEADAuthenticator{
		AEAD: aead,
		NonceGenerator: &StaticBytesGenerator{
			Content: iv,
		},
		AdditionalDataGenerator: &NoOpBytesGenerator{},
	}, cache)

	nBytes, err := writer.Write(payload)
	assert.Error(err).IsNil()
	assert.Int(nBytes).Equals(len(payload))
	assert.Int(cache.Len()).GreaterThan(0)
	_, err = writer.Write([]byte{})
	assert.Error(err).IsNil()

	reader := NewAuthenticationReader(&AEADAuthenticator{
		AEAD: aead,
		NonceGenerator: &StaticBytesGenerator{
			Content: iv,
		},
		AdditionalDataGenerator: &NoOpBytesGenerator{},
	}, cache, false)

	actualPayload := make([]byte, 7*1024)
	nBytes, err = reader.Read(actualPayload)
	assert.Error(err).IsNil()
	assert.Int(nBytes).Equals(len(actualPayload))
	assert.Bytes(actualPayload[:nBytes]).Equals(payload[:nBytes])

	nBytes, err = reader.Read(actualPayload)
	assert.Error(err).IsNil()
	assert.Int(nBytes).Equals(len(payload) - len(actualPayload))
	assert.Bytes(actualPayload[:nBytes]).Equals(payload[7*1024:])

	_, err = reader.Read(actualPayload)
	assert.Error(err).Equals(io.EOF)
}
コード例 #19
0
ファイル: socks4_test.go プロジェクト: v2ray/v2ray-core
func TestSocks4AuthenticationResponseToBytes(t *testing.T) {
	assert := assert.On(t)

	response := NewSocks4AuthenticationResponse(byte(0x10), 443, []byte{1, 2, 3, 4})

	buffer := buf.NewLocal(2048)
	defer buffer.Release()

	response.Write(buffer)
	assert.Bytes(buffer.Bytes()).Equals([]byte{0x00, 0x10, 0x01, 0xBB, 0x01, 0x02, 0x03, 0x04})
}
コード例 #20
0
ファイル: utp_test.go プロジェクト: v2ray/v2ray-core
func TestUTPWrite(t *testing.T) {
	assert := assert.On(t)

	content := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g'}
	utp := UTP{}

	payload := buf.NewLocal(2048)
	payload.AppendSupplier(utp.Write)
	payload.Append(content)

	assert.Int(payload.Len()).Equals(len(content) + utp.Size())
}
コード例 #21
0
ファイル: socks_test.go プロジェクト: v2ray/v2ray-core
func TestSetIPv6(t *testing.T) {
	assert := assert.On(t)

	response := NewSocks5Response()
	response.SetIPv6([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15})

	buffer := buf.NewLocal(2048)
	defer buffer.Release()
	response.Write(buffer)
	assert.Bytes(buffer.Bytes()).Equals([]byte{
		socksVersion, 0, 0, AddrTypeIPv6, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0})
}
コード例 #22
0
ファイル: socks_test.go プロジェクト: v2ray/v2ray-core
func TestSetDomain(t *testing.T) {
	assert := assert.On(t)

	response := NewSocks5Response()
	response.SetDomain("v2ray.com")

	buffer := buf.NewLocal(2048)
	defer buffer.Release()
	response.Write(buffer)
	assert.Bytes(buffer.Bytes()).Equals([]byte{
		socksVersion, 0, 0, AddrTypeDomain, 9, 118, 50, 114, 97, 121, 46, 99, 111, 109, 0, 0})
}
コード例 #23
0
ファイル: socks.go プロジェクト: v2ray/v2ray-core
func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
	buffer := buf.NewLocal(512)
	defer buffer.Release()

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 4))
	if err != nil {
		return
	}

	request = &Socks5Request{
		Version: buffer.Byte(0),
		Command: buffer.Byte(1),
		// buffer[2] is a reserved field
		AddrType: buffer.Byte(3),
	}
	switch request.AddrType {
	case AddrTypeIPv4:
		_, err = io.ReadFull(reader, request.IPv4[:])
		if err != nil {
			return
		}
	case AddrTypeDomain:
		buffer.Clear()
		err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
		if err != nil {
			return
		}
		domainLength := int(buffer.Byte(0))
		err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength))
		if err != nil {
			return
		}

		request.Domain = string(buffer.BytesFrom(-domainLength))
	case AddrTypeIPv6:
		_, err = io.ReadFull(reader, request.IPv6[:])
		if err != nil {
			return
		}
	default:
		err = errors.Format("Socks: Unexpected address type %d", request.AddrType)
		return
	}

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2))
	if err != nil {
		return
	}

	request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2))
	return
}
コード例 #24
0
ファイル: server_udp.go プロジェクト: v2ray/v2ray-core
func (v *Server) handleUDPPayload(payload *buf.Buffer, session *proxy.SessionInfo) {
	source := session.Source
	log.Info("Socks: Client UDP connection from ", source)
	request, err := protocol.ReadUDPRequest(payload.Bytes())
	payload.Release()

	if err != nil {
		log.Error("Socks: Failed to parse UDP request: ", err)
		return
	}
	if request.Data.Len() == 0 {
		request.Data.Release()
		return
	}
	if request.Fragment != 0 {
		log.Warning("Socks: Dropping fragmented UDP packets.")
		// TODO handle fragments
		request.Data.Release()
		return
	}

	log.Info("Socks: Send packet to ", request.Destination(), " with ", request.Data.Len(), " bytes")
	log.Access(source, request.Destination, log.AccessAccepted, "")
	v.udpServer.Dispatch(&proxy.SessionInfo{Source: source, Destination: request.Destination(), Inbound: v.meta}, request.Data, func(destination v2net.Destination, payload *buf.Buffer) {
		response := &protocol.Socks5UDPRequest{
			Fragment: 0,
			Address:  request.Destination().Address,
			Port:     request.Destination().Port,
			Data:     payload,
		}
		log.Info("Socks: Writing back UDP response with ", payload.Len(), " bytes to ", destination)

		udpMessage := buf.NewLocal(2048)
		response.Write(udpMessage)

		v.udpMutex.RLock()
		if !v.accepting {
			v.udpMutex.RUnlock()
			return
		}
		nBytes, err := v.udpHub.WriteTo(udpMessage.Bytes(), destination)
		v.udpMutex.RUnlock()
		udpMessage.Release()
		response.Data.Release()
		if err != nil {
			log.Error("Socks: failed to write UDP message (", nBytes, " bytes) to ", destination, ": ", err)
		}
	})
}
コード例 #25
0
ファイル: http_test.go プロジェクト: ylywyn/v2ray-core
func TestReaderWriter(t *testing.T) {
	assert := assert.On(t)

	cache := buf.New()
	b := buf.NewLocal(256)
	b.AppendSupplier(serial.WriteString("abcd" + ENDING))
	writer := NewHeaderWriter(b)
	err := writer.Write(cache)
	assert.Error(err).IsNil()
	assert.Int(cache.Len()).Equals(8)
	_, err = cache.Write([]byte{'e', 'f', 'g'})
	assert.Error(err).IsNil()

	reader := &HeaderReader{}
	buffer, err := reader.Read(cache)
	assert.Error(err).IsNil()
	assert.Bytes(buffer.Bytes()).Equals([]byte{'e', 'f', 'g'})
}
コード例 #26
0
ファイル: freedom_test.go プロジェクト: v2ray/v2ray-core
func TestSinglePacket(t *testing.T) {
	assert := assert.On(t)

	tcpServer := &tcp.Server{
		MsgProcessor: func(data []byte) []byte {
			buffer := make([]byte, 0, 2048)
			buffer = append(buffer, []byte("Processed: ")...)
			buffer = append(buffer, data...)
			return buffer
		},
	}
	_, err := tcpServer.Start()
	assert.Error(err).IsNil()

	space := app.NewSpace()
	freedom := NewFreedomConnection(
		&Config{},
		space,
		&proxy.OutboundHandlerMeta{
			Address: v2net.AnyIP,
			StreamSettings: &internet.StreamConfig{
				Network: v2net.Network_RawTCP,
			},
		})
	space.Initialize()

	traffic := ray.NewRay()
	data2Send := "Data to be sent to remote"
	payload := buf.NewLocal(2048)
	payload.Append([]byte(data2Send))

	go freedom.Dispatch(v2net.TCPDestination(v2net.LocalHostIP, tcpServer.Port), payload, traffic)
	traffic.InboundInput().Close()

	respPayload, err := traffic.InboundOutput().Read()
	assert.Error(err).IsNil()
	assert.String(respPayload.String()).Equals("Processed: Data to be sent to remote")

	tcpServer.Close()
}
コード例 #27
0
ファイル: writer_test.go プロジェクト: ylywyn/v2ray-core
func TestBufferedWriterLargePayload(t *testing.T) {
	assert := assert.On(t)

	content := buf.NewLocal(128 * 1024)

	writer := NewWriter(content)
	assert.Bool(writer.IsBuffered()).IsTrue()

	payload := make([]byte, 64*1024)
	rand.Read(payload)

	nBytes, err := writer.Write(payload[:512])
	assert.Int(nBytes).Equals(512)
	assert.Error(err).IsNil()

	assert.Bool(content.IsEmpty()).IsTrue()

	nBytes, err = writer.Write(payload[512:])
	assert.Error(err).IsNil()
	assert.Int(nBytes).Equals(64*1024 - 512)
	assert.Bytes(content.Bytes()).Equals(payload)
}
コード例 #28
0
ファイル: protocol_test.go プロジェクト: v2ray/v2ray-core
func TestTCPRequest(t *testing.T) {
	assert := assert.On(t)

	request := &protocol.RequestHeader{
		Version: Version,
		Command: protocol.RequestCommandTCP,
		Address: v2net.LocalHostIP,
		Option:  RequestOptionOneTimeAuth,
		Port:    1234,
		User: &protocol.User{
			Email: "*****@*****.**",
			Account: serial.ToTypedMessage(&Account{
				Password:   "******",
				CipherType: CipherType_CHACHA20,
			}),
		},
	}

	data := buf.NewLocal(256)
	data.AppendSupplier(serial.WriteString("test string"))
	cache := buf.New()

	writer, err := WriteTCPRequest(request, cache)
	assert.Error(err).IsNil()

	writer.Write(data)

	decodedRequest, reader, err := ReadTCPSession(request.User, cache)
	assert.Error(err).IsNil()
	assert.Address(decodedRequest.Address).Equals(request.Address)
	assert.Port(decodedRequest.Port).Equals(request.Port)

	decodedData, err := reader.Read()
	assert.Error(err).IsNil()
	assert.String(decodedData.String()).Equals("test string")
}
コード例 #29
0
ファイル: protocol.go プロジェクト: v2ray/v2ray-core
func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {
	rawAccount, err := user.GetTypedAccount()
	if err != nil {
		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
	}
	account := rawAccount.(*ShadowsocksAccount)

	buffer := buf.NewLocal(512)
	defer buffer.Release()

	ivLen := account.Cipher.IVSize()
	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, ivLen))
	if err != nil {
		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IV.")
	}

	iv := append([]byte(nil), buffer.BytesTo(ivLen)...)

	stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
	if err != nil {
		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to initialize decoding stream.")
	}
	reader = crypto.NewCryptionReader(stream, reader)

	authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
	request := &protocol.RequestHeader{
		Version: Version,
		User:    user,
		Command: protocol.RequestCommandTCP,
	}

	buffer.Clear()
	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
	if err != nil {
		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read address type.")
	}

	addrType := (buffer.Byte(0) & 0x0F)
	if (buffer.Byte(0) & 0x10) == 0x10 {
		request.Option |= RequestOptionOneTimeAuth
	}

	if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
		return nil, nil, errors.New("Shadowsocks|TCP: Rejecting connection with OTA enabled, while server disables OTA.")
	}

	if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
		return nil, nil, errors.New("Shadowsocks|TCP: Rejecting connection with OTA disabled, while server enables OTA.")
	}

	switch addrType {
	case AddrTypeIPv4:
		err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4))
		if err != nil {
			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv4 address.")
		}
		request.Address = v2net.IPAddress(buffer.BytesFrom(-4))
	case AddrTypeIPv6:
		err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16))
		if err != nil {
			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv6 address.")
		}
		request.Address = v2net.IPAddress(buffer.BytesFrom(-16))
	case AddrTypeDomain:
		err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
		if err != nil {
			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain lenth.")
		}
		domainLength := int(buffer.BytesFrom(-1)[0])
		err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength))
		if err != nil {
			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain.")
		}
		request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength)))
	default:
		// Check address validity after OTA verification.
	}

	err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2))
	if err != nil {
		return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read port.")
	}
	request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2))

	if request.Option.Has(RequestOptionOneTimeAuth) {
		actualAuth := make([]byte, AuthSize)
		authenticator.Authenticate(buffer.Bytes())(actualAuth)

		err := buffer.AppendSupplier(buf.ReadFullFrom(reader, AuthSize))
		if err != nil {
			return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read OTA.")
		}

		if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) {
			return nil, nil, errors.New("Shadowsocks|TCP: Invalid OTA")
		}
	}

	if request.Address == nil {
		return nil, nil, errors.New("Shadowsocks|TCP: Invalid remote address.")
	}

	var chunkReader buf.Reader
	if request.Option.Has(RequestOptionOneTimeAuth) {
		chunkReader = NewChunkReader(reader, NewAuthenticator(ChunkKeyGenerator(iv)))
	} else {
		chunkReader = buf.NewReader(reader)
	}

	return request, chunkReader, nil
}
コード例 #30
0
ファイル: protocol.go プロジェクト: v2ray/v2ray-core
func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {
	user := request.User
	rawAccount, err := user.GetTypedAccount()
	if err != nil {
		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
	}
	account := rawAccount.(*ShadowsocksAccount)

	iv := make([]byte, account.Cipher.IVSize())
	rand.Read(iv)
	_, err = writer.Write(iv)
	if err != nil {
		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write IV.")
	}

	stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
	if err != nil {
		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.")
	}

	writer = crypto.NewCryptionWriter(stream, writer)

	header := buf.NewLocal(512)

	switch request.Address.Family() {
	case v2net.AddressFamilyIPv4:
		header.AppendBytes(AddrTypeIPv4)
		header.Append([]byte(request.Address.IP()))
	case v2net.AddressFamilyIPv6:
		header.AppendBytes(AddrTypeIPv6)
		header.Append([]byte(request.Address.IP()))
	case v2net.AddressFamilyDomain:
		header.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
		header.Append([]byte(request.Address.Domain()))
	default:
		return nil, errors.New("Shadowsocks|TCP: Unsupported address type: ", request.Address.Family())
	}

	header.AppendSupplier(serial.WriteUint16(uint16(request.Port)))

	if request.Option.Has(RequestOptionOneTimeAuth) {
		header.SetByte(0, header.Byte(0)|0x10)

		authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
		header.AppendSupplier(authenticator.Authenticate(header.Bytes()))
	}

	_, err = writer.Write(header.Bytes())
	if err != nil {
		return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write header.")
	}

	var chunkWriter buf.Writer
	if request.Option.Has(RequestOptionOneTimeAuth) {
		chunkWriter = NewChunkWriter(writer, NewAuthenticator(ChunkKeyGenerator(iv)))
	} else {
		chunkWriter = buf.NewWriter(writer)
	}

	return chunkWriter, nil
}