Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
gost
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
gost
Commits
dc4c78ca
Commit
dc4c78ca
authored
Nov 29, 2018
by
ginuerzh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add stop for live reloading
parent
5e0e08d5
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
337 additions
and
203 deletions
+337
-203
bypass.go
bypass.go
+30
-1
chain.go
chain.go
+4
-1
cmd/gost/cfg.go
cmd/gost/cfg.go
+41
-68
cmd/gost/gost.json
cmd/gost/gost.json
+0
-30
cmd/gost/main.go
cmd/gost/main.go
+15
-4
cmd/gost/peer.go
cmd/gost/peer.go
+33
-31
cmd/gost/route.go
cmd/gost/route.go
+72
-26
hosts.go
hosts.go
+33
-4
http.go
http.go
+1
-1
http2.go
http2.go
+4
-2
node.go
node.go
+11
-6
node_test.go
node_test.go
+1
-1
reload.go
reload.go
+39
-11
resolver.go
resolver.go
+32
-1
selector.go
selector.go
+14
-0
server.go
server.go
+0
-10
ss.go
ss.go
+3
-2
ws.go
ws.go
+4
-4
No files found.
bypass.go
View file @
dc4c78ca
...
@@ -124,6 +124,7 @@ type Bypass struct {
...
@@ -124,6 +124,7 @@ type Bypass struct {
matchers
[]
Matcher
matchers
[]
Matcher
period
time
.
Duration
// the period for live reloading
period
time
.
Duration
// the period for live reloading
reversed
bool
reversed
bool
stopped
chan
struct
{}
mux
sync
.
RWMutex
mux
sync
.
RWMutex
}
}
...
@@ -133,6 +134,7 @@ func NewBypass(reversed bool, matchers ...Matcher) *Bypass {
...
@@ -133,6 +134,7 @@ func NewBypass(reversed bool, matchers ...Matcher) *Bypass {
return
&
Bypass
{
return
&
Bypass
{
matchers
:
matchers
,
matchers
:
matchers
,
reversed
:
reversed
,
reversed
:
reversed
,
stopped
:
make
(
chan
struct
{}),
}
}
}
}
...
@@ -207,6 +209,10 @@ func (bp *Bypass) Reload(r io.Reader) error {
...
@@ -207,6 +209,10 @@ func (bp *Bypass) Reload(r io.Reader) error {
var
period
time
.
Duration
var
period
time
.
Duration
var
reversed
bool
var
reversed
bool
if
bp
.
Stopped
()
{
return
nil
}
scanner
:=
bufio
.
NewScanner
(
r
)
scanner
:=
bufio
.
NewScanner
(
r
)
for
scanner
.
Scan
()
{
for
scanner
.
Scan
()
{
line
:=
scanner
.
Text
()
line
:=
scanner
.
Text
()
...
@@ -264,14 +270,37 @@ func (bp *Bypass) Reload(r io.Reader) error {
...
@@ -264,14 +270,37 @@ func (bp *Bypass) Reload(r io.Reader) error {
return
nil
return
nil
}
}
// Period returns the reload period
// Period returns the reload period
.
func
(
bp
*
Bypass
)
Period
()
time
.
Duration
{
func
(
bp
*
Bypass
)
Period
()
time
.
Duration
{
if
bp
.
Stopped
()
{
return
-
1
}
bp
.
mux
.
RLock
()
bp
.
mux
.
RLock
()
defer
bp
.
mux
.
RUnlock
()
defer
bp
.
mux
.
RUnlock
()
return
bp
.
period
return
bp
.
period
}
}
// Stop stops reloading.
func
(
bp
*
Bypass
)
Stop
()
{
select
{
case
<-
bp
.
stopped
:
default
:
close
(
bp
.
stopped
)
}
}
// Stopped checks whether the reloader is stopped.
func
(
bp
*
Bypass
)
Stopped
()
bool
{
select
{
case
<-
bp
.
stopped
:
return
true
default
:
return
false
}
}
func
(
bp
*
Bypass
)
String
()
string
{
func
(
bp
*
Bypass
)
String
()
string
{
bp
.
mux
.
RLock
()
bp
.
mux
.
RLock
()
defer
bp
.
mux
.
RUnlock
()
defer
bp
.
mux
.
RUnlock
()
...
...
chain.go
View file @
dc4c78ca
...
@@ -15,7 +15,7 @@ var (
...
@@ -15,7 +15,7 @@ var (
ErrEmptyChain
=
errors
.
New
(
"empty chain"
)
ErrEmptyChain
=
errors
.
New
(
"empty chain"
)
)
)
// Chain is a proxy chain that holds a list of proxy nodes.
// Chain is a proxy chain that holds a list of proxy node
group
s.
type
Chain
struct
{
type
Chain
struct
{
isRoute
bool
isRoute
bool
Retries
int
Retries
int
...
@@ -23,6 +23,7 @@ type Chain struct {
...
@@ -23,6 +23,7 @@ type Chain struct {
}
}
// NewChain creates a proxy chain with a list of proxy nodes.
// NewChain creates a proxy chain with a list of proxy nodes.
// It creates the node groups automatically, one group per node.
func
NewChain
(
nodes
...
Node
)
*
Chain
{
func
NewChain
(
nodes
...
Node
)
*
Chain
{
chain
:=
&
Chain
{}
chain
:=
&
Chain
{}
for
_
,
node
:=
range
nodes
{
for
_
,
node
:=
range
nodes
{
...
@@ -31,6 +32,8 @@ func NewChain(nodes ...Node) *Chain {
...
@@ -31,6 +32,8 @@ func NewChain(nodes ...Node) *Chain {
return
chain
return
chain
}
}
// newRoute creates a chain route.
// a chain route is the final route after node selection.
func
newRoute
(
nodes
...
Node
)
*
Chain
{
func
newRoute
(
nodes
...
Node
)
*
Chain
{
chain
:=
NewChain
(
nodes
...
)
chain
:=
NewChain
(
nodes
...
)
chain
.
isRoute
=
true
chain
.
isRoute
=
true
...
...
cmd/gost/cfg.go
View file @
dc4c78ca
...
@@ -6,8 +6,6 @@ import (
...
@@ -6,8 +6,6 @@ import (
"crypto/x509"
"crypto/x509"
"encoding/json"
"encoding/json"
"errors"
"errors"
"fmt"
"io"
"io/ioutil"
"io/ioutil"
"net/url"
"net/url"
"os"
"os"
...
@@ -17,6 +15,34 @@ import (
...
@@ -17,6 +15,34 @@ import (
"github.com/ginuerzh/gost"
"github.com/ginuerzh/gost"
)
)
var
(
routers
[]
router
)
type
baseConfig
struct
{
route
Routes
[]
route
Debug
bool
}
func
parseBaseConfig
(
s
string
)
(
*
baseConfig
,
error
)
{
file
,
err
:=
os
.
Open
(
s
)
if
err
!=
nil
{
return
nil
,
err
}
defer
file
.
Close
()
if
err
:=
json
.
NewDecoder
(
file
)
.
Decode
(
baseCfg
);
err
!=
nil
{
return
nil
,
err
}
return
baseCfg
,
nil
}
func
(
cfg
*
baseConfig
)
IsValid
()
bool
{
return
len
(
cfg
.
route
.
ServeNodes
)
>
0
}
var
(
var
(
defaultCertFile
=
"cert.pem"
defaultCertFile
=
"cert.pem"
defaultKeyFile
=
"key.pem"
defaultKeyFile
=
"key.pem"
...
@@ -52,70 +78,6 @@ func loadCA(caFile string) (cp *x509.CertPool, err error) {
...
@@ -52,70 +78,6 @@ func loadCA(caFile string) (cp *x509.CertPool, err error) {
return
return
}
}
type
baseConfig
struct
{
route
Routes
[]
route
ReloadPeriod
string
Debug
bool
}
func
parseBaseConfig
(
s
string
)
(
*
baseConfig
,
error
)
{
file
,
err
:=
os
.
Open
(
s
)
if
err
!=
nil
{
return
nil
,
err
}
defer
file
.
Close
()
if
err
:=
json
.
NewDecoder
(
file
)
.
Decode
(
baseCfg
);
err
!=
nil
{
return
nil
,
err
}
return
baseCfg
,
nil
}
func
(
cfg
*
baseConfig
)
IsValid
()
bool
{
return
len
(
cfg
.
route
.
ServeNodes
)
>
0
}
func
(
cfg
*
baseConfig
)
Reload
(
r
io
.
Reader
)
error
{
c
:=
baseConfig
{}
if
err
:=
json
.
NewDecoder
(
r
)
.
Decode
(
&
c
);
err
!=
nil
{
return
err
}
cfg
.
route
.
Close
()
for
_
,
r
:=
range
cfg
.
Routes
{
r
.
Close
()
}
*
cfg
=
c
gost
.
Debug
=
cfg
.
Debug
if
err
:=
cfg
.
route
.
serve
();
err
!=
nil
{
return
err
}
for
_
,
route
:=
range
cfg
.
Routes
{
if
err
:=
route
.
serve
();
err
!=
nil
{
return
err
}
}
return
nil
}
func
(
cfg
*
baseConfig
)
Period
()
time
.
Duration
{
d
,
_
:=
time
.
ParseDuration
(
cfg
.
ReloadPeriod
)
return
d
}
type
stringList
[]
string
func
(
l
*
stringList
)
String
()
string
{
return
fmt
.
Sprintf
(
"%s"
,
*
l
)
}
func
(
l
*
stringList
)
Set
(
value
string
)
error
{
*
l
=
append
(
*
l
,
value
)
return
nil
}
func
parseKCPConfig
(
configFile
string
)
(
*
gost
.
KCPConfig
,
error
)
{
func
parseKCPConfig
(
configFile
string
)
(
*
gost
.
KCPConfig
,
error
)
{
if
configFile
==
""
{
if
configFile
==
""
{
return
nil
,
nil
return
nil
,
nil
...
@@ -221,9 +183,10 @@ func parseBypass(s string) *gost.Bypass {
...
@@ -221,9 +183,10 @@ func parseBypass(s string) *gost.Bypass {
}
}
return
gost
.
NewBypass
(
reversed
,
matchers
...
)
return
gost
.
NewBypass
(
reversed
,
matchers
...
)
}
}
f
.
Close
()
defer
f
.
Close
()
bp
:=
gost
.
NewBypass
(
reversed
)
bp
:=
gost
.
NewBypass
(
reversed
)
bp
.
Reload
(
f
)
go
gost
.
PeriodReload
(
bp
,
s
)
go
gost
.
PeriodReload
(
bp
,
s
)
return
bp
return
bp
...
@@ -259,16 +222,26 @@ func parseResolver(cfg string) gost.Resolver {
...
@@ -259,16 +222,26 @@ func parseResolver(cfg string) gost.Resolver {
}
}
return
gost
.
NewResolver
(
timeout
,
ttl
,
nss
...
)
return
gost
.
NewResolver
(
timeout
,
ttl
,
nss
...
)
}
}
f
.
Close
()
defer
f
.
Close
()
resolver
:=
gost
.
NewResolver
(
timeout
,
ttl
)
resolver
:=
gost
.
NewResolver
(
timeout
,
ttl
)
resolver
.
Reload
(
f
)
go
gost
.
PeriodReload
(
resolver
,
cfg
)
go
gost
.
PeriodReload
(
resolver
,
cfg
)
return
resolver
return
resolver
}
}
func
parseHosts
(
s
string
)
*
gost
.
Hosts
{
func
parseHosts
(
s
string
)
*
gost
.
Hosts
{
f
,
err
:=
os
.
Open
(
s
)
if
err
!=
nil
{
return
nil
}
defer
f
.
Close
()
hosts
:=
gost
.
NewHosts
()
hosts
:=
gost
.
NewHosts
()
hosts
.
Reload
(
f
)
go
gost
.
PeriodReload
(
hosts
,
s
)
go
gost
.
PeriodReload
(
hosts
,
s
)
return
hosts
return
hosts
...
...
cmd/gost/gost.json
deleted
100644 → 0
View file @
5e0e08d5
{
"Debug"
:
false
,
"Retries"
:
1
,
"ServeNodes"
:
[
":8080"
,
"ss://chacha20:12345678@:8338"
],
"ChainNodes"
:
[
"http://192.168.1.1:8080"
,
"https://10.0.2.1:443"
],
"Routes"
:
[
{
"Retries"
:
1
,
"ServeNodes"
:
[
"ws://:1443"
],
"ChainNodes"
:
[
"socks://:192.168.1.1:1080"
]
},
{
"Retries"
:
3
,
"ServeNodes"
:
[
"quic://:443"
]
}
]
}
\ No newline at end of file
cmd/gost/main.go
View file @
dc4c78ca
...
@@ -71,7 +71,10 @@ func main() {
...
@@ -71,7 +71,10 @@ func main() {
}
}
gost
.
DefaultTLSConfig
=
tlsConfig
gost
.
DefaultTLSConfig
=
tlsConfig
start
()
if
err
:=
start
();
err
!=
nil
{
log
.
Log
(
err
)
os
.
Exit
(
1
)
}
select
{}
select
{}
}
}
...
@@ -79,16 +82,24 @@ func main() {
...
@@ -79,16 +82,24 @@ func main() {
func
start
()
error
{
func
start
()
error
{
gost
.
Debug
=
baseCfg
.
Debug
gost
.
Debug
=
baseCfg
.
Debug
if
err
:=
baseCfg
.
route
.
serve
();
err
!=
nil
{
var
routers
[]
router
rts
,
err
:=
baseCfg
.
route
.
GenRouters
()
if
err
!=
nil
{
return
err
return
err
}
}
routers
=
append
(
routers
,
rts
...
)
for
_
,
route
:=
range
baseCfg
.
Routes
{
for
_
,
route
:=
range
baseCfg
.
Routes
{
if
err
:=
route
.
serve
();
err
!=
nil
{
rts
,
err
:=
route
.
GenRouters
()
if
err
!=
nil
{
return
err
return
err
}
}
routers
=
append
(
routers
,
rts
...
)
}
}
go
gost
.
PeriodReload
(
baseCfg
,
configureFile
)
for
i
:=
range
routers
{
go
routers
[
i
]
.
Serve
()
}
return
nil
return
nil
}
}
cmd/gost/peer.go
View file @
dc4c78ca
...
@@ -26,20 +26,13 @@ type peerConfig struct {
...
@@ -26,20 +26,13 @@ type peerConfig struct {
Nodes
[]
string
`json:"nodes"`
Nodes
[]
string
`json:"nodes"`
group
*
gost
.
NodeGroup
group
*
gost
.
NodeGroup
baseNodes
[]
gost
.
Node
baseNodes
[]
gost
.
Node
stopped
chan
struct
{}
}
}
type
bypass
struct
{
func
newPeerConfig
()
*
peerConfig
{
Reverse
bool
`json:"reverse"`
return
&
peerConfig
{
Patterns
[]
string
`json:"patterns"`
stopped
:
make
(
chan
struct
{}),
}
func
parsePeerConfig
(
cfg
string
,
group
*
gost
.
NodeGroup
,
baseNodes
[]
gost
.
Node
)
*
peerConfig
{
pc
:=
&
peerConfig
{
group
:
group
,
baseNodes
:
baseNodes
,
}
}
go
gost
.
PeriodReload
(
pc
,
cfg
)
return
pc
}
}
func
(
cfg
*
peerConfig
)
Validate
()
{
func
(
cfg
*
peerConfig
)
Validate
()
{
...
@@ -52,28 +45,23 @@ func (cfg *peerConfig) Validate() {
...
@@ -52,28 +45,23 @@ func (cfg *peerConfig) Validate() {
}
}
func
(
cfg
*
peerConfig
)
Reload
(
r
io
.
Reader
)
error
{
func
(
cfg
*
peerConfig
)
Reload
(
r
io
.
Reader
)
error
{
if
cfg
.
Stopped
()
{
return
nil
}
if
err
:=
cfg
.
parse
(
r
);
err
!=
nil
{
if
err
:=
cfg
.
parse
(
r
);
err
!=
nil
{
return
err
return
err
}
}
cfg
.
Validate
()
cfg
.
Validate
()
group
:=
cfg
.
group
group
:=
cfg
.
group
/*
strategy := cfg.Strategy
if len(cfg.baseNodes) > 0 {
// overwrite the strategry in the peer config if `strategy` param exists.
if s := cfg.baseNodes[0].Get("strategy"); s != "" {
strategy = s
}
}
*/
group
.
SetSelector
(
group
.
SetSelector
(
nil
,
nil
,
gost
.
WithFilter
(
&
gost
.
FailFilter
{
gost
.
WithFilter
(
&
gost
.
FailFilter
{
MaxFails
:
cfg
.
MaxFails
,
MaxFails
:
cfg
.
MaxFails
,
FailTimeout
:
cfg
.
FailTimeout
,
FailTimeout
:
cfg
.
FailTimeout
,
}),
}),
gost
.
WithStrategy
(
parse
Strategy
(
cfg
.
Strategy
)),
gost
.
WithStrategy
(
gost
.
New
Strategy
(
cfg
.
Strategy
)),
)
)
gNodes
:=
cfg
.
baseNodes
gNodes
:=
cfg
.
baseNodes
...
@@ -92,7 +80,12 @@ func (cfg *peerConfig) Reload(r io.Reader) error {
...
@@ -92,7 +80,12 @@ func (cfg *peerConfig) Reload(r io.Reader) error {
gNodes
=
append
(
gNodes
,
nodes
...
)
gNodes
=
append
(
gNodes
,
nodes
...
)
}
}
group
.
SetNodes
(
gNodes
...
)
nodes
:=
group
.
SetNodes
(
gNodes
...
)
for
_
,
node
:=
range
nodes
[
len
(
cfg
.
baseNodes
)
:
]
{
if
node
.
Bypass
!=
nil
{
node
.
Bypass
.
Stop
()
// clear the old nodes
}
}
return
nil
return
nil
}
}
...
@@ -154,18 +147,27 @@ func (cfg *peerConfig) parse(r io.Reader) error {
...
@@ -154,18 +147,27 @@ func (cfg *peerConfig) parse(r io.Reader) error {
}
}
func
(
cfg
*
peerConfig
)
Period
()
time
.
Duration
{
func
(
cfg
*
peerConfig
)
Period
()
time
.
Duration
{
if
cfg
.
Stopped
()
{
return
-
1
}
return
cfg
.
period
return
cfg
.
period
}
}
func
parseStrategy
(
s
string
)
gost
.
Strategy
{
// Stop stops reloading.
switch
s
{
func
(
cfg
*
peerConfig
)
Stop
()
{
case
"random"
:
select
{
return
&
gost
.
RandomStrategy
{}
case
<-
cfg
.
stopped
:
case
"fifo"
:
default
:
return
&
gost
.
FIFOStrategy
{}
close
(
cfg
.
stopped
)
case
"round"
:
}
fallthrough
}
// Stopped checks whether the reloader is stopped.
func
(
cfg
*
peerConfig
)
Stopped
()
bool
{
select
{
case
<-
cfg
.
stopped
:
return
true
default
:
default
:
return
&
gost
.
RoundStrategy
{}
return
false
}
}
}
}
cmd/gost/route.go
View file @
dc4c78ca
...
@@ -3,20 +3,32 @@ package main
...
@@ -3,20 +3,32 @@ package main
import
(
import
(
"crypto/sha256"
"crypto/sha256"
"crypto/tls"
"crypto/tls"
"fmt"
"net"
"net"
"os"
"time"
"time"
"github.com/ginuerzh/gost"
"github.com/ginuerzh/gost"
"github.com/go-log/log"
)
)
type
stringList
[]
string
func
(
l
*
stringList
)
String
()
string
{
return
fmt
.
Sprintf
(
"%s"
,
*
l
)
}
func
(
l
*
stringList
)
Set
(
value
string
)
error
{
*
l
=
append
(
*
l
,
value
)
return
nil
}
type
route
struct
{
type
route
struct
{
ServeNodes
stringList
ServeNodes
stringList
ChainNodes
stringList
ChainNodes
stringList
Retries
int
Retries
int
server
*
gost
.
Server
}
}
func
(
r
*
route
)
init
Chain
()
(
*
gost
.
Chain
,
error
)
{
func
(
r
*
route
)
parse
Chain
()
(
*
gost
.
Chain
,
error
)
{
chain
:=
gost
.
NewChain
()
chain
:=
gost
.
NewChain
()
chain
.
Retries
=
r
.
Retries
chain
.
Retries
=
r
.
Retries
gid
:=
1
// group ID
gid
:=
1
// group ID
...
@@ -44,13 +56,20 @@ func (r *route) initChain() (*gost.Chain, error) {
...
@@ -44,13 +56,20 @@ func (r *route) initChain() (*gost.Chain, error) {
MaxFails
:
defaultMaxFails
,
MaxFails
:
defaultMaxFails
,
FailTimeout
:
defaultFailTimeout
,
FailTimeout
:
defaultFailTimeout
,
}),
}),
gost
.
WithStrategy
(
parse
Strategy
(
nodes
[
0
]
.
Get
(
"strategy"
))),
gost
.
WithStrategy
(
gost
.
New
Strategy
(
nodes
[
0
]
.
Get
(
"strategy"
))),
)
)
go
gost
.
PeriodReload
(
&
peerConfig
{
cfg
:=
nodes
[
0
]
.
Get
(
"peer"
)
group
:
ngroup
,
f
,
err
:=
os
.
Open
(
cfg
)
baseNodes
:
nodes
,
if
err
==
nil
{
},
nodes
[
0
]
.
Get
(
"peer"
))
peerCfg
:=
newPeerConfig
()
peerCfg
.
group
=
ngroup
peerCfg
.
baseNodes
=
nodes
peerCfg
.
Reload
(
f
)
f
.
Close
()
go
gost
.
PeriodReload
(
peerCfg
,
cfg
)
}
chain
.
AddNodeGroup
(
ngroup
)
chain
.
AddNodeGroup
(
ngroup
)
}
}
...
@@ -219,20 +238,22 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
...
@@ -219,20 +238,22 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
return
return
}
}
func
(
r
*
route
)
serve
()
error
{
func
(
r
*
route
)
GenRouters
()
([]
router
,
error
)
{
chain
,
err
:=
r
.
init
Chain
()
chain
,
err
:=
r
.
parse
Chain
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
var
rts
[]
router
for
_
,
ns
:=
range
r
.
ServeNodes
{
for
_
,
ns
:=
range
r
.
ServeNodes
{
node
,
err
:=
gost
.
ParseNode
(
ns
)
node
,
err
:=
gost
.
ParseNode
(
ns
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
users
,
err
:=
parseUsers
(
node
.
Get
(
"secrets"
))
users
,
err
:=
parseUsers
(
node
.
Get
(
"secrets"
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
if
node
.
User
!=
nil
{
if
node
.
User
!=
nil
{
users
=
append
(
users
,
node
.
User
)
users
=
append
(
users
,
node
.
User
)
...
@@ -240,7 +261,7 @@ func (r *route) serve() error {
...
@@ -240,7 +261,7 @@ func (r *route) serve() error {
certFile
,
keyFile
:=
node
.
Get
(
"cert"
),
node
.
Get
(
"key"
)
certFile
,
keyFile
:=
node
.
Get
(
"cert"
),
node
.
Get
(
"key"
)
tlsCfg
,
err
:=
tlsConfig
(
certFile
,
keyFile
)
tlsCfg
,
err
:=
tlsConfig
(
certFile
,
keyFile
)
if
err
!=
nil
&&
certFile
!=
""
&&
keyFile
!=
""
{
if
err
!=
nil
&&
certFile
!=
""
&&
keyFile
!=
""
{
return
err
return
nil
,
err
}
}
wsOpts
:=
&
gost
.
WSOptions
{}
wsOpts
:=
&
gost
.
WSOptions
{}
...
@@ -266,7 +287,7 @@ func (r *route) serve() error {
...
@@ -266,7 +287,7 @@ func (r *route) serve() error {
case
"kcp"
:
case
"kcp"
:
config
,
er
:=
parseKCPConfig
(
node
.
Get
(
"c"
))
config
,
er
:=
parseKCPConfig
(
node
.
Get
(
"c"
))
if
er
!=
nil
{
if
er
!=
nil
{
return
er
return
nil
,
er
}
}
ln
,
err
=
gost
.
KCPListener
(
node
.
Addr
,
config
)
ln
,
err
=
gost
.
KCPListener
(
node
.
Addr
,
config
)
case
"ssh"
:
case
"ssh"
:
...
@@ -320,7 +341,7 @@ func (r *route) serve() error {
...
@@ -320,7 +341,7 @@ func (r *route) serve() error {
ln
,
err
=
gost
.
ShadowUDPListener
(
node
.
Addr
,
node
.
User
,
time
.
Duration
(
node
.
GetInt
(
"ttl"
))
*
time
.
Second
)
ln
,
err
=
gost
.
ShadowUDPListener
(
node
.
Addr
,
node
.
User
,
time
.
Duration
(
node
.
GetInt
(
"ttl"
))
*
time
.
Second
)
case
"obfs4"
:
case
"obfs4"
:
if
err
=
gost
.
Obfs4Init
(
node
,
true
);
err
!=
nil
{
if
err
=
gost
.
Obfs4Init
(
node
,
true
);
err
!=
nil
{
return
err
return
nil
,
err
}
}
ln
,
err
=
gost
.
Obfs4Listener
(
node
.
Addr
)
ln
,
err
=
gost
.
Obfs4Listener
(
node
.
Addr
)
case
"ohttp"
:
case
"ohttp"
:
...
@@ -329,7 +350,7 @@ func (r *route) serve() error {
...
@@ -329,7 +350,7 @@ func (r *route) serve() error {
ln
,
err
=
gost
.
TCPListener
(
node
.
Addr
)
ln
,
err
=
gost
.
TCPListener
(
node
.
Addr
)
}
}
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
nil
,
err
}
}
var
handler
gost
.
Handler
var
handler
gost
.
Handler
...
@@ -372,15 +393,19 @@ func (r *route) serve() error {
...
@@ -372,15 +393,19 @@ func (r *route) serve() error {
var
whitelist
,
blacklist
*
gost
.
Permissions
var
whitelist
,
blacklist
*
gost
.
Permissions
if
node
.
Values
.
Get
(
"whitelist"
)
!=
""
{
if
node
.
Values
.
Get
(
"whitelist"
)
!=
""
{
if
whitelist
,
err
=
gost
.
ParsePermissions
(
node
.
Get
(
"whitelist"
));
err
!=
nil
{
if
whitelist
,
err
=
gost
.
ParsePermissions
(
node
.
Get
(
"whitelist"
));
err
!=
nil
{
return
err
return
nil
,
err
}
}
}
}
if
node
.
Values
.
Get
(
"blacklist"
)
!=
""
{
if
node
.
Values
.
Get
(
"blacklist"
)
!=
""
{
if
blacklist
,
err
=
gost
.
ParsePermissions
(
node
.
Get
(
"blacklist"
));
err
!=
nil
{
if
blacklist
,
err
=
gost
.
ParsePermissions
(
node
.
Get
(
"blacklist"
));
err
!=
nil
{
return
err
return
nil
,
err
}
}
}
}
node
.
Bypass
=
parseBypass
(
node
.
Get
(
"bypass"
))
resolver
:=
parseResolver
(
node
.
Get
(
"dns"
))
hosts
:=
parseHosts
(
node
.
Get
(
"hosts"
))
handler
.
Init
(
handler
.
Init
(
gost
.
AddrHandlerOption
(
node
.
Addr
),
gost
.
AddrHandlerOption
(
node
.
Addr
),
gost
.
ChainHandlerOption
(
chain
),
gost
.
ChainHandlerOption
(
chain
),
...
@@ -388,23 +413,44 @@ func (r *route) serve() error {
...
@@ -388,23 +413,44 @@ func (r *route) serve() error {
gost
.
TLSConfigHandlerOption
(
tlsCfg
),
gost
.
TLSConfigHandlerOption
(
tlsCfg
),
gost
.
WhitelistHandlerOption
(
whitelist
),
gost
.
WhitelistHandlerOption
(
whitelist
),
gost
.
BlacklistHandlerOption
(
blacklist
),
gost
.
BlacklistHandlerOption
(
blacklist
),
gost
.
StrategyHandlerOption
(
parse
Strategy
(
node
.
Get
(
"strategy"
))),
gost
.
StrategyHandlerOption
(
gost
.
New
Strategy
(
node
.
Get
(
"strategy"
))),
gost
.
BypassHandlerOption
(
parseBypass
(
node
.
Get
(
"bypass"
))
),
gost
.
BypassHandlerOption
(
node
.
Bypass
),
gost
.
ResolverHandlerOption
(
parseResolver
(
node
.
Get
(
"dns"
))
),
gost
.
ResolverHandlerOption
(
resolver
),
gost
.
HostsHandlerOption
(
parseHosts
(
node
.
Get
(
"hosts"
))
),
gost
.
HostsHandlerOption
(
hosts
),
gost
.
RetryHandlerOption
(
node
.
GetInt
(
"retry"
)),
gost
.
RetryHandlerOption
(
node
.
GetInt
(
"retry"
)),
gost
.
TimeoutHandlerOption
(
time
.
Duration
(
node
.
GetInt
(
"timeout"
))
*
time
.
Second
),
gost
.
TimeoutHandlerOption
(
time
.
Duration
(
node
.
GetInt
(
"timeout"
))
*
time
.
Second
),
gost
.
ProbeResistHandlerOption
(
node
.
Get
(
"probe_resist"
)),
gost
.
ProbeResistHandlerOption
(
node
.
Get
(
"probe_resist"
)),
)
)
r
.
server
=
&
gost
.
Server
{
Listener
:
ln
}
rt
:=
router
{
go
r
.
server
.
Serve
(
handler
)
node
:
node
,
server
:
&
gost
.
Server
{
Listener
:
ln
},
handler
:
handler
,
chain
:
chain
,
resolver
:
resolver
,
hosts
:
hosts
,
}
rts
=
append
(
rts
,
rt
)
}
}
return
nil
return
rts
,
nil
}
type
router
struct
{
node
gost
.
Node
server
*
gost
.
Server
handler
gost
.
Handler
chain
*
gost
.
Chain
resolver
gost
.
Resolver
hosts
*
gost
.
Hosts
}
func
(
r
*
router
)
Serve
()
error
{
log
.
Logf
(
"[route] start %s on %s"
,
r
.
node
.
String
(),
r
.
server
.
Addr
())
return
r
.
server
.
Serve
(
r
.
handler
)
}
}
func
(
r
*
route
)
Close
()
error
{
func
(
r
*
route
r
)
Close
()
error
{
if
r
==
nil
||
r
.
server
==
nil
{
if
r
==
nil
||
r
.
server
==
nil
{
return
nil
return
nil
}
}
...
...
hosts.go
View file @
dc4c78ca
...
@@ -24,15 +24,17 @@ type Host struct {
...
@@ -24,15 +24,17 @@ type Host struct {
// Fields of the entry are separated by any number of blanks and/or tab characters.
// Fields of the entry are separated by any number of blanks and/or tab characters.
// Text from a "#" character until the end of the line is a comment, and is ignored.
// Text from a "#" character until the end of the line is a comment, and is ignored.
type
Hosts
struct
{
type
Hosts
struct
{
hosts
[]
Host
hosts
[]
Host
period
time
.
Duration
period
time
.
Duration
mux
sync
.
RWMutex
stopped
chan
struct
{}
mux
sync
.
RWMutex
}
}
// NewHosts creates a Hosts with optional list of host
// NewHosts creates a Hosts with optional list of host
func
NewHosts
(
hosts
...
Host
)
*
Hosts
{
func
NewHosts
(
hosts
...
Host
)
*
Hosts
{
return
&
Hosts
{
return
&
Hosts
{
hosts
:
hosts
,
hosts
:
hosts
,
stopped
:
make
(
chan
struct
{}),
}
}
}
}
...
@@ -76,6 +78,10 @@ func (h *Hosts) Reload(r io.Reader) error {
...
@@ -76,6 +78,10 @@ func (h *Hosts) Reload(r io.Reader) error {
var
period
time
.
Duration
var
period
time
.
Duration
var
hosts
[]
Host
var
hosts
[]
Host
if
h
.
Stopped
()
{
return
nil
}
scanner
:=
bufio
.
NewScanner
(
r
)
scanner
:=
bufio
.
NewScanner
(
r
)
for
scanner
.
Scan
()
{
for
scanner
.
Scan
()
{
line
:=
scanner
.
Text
()
line
:=
scanner
.
Text
()
...
@@ -130,8 +136,31 @@ func (h *Hosts) Reload(r io.Reader) error {
...
@@ -130,8 +136,31 @@ func (h *Hosts) Reload(r io.Reader) error {
// Period returns the reload period
// Period returns the reload period
func
(
h
*
Hosts
)
Period
()
time
.
Duration
{
func
(
h
*
Hosts
)
Period
()
time
.
Duration
{
if
h
.
Stopped
()
{
return
-
1
}
h
.
mux
.
RLock
()
h
.
mux
.
RLock
()
defer
h
.
mux
.
RUnlock
()
defer
h
.
mux
.
RUnlock
()
return
h
.
period
return
h
.
period
}
}
// Stop stops reloading.
func
(
h
*
Hosts
)
Stop
()
{
select
{
case
<-
h
.
stopped
:
default
:
close
(
h
.
stopped
)
}
}
// Stopped checks whether the reloader is stopped.
func
(
h
*
Hosts
)
Stopped
()
bool
{
select
{
case
<-
h
.
stopped
:
return
true
default
:
return
false
}
}
http.go
View file @
dc4c78ca
...
@@ -263,7 +263,7 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
...
@@ -263,7 +263,7 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
if
err
==
nil
{
if
err
==
nil
{
return
return
}
}
log
.
Logf
(
"[http] %s -> %s : %s"
,
conn
.
RemoteAddr
(),
req
.
Host
,
err
)
//
log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), req.Host, err)
continue
continue
}
}
...
...
http2.go
View file @
dc4c78ca
...
@@ -468,6 +468,7 @@ func (h *http2Handler) writeResponse(w http.ResponseWriter, resp *http.Response)
...
@@ -468,6 +468,7 @@ func (h *http2Handler) writeResponse(w http.ResponseWriter, resp *http.Response)
type
http2Listener
struct
{
type
http2Listener
struct
{
server
*
http
.
Server
server
*
http
.
Server
connChan
chan
*
http2ServerConn
connChan
chan
*
http2ServerConn
addr
net
.
Addr
errChan
chan
error
errChan
chan
error
}
}
...
@@ -494,6 +495,8 @@ func HTTP2Listener(addr string, config *tls.Config) (Listener, error) {
...
@@ -494,6 +495,8 @@ func HTTP2Listener(addr string, config *tls.Config) (Listener, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
l
.
addr
=
ln
.
Addr
()
go
func
()
{
go
func
()
{
err
:=
server
.
Serve
(
ln
)
err
:=
server
.
Serve
(
ln
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -532,8 +535,7 @@ func (l *http2Listener) Accept() (conn net.Conn, err error) {
...
@@ -532,8 +535,7 @@ func (l *http2Listener) Accept() (conn net.Conn, err error) {
}
}
func
(
l
*
http2Listener
)
Addr
()
net
.
Addr
{
func
(
l
*
http2Listener
)
Addr
()
net
.
Addr
{
addr
,
_
:=
net
.
ResolveTCPAddr
(
"tcp"
,
l
.
server
.
Addr
)
return
l
.
addr
return
addr
}
}
func
(
l
*
http2Listener
)
Close
()
(
err
error
)
{
func
(
l
*
http2Listener
)
Close
()
(
err
error
)
{
...
...
node.go
View file @
dc4c78ca
...
@@ -2,7 +2,6 @@ package gost
...
@@ -2,7 +2,6 @@ package gost
import
(
import
(
"errors"
"errors"
"fmt"
"net/url"
"net/url"
"strconv"
"strconv"
"strings"
"strings"
...
@@ -22,6 +21,7 @@ type Node struct {
...
@@ -22,6 +21,7 @@ type Node struct {
Protocol
string
Protocol
string
Transport
string
Transport
string
Remote
string
// remote address, used by tcp/udp port forwarding
Remote
string
// remote address, used by tcp/udp port forwarding
url
string
// raw url
User
*
url
.
Userinfo
User
*
url
.
Userinfo
Values
url
.
Values
Values
url
.
Values
DialOptions
[]
DialOption
DialOptions
[]
DialOption
...
@@ -57,6 +57,9 @@ func ParseNode(s string) (node Node, err error) {
...
@@ -57,6 +57,9 @@ func ParseNode(s string) (node Node, err error) {
marker
:
&
failMarker
{},
marker
:
&
failMarker
{},
}
}
u
.
RawQuery
=
""
node
.
url
=
u
.
String
()
schemes
:=
strings
.
Split
(
u
.
Scheme
,
"+"
)
schemes
:=
strings
.
Split
(
u
.
Scheme
,
"+"
)
if
len
(
schemes
)
==
1
{
if
len
(
schemes
)
==
1
{
node
.
Protocol
=
schemes
[
0
]
node
.
Protocol
=
schemes
[
0
]
...
@@ -136,8 +139,7 @@ func (node *Node) GetInt(key string) int {
...
@@ -136,8 +139,7 @@ func (node *Node) GetInt(key string) int {
}
}
func
(
node
Node
)
String
()
string
{
func
(
node
Node
)
String
()
string
{
return
fmt
.
Sprintf
(
"%d@%s+%s://%s"
,
return
node
.
url
node
.
ID
,
node
.
Protocol
,
node
.
Transport
,
node
.
Addr
)
}
}
// NodeGroup is a group of nodes.
// NodeGroup is a group of nodes.
...
@@ -167,16 +169,19 @@ func (group *NodeGroup) AddNode(node ...Node) {
...
@@ -167,16 +169,19 @@ func (group *NodeGroup) AddNode(node ...Node) {
group
.
nodes
=
append
(
group
.
nodes
,
node
...
)
group
.
nodes
=
append
(
group
.
nodes
,
node
...
)
}
}
// SetNodes replaces the group nodes to the specified nodes.
// SetNodes replaces the group nodes to the specified nodes,
func
(
group
*
NodeGroup
)
SetNodes
(
nodes
...
Node
)
{
// and returns the previous nodes.
func
(
group
*
NodeGroup
)
SetNodes
(
nodes
...
Node
)
[]
Node
{
if
group
==
nil
{
if
group
==
nil
{
return
return
nil
}
}
group
.
mux
.
Lock
()
group
.
mux
.
Lock
()
defer
group
.
mux
.
Unlock
()
defer
group
.
mux
.
Unlock
()
old
:=
group
.
nodes
group
.
nodes
=
nodes
group
.
nodes
=
nodes
return
old
}
}
// SetSelector sets node selector with options for the group.
// SetSelector sets node selector with options for the group.
...
...
node_test.go
View file @
dc4c78ca
...
@@ -8,7 +8,7 @@ var nodeTests = []struct {
...
@@ -8,7 +8,7 @@ var nodeTests = []struct {
out
Node
out
Node
hasError
bool
hasError
bool
}{
}{
{
""
,
Node
{},
fals
e
},
{
""
,
Node
{},
tru
e
},
{
"://"
,
Node
{},
true
},
{
"://"
,
Node
{},
true
},
{
"localhost"
,
Node
{
Addr
:
"localhost"
,
Transport
:
"tcp"
},
false
},
{
"localhost"
,
Node
{
Addr
:
"localhost"
,
Transport
:
"tcp"
},
false
},
{
":"
,
Node
{
Addr
:
":"
,
Transport
:
"tcp"
},
false
},
{
":"
,
Node
{
Addr
:
":"
,
Transport
:
"tcp"
},
false
},
...
...
reload.go
View file @
dc4c78ca
...
@@ -14,43 +14,71 @@ type Reloader interface {
...
@@ -14,43 +14,71 @@ type Reloader interface {
Period
()
time
.
Duration
Period
()
time
.
Duration
}
}
// PeriodReload reloads the config periodically according to the period of the reloader.
// Stoppable is the interface that indicates a Reloader can be stopped.
type
Stoppable
interface
{
Stop
()
}
//StopReloader is the interface that adds Stop method to the Reloader.
type
StopReloader
interface
{
Reloader
Stoppable
}
type
nopStoppable
struct
{
Reloader
}
func
(
nopStoppable
)
Stop
()
{
return
}
// NopStoppable returns a StopReloader with a no-op Stop method,
// wrapping the provided Reloader r.
func
NopStoppable
(
r
Reloader
)
StopReloader
{
return
nopStoppable
{
r
}
}
// PeriodReload reloads the config configFile periodically according to the period of the Reloader r.
func
PeriodReload
(
r
Reloader
,
configFile
string
)
error
{
func
PeriodReload
(
r
Reloader
,
configFile
string
)
error
{
if
configFile
==
""
{
if
r
==
nil
||
configFile
==
""
{
return
nil
return
nil
}
}
var
lastMod
time
.
Time
var
lastMod
time
.
Time
for
{
for
{
if
r
.
Period
()
<
0
{
log
.
Log
(
"[reload] stopped:"
,
configFile
)
return
nil
}
f
,
err
:=
os
.
Open
(
configFile
)
f
,
err
:=
os
.
Open
(
configFile
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
finfo
,
err
:=
f
.
Stat
()
mt
:=
lastMod
if
err
!=
nil
{
if
finfo
,
err
:=
f
.
Stat
();
err
==
nil
{
f
.
Close
()
mt
=
finfo
.
ModTime
()
return
err
}
}
mt
:=
finfo
.
ModTime
()
if
!
mt
.
Equal
(
lastMod
)
{
if
!
lastMod
.
IsZero
()
&&
!
mt
.
Equal
(
lastMod
)
{
log
.
Log
(
"[reload]"
,
configFile
)
log
.
Log
(
"[reload]"
,
configFile
)
if
err
:=
r
.
Reload
(
f
);
err
!=
nil
{
if
err
:=
r
.
Reload
(
f
);
err
!=
nil
{
log
.
Logf
(
"[reload] %s: %s"
,
configFile
,
err
)
log
.
Logf
(
"[reload] %s: %s"
,
configFile
,
err
)
}
}
lastMod
=
mt
}
}
f
.
Close
()
f
.
Close
()
lastMod
=
mt
period
:=
r
.
Period
()
period
:=
r
.
Period
()
if
period
<
=
0
{
if
period
=
=
0
{
log
.
Log
(
"[reload] disabled:"
,
configFile
)
log
.
Log
(
"[reload] disabled:"
,
configFile
)
return
nil
return
nil
}
}
if
period
<
time
.
Second
{
if
period
<
time
.
Second
{
period
=
time
.
Second
period
=
time
.
Second
}
}
<-
time
.
After
(
period
)
<-
time
.
After
(
period
)
}
}
}
}
resolver.go
View file @
dc4c78ca
...
@@ -29,10 +29,11 @@ type Resolver interface {
...
@@ -29,10 +29,11 @@ type Resolver interface {
Resolve
(
host
string
)
([]
net
.
IP
,
error
)
Resolve
(
host
string
)
([]
net
.
IP
,
error
)
}
}
// ReloadResolver is resolover that support live reloading
// ReloadResolver is resolover that support live reloading
.
type
ReloadResolver
interface
{
type
ReloadResolver
interface
{
Resolver
Resolver
Reloader
Reloader
Stoppable
}
}
// NameServer is a name server.
// NameServer is a name server.
...
@@ -68,6 +69,7 @@ type resolver struct {
...
@@ -68,6 +69,7 @@ type resolver struct {
TTL
time
.
Duration
TTL
time
.
Duration
period
time
.
Duration
period
time
.
Duration
domain
string
domain
string
stopped
chan
struct
{}
mux
sync
.
RWMutex
mux
sync
.
RWMutex
}
}
...
@@ -78,6 +80,7 @@ func NewResolver(timeout, ttl time.Duration, servers ...NameServer) ReloadResolv
...
@@ -78,6 +80,7 @@ func NewResolver(timeout, ttl time.Duration, servers ...NameServer) ReloadResolv
Timeout
:
timeout
,
Timeout
:
timeout
,
TTL
:
ttl
,
TTL
:
ttl
,
mCache
:
&
sync
.
Map
{},
mCache
:
&
sync
.
Map
{},
stopped
:
make
(
chan
struct
{}),
}
}
if
r
.
Timeout
<=
0
{
if
r
.
Timeout
<=
0
{
...
@@ -110,6 +113,7 @@ func (r *resolver) Resolve(host string) (ips []net.IP, err error) {
...
@@ -110,6 +113,7 @@ func (r *resolver) Resolve(host string) (ips []net.IP, err error) {
r
.
mux
.
RLock
()
r
.
mux
.
RLock
()
domain
=
r
.
domain
domain
=
r
.
domain
timeout
=
r
.
Timeout
timeout
=
r
.
Timeout
ttl
=
r
.
TTL
servers
=
r
.
copyServers
()
servers
=
r
.
copyServers
()
r
.
mux
.
RUnlock
()
r
.
mux
.
RUnlock
()
...
@@ -219,6 +223,10 @@ func (r *resolver) Reload(rd io.Reader) error {
...
@@ -219,6 +223,10 @@ func (r *resolver) Reload(rd io.Reader) error {
var
domain
string
var
domain
string
var
nss
[]
NameServer
var
nss
[]
NameServer
if
r
.
Stopped
()
{
return
nil
}
split
:=
func
(
line
string
)
[]
string
{
split
:=
func
(
line
string
)
[]
string
{
if
line
==
""
{
if
line
==
""
{
return
nil
return
nil
...
@@ -305,12 +313,35 @@ func (r *resolver) Reload(rd io.Reader) error {
...
@@ -305,12 +313,35 @@ func (r *resolver) Reload(rd io.Reader) error {
}
}
func
(
r
*
resolver
)
Period
()
time
.
Duration
{
func
(
r
*
resolver
)
Period
()
time
.
Duration
{
if
r
.
Stopped
()
{
return
-
1
}
r
.
mux
.
RLock
()
r
.
mux
.
RLock
()
defer
r
.
mux
.
RUnlock
()
defer
r
.
mux
.
RUnlock
()
return
r
.
period
return
r
.
period
}
}
// Stop stops reloading.
func
(
r
*
resolver
)
Stop
()
{
select
{
case
<-
r
.
stopped
:
default
:
close
(
r
.
stopped
)
}
}
// Stopped checks whether the reloader is stopped.
func
(
r
*
resolver
)
Stopped
()
bool
{
select
{
case
<-
r
.
stopped
:
return
true
default
:
return
false
}
}
func
(
r
*
resolver
)
String
()
string
{
func
(
r
*
resolver
)
String
()
string
{
if
r
==
nil
{
if
r
==
nil
{
return
""
return
""
...
...
selector.go
View file @
dc4c78ca
...
@@ -68,6 +68,20 @@ type Strategy interface {
...
@@ -68,6 +68,20 @@ type Strategy interface {
String
()
string
String
()
string
}
}
// NewStrategy creates a Strategy by the name s.
func
NewStrategy
(
s
string
)
Strategy
{
switch
s
{
case
"random"
:
return
&
RandomStrategy
{}
case
"fifo"
:
return
&
FIFOStrategy
{}
case
"round"
:
fallthrough
default
:
return
&
RoundStrategy
{}
}
}
// RoundStrategy is a strategy for node selector.
// RoundStrategy is a strategy for node selector.
// The node will be selected by round-robin algorithm.
// The node will be selected by round-robin algorithm.
type
RoundStrategy
struct
{
type
RoundStrategy
struct
{
...
...
server.go
View file @
dc4c78ca
...
@@ -86,21 +86,11 @@ func (s *Server) Serve(h Handler, opts ...ServerOption) error {
...
@@ -86,21 +86,11 @@ func (s *Server) Serve(h Handler, opts ...ServerOption) error {
// ServerOptions holds the options for Server.
// ServerOptions holds the options for Server.
type
ServerOptions
struct
{
type
ServerOptions
struct
{
Bypass
*
Bypass
}
}
// ServerOption allows a common way to set server options.
// ServerOption allows a common way to set server options.
type
ServerOption
func
(
opts
*
ServerOptions
)
type
ServerOption
func
(
opts
*
ServerOptions
)
/*
// BypassServerOption sets the bypass option of ServerOptions.
func BypassServerOption(bypass *Bypass) ServerOption {
return func(opts *ServerOptions) {
opts.Bypass = bypass
}
}
*/
// Listener is a proxy server listener, just like a net.Listener.
// Listener is a proxy server listener, just like a net.Listener.
type
Listener
interface
{
type
Listener
interface
{
net
.
Listener
net
.
Listener
...
...
ss.go
View file @
dc4c78ca
...
@@ -84,8 +84,9 @@ func (c *shadowConnector) Connect(conn net.Conn, addr string, options ...Connect
...
@@ -84,8 +84,9 @@ func (c *shadowConnector) Connect(conn net.Conn, addr string, options ...Connect
return
nil
,
err
return
nil
,
err
}
}
sc
,
err
:=
ss
.
DialWithRawAddrConn
(
rawaddr
,
conn
,
cipher
)
sc
:=
ss
.
NewConn
(
conn
,
cipher
)
if
err
!=
nil
{
// sc, err := ss.DialWithRawAddrConn(rawaddr, conn, cipher)
if
_
,
err
:=
sc
.
Write
(
rawaddr
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
&
shadowConn
{
conn
:
sc
},
nil
return
&
shadowConn
{
conn
:
sc
},
nil
...
...
ws.go
View file @
dc4c78ca
...
@@ -384,7 +384,6 @@ func WSListener(addr string, options *WSOptions) (Listener, error) {
...
@@ -384,7 +384,6 @@ func WSListener(addr string, options *WSOptions) (Listener, error) {
options
=
&
WSOptions
{}
options
=
&
WSOptions
{}
}
}
l
:=
&
wsListener
{
l
:=
&
wsListener
{
addr
:
tcpAddr
,
upgrader
:
&
websocket
.
Upgrader
{
upgrader
:
&
websocket
.
Upgrader
{
ReadBufferSize
:
options
.
ReadBufferSize
,
ReadBufferSize
:
options
.
ReadBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
...
@@ -403,6 +402,7 @@ func WSListener(addr string, options *WSOptions) (Listener, error) {
...
@@ -403,6 +402,7 @@ func WSListener(addr string, options *WSOptions) (Listener, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
l
.
addr
=
ln
.
Addr
()
go
func
()
{
go
func
()
{
err
:=
l
.
srv
.
Serve
(
tcpKeepAliveListener
{
ln
})
err
:=
l
.
srv
.
Serve
(
tcpKeepAliveListener
{
ln
})
...
@@ -473,7 +473,6 @@ func MWSListener(addr string, options *WSOptions) (Listener, error) {
...
@@ -473,7 +473,6 @@ func MWSListener(addr string, options *WSOptions) (Listener, error) {
options
=
&
WSOptions
{}
options
=
&
WSOptions
{}
}
}
l
:=
&
mwsListener
{
l
:=
&
mwsListener
{
addr
:
tcpAddr
,
upgrader
:
&
websocket
.
Upgrader
{
upgrader
:
&
websocket
.
Upgrader
{
ReadBufferSize
:
options
.
ReadBufferSize
,
ReadBufferSize
:
options
.
ReadBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
...
@@ -492,6 +491,7 @@ func MWSListener(addr string, options *WSOptions) (Listener, error) {
...
@@ -492,6 +491,7 @@ func MWSListener(addr string, options *WSOptions) (Listener, error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
l
.
addr
=
ln
.
Addr
()
go
func
()
{
go
func
()
{
err
:=
l
.
srv
.
Serve
(
tcpKeepAliveListener
{
ln
})
err
:=
l
.
srv
.
Serve
(
tcpKeepAliveListener
{
ln
})
...
@@ -584,7 +584,6 @@ func WSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Listen
...
@@ -584,7 +584,6 @@ func WSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Listen
}
}
l
:=
&
wssListener
{
l
:=
&
wssListener
{
wsListener
:
&
wsListener
{
wsListener
:
&
wsListener
{
addr
:
tcpAddr
,
upgrader
:
&
websocket
.
Upgrader
{
upgrader
:
&
websocket
.
Upgrader
{
ReadBufferSize
:
options
.
ReadBufferSize
,
ReadBufferSize
:
options
.
ReadBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
...
@@ -612,6 +611,7 @@ func WSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Listen
...
@@ -612,6 +611,7 @@ func WSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Listen
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
l
.
addr
=
ln
.
Addr
()
go
func
()
{
go
func
()
{
err
:=
l
.
srv
.
Serve
(
tls
.
NewListener
(
tcpKeepAliveListener
{
ln
},
tlsConfig
))
err
:=
l
.
srv
.
Serve
(
tls
.
NewListener
(
tcpKeepAliveListener
{
ln
},
tlsConfig
))
...
@@ -644,7 +644,6 @@ func MWSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Liste
...
@@ -644,7 +644,6 @@ func MWSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Liste
}
}
l
:=
&
mwssListener
{
l
:=
&
mwssListener
{
mwsListener
:
&
mwsListener
{
mwsListener
:
&
mwsListener
{
addr
:
tcpAddr
,
upgrader
:
&
websocket
.
Upgrader
{
upgrader
:
&
websocket
.
Upgrader
{
ReadBufferSize
:
options
.
ReadBufferSize
,
ReadBufferSize
:
options
.
ReadBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
WriteBufferSize
:
options
.
WriteBufferSize
,
...
@@ -672,6 +671,7 @@ func MWSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Liste
...
@@ -672,6 +671,7 @@ func MWSSListener(addr string, tlsConfig *tls.Config, options *WSOptions) (Liste
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
l
.
addr
=
ln
.
Addr
()
go
func
()
{
go
func
()
{
err
:=
l
.
srv
.
Serve
(
tls
.
NewListener
(
tcpKeepAliveListener
{
ln
},
tlsConfig
))
err
:=
l
.
srv
.
Serve
(
tls
.
NewListener
(
tcpKeepAliveListener
{
ln
},
tlsConfig
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment