Version 1.0 alpha

This commit is contained in:
V2Ray
2015-09-12 20:36:21 +02:00
parent f3a12e9f57
commit cc3fdb6ef4
21 changed files with 279 additions and 103 deletions
+9 -7
View File
@@ -2,10 +2,10 @@ package freedom
import (
"io"
"log"
"net"
"github.com/v2ray/v2ray-core"
"github.com/v2ray/v2ray-core/log"
v2net "github.com/v2ray/v2ray-core/net"
)
@@ -24,10 +24,9 @@ func (vconn *VFreeConnection) Start(vRay core.OutboundVRay) error {
output := vRay.OutboundOutput()
conn, err := net.Dial("tcp", vconn.dest.String())
if err != nil {
log.Print(err)
return err
return log.Error("Failed to open tcp: %s", vconn.dest.String())
}
log.Print("Working on tcp:" + vconn.dest.String())
log.Debug("Sending outbound tcp: %s", vconn.dest.String())
finish := make(chan bool, 2)
go vconn.DumpInput(conn, input, finish)
@@ -41,22 +40,25 @@ func (vconn *VFreeConnection) DumpInput(conn net.Conn, input <-chan []byte, fini
data, open := <-input
if !open {
finish <- true
log.Debug("Freedom finishing input.")
break
}
conn.Write(data)
nBytes, err := conn.Write(data)
log.Debug("Freedom wrote %d bytes with error %v", nBytes, err)
}
}
func (vconn *VFreeConnection) DumpOutput(conn net.Conn, output chan<- []byte, finish chan<- bool) {
for {
buffer := make([]byte, 128)
buffer := make([]byte, 512)
nBytes, err := conn.Read(buffer)
log.Debug("Freedom reading %d bytes with error %v", nBytes, err)
if err == io.EOF {
close(output)
finish <- true
log.Debug("Freedom finishing output.")
break
}
log.Print(buffer[:nBytes])
output <- buffer[:nBytes]
}
}
+4
View File
@@ -11,3 +11,7 @@ type FreedomFactory struct {
func (factory FreedomFactory) Create(vp *core.VPoint, config []byte, dest v2net.VAddress) (core.OutboundConnectionHandler, error) {
return NewVFreeConnection(dest), nil
}
func init() {
core.RegisterOutboundConnectionHandlerFactory("freedom", FreedomFactory{})
}
+16 -7
View File
@@ -37,8 +37,10 @@ func NewSocksServer(vp *core.VPoint, rawConfig []byte) *SocksServer {
func (server *SocksServer) Listen(port uint16) error {
listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
if err != nil {
return log.Error("Error on listening port %d: %v", port, err)
log.Error("Error on listening port %d: %v", port, err)
return err
}
log.Debug("Working on tcp:%d", port)
server.accepting = true
go server.AcceptConnections(listener)
return nil
@@ -48,7 +50,8 @@ func (server *SocksServer) AcceptConnections(listener net.Listener) error {
for server.accepting {
connection, err := listener.Accept()
if err != nil {
return log.Error("Error on accepting socks connection: %v", err)
log.Error("Error on accepting socks connection: %v", err)
return err
}
go server.HandleConnection(connection)
}
@@ -60,7 +63,8 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
auth, err := socksio.ReadAuthentication(connection)
if err != nil {
return log.Error("Error on reading authentication: %v", err)
log.Error("Error on reading authentication: %v", err)
return err
}
expectedAuthMethod := socksio.AuthNotRequired
@@ -76,12 +80,14 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
return ErrorAuthenticationFailed
}
log.Debug("Auth accepted, responding auth.")
authResponse := socksio.NewAuthenticationResponse(socksio.AuthNotRequired)
socksio.WriteAuthentication(connection, authResponse)
request, err := socksio.ReadRequest(connection)
if err != nil {
return log.Error("Error on reading socks request: %v", err)
log.Error("Error on reading socks request: %v", err)
return err
}
response := socksio.NewSocks5Response()
@@ -105,6 +111,7 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
case socksio.AddrTypeDomain:
response.Domain = request.Domain
}
log.Debug("Socks response port = %d", response.Port)
socksio.WriteResponse(connection, response)
ray := server.vPoint.NewInboundConnectionAccepted(request.Destination())
@@ -121,12 +128,13 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
func (server *SocksServer) dumpInput(conn net.Conn, input chan<- []byte, finish chan<- bool) {
for {
buffer := make([]byte, 256)
buffer := make([]byte, 512)
nBytes, err := conn.Read(buffer)
log.Debug("Reading %d bytes, with error %v", nBytes, err)
if err == io.EOF {
close(input)
finish <- true
log.Debug("Socks finishing input.")
break
}
input <- buffer[:nBytes]
@@ -138,10 +146,11 @@ func (server *SocksServer) dumpOutput(conn net.Conn, output <-chan []byte, finis
buffer, open := <-output
if !open {
finish <- true
log.Debug("Socks finishing output")
break
}
nBytes, _ := conn.Write(buffer)
log.Debug("Writing %d bytes", nBytes)
nBytes, err := conn.Write(buffer)
log.Debug("Writing %d bytes with error %v", nBytes, err)
}
}
+19 -19
View File
@@ -11,29 +11,29 @@ import (
func TestSocksTcpConnect(t *testing.T) {
t.Skip("Not ready yet.")
/*
assert := unit.Assert(t)
/*
assert := unit.Assert(t)
port := uint16(12384)
port := uint16(12384)
uuid := "2418d087-648d-4990-86e8-19dca1d006d3"
vid, err := core.UUIDToVID(uuid)
assert.Error(err).IsNil()
uuid := "2418d087-648d-4990-86e8-19dca1d006d3"
vid, err := core.UUIDToVID(uuid)
assert.Error(err).IsNil()
config := core.VConfig{
port,
[]core.VUser{core.VUser{vid}},
"",
[]core.VNext{}}
config := core.VConfig{
port,
[]core.VUser{core.VUser{vid}},
"",
[]core.VNext{}}
och := new(mocks.FakeOutboundConnectionHandler)
och.Data2Send = bytes.NewBuffer(make([]byte, 1024))
och.Data2Return = []byte("The data to be returned to socks server.")
och := new(mocks.FakeOutboundConnectionHandler)
och.Data2Send = bytes.NewBuffer(make([]byte, 1024))
och.Data2Return = []byte("The data to be returned to socks server.")
vpoint, err := core.NewVPoint(&config, SocksServerFactory{}, och)
assert.Error(err).IsNil()
vpoint, err := core.NewVPoint(&config, SocksServerFactory{}, och)
assert.Error(err).IsNil()
err = vpoint.Start()
assert.Error(err).IsNil()
*/
err = vpoint.Start()
assert.Error(err).IsNil()
*/
}
+4
View File
@@ -10,3 +10,7 @@ type SocksServerFactory struct {
func (factory SocksServerFactory) Create(vp *core.VPoint, config []byte) (core.InboundConnectionHandler, error) {
return NewSocksServer(vp, config), nil
}
func init() {
core.RegisterInboundConnectionHandlerFactory("socks", SocksServerFactory{})
}
+25 -6
View File
@@ -4,11 +4,22 @@ import (
"encoding/json"
"github.com/v2ray/v2ray-core"
"github.com/v2ray/v2ray-core/log"
v2net "github.com/v2ray/v2ray-core/net"
)
type VMessUser struct {
Id string `json:"id"`
Email string `json:"email"`
}
func (u *VMessUser) ToVUser() (core.VUser, error) {
id, err := core.UUIDToVID(u.Id)
return core.VUser{id}, err
}
type VMessInboundConfig struct {
AllowedClients []core.VUser `json:"clients"`
AllowedClients []VMessUser `json:"clients"`
}
func loadInboundConfig(rawConfig []byte) (VMessInboundConfig, error) {
@@ -18,19 +29,27 @@ func loadInboundConfig(rawConfig []byte) (VMessInboundConfig, error) {
}
type VNextConfig struct {
Address string `json:"address"`
Port uint16 `json:"port"`
Users []core.VUser `json:"users"`
Address string `json:"address"`
Port uint16 `json:"port"`
Users []VMessUser `json:"users"`
}
func (config VNextConfig) ToVNextServer() VNextServer {
users := make([]core.VUser, 0, len(config.Users))
for _, user := range config.Users {
vuser, err := user.ToVUser()
if err != nil {
panic(log.Error("Failed to convert %v to VUser.", user))
}
users = append(users, vuser)
}
return VNextServer{
v2net.DomainAddress(config.Address, config.Port),
config.Users}
users}
}
type VMessOutboundConfig struct {
VNextList []VNextConfig
VNextList []VNextConfig `json:"vnext"`
}
func loadOutboundConfig(rawConfig []byte) (VMessOutboundConfig, error) {
+1 -1
View File
@@ -1,5 +1,5 @@
package vmess
const (
BufferSize = 256
BufferSize = 512
)
+29 -11
View File
@@ -4,6 +4,7 @@ import (
"crypto/md5"
"io"
"net"
"strconv"
"github.com/v2ray/v2ray-core"
v2io "github.com/v2ray/v2ray-core/io"
@@ -24,10 +25,10 @@ func NewVMessInboundHandler(vp *core.VPoint, clients *core.VUserSet) *VMessInbou
return handler
}
func (handler *VMessInboundHandler) Listen(port uint8) error {
listener, err := net.Listen("tcp", ":"+string(port))
func (handler *VMessInboundHandler) Listen(port uint16) error {
listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
if err != nil {
return err
return log.Error("Unable to listen tcp:%d", port)
}
handler.accepting = true
go handler.AcceptConnections(listener)
@@ -39,7 +40,7 @@ func (handler *VMessInboundHandler) AcceptConnections(listener net.Listener) err
for handler.accepting {
connection, err := listener.Accept()
if err != nil {
return err
return log.Error("Failed to accpet connection: %s", err.Error())
}
go handler.HandleConnection(connection)
}
@@ -54,9 +55,14 @@ func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error
if err != nil {
return err
}
log.Debug("Received request for %s", request.Address.String())
response := vmessio.NewVMessResponse(request)
connection.Write(response[:])
nBytes, err := connection.Write(response[:])
log.Debug("Writing VMess response %v", response)
if err != nil {
return log.Error("Failed to write VMess response (%d bytes): %v", nBytes, err)
}
requestKey := request.RequestKey[:]
requestIV := request.RequestIV[:]
@@ -65,12 +71,12 @@ func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error
requestReader, err := v2io.NewAesDecryptReader(requestKey, requestIV, connection)
if err != nil {
return err
return log.Error("Failed to create decrypt reader: %v", err)
}
responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], connection)
if err != nil {
return err
return log.Error("Failed to create encrypt writer: %v", err)
}
ray := handler.vPoint.NewInboundConnectionAccepted(request.Address)
@@ -89,8 +95,10 @@ func (handler *VMessInboundHandler) dumpInput(reader io.Reader, input chan<- []b
for {
buffer := make([]byte, BufferSize)
nBytes, err := reader.Read(buffer)
log.Debug("VMessInbound: Reading %d bytes with error %v", nBytes, err)
if err == io.EOF {
close(input)
log.Debug("VMessInbound finishing input.")
finish <- true
break
}
@@ -103,9 +111,11 @@ func (handler *VMessInboundHandler) dumpOutput(writer io.Writer, output <-chan [
buffer, open := <-output
if !open {
finish <- true
log.Debug("VMessInbound finishing output.")
break
}
writer.Write(buffer)
nBytes, err := writer.Write(buffer)
log.Debug("VmessInbound: Wrote %d bytes with error %v", nBytes, err)
}
}
@@ -118,14 +128,22 @@ func (handler *VMessInboundHandler) waitForFinish(finish <-chan bool) {
type VMessInboundHandlerFactory struct {
}
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte) *VMessInboundHandler {
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte) (core.InboundConnectionHandler, error) {
config, err := loadInboundConfig(rawConfig)
if err != nil {
panic(log.Error("Failed to load VMess inbound config: %v", err))
}
allowedClients := core.NewVUserSet()
for _, user := range config.AllowedClients {
for _, client := range config.AllowedClients {
user, err := client.ToVUser()
if err != nil {
panic(log.Error("Failed to parse user id %s: %v", client.Id, err))
}
allowedClients.AddUser(user)
}
return NewVMessInboundHandler(vp, allowedClients)
return NewVMessInboundHandler(vp, allowedClients), nil
}
func init() {
core.RegisterInboundConnectionHandlerFactory("vmess", &VMessInboundHandlerFactory{})
}
+39 -8
View File
@@ -62,26 +62,48 @@ func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error {
request.Command = byte(0x01)
request.Address = handler.dest
conn, err := net.Dial("tcp", vNextAddress.String())
go handler.startCommunicate(request, vNextAddress, ray)
return nil
}
func (handler *VMessOutboundHandler) startCommunicate(request *vmessio.VMessRequest, dest v2net.VAddress, ray core.OutboundVRay) error {
conn, err := net.Dial("tcp", dest.String())
log.Debug("VMessOutbound dialing tcp: %s", dest.String())
if err != nil {
log.Error("Failed to open tcp (%s): %v", dest.String(), err)
return err
}
defer conn.Close()
requestWriter := vmessio.NewVMessRequestWriter()
requestWriter.Write(conn, request)
err = requestWriter.Write(conn, request)
if err != nil {
log.Error("Failed to write VMess request: %v", err)
return err
}
requestKey := request.RequestKey[:]
requestIV := request.RequestIV[:]
responseKey := md5.Sum(requestKey)
responseIV := md5.Sum(requestIV)
encryptRequestWriter, err := v2io.NewAesEncryptWriter(requestKey, requestIV, conn)
response := vmessio.VMessResponse{}
nBytes, err := conn.Read(response[:])
if err != nil {
log.Error("Failed to read VMess response (%d bytes): %v", nBytes, err)
return err
}
responseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
log.Debug("Got response %v", response)
// TODO: check response
encryptRequestWriter, err := v2io.NewAesEncryptWriter(requestKey, requestIV, conn)
if err != nil {
log.Error("Failed to create encrypt writer: %v", err)
return err
}
decryptResponseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
if err != nil {
log.Error("Failed to create decrypt reader: %v", err)
return err
}
@@ -90,7 +112,7 @@ func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error {
finish := make(chan bool, 2)
go handler.dumpInput(encryptRequestWriter, input, finish)
go handler.dumpOutput(responseReader, output, finish)
go handler.dumpOutput(decryptResponseReader, output, finish)
handler.waitForFinish(finish)
return nil
}
@@ -99,9 +121,11 @@ func (handler *VMessOutboundHandler) dumpOutput(reader io.Reader, output chan<-
for {
buffer := make([]byte, BufferSize)
nBytes, err := reader.Read(buffer)
log.Debug("VMessOutbound: Reading %d bytes, with error %v", nBytes, err)
if err == io.EOF {
close(output)
finish <- true
log.Debug("VMessOutbound finishing output.")
break
}
output <- buffer[:nBytes]
@@ -113,9 +137,11 @@ func (handler *VMessOutboundHandler) dumpInput(writer io.Writer, input <-chan []
buffer, open := <-input
if !open {
finish <- true
log.Debug("VMessOutbound finishing input.")
break
}
writer.Write(buffer)
nBytes, err := writer.Write(buffer)
log.Debug("VMessOutbound: Wrote %d bytes with error %v", nBytes, err)
}
}
@@ -123,12 +149,13 @@ func (handler *VMessOutboundHandler) waitForFinish(finish <-chan bool) {
for i := 0; i < 2; i++ {
<-finish
}
log.Debug("Finishing waiting for VMessOutbound ending.")
}
type VMessOutboundHandlerFactory struct {
}
func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte, destination v2net.VAddress) *VMessOutboundHandler {
func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte, destination v2net.VAddress) (core.OutboundConnectionHandler, error) {
config, err := loadOutboundConfig(rawConfig)
if err != nil {
panic(log.Error("Failed to load VMess outbound config: %v", err))
@@ -137,5 +164,9 @@ func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, rawConfig []
for _, server := range config.VNextList {
servers = append(servers, server.ToVNextServer())
}
return NewVMessOutboundHandler(vp, servers, destination)
return NewVMessOutboundHandler(vp, servers, destination), nil
}
func init() {
core.RegisterOutboundConnectionHandlerFactory("vmess", &VMessOutboundHandlerFactory{})
}