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
003c5a50
Commit
003c5a50
authored
Nov 15, 2017
by
rui.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
enhancement configuration
parent
3befde01
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
105 additions
and
32 deletions
+105
-32
chain.go
chain.go
+6
-2
cmd/gost/gost.json
cmd/gost/gost.json
+20
-0
cmd/gost/main.go
cmd/gost/main.go
+47
-19
handler.go
handler.go
+2
-1
node.go
node.go
+25
-5
selector.go
selector.go
+5
-5
No files found.
chain.go
View file @
003c5a50
...
@@ -17,6 +17,7 @@ var (
...
@@ -17,6 +17,7 @@ var (
// Chain is a proxy chain that holds a list of proxy nodes.
// Chain is a proxy chain that holds a list of proxy nodes.
type
Chain
struct
{
type
Chain
struct
{
isRoute
bool
isRoute
bool
Retries
int
nodeGroups
[]
*
NodeGroup
nodeGroups
[]
*
NodeGroup
}
}
...
@@ -58,8 +59,8 @@ func (c *Chain) LastNode() Node {
...
@@ -58,8 +59,8 @@ func (c *Chain) LastNode() Node {
if
c
.
IsEmpty
()
{
if
c
.
IsEmpty
()
{
return
Node
{}
return
Node
{}
}
}
last
:=
c
.
nodeGroups
[
len
(
c
.
nodeGroups
)
-
1
]
group
:=
c
.
nodeGroups
[
len
(
c
.
nodeGroups
)
-
1
]
return
last
.
nodes
[
0
]
return
group
.
nodes
[
0
]
.
Clone
()
}
}
// LastNodeGroup returns the last group of the group list.
// LastNodeGroup returns the last group of the group list.
...
@@ -185,6 +186,8 @@ func (c *Chain) selectRoute() (route *Chain, err error) {
...
@@ -185,6 +186,8 @@ func (c *Chain) selectRoute() (route *Chain, err error) {
buf
:=
bytes
.
Buffer
{}
buf
:=
bytes
.
Buffer
{}
route
=
newRoute
()
route
=
newRoute
()
route
.
Retries
=
c
.
Retries
for
_
,
group
:=
range
c
.
nodeGroups
{
for
_
,
group
:=
range
c
.
nodeGroups
{
node
,
err
:=
group
.
Next
()
node
,
err
:=
group
.
Next
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -197,6 +200,7 @@ func (c *Chain) selectRoute() (route *Chain, err error) {
...
@@ -197,6 +200,7 @@ func (c *Chain) selectRoute() (route *Chain, err error) {
ChainDialOption
(
route
),
ChainDialOption
(
route
),
)
)
route
=
newRoute
()
// cutoff the chain for multiplex.
route
=
newRoute
()
// cutoff the chain for multiplex.
route
.
Retries
=
c
.
Retries
}
}
route
.
AddNode
(
node
)
route
.
AddNode
(
node
)
...
...
cmd/gost/gost.json
View file @
003c5a50
{
{
"Debug"
:
false
,
"Retries"
:
1
,
"ServeNodes"
:
[
"ServeNodes"
:
[
":8080"
,
":8080"
,
"ss://chacha20:12345678@:8338"
"ss://chacha20:12345678@:8338"
...
@@ -6,5 +8,23 @@
...
@@ -6,5 +8,23 @@
"ChainNodes"
:
[
"ChainNodes"
:
[
"http://192.168.1.1:8080"
,
"http://192.168.1.1:8080"
,
"https://10.0.2.1:443"
"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 @
003c5a50
...
@@ -22,10 +22,8 @@ import (
...
@@ -22,10 +22,8 @@ import (
)
)
var
(
var
(
options
struct
{
options
route
ChainNodes
,
ServeNodes
stringList
routes
[]
route
Debug
bool
}
)
)
func
init
()
{
func
init
()
{
...
@@ -43,12 +41,17 @@ func init() {
...
@@ -43,12 +41,17 @@ func init() {
flag
.
BoolVar
(
&
printVersion
,
"V"
,
false
,
"print version"
)
flag
.
BoolVar
(
&
printVersion
,
"V"
,
false
,
"print version"
)
flag
.
Parse
()
flag
.
Parse
()
if
len
(
options
.
ServeNodes
)
>
0
{
routes
=
append
(
routes
,
options
)
}
gost
.
Debug
=
options
.
Debug
if
err
:=
loadConfigureFile
(
configureFile
);
err
!=
nil
{
if
err
:=
loadConfigureFile
(
configureFile
);
err
!=
nil
{
log
.
Log
(
err
)
log
.
Log
(
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
if
flag
.
NFlag
()
==
0
{
if
flag
.
NFlag
()
==
0
||
len
(
routes
)
==
0
{
flag
.
PrintDefaults
()
flag
.
PrintDefaults
()
os
.
Exit
(
0
)
os
.
Exit
(
0
)
}
}
...
@@ -58,7 +61,7 @@ func init() {
...
@@ -58,7 +61,7 @@ func init() {
os
.
Exit
(
0
)
os
.
Exit
(
0
)
}
}
gost
.
Debug
=
options
.
Debug
log
.
Log
(
"Debug:"
,
gost
.
Debug
)
}
}
func
main
()
{
func
main
()
{
...
@@ -72,24 +75,29 @@ func main() {
...
@@ -72,24 +75,29 @@ func main() {
Certificates
:
[]
tls
.
Certificate
{
cert
},
Certificates
:
[]
tls
.
Certificate
{
cert
},
}
}
chain
,
err
:=
initChain
()
for
_
,
route
:=
range
routes
{
if
err
!=
nil
{
if
err
:=
route
.
serve
();
err
!=
nil
{
log
.
Log
(
err
)
log
.
Log
(
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
if
err
:=
serve
(
chain
);
err
!=
nil
{
log
.
Log
(
err
)
os
.
Exit
(
1
)
}
}
select
{}
select
{}
}
}
func
initChain
()
(
*
gost
.
Chain
,
error
)
{
type
route
struct
{
ChainNodes
,
ServeNodes
stringList
Retries
int
Debug
bool
}
func
(
r
*
route
)
initChain
()
(
*
gost
.
Chain
,
error
)
{
chain
:=
gost
.
NewChain
()
chain
:=
gost
.
NewChain
()
chain
.
Retries
=
r
.
Retries
gid
:=
1
// group ID
gid
:=
1
// group ID
for
_
,
ns
:=
range
options
.
ChainNodes
{
for
_
,
ns
:=
range
r
.
ChainNodes
{
ngroup
:=
gost
.
NewNodeGroup
()
ngroup
:=
gost
.
NewNodeGroup
()
ngroup
.
ID
=
gid
ngroup
.
ID
=
gid
gid
++
gid
++
...
@@ -297,8 +305,13 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
...
@@ -297,8 +305,13 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
return
return
}
}
func
serve
(
chain
*
gost
.
Chain
)
error
{
func
(
r
*
route
)
serve
()
error
{
for
_
,
ns
:=
range
options
.
ServeNodes
{
chain
,
err
:=
r
.
initChain
()
if
err
!=
nil
{
return
err
}
for
_
,
ns
:=
range
r
.
ServeNodes
{
node
,
err
:=
gost
.
ParseNode
(
ns
)
node
,
err
:=
gost
.
ParseNode
(
ns
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -507,9 +520,24 @@ func loadConfigureFile(configureFile string) error {
...
@@ -507,9 +520,24 @@ func loadConfigureFile(configureFile string) error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
err
:=
json
.
Unmarshal
(
content
,
&
options
);
err
!=
nil
{
var
cfg
struct
{
route
Routes
[]
route
}
if
err
:=
json
.
Unmarshal
(
content
,
&
cfg
);
err
!=
nil
{
return
err
return
err
}
}
if
len
(
cfg
.
route
.
ServeNodes
)
>
0
{
routes
=
append
(
routes
,
cfg
.
route
)
}
for
_
,
route
:=
range
cfg
.
Routes
{
if
len
(
cfg
.
route
.
ServeNodes
)
>
0
{
routes
=
append
(
routes
,
route
)
}
}
gost
.
Debug
=
cfg
.
Debug
return
nil
return
nil
}
}
...
...
handler.go
View file @
003c5a50
...
@@ -95,7 +95,8 @@ func (h *autoHandler) Handle(conn net.Conn) {
...
@@ -95,7 +95,8 @@ func (h *autoHandler) Handle(conn net.Conn) {
cc
:=
&
bufferdConn
{
Conn
:
conn
,
br
:
br
}
cc
:=
&
bufferdConn
{
Conn
:
conn
,
br
:
br
}
switch
b
[
0
]
{
switch
b
[
0
]
{
case
gosocks4
.
Ver4
:
case
gosocks4
.
Ver4
:
return
// SOCKS4(a) does not suppport authentication method, so we ignore it.
cc
.
Close
()
return
// SOCKS4(a) does not suppport authentication method, so we ignore it for security reason.
case
gosocks5
.
Ver5
:
case
gosocks5
.
Ver5
:
SOCKS5Handler
(
h
.
options
...
)
.
Handle
(
cc
)
SOCKS5Handler
(
h
.
options
...
)
.
Handle
(
cc
)
default
:
// http
default
:
// http
...
...
node.go
View file @
003c5a50
...
@@ -23,7 +23,7 @@ type Node struct {
...
@@ -23,7 +23,7 @@ type Node struct {
Client
*
Client
Client
*
Client
group
*
NodeGroup
group
*
NodeGroup
failCount
uint32
failCount
uint32
failTime
time
.
Time
failTime
int64
}
}
// ParseNode parses the node info.
// ParseNode parses the node info.
...
@@ -89,7 +89,7 @@ func ParseNode(s string) (node Node, err error) {
...
@@ -89,7 +89,7 @@ func ParseNode(s string) (node Node, err error) {
// MarkDead marks the node fail status.
// MarkDead marks the node fail status.
func
(
node
*
Node
)
MarkDead
()
{
func
(
node
*
Node
)
MarkDead
()
{
atomic
.
AddUint32
(
&
node
.
failCount
,
1
)
atomic
.
AddUint32
(
&
node
.
failCount
,
1
)
node
.
failTime
=
time
.
Now
(
)
atomic
.
StoreInt64
(
&
node
.
failTime
,
time
.
Now
()
.
Unix
()
)
if
node
.
group
==
nil
{
if
node
.
group
==
nil
{
return
return
...
@@ -97,7 +97,7 @@ func (node *Node) MarkDead() {
...
@@ -97,7 +97,7 @@ func (node *Node) MarkDead() {
for
i
:=
range
node
.
group
.
nodes
{
for
i
:=
range
node
.
group
.
nodes
{
if
node
.
group
.
nodes
[
i
]
.
ID
==
node
.
ID
{
if
node
.
group
.
nodes
[
i
]
.
ID
==
node
.
ID
{
atomic
.
AddUint32
(
&
node
.
group
.
nodes
[
i
]
.
failCount
,
1
)
atomic
.
AddUint32
(
&
node
.
group
.
nodes
[
i
]
.
failCount
,
1
)
node
.
group
.
nodes
[
i
]
.
failTime
=
time
.
Now
(
)
atomic
.
StoreInt64
(
&
node
.
group
.
nodes
[
i
]
.
failTime
,
time
.
Now
()
.
Unix
()
)
break
break
}
}
}
}
...
@@ -106,7 +106,7 @@ func (node *Node) MarkDead() {
...
@@ -106,7 +106,7 @@ func (node *Node) MarkDead() {
// ResetDead resets the node fail status.
// ResetDead resets the node fail status.
func
(
node
*
Node
)
ResetDead
()
{
func
(
node
*
Node
)
ResetDead
()
{
atomic
.
StoreUint32
(
&
node
.
failCount
,
0
)
atomic
.
StoreUint32
(
&
node
.
failCount
,
0
)
node
.
failTime
=
time
.
Time
{}
atomic
.
StoreInt64
(
&
node
.
failTime
,
0
)
if
node
.
group
==
nil
{
if
node
.
group
==
nil
{
return
return
...
@@ -115,12 +115,32 @@ func (node *Node) ResetDead() {
...
@@ -115,12 +115,32 @@ func (node *Node) ResetDead() {
for
i
:=
range
node
.
group
.
nodes
{
for
i
:=
range
node
.
group
.
nodes
{
if
node
.
group
.
nodes
[
i
]
.
ID
==
node
.
ID
{
if
node
.
group
.
nodes
[
i
]
.
ID
==
node
.
ID
{
atomic
.
StoreUint32
(
&
node
.
group
.
nodes
[
i
]
.
failCount
,
0
)
atomic
.
StoreUint32
(
&
node
.
group
.
nodes
[
i
]
.
failCount
,
0
)
node
.
group
.
nodes
[
i
]
.
failTime
=
time
.
Time
{}
atomic
.
StoreInt64
(
&
node
.
group
.
nodes
[
i
]
.
failTime
,
0
)
break
break
}
}
}
}
}
}
// Clone clones the node, it will prevent data race.
func
(
node
*
Node
)
Clone
()
Node
{
return
Node
{
ID
:
node
.
ID
,
Addr
:
node
.
Addr
,
Host
:
node
.
Host
,
Protocol
:
node
.
Protocol
,
Transport
:
node
.
Transport
,
Remote
:
node
.
Remote
,
User
:
node
.
User
,
Values
:
node
.
Values
,
DialOptions
:
node
.
DialOptions
,
HandshakeOptions
:
node
.
HandshakeOptions
,
Client
:
node
.
Client
,
group
:
node
.
group
,
failCount
:
atomic
.
LoadUint32
(
&
node
.
failCount
),
failTime
:
atomic
.
LoadInt64
(
&
node
.
failTime
),
}
}
func
(
node
*
Node
)
String
()
string
{
func
(
node
*
Node
)
String
()
string
{
return
fmt
.
Sprintf
(
"%d@%s"
,
node
.
ID
,
node
.
Addr
)
return
fmt
.
Sprintf
(
"%d@%s"
,
node
.
ID
,
node
.
Addr
)
}
}
...
...
selector.go
View file @
003c5a50
...
@@ -79,7 +79,7 @@ func (s *RoundStrategy) Apply(nodes []Node) Node {
...
@@ -79,7 +79,7 @@ func (s *RoundStrategy) Apply(nodes []Node) Node {
if
len
(
nodes
)
==
0
{
if
len
(
nodes
)
==
0
{
return
Node
{}
return
Node
{}
}
}
old
:=
s
.
count
old
:=
atomic
.
LoadUint64
(
&
s
.
count
)
atomic
.
AddUint64
(
&
s
.
count
,
1
)
atomic
.
AddUint64
(
&
s
.
count
,
1
)
return
nodes
[
int
(
old
%
uint64
(
len
(
nodes
)))]
return
nodes
[
int
(
old
%
uint64
(
len
(
nodes
)))]
}
}
...
@@ -134,10 +134,10 @@ func (f *FailFilter) Filter(nodes []Node) []Node {
...
@@ -134,10 +134,10 @@ func (f *FailFilter) Filter(nodes []Node) []Node {
return
nodes
return
nodes
}
}
nl
:=
[]
Node
{}
nl
:=
[]
Node
{}
for
_
,
node
:=
range
nodes
{
for
i
:=
range
nodes
{
if
node
.
failCount
<
uint32
(
f
.
MaxFails
)
||
if
atomic
.
LoadUint32
(
&
nodes
[
i
]
.
failCount
)
<
uint32
(
f
.
MaxFails
)
||
time
.
Since
(
node
.
failTime
)
>=
f
.
FailTimeout
{
time
.
Since
(
time
.
Unix
(
atomic
.
LoadInt64
(
&
nodes
[
i
]
.
failTime
),
0
)
)
>=
f
.
FailTimeout
{
nl
=
append
(
nl
,
node
)
nl
=
append
(
nl
,
node
s
[
i
]
.
Clone
()
)
}
}
}
}
return
nl
return
nl
...
...
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