Skip to content

Commit

Permalink
implemented factory listen on shadow and Optimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
CryptoSax committed Jun 25, 2020
1 parent 39a0973 commit 2f99699
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 51 deletions.
80 changes: 42 additions & 38 deletions transports/Optimizer/v3/Optimizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@ import (

const timeoutInSeconds = 60

//Transport is a program that transforms network traffic
type Transport interface {
//TransportDialer is a program that transforms network traffic
type TransportDialer interface {
Dial() (net.Conn, error)
}

type TransportListener interface {
Listen() (net.Listener, error)
}

//Client contains the two parameters needed to use Optimizer.
type Client struct {
Transports []Transport
Transports []TransportDialer
Strategy Strategy
}

//NewOptimizerClient is the initializer
func NewOptimizerClient(Transports []Transport, Strategy Strategy) *Client {
func NewOptimizerClient(Transports []TransportDialer, Strategy Strategy) *Client {
return &Client{Transports, Strategy}
}

Expand Down Expand Up @@ -54,63 +58,63 @@ func (OptT *Client) Dial() (net.Conn, error) {

//Strategy is the method used to choose a transport
type Strategy interface {
Choose() Transport
Report(transport Transport, success bool, durationElapsed float64)
Choose() TransportDialer
Report(transport TransportDialer, success bool, durationElapsed float64)
}

//FirstStrategy returns the first strategy in the array
type FirstStrategy struct {
transports []Transport
transports []TransportDialer
}

//NewFirstStrategy initializes FirstStrategy
func NewFirstStrategy(transports []Transport) Strategy {
func NewFirstStrategy(transports []TransportDialer) Strategy {
return &FirstStrategy{transports}
}

//Choose selects a transport in the array
func (strategy *FirstStrategy) Choose() Transport {
func (strategy *FirstStrategy) Choose() TransportDialer {
return strategy.transports[0]
}

//Report returns if the transport was successful and how long the connection took
func (strategy *FirstStrategy) Report(Transport, bool, float64) {
func (strategy *FirstStrategy) Report(TransportDialer, bool, float64) {

}

//NewRandomStrategy initializes RandomStrategy
func NewRandomStrategy(transports []Transport) Strategy {
func NewRandomStrategy(transports []TransportDialer) Strategy {
return &RandomStrategy{transports}
}

//RandomStrategy returns a transport at random
type RandomStrategy struct {
transports []Transport
transports []TransportDialer
}

//Choose selects a transport in the array
func (strategy *RandomStrategy) Choose() Transport {
func (strategy *RandomStrategy) Choose() TransportDialer {
return strategy.transports[0]
}

//Report returns if the transport was successful and how long the connection took
func (strategy *RandomStrategy) Report(Transport, bool, float64) {
func (strategy *RandomStrategy) Report(TransportDialer, bool, float64) {

}

//NewRotateStrategy initializes RotateStrategy
func NewRotateStrategy(transports []Transport) Strategy {
func NewRotateStrategy(transports []TransportDialer) Strategy {
return &RotateStrategy{transports, 1}
}

//RotateStrategy cycles through the list of transports, using a different one each time
type RotateStrategy struct {
transports []Transport
transports []TransportDialer
index int
}

//Choose selects a transport in the array
func (strategy *RotateStrategy) Choose() Transport {
func (strategy *RotateStrategy) Choose() TransportDialer {
transport := strategy.transports[strategy.index]
strategy.index++
if strategy.index >= len(strategy.transports) {
Expand All @@ -120,27 +124,27 @@ func (strategy *RotateStrategy) Choose() Transport {
}

//Report returns if the transport was successful and how long the connection took
func (strategy *RotateStrategy) Report(Transport, bool, float64) {
func (strategy *RotateStrategy) Report(TransportDialer, bool, float64) {

}

//TrackStrategy assigns a score to each transport and server that is remembered and used to
//choose the best option
type TrackStrategy struct {
index int
trackMap map[Transport]int
transport []Transport
trackMap map[TransportDialer]int
transport []TransportDialer
}

//NewTrackStrategy initializes TrackStrategy
func NewTrackStrategy(transport []Transport) Strategy {
track := TrackStrategy{0, map[Transport]int{}, transport}
track.trackMap = make(map[Transport]int)
func NewTrackStrategy(transport []TransportDialer) Strategy {
track := TrackStrategy{0, map[TransportDialer]int{}, transport}
track.trackMap = make(map[TransportDialer]int)
return &track
}

//Choose selects a transport in the array
func (strategy *TrackStrategy) Choose() Transport {
func (strategy *TrackStrategy) Choose() TransportDialer {
transport := strategy.transport[strategy.index]
score := strategy.findScore(strategy.transport)
startIndex := strategy.index
Expand All @@ -158,7 +162,7 @@ func (strategy *TrackStrategy) Choose() Transport {
}

//findScore is used to find the score given to each transport based on performance
func (strategy *TrackStrategy) findScore(transports []Transport) int {
func (strategy *TrackStrategy) findScore(transports []TransportDialer) int {
transport := transports[strategy.index]
score, ok := strategy.trackMap[transport]
if ok {
Expand All @@ -169,15 +173,15 @@ func (strategy *TrackStrategy) findScore(transports []Transport) int {
}

//incrementIndex is used to cycle through the transport index
func (strategy *TrackStrategy) incrementIndex(transports []Transport) {
func (strategy *TrackStrategy) incrementIndex(transports []TransportDialer) {
strategy.index++
if strategy.index >= len(transports) {
strategy.index = 0
}
}

//Report returns if the transport was successful and how long the connection took
func (strategy *TrackStrategy) Report(transport Transport, success bool, _ float64) {
func (strategy *TrackStrategy) Report(transport TransportDialer, success bool, _ float64) {
if success {
strategy.trackMap[transport] = 1
} else {
Expand All @@ -188,19 +192,19 @@ func (strategy *TrackStrategy) Report(transport Transport, success bool, _ float
//minimizeDialDuration is used to find the transport with the fastest response time
type minimizeDialDuration struct {
index int
trackMap map[Transport]float64
transports []Transport
trackMap map[TransportDialer]float64
transports []TransportDialer
}

//NewMinimizeDialDuration initializes minimizeDialDuration
func NewMinimizeDialDuration(transport []Transport) Strategy {
duration := minimizeDialDuration{0, map[Transport]float64{}, transport}
duration.trackMap = make(map[Transport]float64)
func NewMinimizeDialDuration(transport []TransportDialer) Strategy {
duration := minimizeDialDuration{0, map[TransportDialer]float64{}, transport}
duration.trackMap = make(map[TransportDialer]float64)
return &duration
}

//Choose selects a transport in the array
func (strategy *minimizeDialDuration) Choose() Transport {
func (strategy *minimizeDialDuration) Choose() TransportDialer {
transport := strategy.transports[strategy.index]
score := strategy.findScore(strategy.transports)
startIndex := strategy.index
Expand All @@ -224,15 +228,15 @@ func (strategy *minimizeDialDuration) Choose() Transport {
}

//incrementIndex is used to cycle through the transport index
func (strategy *minimizeDialDuration) incrementIndex(transports []Transport) {
func (strategy *minimizeDialDuration) incrementIndex(transports []TransportDialer) {
strategy.index++
if strategy.index >= len(transports) {
strategy.index = 0
}
}

//findScore is used to find the score given to each transport based on performance
func (strategy *minimizeDialDuration) findScore(transports []Transport) float64 {
func (strategy *minimizeDialDuration) findScore(transports []TransportDialer) float64 {
transport := transports[strategy.index]
score, ok := strategy.trackMap[transport]
if ok {
Expand All @@ -243,7 +247,7 @@ func (strategy *minimizeDialDuration) findScore(transports []Transport) float64
}

//Report returns if the transport was successful and how long the connection took
func (strategy *minimizeDialDuration) Report(transport Transport, success bool, durationElapsed float64) {
func (strategy *minimizeDialDuration) Report(transport TransportDialer, success bool, durationElapsed float64) {
if success {
if durationElapsed < 60 {
strategy.trackMap[transport] = durationElapsed
Expand All @@ -256,9 +260,9 @@ func (strategy *minimizeDialDuration) Report(transport Transport, success bool,
}

//minDuration assigns a value to the response time
func (strategy *minimizeDialDuration) minDuration() Transport {
func (strategy *minimizeDialDuration) minDuration() TransportDialer {
min := 61.0
var transport Transport = nil
var transport TransportDialer = nil
for key, value := range strategy.trackMap {
if value < min {
min = value
Expand Down
18 changes: 9 additions & 9 deletions transports/Optimizer/v3/Optimizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestOptimizerMeekliteDial(t *testing.T) {
t.Fail()
}
meekliteTransport := meeklite.Transport{URL: URL, Front: "a0.awsstatic.com", Address: "127.0.0.1:1235" }
transports := []Transport{meekliteTransport}
transports := []TransportDialer{meekliteTransport}
strategy := NewFirstStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)
_, err := optimizerTransport.Dial()
Expand All @@ -82,7 +82,7 @@ func TestShadowDial(t *testing.T) {

func TestOptimizerShadowDial(t *testing.T) {
shadowTransport := shadow.NewTransport("1234", "CHACHA20-IETF-POLY1305", "127.0.0.1:1235")
transports := []Transport{&shadowTransport}
transports := []TransportDialer{&shadowTransport}
strategy := NewFirstStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)
_, err := optimizerTransport.Dial()
Expand All @@ -93,7 +93,7 @@ func TestOptimizerShadowDial(t *testing.T) {

func TestOptimizerObfs2Dial(t *testing.T) {
obfs2Transport := obfs2.New("127.0.0.1:1237", proxy.Direct)
transports := []Transport{obfs2Transport}
transports := []TransportDialer{obfs2Transport}
strategy := NewFirstStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)
_, err := optimizerTransport.Dial()
Expand Down Expand Up @@ -126,7 +126,7 @@ func TestOptimizerObfs4Transport_Dial(t *testing.T) {
IatMode: 0,
Address: "127.0.0.1:1234",
Dialer: dialer}
transports := []Transport{obfs4Transport}
transports := []TransportDialer{obfs4Transport}
strategy := NewFirstStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)
_, err := optimizerTransport.Dial()
Expand All @@ -148,7 +148,7 @@ func TestOptimizerTransportFirstDial(t *testing.T) {
Address: "127.0.0.1:1234",
Dialer: dialer}
shadowTransport := shadow.NewTransport("1234", "CHACHA20-IETF-POLY1305", "127.0.0.1:1235")
transports := []Transport{obfs4Transport, &shadowTransport}
transports := []TransportDialer{obfs4Transport, &shadowTransport}
strategy := NewFirstStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)
for i := 1; i <= 3; i++ {
Expand All @@ -173,7 +173,7 @@ func TestOptimizerTransportRandomDial(t *testing.T) {
Dialer: dialer,
}
shadowTransport := shadow.NewTransport("1234", "CHACHA20-IETF-POLY1305", "127.0.0.1:1235")
transports := []Transport{obfs4Transport, &shadowTransport}
transports := []TransportDialer{obfs4Transport, &shadowTransport}
strategy := NewRandomStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)

Expand All @@ -199,7 +199,7 @@ func TestOptimizerTransportRotateDial(t *testing.T) {
Dialer: dialer,
}
shadowTransport := shadow.NewTransport("1234", "CHACHA20-IETF-POLY1305", "127.0.0.1:1235")
transports := []Transport{obfs4Transport, &shadowTransport}
transports := []TransportDialer{obfs4Transport, &shadowTransport}
strategy := NewRotateStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)

Expand All @@ -225,7 +225,7 @@ func TestOptimizerTransportTrackDial(t *testing.T) {
Dialer: dialer,
}
shadowTransport := shadow.NewTransport("1234", "CHACHA20-IETF-POLY1305", "127.0.0.1:1235")
transports := []Transport{obfs4Transport, &shadowTransport}
transports := []TransportDialer{obfs4Transport, &shadowTransport}
strategy := NewTrackStrategy(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)

Expand All @@ -251,7 +251,7 @@ func TestOptimizerTransportMinimizeDialDurationDial(t *testing.T) {
Dialer: dialer,
}
shadowTransport := shadow.NewTransport("1234", "CHACHA20-IETF-POLY1305", "127.0.0.1:1235")
transports := []Transport{obfs4Transport, &shadowTransport}
transports := []TransportDialer{obfs4Transport, &shadowTransport}
strategy := NewMinimizeDialDuration(transports)
optimizerTransport := NewOptimizerClient(transports, strategy)

Expand Down
8 changes: 4 additions & 4 deletions transports/Optimizer/v3/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/OperatorFoundation/shapeshifter-transports/transports/Optimize
go 1.12

require (
github.com/OperatorFoundation/shapeshifter-transports/transports/meeklite/v3 v3.0.1
github.com/OperatorFoundation/shapeshifter-transports/transports/obfs2/v3 v3.0.1
github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/v3 v3.0.1
github.com/OperatorFoundation/shapeshifter-transports/transports/shadow/v3 v3.0.1
github.com/OperatorFoundation/shapeshifter-transports/transports/meeklite/v3 v3.0.2
github.com/OperatorFoundation/shapeshifter-transports/transports/obfs2/v3 v3.0.2
github.com/OperatorFoundation/shapeshifter-transports/transports/obfs4/v3 v3.0.2
github.com/OperatorFoundation/shapeshifter-transports/transports/shadow/v3 v3.0.2
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
)
15 changes: 15 additions & 0 deletions transports/shadow/v3/shadow.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,18 @@ func (transport *Transport) Dial() (net.Conn, error) {

return shadowsocks.Dial("tcp", transport.Address, cipher)
}

func (transport *Transport) Listen() (net.Listener, error) {
cipher, err := shadowsocks.PickCipher(transport.CipherName, nil, transport.Password)
if err != nil {
log.Fatal("Failed generating ciphers:", err)
return nil, err
}

listener, listenerErr := shadowsocks.Listen("tcp", transport.Address, cipher)
if listenerErr != nil {
log.Fatal("Failed to start listener:", listenerErr)
return nil, listenerErr
}
return listener, nil
}

0 comments on commit 2f99699

Please sign in to comment.