mirror of
https://github.com/v2fly/v2ray-core
synced 2024-02-27 03:18:06 +00:00
Version 1.0 alpha
This commit is contained in:
@@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -1,5 +1,5 @@
|
||||
package vmess
|
||||
|
||||
const (
|
||||
BufferSize = 256
|
||||
BufferSize = 512
|
||||
)
|
||||
|
||||
+29
-11
@@ -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
@@ -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{})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user