mirror of https://github.com/v2ray/v2ray-core
V2Ray
9 years ago
3 changed files with 92 additions and 92 deletions
@ -1,75 +1,75 @@
|
||||
package io |
||||
|
||||
import( |
||||
"errors" |
||||
import ( |
||||
"errors" |
||||
) |
||||
|
||||
const ( |
||||
SizeSmall = 16 |
||||
SizeMedium = 128 |
||||
SizeLarge = 512 |
||||
SizeSmall = 16 |
||||
SizeMedium = 128 |
||||
SizeLarge = 512 |
||||
) |
||||
|
||||
var ( |
||||
ErrorNoChannel = errors.New("No suitable channels found.") |
||||
ErrorNoChannel = errors.New("No suitable channels found.") |
||||
) |
||||
|
||||
type VBufferSet struct { |
||||
small chan []byte |
||||
medium chan []byte |
||||
large chan []byte |
||||
small chan []byte |
||||
medium chan []byte |
||||
large chan []byte |
||||
} |
||||
|
||||
func NewVBufferSet() *VBufferSet { |
||||
bSet := new(VBufferSet) |
||||
bSet.small = make(chan []byte, 128) |
||||
bSet.medium = make(chan []byte, 128) |
||||
bSet.large = make(chan []byte, 128) |
||||
return bSet |
||||
bSet := new(VBufferSet) |
||||
bSet.small = make(chan []byte, 128) |
||||
bSet.medium = make(chan []byte, 128) |
||||
bSet.large = make(chan []byte, 128) |
||||
return bSet |
||||
} |
||||
|
||||
func (bSet *VBufferSet) detectBucket(size int, strict bool) (chan []byte, error) { |
||||
if strict { |
||||
if size == SizeSmall { |
||||
return bSet.small, nil |
||||
} else if size == SizeMedium { |
||||
return bSet.medium, nil |
||||
} else if size == SizeLarge { |
||||
return bSet.large, nil |
||||
} |
||||
} else { |
||||
if size <= SizeSmall { |
||||
return bSet.small, nil |
||||
} else if size <= SizeMedium { |
||||
return bSet.medium, nil |
||||
} else if size <= SizeLarge { |
||||
return bSet.large, nil |
||||
} |
||||
} |
||||
return nil, ErrorNoChannel |
||||
if strict { |
||||
if size == SizeSmall { |
||||
return bSet.small, nil |
||||
} else if size == SizeMedium { |
||||
return bSet.medium, nil |
||||
} else if size == SizeLarge { |
||||
return bSet.large, nil |
||||
} |
||||
} else { |
||||
if size <= SizeSmall { |
||||
return bSet.small, nil |
||||
} else if size <= SizeMedium { |
||||
return bSet.medium, nil |
||||
} else if size <= SizeLarge { |
||||
return bSet.large, nil |
||||
} |
||||
} |
||||
return nil, ErrorNoChannel |
||||
} |
||||
|
||||
func (bSet *VBufferSet) FetchBuffer(minSize int) []byte { |
||||
var buffer []byte |
||||
byteChan, err := bSet.detectBucket(minSize, false) |
||||
if err != nil { |
||||
return make([]byte, minSize) |
||||
} |
||||
select { |
||||
case buffer = <- byteChan: |
||||
default: |
||||
buffer = make([]byte, minSize) |
||||
} |
||||
return buffer |
||||
var buffer []byte |
||||
byteChan, err := bSet.detectBucket(minSize, false) |
||||
if err != nil { |
||||
return make([]byte, minSize) |
||||
} |
||||
select { |
||||
case buffer = <-byteChan: |
||||
default: |
||||
buffer = make([]byte, minSize) |
||||
} |
||||
return buffer |
||||
} |
||||
|
||||
func (bSet *VBufferSet) ReturnBuffer(buffer []byte) { |
||||
byteChan, err := bSet.detectBucket(len(buffer), true) |
||||
if err != nil { |
||||
return |
||||
} |
||||
select { |
||||
case byteChan <- buffer: |
||||
default: |
||||
} |
||||
byteChan, err := bSet.detectBucket(len(buffer), true) |
||||
if err != nil { |
||||
return |
||||
} |
||||
select { |
||||
case byteChan <- buffer: |
||||
default: |
||||
} |
||||
} |
||||
|
@ -1,62 +1,62 @@
|
||||
package tcp |
||||
|
||||
import ( |
||||
"net" |
||||
"io" |
||||
"io" |
||||
"net" |
||||
) |
||||
|
||||
type VFreeConnection struct { |
||||
network string |
||||
address string |
||||
network string |
||||
address string |
||||
} |
||||
|
||||
func NewVFreeConnection(network string, address string) *VFreeConnection { |
||||
conn := new(VFreeConnection) |
||||
conn.network = network |
||||
conn.address = address |
||||
return conn |
||||
conn := new(VFreeConnection) |
||||
conn.network = network |
||||
conn.address = address |
||||
return conn |
||||
} |
||||
|
||||
func (vconn *VFreeConnection) Start(input <-chan []byte) chan<- []byte { |
||||
output := make(chan []byte, 128) |
||||
conn, err := net.Dial(vconn.network, vconn.address) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
|
||||
finish := make(chan bool, 2) |
||||
go vconn.DumpInput(conn, input, finish) |
||||
go vconn.DumpOutput(conn, output, finish) |
||||
go vconn.CloseConn(conn, finish) |
||||
return output |
||||
output := make(chan []byte, 128) |
||||
conn, err := net.Dial(vconn.network, vconn.address) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
|
||||
finish := make(chan bool, 2) |
||||
go vconn.DumpInput(conn, input, finish) |
||||
go vconn.DumpOutput(conn, output, finish) |
||||
go vconn.CloseConn(conn, finish) |
||||
return output |
||||
} |
||||
|
||||
func (vconn *VFreeConnection) DumpInput(conn net.Conn, input <-chan []byte, finish chan<- bool) { |
||||
for { |
||||
data, open := <-input |
||||
if !open { |
||||
finish <- true |
||||
break |
||||
} |
||||
conn.Write(data) |
||||
} |
||||
for { |
||||
data, open := <-input |
||||
if !open { |
||||
finish <- true |
||||
break |
||||
} |
||||
conn.Write(data) |
||||
} |
||||
} |
||||
|
||||
func (vconn *VFreeConnection) DumpOutput(conn net.Conn, output chan<- []byte, finish chan<- bool) { |
||||
for { |
||||
buffer := make([]byte, 128) |
||||
nBytes, err := conn.Read(buffer) |
||||
if err == io.EOF { |
||||
finish <- true |
||||
break |
||||
} |
||||
output <- buffer[:nBytes] |
||||
} |
||||
for { |
||||
buffer := make([]byte, 128) |
||||
nBytes, err := conn.Read(buffer) |
||||
if err == io.EOF { |
||||
finish <- true |
||||
break |
||||
} |
||||
output <- buffer[:nBytes] |
||||
} |
||||
} |
||||
|
||||
func (vconn *VFreeConnection) CloseConn(conn net.Conn, finish <-chan bool) { |
||||
for i := 0; i < 2; i++ { |
||||
<-finish |
||||
} |
||||
conn.Close() |
||||
for i := 0; i < 2; i++ { |
||||
<-finish |
||||
} |
||||
conn.Close() |
||||
} |
||||
|
Loading…
Reference in new issue