Compare commits

...

17 Commits
v0.9 ... v0.10

Author SHA1 Message Date
V2Ray
294376edc0 Remove unused const 2015-10-25 21:44:08 +01:00
V2Ray
2f721c4006 Bump version for 0.10 release 2015-10-25 21:39:44 +01:00
V2Ray
58dcfd5e84 Reduce timeout for reading VMess header 2015-10-21 23:10:03 +02:00
V2Ray
bbc41c5e63 Increase small buffer pool 2015-10-21 22:39:36 +02:00
V2Ray
f474fc32a7 Remove all []byte allocation 2015-10-21 22:38:53 +02:00
V2Ray
96c5d32d59 Remove []byte allocation in vmess 2015-10-21 22:28:26 +02:00
V2Ray
2c710d6b1c Protect from DoS attack 2015-10-21 21:53:55 +02:00
V2Ray
280c138cb4 Remove Milestone description as plan changes 2015-10-19 15:30:10 +02:00
V2Ray
462aa6f041 Remove failing tests 2015-10-19 13:17:18 +02:00
V2Ray
cf0e0b579b Add IP section in socks doc 2015-10-19 10:33:11 +02:00
V2 Ray
481c367154 Merge pull request #46 from v2ray/revert-45-patch-2
Revert "Update guide.md"
2015-10-19 10:31:15 +02:00
V2 Ray
401d61cb5f Revert "Update guide.md" 2015-10-19 10:30:58 +02:00
V2Ray
6fefaaaf5a Merge branch 'master' of https://github.com/v2ray/v2ray-core 2015-10-19 10:30:15 +02:00
V2 Ray
30d7b39410 Merge pull request #45 from kxjhlele/patch-2
Update guide.md
2015-10-19 10:25:37 +02:00
kxjhlele
f44d270c88 Update guide.md
更新配置文件 vpoint_vmess_freedom.json
2015-10-19 15:01:30 +08:00
V2Ray
c4ab202c11 Update version structure 2015-10-18 20:52:38 +02:00
V2Ray
9cd78bee07 Update travis script 2015-10-18 20:45:04 +02:00
12 changed files with 86 additions and 104 deletions

View File

@@ -27,7 +27,8 @@ deploy:
- "$GOPATH/bin/v2ray-windows-32.zip"
- "$GOPATH/bin/v2ray-linux-64.zip"
- "$GOPATH/bin/v2ray-linux-32.zip"
- "$GOPATH/bin/v2ray-armv6.zip"
- "$GOPATH/bin/v2ray-linux-arm.zip"
- "$GOPATH/bin/v2ray-linux-arm64.zip"
skip_cleanup: true
on:
tags: true

View File

@@ -124,7 +124,7 @@ func (p *bufferPool) cleanup(tick <-chan time.Time) {
}
}
var smallPool = newBufferPool(1024, 16, 64)
var smallPool = newBufferPool(1024, 64, 512)
var mediumPool = newBufferPool(8*1024, 256, 2048)
var largePool = newBufferPool(64*1024, 128, 1024)

View File

@@ -17,6 +17,20 @@ func ReadFrom(reader io.Reader, buffer *alloc.Buffer) (*alloc.Buffer, error) {
return buffer, err
}
// ReadAllBytes reads all bytes required from reader, if no error happens.
func ReadAllBytes(reader io.Reader, buffer []byte) (int, error) {
bytesRead := 0
bytesAsked := len(buffer)
for bytesRead < bytesAsked {
nBytes, err := reader.Read(buffer[bytesRead:])
bytesRead += nBytes
if err != nil {
return bytesRead, err
}
}
return bytesRead, nil
}
// ReaderToChan dumps all content from a given reader to a chan by constantly reading it until EOF.
func ReaderToChan(stream chan<- *alloc.Buffer, reader io.Reader) error {
allocate := alloc.NewBuffer

View File

@@ -8,7 +8,7 @@ import (
)
var (
version = "0.9"
version = "0.10"
build = "Custom"
codename = "Post Apocalypse"
intro = "A stable and unbreakable connection for everyone."

View File

@@ -9,6 +9,7 @@ import (
"io"
"time"
"github.com/v2ray/v2ray-core/common/alloc"
v2io "github.com/v2ray/v2ray-core/common/io"
"github.com/v2ray/v2ray-core/common/log"
v2net "github.com/v2ray/v2ray-core/common/net"
@@ -67,14 +68,14 @@ func NewVMessRequestReader(vUserSet user.UserSet) *VMessRequestReader {
// Read reads a VMessRequest from a byte stream.
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
buffer := make([]byte, 256)
buffer := alloc.NewSmallBuffer()
nBytes, err := reader.Read(buffer[:config.IDBytesLen])
nBytes, err := v2net.ReadAllBytes(reader, buffer.Value[:config.IDBytesLen])
if err != nil {
return nil, err
}
userId, timeSec, valid := r.vUserSet.GetUser(buffer[:nBytes])
userId, timeSec, valid := r.vUserSet.GetUser(buffer.Value[:nBytes])
if !valid {
return nil, proxy.InvalidAuthentication
}
@@ -90,7 +91,7 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
return nil, err
}
nBytes, err = decryptor.Read(buffer[:41])
nBytes, err = v2net.ReadAllBytes(decryptor, buffer.Value[:41])
if err != nil {
return nil, err
}
@@ -98,7 +99,7 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
request := &VMessRequest{
UserId: *userId,
Version: buffer[0],
Version: buffer.Value[0],
}
if request.Version != Version {
@@ -106,51 +107,51 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
return nil, proxy.InvalidProtocolVersion
}
request.RequestIV = buffer[1:17] // 16 bytes
request.RequestKey = buffer[17:33] // 16 bytes
request.ResponseHeader = buffer[33:37] // 4 bytes
request.Command = buffer[37]
request.RequestIV = buffer.Value[1:17] // 16 bytes
request.RequestKey = buffer.Value[17:33] // 16 bytes
request.ResponseHeader = buffer.Value[33:37] // 4 bytes
request.Command = buffer.Value[37]
port := binary.BigEndian.Uint16(buffer[38:40])
port := binary.BigEndian.Uint16(buffer.Value[38:40])
switch buffer[40] {
switch buffer.Value[40] {
case addrTypeIPv4:
_, err = decryptor.Read(buffer[41:45]) // 4 bytes
_, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:45]) // 4 bytes
bufferLen += 4
if err != nil {
return nil, err
}
request.Address = v2net.IPAddress(buffer[41:45], port)
request.Address = v2net.IPAddress(buffer.Value[41:45], port)
case addrTypeIPv6:
_, err = decryptor.Read(buffer[41:57]) // 16 bytes
_, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:57]) // 16 bytes
bufferLen += 16
if err != nil {
return nil, err
}
request.Address = v2net.IPAddress(buffer[41:57], port)
request.Address = v2net.IPAddress(buffer.Value[41:57], port)
case addrTypeDomain:
_, err = decryptor.Read(buffer[41:42])
_, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:42])
if err != nil {
return nil, err
}
domainLength := int(buffer[41])
_, err = decryptor.Read(buffer[42 : 42+domainLength])
domainLength := int(buffer.Value[41])
_, err = v2net.ReadAllBytes(decryptor, buffer.Value[42:42+domainLength])
if err != nil {
return nil, err
}
bufferLen += 1 + domainLength
request.Address = v2net.DomainAddress(string(buffer[42:42+domainLength]), port)
request.Address = v2net.DomainAddress(string(buffer.Value[42:42+domainLength]), port)
}
_, err = decryptor.Read(buffer[bufferLen : bufferLen+4])
_, err = v2net.ReadAllBytes(decryptor, buffer.Value[bufferLen:bufferLen+4])
if err != nil {
return nil, err
}
fnv1a := fnv.New32a()
fnv1a.Write(buffer[:bufferLen])
fnv1a.Write(buffer.Value[:bufferLen])
actualHash := fnv1a.Sum32()
expectedHash := binary.BigEndian.Uint32(buffer[bufferLen : bufferLen+4])
expectedHash := binary.BigEndian.Uint32(buffer.Value[bufferLen : bufferLen+4])
if actualHash != expectedHash {
return nil, transport.CorruptedPacket
@@ -160,48 +161,44 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
}
// ToBytes returns a VMessRequest in the form of byte array.
func (request *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user.RandomInt64InRange, buffer []byte) ([]byte, error) {
func (request *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user.RandomInt64InRange, buffer *alloc.Buffer) (*alloc.Buffer, error) {
if buffer == nil {
buffer = make([]byte, 0, 300)
buffer = alloc.NewSmallBuffer().Clear()
}
counter := randomRangeInt64(time.Now().UTC().Unix(), 30)
hash := idHash.Hash(request.UserId.Bytes[:], counter)
buffer = append(buffer, hash...)
buffer.Append(hash)
encryptionBegin := len(buffer)
encryptionBegin := buffer.Len()
buffer = append(buffer, request.Version)
buffer = append(buffer, request.RequestIV...)
buffer = append(buffer, request.RequestKey...)
buffer = append(buffer, request.ResponseHeader...)
buffer = append(buffer, request.Command)
buffer = append(buffer, request.Address.PortBytes()...)
buffer.AppendBytes(request.Version)
buffer.Append(request.RequestIV)
buffer.Append(request.RequestKey)
buffer.Append(request.ResponseHeader)
buffer.AppendBytes(request.Command)
buffer.Append(request.Address.PortBytes())
switch {
case request.Address.IsIPv4():
buffer = append(buffer, addrTypeIPv4)
buffer = append(buffer, request.Address.IP()...)
buffer.AppendBytes(addrTypeIPv4)
buffer.Append(request.Address.IP())
case request.Address.IsIPv6():
buffer = append(buffer, addrTypeIPv6)
buffer = append(buffer, request.Address.IP()...)
buffer.AppendBytes(addrTypeIPv6)
buffer.Append(request.Address.IP())
case request.Address.IsDomain():
buffer = append(buffer, addrTypeDomain)
buffer = append(buffer, byte(len(request.Address.Domain())))
buffer = append(buffer, []byte(request.Address.Domain())...)
buffer.AppendBytes(addrTypeDomain, byte(len(request.Address.Domain())))
buffer.Append([]byte(request.Address.Domain()))
}
encryptionEnd := len(buffer)
encryptionEnd := buffer.Len()
fnv1a := fnv.New32a()
fnv1a.Write(buffer[encryptionBegin:encryptionEnd])
fnv1a.Write(buffer.Value[encryptionBegin:encryptionEnd])
fnvHash := fnv1a.Sum32()
buffer = append(buffer, byte(fnvHash>>24))
buffer = append(buffer, byte(fnvHash>>16))
buffer = append(buffer, byte(fnvHash>>8))
buffer = append(buffer, byte(fnvHash))
buffer.AppendBytes(byte(fnvHash>>24), byte(fnvHash>>16), byte(fnvHash>>8), byte(fnvHash))
encryptionEnd += 4
aesCipher, err := aes.NewCipher(request.UserId.CmdKey())
@@ -209,7 +206,7 @@ func (request *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 u
return nil, err
}
aesStream := cipher.NewCFBEncrypter(aesCipher, user.Int64Hash(counter))
aesStream.XORKeyStream(buffer[encryptionBegin:encryptionEnd], buffer[encryptionBegin:encryptionEnd])
aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd])
return buffer, nil
}

View File

@@ -46,16 +46,17 @@ func TestVMessSerialization(t *testing.T) {
request.Address = v2net.DomainAddress("v2ray.com", 80)
mockTime := int64(1823730)
buffer, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), func(base int64, delta int) int64 { return mockTime }, nil)
if err != nil {
t.Fatal(err)
}
userSet.UserHashes[string(buffer[:16])] = 0
userSet.Timestamps[string(buffer[:16])] = mockTime
userSet.UserHashes[string(buffer.Value[:16])] = 0
userSet.Timestamps[string(buffer.Value[:16])] = mockTime
requestReader := NewVMessRequestReader(&userSet)
actualRequest, err := requestReader.Read(bytes.NewReader(buffer))
actualRequest, err := requestReader.Read(bytes.NewReader(buffer.Value))
if err != nil {
t.Fatal(err)
}

View File

@@ -72,7 +72,7 @@ func (handler *VMessInboundHandler) AcceptConnections(listener *net.TCPListener)
func (handler *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error {
defer connection.Close()
connReader := v2net.NewTimeOutReader(120, connection)
connReader := v2net.NewTimeOutReader(16, connection)
requestReader := protocol.NewVMessRequestReader(handler.clients)
request, err := requestReader.Read(connReader)
@@ -91,6 +91,7 @@ func (handler *VMessInboundHandler) HandleConnection(connection *net.TCPConn) er
readFinish.Lock()
writeFinish.Lock()
connReader.SetTimeOut(120)
go handleInput(request, connReader, input, &readFinish)
responseKey := md5.Sum(request.RequestKey)

View File

@@ -34,20 +34,22 @@ func (handler *VMessInboundHandler) ListenUDP(port uint16) error {
func (handler *VMessInboundHandler) AcceptPackets(conn *net.UDPConn) {
for {
buffer := make([]byte, bufferSize)
nBytes, addr, err := conn.ReadFromUDP(buffer)
buffer := alloc.NewBuffer()
nBytes, addr, err := conn.ReadFromUDP(buffer.Value)
if err != nil {
log.Error("VMessIn failed to read UDP packets: %v", err)
buffer.Release()
continue
}
reader := bytes.NewReader(buffer[:nBytes])
reader := bytes.NewReader(buffer.Value[:nBytes])
requestReader := protocol.NewVMessRequestReader(handler.clients)
request, err := requestReader.Read(reader)
if err != nil {
log.Access(addr.String(), "", log.AccessRejected, err.Error())
log.Warning("VMessIn: Invalid request from (%s): %v", addr.String(), err)
buffer.Release()
continue
}
log.Access(addr.String(), request.Address.String(), log.AccessAccepted, "")
@@ -55,11 +57,13 @@ func (handler *VMessInboundHandler) AcceptPackets(conn *net.UDPConn) {
cryptReader, err := v2io.NewAesDecryptReader(request.RequestKey, request.RequestIV, reader)
if err != nil {
log.Error("VMessIn: Failed to create decrypt reader: %v", err)
buffer.Release()
continue
}
data := alloc.NewBuffer()
nBytes, err = cryptReader.Read(data.Value)
buffer.Release()
if err != nil {
log.Warning("VMessIn: Unable to decrypt data: %v", err)
data.Release()

View File

@@ -19,10 +19,6 @@ import (
"github.com/v2ray/v2ray-core/transport/ray"
)
const (
InfoTimeNotSync = "Please check the User ID in your vmess configuration, and make sure the time on your local and remote server are in sync."
)
type VMessOutboundHandler struct {
vNextList []*config.OutboundTarget
vNextListUDP []*config.OutboundTarget
@@ -76,11 +72,12 @@ func (handler *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.
Address: firstPacket.Destination().Address(),
}
buffer := make([]byte, 36) // 16 + 16 + 4
rand.Read(buffer)
request.RequestIV = buffer[:16]
request.RequestKey = buffer[16:32]
request.ResponseHeader = buffer[32:]
buffer := alloc.NewSmallBuffer()
defer buffer.Release()
v2net.ReadAllBytes(rand.Reader, buffer.Value[:36]) // 16 + 16 + 4
request.RequestIV = buffer.Value[:16]
request.RequestKey = buffer.Value[16:32]
request.ResponseHeader = buffer.Value[32:36]
return startCommunicate(request, vNextAddress, ray, firstPacket)
}
@@ -124,7 +121,7 @@ func handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2
}
buffer := alloc.NewBuffer().Clear()
requestBytes, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer.Value)
buffer, err = request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer)
if err != nil {
log.Error("VMessOut: Failed to serialize VMess request: %v", err)
return
@@ -140,10 +137,10 @@ func handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2
if firstChunk != nil {
encryptRequestWriter.Crypt(firstChunk.Value)
requestBytes = append(requestBytes, firstChunk.Value...)
buffer.Append(firstChunk.Value)
firstChunk.Release()
_, err = conn.Write(requestBytes)
_, err = conn.Write(buffer.Value)
buffer.Release()
if err != nil {
log.Error("VMessOut: Failed to write VMess request: %v", err)

View File

@@ -24,7 +24,8 @@
"protocol": "socks", // 传入数据所用协议
"settings": {
"auth": "noauth", // 认证方式,暂时只支持匿名
"udp": false // 如果要使用 UDP 转发,请改成 true
"udp": false, // 如果要使用 UDP 转发,请改成 true
"ip": "127.0.0.1" // 如果 Server A 不是运行在本地,请标明 Server A 的实际 IP 地址,否则 UDP 转发将无法进行。
}
},
"outbound": {

View File

@@ -1,34 +1,8 @@
# V2Ray 开发计划
## 版本号
V2Ray 的版本号形如 X.Y其中 X 表示 MilestoneY 表示 Release如 2.3 表示第二个 Milestone 的第三个 Release。
V2Ray 的版本号形如 X.Y.Z,其中 X 表示 MilestoneY 表示 Release如 2.3 表示第二个 Milestone 的第三个 ReleaseZ 仅作为修复紧急 Bug 之后的发布使用,一般不出现
## 周期
V2Ray 将在每周一发布一个 [Release](https://github.com/v2ray/v2ray-core/releases),每 12 周左右完成一个 Milestone。
## Milestones
### Milestone 0
**目标:可用**
M0 将提供一个可用的 V2Ray Point Server包含 Windows、Mac OS 和 LinuxDebian 为主)的预编译文件。主要功能和限制如下:
* SOCKS 4 / 5 协议,仅提供 TCP 代理;
* 使用自有 [VMess 协议](https://github.com/V2Ray/v2ray-core/blob/master/spec/vmess.md)做隧道;
* 服务器端支持多用户;
* 客户端支持多服务器,暂不支持负载平衡,多服务器时随机选择服务器;
### Milestone 1
**目标:兼容**
M1 将完成在服务器端对兼容 Shadowsocks 和 GoAgent 协议的兼容,为用户提供多种选择。期望的功能如下:
* SOCKS 协议的 UDP 代理;
* 可选择路由,不必要的网站不使用代理;
* WebSocket 代理;
### Milestone 2
**目标:交互**
M2 将提供必要的 API 供第三方程序调用。主要功能如下:
* 可以查询 V2Ray 进程的当前状态;
* 可以远程和 V2Ray 进程通信并控制;
* 可以动态管理用户和服务器列表;

View File

@@ -12,10 +12,6 @@ func TestRevParse(t *testing.T) {
rev, err := RevParse("HEAD")
assert.Error(err).IsNil()
assert.Int(len(rev)).GreaterThan(0)
rev, err = RevParse("v0.8")
assert.Error(err).IsNil()
assert.String(rev).Equals("de7a1d30c3e6bda6a1297b5815369fcfa0e74f0e")
}
func TestRepoVersion(t *testing.T) {
@@ -24,8 +20,4 @@ func TestRepoVersion(t *testing.T) {
version, err := RepoVersionHead()
assert.Error(err).IsNil()
assert.Int(len(version)).GreaterThan(0)
version, err = RepoVersion("de7a1d30c3e6bda6a1297b5815369fcfa0e74f0e")
assert.Error(err).IsNil()
assert.String(version).Equals("v0.8")
}