Skip to content

Commit

Permalink
Version 1.0 alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
DarienRaymond committed Sep 12, 2015
1 parent f3a12e9 commit cc3fdb6
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 101 deletions.
8 changes: 4 additions & 4 deletions io/aes.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ func NewAesDecryptReader(key []byte, iv []byte, reader io.Reader) (io.Reader, er
return nil, err
}

aesMode := cipher.NewCBCDecrypter(aesBlock, iv)
return NewCryptionReader(aesMode, reader), nil
aesStream := cipher.NewCFBDecrypter(aesBlock, iv)
return NewCryptionReader(aesStream, reader), nil
}

func NewAesEncryptWriter(key []byte, iv []byte, writer io.Writer) (io.Writer, error) {
Expand All @@ -22,6 +22,6 @@ func NewAesEncryptWriter(key []byte, iv []byte, writer io.Writer) (io.Writer, er
return nil, err
}

aesMode := cipher.NewCBCEncrypter(aesBlock, iv)
return NewCryptionWriter(aesMode, writer), nil
aesStream := cipher.NewCFBEncrypter(aesBlock, iv)
return NewCryptionWriter(aesStream, writer), nil
}
37 changes: 15 additions & 22 deletions io/encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package io
import (
"crypto/cipher"
"io"

"github.com/v2ray/v2ray-core/log"
)

// CryptionReader is a general purpose reader that applies
// block cipher on top of a regular reader.
type CryptionReader struct {
mode cipher.BlockMode
stream cipher.Stream
reader io.Reader
}

func NewCryptionReader(mode cipher.BlockMode, reader io.Reader) *CryptionReader {
func NewCryptionReader(stream cipher.Stream, reader io.Reader) *CryptionReader {
this := new(CryptionReader)
this.mode = mode
this.stream = stream
this.reader = reader
return this
}
Expand All @@ -23,43 +25,34 @@ func NewCryptionReader(mode cipher.BlockMode, reader io.Reader) *CryptionReader
// a multiply of BlockSize()
func (reader CryptionReader) Read(blocks []byte) (int, error) {
nBytes, err := reader.reader.Read(blocks)
if err != nil && err != io.EOF {
return nBytes, err
log.Debug("CryptionReader: Read %d bytes", nBytes)
if nBytes > 0 {
reader.stream.XORKeyStream(blocks[:nBytes], blocks[:nBytes])
}
if nBytes < len(blocks) {
for i, _ := range blocks[nBytes:] {
blocks[i] = 0
}
if err != nil {
log.Error("Error reading blocks: %v", err)
}
reader.mode.CryptBlocks(blocks, blocks)
return nBytes, err
}

func (reader CryptionReader) BlockSize() int {
return reader.mode.BlockSize()
}

// Cryption writer is a general purpose of byte stream writer that applies
// block cipher on top of a regular writer.
type CryptionWriter struct {
mode cipher.BlockMode
stream cipher.Stream
writer io.Writer
}

func NewCryptionWriter(mode cipher.BlockMode, writer io.Writer) *CryptionWriter {
func NewCryptionWriter(stream cipher.Stream, writer io.Writer) *CryptionWriter {
this := new(CryptionWriter)
this.mode = mode
this.stream = stream
this.writer = writer
return this
}

// Write writes the give blocks to underlying writer. The length of the blocks
// must be a multiply of BlockSize()
func (writer CryptionWriter) Write(blocks []byte) (int, error) {
writer.mode.CryptBlocks(blocks, blocks)
log.Debug("CryptionWriter writing %d bytes", len(blocks))
writer.stream.XORKeyStream(blocks, blocks)
return writer.writer.Write(blocks)
}

func (writer CryptionWriter) BlockSize() int {
return writer.mode.BlockSize()
}
4 changes: 2 additions & 2 deletions io/vmess/decryptionreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func NewDecryptionReader(reader io.Reader, key []byte, iv []byte) (*DecryptionRe
if err != nil {
return nil, err
}
aesBlockMode := cipher.NewCBCDecrypter(aesCipher, iv)
decryptionReader.reader = v2io.NewCryptionReader(aesBlockMode, reader)
aesStream := cipher.NewCFBDecrypter(aesCipher, iv)
decryptionReader.reader = v2io.NewCryptionReader(aesStream, reader)
decryptionReader.buffer = bytes.NewBuffer(make([]byte, 0, 2*blockSize))
return decryptionReader, nil
}
Expand Down
4 changes: 2 additions & 2 deletions io/vmess/decryptionreader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ func TestNormalReading(t *testing.T) {
aesBlock, err := aes.NewCipher(key)
assert.Error(err).IsNil()

aesMode := cipher.NewCBCEncrypter(aesBlock, iv)
aesStream := cipher.NewCFBEncrypter(aesBlock, iv)

ciphertext := make([]byte, testSize)
aesMode.CryptBlocks(ciphertext, plaintext)
aesStream.XORKeyStream(ciphertext, plaintext)

ciphertextcopy := make([]byte, testSize)
copy(ciphertextcopy, ciphertext)
Expand Down
4 changes: 2 additions & 2 deletions io/vmess/vmess.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,8 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
if err != nil {
return err
}
aesMode := cipher.NewCBCEncrypter(aesCipher, make([]byte, blockSize))
cWriter := v2io.NewCryptionWriter(aesMode, writer)
aesStream := cipher.NewCFBEncrypter(aesCipher, make([]byte, blockSize))
cWriter := v2io.NewCryptionWriter(aesStream, writer)

_, err = writer.Write(buffer[0:encryptionBegin])
if err != nil {
Expand Down
25 changes: 14 additions & 11 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,33 @@ func SetLogLevel(level LogLevel) {
logLevel = level
}

func writeLog(data string, level LogLevel) {
func writeLog(level LogLevel, prefix, format string, v ...interface{}) string {
if level < logLevel {
return
return ""
}
log.Print(data)
var data string
if v == nil || len(v) == 0 {
data = format
} else {
data = fmt.Sprintf(format, v...)
}
log.Print(prefix + data)
return data
}

func Debug(format string, v ...interface{}) {
data := fmt.Sprintf(format, v)
writeLog("[Debug]"+data, DebugLevel)
writeLog(DebugLevel, "[Debug]", format, v...)
}

func Info(format string, v ...interface{}) {
data := fmt.Sprintf(format, v)
writeLog("[Info]"+data, InfoLevel)
writeLog(InfoLevel, "[Info]", format, v...)
}

func Warning(format string, v ...interface{}) {
data := fmt.Sprintf(format, v)
writeLog("[Warning]"+data, WarningLevel)
writeLog(WarningLevel, "[Warning]", format, v...)
}

func Error(format string, v ...interface{}) error {
data := fmt.Sprintf(format, v)
writeLog("[Error]"+data, ErrorLevel)
data := writeLog(ErrorLevel, "[Error]", format, v...)
return errors.New(data)
}
16 changes: 9 additions & 7 deletions net/freedom/freedom.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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)
Expand All @@ -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]
}
}
Expand Down
4 changes: 4 additions & 0 deletions net/freedom/freedomfactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{})
}
23 changes: 16 additions & 7 deletions net/socks/socks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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())
Expand All @@ -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]
Expand All @@ -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)
}
}

Expand Down
38 changes: 19 additions & 19 deletions net/socks/socks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 4 additions & 0 deletions net/socks/socksfactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{})
}
Loading

0 comments on commit cc3fdb6

Please sign in to comment.