mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 01:27:03 -05:00
freedom connection
This commit is contained in:
parent
f1292f6035
commit
19308037e5
75
io/bufferset.go
Normal file
75
io/bufferset.go
Normal file
@ -0,0 +1,75 @@
|
||||
package io
|
||||
|
||||
import(
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
SizeSmall = 16
|
||||
SizeMedium = 128
|
||||
SizeLarge = 512
|
||||
)
|
||||
|
||||
var (
|
||||
ErrorNoChannel = errors.New("No suitable channels found.")
|
||||
)
|
||||
|
||||
type VBufferSet struct {
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (bSet *VBufferSet) ReturnBuffer(buffer []byte) {
|
||||
byteChan, err := bSet.detectBucket(len(buffer), true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case byteChan <- buffer:
|
||||
default:
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package io
|
||||
// Package json contains io library for VConfig in Json format.
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
_ "fmt"
|
||||
|
||||
"github.com/v2ray/v2ray-core"
|
||||
)
|
||||
|
62
net/freedom/freedom.go
Normal file
62
net/freedom/freedom.go
Normal file
@ -0,0 +1,62 @@
|
||||
package tcp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"io"
|
||||
)
|
||||
|
||||
type VFreeConnection struct {
|
||||
network string
|
||||
address string
|
||||
}
|
||||
|
||||
func NewVFreeConnection(network string, address string) *VFreeConnection {
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
func (vconn *VFreeConnection) CloseConn(conn net.Conn, finish <-chan bool) {
|
||||
for i := 0; i < 2; i++ {
|
||||
<-finish
|
||||
}
|
||||
conn.Close()
|
||||
}
|
Loading…
Reference in New Issue
Block a user