Commit 7686a4bd authored by ginuerzh's avatar ginuerzh

add more detail info for routing

parent 0bb52bc7
...@@ -152,7 +152,7 @@ func NewBypassPatterns(reversed bool, patterns ...string) *Bypass { ...@@ -152,7 +152,7 @@ func NewBypassPatterns(reversed bool, patterns ...string) *Bypass {
// Contains reports whether the bypass includes addr. // Contains reports whether the bypass includes addr.
func (bp *Bypass) Contains(addr string) bool { func (bp *Bypass) Contains(addr string) bool {
if bp == nil { if bp == nil || addr == "" {
return false return false
} }
// try to strip the port // try to strip the port
......
package gost package gost
import ( import (
"bytes"
"errors" "errors"
"fmt"
"net" "net"
"time" "time"
...@@ -20,6 +18,7 @@ type Chain struct { ...@@ -20,6 +18,7 @@ type Chain struct {
isRoute bool isRoute bool
Retries int Retries int
nodeGroups []*NodeGroup nodeGroups []*NodeGroup
route []Node // nodes in the selected route
} }
// NewChain creates a proxy chain with a list of proxy nodes. // NewChain creates a proxy chain with a list of proxy nodes.
...@@ -197,18 +196,14 @@ func (c *Chain) Conn(opts ...ChainOption) (conn net.Conn, err error) { ...@@ -197,18 +196,14 @@ func (c *Chain) Conn(opts ...ChainOption) (conn net.Conn, err error) {
continue continue
} }
conn, err = route.getConn() conn, err = route.getConn()
if err != nil { if err == nil {
log.Log(err) break
continue
} }
break
} }
return return
} }
// getConn obtains a connection to the last node of the chain. // getConn obtains a connection to the last node of the chain.
// It does not handshake with the last node.
func (c *Chain) getConn() (conn net.Conn, err error) { func (c *Chain) getConn() (conn net.Conn, err error) {
if c.IsEmpty() { if c.IsEmpty() {
err = ErrEmptyChain err = ErrEmptyChain
...@@ -256,35 +251,7 @@ func (c *Chain) getConn() (conn net.Conn, err error) { ...@@ -256,35 +251,7 @@ func (c *Chain) getConn() (conn net.Conn, err error) {
} }
func (c *Chain) selectRoute() (route *Chain, err error) { func (c *Chain) selectRoute() (route *Chain, err error) {
if c.IsEmpty() || c.isRoute { return c.selectRouteFor("")
return c, nil
}
buf := bytes.Buffer{}
route = newRoute()
for _, group := range c.nodeGroups {
node, err := group.Next()
if err != nil {
return nil, err
}
buf.WriteString(fmt.Sprintf("%s -> ", node.String()))
if node.Client.Transporter.Multiplex() {
node.DialOptions = append(node.DialOptions,
ChainDialOption(route),
)
route = newRoute() // cutoff the chain for multiplex.
}
route.AddNode(node)
}
route.Retries = c.Retries
if Debug {
log.Log("select route:", buf.String())
}
return
} }
// selectRouteFor selects route with bypass testing. // selectRouteFor selects route with bypass testing.
...@@ -293,8 +260,8 @@ func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) { ...@@ -293,8 +260,8 @@ func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) {
return c, nil return c, nil
} }
buf := bytes.Buffer{}
route = newRoute() route = newRoute()
var nl []Node
for _, group := range c.nodeGroups { for _, group := range c.nodeGroups {
var node Node var node Node
...@@ -304,28 +271,21 @@ func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) { ...@@ -304,28 +271,21 @@ func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) {
} }
if node.Bypass.Contains(addr) { if node.Bypass.Contains(addr) {
if Debug { break
buf.WriteString(fmt.Sprintf("[bypass]%s -> %s", node.String(), addr))
log.Log("[route]", buf.String())
}
return
} }
buf.WriteString(fmt.Sprintf("%s -> ", node.String()))
if node.Client.Transporter.Multiplex() { if node.Client.Transporter.Multiplex() {
node.DialOptions = append(node.DialOptions, node.DialOptions = append(node.DialOptions,
ChainDialOption(route), ChainDialOption(route),
) )
route = newRoute() // cutoff the chain for multiplex. route = newRoute() // cutoff the chain for multiplex node.
} }
route.AddNode(node) route.AddNode(node)
nl = append(nl, node)
} }
route.Retries = c.Retries
buf.WriteString(addr) route.route = nl
log.Log("[route]", buf.String())
return return
} }
......
Hello World!
\ No newline at end of file
{
"key": "it's a secrect",
"crypt": "aes",
"mode": "fast",
"mtu" : 1350,
"sndwnd": 1024,
"rcvwnd": 1024,
"datashard": 10,
"parityshard": 3,
"dscp": 0,
"nocomp": false,
"acknodelay": false,
"nodelay": 0,
"interval": 40,
"resend": 0,
"nc": 0,
"sockbuf": 4194304,
"keepalive": 10,
"snmplog": "",
"snmpperiod": 60
}
\ No newline at end of file
...@@ -407,7 +407,8 @@ func (r *route) GenRouters() ([]router, error) { ...@@ -407,7 +407,8 @@ func (r *route) GenRouters() ([]router, error) {
hosts := parseHosts(node.Get("hosts")) hosts := parseHosts(node.Get("hosts"))
handler.Init( handler.Init(
gost.AddrHandlerOption(node.Addr), // gost.AddrHandlerOption(node.Addr),
gost.AddrHandlerOption(ln.Addr().String()),
gost.ChainHandlerOption(chain), gost.ChainHandlerOption(chain),
gost.UsersHandlerOption(users...), gost.UsersHandlerOption(users...),
gost.TLSConfigHandlerOption(tlsCfg), gost.TLSConfigHandlerOption(tlsCfg),
...@@ -417,9 +418,10 @@ func (r *route) GenRouters() ([]router, error) { ...@@ -417,9 +418,10 @@ func (r *route) GenRouters() ([]router, error) {
gost.BypassHandlerOption(node.Bypass), gost.BypassHandlerOption(node.Bypass),
gost.ResolverHandlerOption(resolver), gost.ResolverHandlerOption(resolver),
gost.HostsHandlerOption(hosts), gost.HostsHandlerOption(hosts),
gost.RetryHandlerOption(node.GetInt("retry")), gost.RetryHandlerOption(node.GetInt("retry")), // override the global retry option.
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")),
gost.NodeHandlerOption(node),
) )
rt := router{ rt := router{
...@@ -446,7 +448,7 @@ type router struct { ...@@ -446,7 +448,7 @@ type router struct {
} }
func (r *router) Serve() error { func (r *router) Serve() error {
log.Logf("[route] start %s on %s", r.node.String(), r.server.Addr()) log.Logf("%s on %s", r.node.String(), r.server.Addr())
return r.server.Serve(r.handler) return r.server.Serve(r.handler)
} }
......
[//]: <> (https://gist.github.com/fntlnz/cf14feb5a46b2eda428e000157447309)
# Create Root CA (Done once)
## Create Root Key
**Attention:** this is the key used to sign the certificate requests, anyone holding this can sign certificates on your behalf. So keep it in a safe place!
```bash
openssl genrsa -des3 -out rootCA.key 4096
```
If you want a non password protected key just remove the `-des3` option
## Create and self sign the Root Certificate
```bash
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt
```
Here we used our root key to create the root certificate that needs to be distributed in all the computers that have to trust us.
# Create a certificate (Done for each server)
This procedure needs to be followed for each server/appliance that needs a trusted certificate from our CA
## Create the certificate key
```
openssl genrsa -out mydomain.com.key 2048
```
## Create the signing request
**Important:** Please mind that while creating the signign request is important to specify the `Common Name` providing the IP address or URL for the service, otherwise the certificate
cannot be verified
```
openssl req -new -key mydomain.com.key -out mydomain.com.csr
```
## Generate the certificate using the `mydomain` csr and key along with the CA Root key
```
openssl x509 -req -in mydomain.com.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out mydomain.com.crt -days 500 -sha256
```
-----BEGIN CERTIFICATE-----
MIIDvjCCAaYCCQC0XjV3wljvnjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMTgwNzA4MDQ1MzIyWhcNMTkxMTIwMDQ1MzIyWjAuMQswCQYD
VQQGEwJDTjELMAkGA1UEBwwCU0gxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOKgzWil/KjyRy2Axb3XlLB1nMwLFJC
pC6r8yb+1Kq/ldZghJZvymuFVjn+bihvJqvZiOv4KRtnM8gD55AhaQp6Ese5M9b+
47HLB//SkfJsQREsmnrHfHxjmUQjhMy7jrpcf9OnDOXQ5zk3v6AWEIqMtAiZ99ku
AQvyJJ07+VpwZrMuzbSGfFBCKEbbqP7yKHjSUm3QDTpTiK4AnBmzlVeThUIA68oa
XZKQVXX/8U2i6H4eq5eNpyUsKSnnuK+cryHpAIK4vNMzw96vATTfEmuWASEzkHhW
3KtfXE0CIH0GsK5zueGDo9ygnO7hjtx60SWynlGf6c6edxPwNvEmTZcCAwEAATAN
BgkqhkiG9w0BAQsFAAOCAgEApLkdhnDzErgBljY6qRaR0JlouTpqJXwi5BRi7F1P
bx5ukrZAVSOsZ7ncEkZuxkIX+ktBVFBL8twkvMEl+sMQ24R+F+TrlHWN2xPR/pez
9V19hq26yMIlYLqSq3KZ0W9ZlT2ge+3sTvY+gAJhZ6nOz9WGRJ1mi+pN/ok678QX
KdOJXcePzYr5iKqMq/5cJ2sA1xYwVl+0xrvfRVTFkp4yR6wzGODtjquB+scZ9S64
GWnFTjHAJvUKYxpeoLAt9lZHsESDqGq7hA4z1uVjhNEDJHKnXW4OhXxMB8Gk2hY8
3k4zbnKsouNNW0a7jijCMpXOem/vgQF4GK5ecp0S+Ml/AunsPoi6rGgOCX8XXmti
6DfQhsxxgn1co/JKNxhgsnQftXFwKivh73JFctSh+bMLsewfXsvq+b0K3EuuV9bV
EttVCgbUaCDYdA6IDkqD2PRx9tsotne76r+cX+ah+NjnA6XN+XY2bJgV1UaiKTrP
moNHglw+xoUqOJ7FlGJcVC7uIFPhMviNkpSZh6WxX+OSS4fPO25kxxNpldql6I+3
xb5XEHLpPCEI4PyK0rYnsjk764Loqff8YBMFRQSXIUz9ot5SgGs/FY1vsQap5OeD
Hw2usWhCvkSzr7kiXI+30BvJKK2r9GOAM7mtO9dfkM9MMKKnMzd+O2XE4r6PNLrg
Rds=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE REQUEST-----
MIICczCCAVsCAQAwLjELMAkGA1UEBhMCQ04xCzAJBgNVBAcMAlNIMRIwEAYDVQQD
DAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDioM1
opfyo8kctgMW915SwdZzMCxSQqQuq/Mm/tSqv5XWYISWb8prhVY5/m4obyar2Yjr
+CkbZzPIA+eQIWkKehLHuTPW/uOxywf/0pHybEERLJp6x3x8Y5lEI4TMu466XH/T
pwzl0Oc5N7+gFhCKjLQImffZLgEL8iSdO/lacGazLs20hnxQQihG26j+8ih40lJt
0A06U4iuAJwZs5VXk4VCAOvKGl2SkFV1//FNouh+HquXjaclLCkp57ivnK8h6QCC
uLzTM8PerwE03xJrlgEhM5B4VtyrX1xNAiB9BrCuc7nhg6PcoJzu4Y7cetElsp5R
n+nOnncT8DbxJk2XAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAr+AkYRAPulBU
B5HR3pAreYrf3Y2fvGLSNo4hvsJkmXJxDgMZnGsjVzW1IZLF8szn4v050y6Qm/Ne
qupabYP5zpj0vKkACYGJ2zadnowmwlTzwlxEOv27uQykC/IuRcjdloAD7ZwhNwmO
dLNjdiXn63GUeSL/JK0UHyXTqvpmiHq+6TAOdl3vmsRFCQDChRtViK2fwSeX2y87
hLicSVQyNOe0gUx7IvE9B2QPNhdzaMVPYeN8I/cayNeUKhiWxEGKhwPAaievuSXJ
fUsz11XYBYW+kjFsTqkV1OjkG0mxvwaiq5W3CRx8365w71IMdKV5t5xhc0n0TXp7
cT27XN7cdw==
-----END CERTIFICATE REQUEST-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAw4qDNaKX8qPJHLYDFvdeUsHWczAsUkKkLqvzJv7Uqr+V1mCE
lm/Ka4VWOf5uKG8mq9mI6/gpG2czyAPnkCFpCnoSx7kz1v7jscsH/9KR8mxBESya
esd8fGOZRCOEzLuOulx/06cM5dDnOTe/oBYQioy0CJn32S4BC/IknTv5WnBmsy7N
tIZ8UEIoRtuo/vIoeNJSbdANOlOIrgCcGbOVV5OFQgDryhpdkpBVdf/xTaLofh6r
l42nJSwpKee4r5yvIekAgri80zPD3q8BNN8Sa5YBITOQeFbcq19cTQIgfQawrnO5
4YOj3KCc7uGO3HrRJbKeUZ/pzp53E/A28SZNlwIDAQABAoIBAGx1pMeYMw3L2R5K
urX/aVsf1xI3My5Bdo3IpGsJx+4ZrEOnb4N96FnxMF2kiXd2B44kb/TqxepEOQ2F
VOi2D2xXP5l2WZGz+ZnBUuOL6ZX8g67B/cGCasMX/4gy51Mj6UvnSKOeMeI7GDW9
fVWPR4eB+c4XkMju4ne8zKBGBs4pN4KoxTWSnZSM4p+q/Jb/DMa+kVhFfRjkqfWc
vCpDgHs1uMcHvPBNYO9flDaC2Jgk4cvV9mX0TolXAvaNo8aN0joM7WH3fvw7NCD9
LCkqCmpjOxJIqJQT1twIkSy42q7VaFi7ApyIaMfXlmnj4UTlVTe5bBO+2AgwLYtC
cKgDMjECgYEA8JPm3Pc80EsYB6d4qp/Qmy2VrnlaxZwvaRwh63Pssqthg4SZkIp5
yjXOT4MDlJdrEzMtATRZUXTCRxGFSs0tolNY2KQ2WvYRhISlN8UBkGuMEkRGLuct
p++qpPcSZJcox25kT82CKin1nQYb48k33JAOMUOWIBJO56G35sfPj28CgYEA0BOE
pa+FYj/WxZS79YT1ZbsajeuUKlNUtAIxKJ2cKSQyfFuPM+xZG3H+iroRfR8HCVai
2+Oz9/TlxZOPR7+P+2fpS8W2tT+Qkmiyz8QJAULd+Irw5XIdatkpVm343XxMx3Pa
2qtBmgj6RINvsWTWRotMqhcuDRirxqm1IIQhkFkCgYBLNmIhyOXpVODRW8k8xrQI
H6tBHc2EJD0qRlJQczCX9z6ISIdeCfzjfAjhENuos+IU4ZX7X2thLPikEVUzuou+
yQHo0QXxUCbP4Exq8Bt6FDV5bIDonvvGGgamhlvouN1V5CxWSrCcD/wquEM15q2h
NiRJwJCJvE+Q2R1OeD9q3wKBgFWDkAJf7luAjQ3KoKy4pfnXOYSWCuCSOr94Hyfo
DmPCIpWFM4dNXRmwccIl0kYv2D54QppILJB9L2lRyZLdIZlbDUA802gN5aamLMbC
dEj2aC9bOsGxcnGVKi4BKEQub4eRD6LKuz1I70H1GpQ3MvDvEuTcfeqX9xDAclYY
t4qRAoGBAI6YSTs97DUe7Zwk7q+S3PBU5uct4Dwtmy2XWZdgHwl5aP8apSLciL5Y
PMkpcTMzkuC+QFaPZ8wFcI7GLg0bOs91hkrqscDKEg4nGB9fJkU82iOQZNL4Hv1u
wO7uIGa2kcpNtQOLNO88y45WFyrn5a+T6VhDmIuc+F+TU1ZzdYdH
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIEpDCCAowCCQDwV08QFUCcSzANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMTgwNzA4MDQ1MzE3WhcNMjEwNDI3MDQ1MzE3WjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDE
+71yX9vQY3l52C31e04ACvm2oNMLSCrLOXGewOTFpv9yXjinMC0Ab6Xa4yB4MPtd
ujWDSEq9gkKCkILoalVX7R4gtLDN+EdoVadBw/WHbrGB4sHnFOWwpUbjiiwwPSU5
qXjcqIqR2sA1BgoAv6c1qHq7V4bgbEjtGL71KkDoQZSIgNyJlXe1mcUKqmqeAnro
0WfwrNXyYt66L3PmCy9MIpWRxf9sa8PDsgT3SQEN4BHb70Z8hNj6RXfVGDZcpfcI
iwbrL//YnK7waRKaKD4LoLOodE0cx3fowSWYvlwUAoYx8wFKOcdtM1zaUp+QDAug
xT5g5ghU150XuqhDU6Wq1An8dLgcDU1D4cxhLk/W8OXtIk4k7yny6eUJi2zHziMm
8jfHd3M6SwohUrE3LsQI5gpvu4sAVFLMkRxaWZ95XhsVMmIsE/L5FHwDfqid0dvx
bafOKT+fI3N3BaUPJlVHCNqSzSZIW59+ufnDwBV7SmJj4KMlvixEU+EFfPFdGiCA
Lr0dSG5+Scx1aClaMUeVccCljp2f99IEa9wI+xwMPDStkOmnhVuqG1aEogggQZkD
/5yh04wrn8EwYCAiasNNUXTV7AoqIt2bgeFbGo2Qr7LdsYuUmaWEzTm0KsHogkkg
Ibd3RPBLDr/WfWI13oHMdsz8jjbXG/D1AhrcdozYDQIDAQABMA0GCSqGSIb3DQEB
CwUAA4ICAQC1EeQqn2AwrS+UVc5fKRpHzV9ZMiDpxFMRLsDWBP5kNr1nSA72yYcR
WgxvdqG/rGRds6lvRbvIaWD0zeujPkR3iCpb1V5oRXQ6lWOlY44pZEwCdnDd2M8I
yQ7BLZCHHmlCN7a51n2o0D78HeILIeeTCQlKFDc5r51qrZbZR5DZmrp9jaZ+3eCg
LQ3Onfj0WEmQFuMFGQrbJ2oaCC1GvuZWEbRh+lrxjRKOyCaRQFTY4Efe8tIwMm6J
1iyMtqK7BxminQCfizQrstB67wMljydYeUf+wwbgkiKGYc9VGopckrO3lntzKycu
9l0BmlZYkmCFt3cv23BcqAbcLdyLXh3yASwVMXaLZ4iVSaslRm4uX+gbKFCBABLa
vqu7JQHfAPOeYj7zCrN12EHejPxdCjSImBeAbe56vax4uFGAodXxDGcepRItSzax
qPKJd8U/8e3JDn+wmZNKwD9UGLZPbiuYOg7X+EWhjki0J6ZjgLc8dMleeD2rO+j2
P/Wgv1gMr6J1svUlqkNf1Ng9eSbl/nMhuOBVOGcPnK7+wCLxM7ByaR0QgeH6/9VO
4urq53/vspBC679BHsZx3gIhcg4VefmOM2cZnTRM4izPstq1JBQkbuvz+5XuT7Yj
5Fk1/xkapCUifntKYSoslkkbNHRYxAInqkc0txn3qNBI8GAQFksz5g==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
...@@ -33,6 +33,7 @@ type HandlerOptions struct { ...@@ -33,6 +33,7 @@ type HandlerOptions struct {
Resolver Resolver Resolver Resolver
Hosts *Hosts Hosts *Hosts
ProbeResist string ProbeResist string
Node Node
} }
// HandlerOption allows a common way to set handler options. // HandlerOption allows a common way to set handler options.
...@@ -129,6 +130,13 @@ func ProbeResistHandlerOption(pr string) HandlerOption { ...@@ -129,6 +130,13 @@ func ProbeResistHandlerOption(pr string) HandlerOption {
} }
} }
// NodeHandlerOption set the server node for server handler.
func NodeHandlerOption(node Node) HandlerOption {
return func(opts *HandlerOptions) {
opts.Node = node
}
}
type autoHandler struct { type autoHandler struct {
options *HandlerOptions options *HandlerOptions
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -20,8 +20,8 @@ type Node struct { ...@@ -20,8 +20,8 @@ type Node struct {
Host string Host string
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 url *url.URL // raw url
User *url.Userinfo User *url.Userinfo
Values url.Values Values url.Values
DialOptions []DialOption DialOptions []DialOption
...@@ -55,10 +55,11 @@ func ParseNode(s string) (node Node, err error) { ...@@ -55,10 +55,11 @@ func ParseNode(s string) (node Node, err error) {
Values: u.Query(), Values: u.Query(),
User: u.User, User: u.User,
marker: &failMarker{}, marker: &failMarker{},
url: u,
} }
u.RawQuery = "" u.RawQuery = ""
node.url = u.String() u.User = nil
schemes := strings.Split(u.Scheme, "+") schemes := strings.Split(u.Scheme, "+")
if len(schemes) == 1 { if len(schemes) == 1 {
...@@ -139,7 +140,7 @@ func (node *Node) GetInt(key string) int { ...@@ -139,7 +140,7 @@ func (node *Node) GetInt(key string) int {
} }
func (node Node) String() string { func (node Node) String() string {
return node.url return node.url.String()
} }
// NodeGroup is a group of nodes. // NodeGroup is a group of nodes.
......
...@@ -173,7 +173,7 @@ func (f *FailFilter) Filter(nodes []Node) []Node { ...@@ -173,7 +173,7 @@ func (f *FailFilter) Filter(nodes []Node) []Node {
nl := []Node{} nl := []Node{}
for i := range nodes { for i := range nodes {
marker := nodes[i].marker.Clone() marker := nodes[i].marker.Clone()
// log.Logf("%s: %d/%d %d/%d", nodes[i], marker.failCount, f.MaxFails, marker.failTime, f.FailTimeout) // log.Logf("%s: %d/%d %v/%v", nodes[i], marker.failCount, f.MaxFails, marker.failTime, f.FailTimeout)
if marker.failCount < uint32(f.MaxFails) || if marker.failCount < uint32(f.MaxFails) ||
time.Since(time.Unix(marker.failTime, 0)) >= f.FailTimeout { time.Since(time.Unix(marker.failTime, 0)) >= f.FailTimeout {
nl = append(nl, nodes[i]) nl = append(nl, nodes[i])
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"hash/crc32" "hash/crc32"
"io" "io"
"net" "net"
...@@ -55,22 +56,23 @@ func (h *sniHandler) Init(options ...HandlerOption) { ...@@ -55,22 +56,23 @@ func (h *sniHandler) Init(options ...HandlerOption) {
} }
func (h *sniHandler) Handle(conn net.Conn) { func (h *sniHandler) Handle(conn net.Conn) {
br := bufio.NewReader(conn) defer conn.Close()
br := bufio.NewReader(conn)
hdr, err := br.Peek(dissector.RecordHeaderLen) hdr, err := br.Peek(dissector.RecordHeaderLen)
if err != nil { if err != nil {
log.Log("[sni]", err) log.Logf("[sni] %s -> %s : %s",
conn.Close() conn.RemoteAddr(), conn.LocalAddr(), err)
return return
} }
conn = &bufferdConn{br: br, Conn: conn} conn = &bufferdConn{br: br, Conn: conn}
defer conn.Close()
if hdr[0] != dissector.Handshake { if hdr[0] != dissector.Handshake {
// We assume it is an HTTP request // We assume it is an HTTP request
req, err := http.ReadRequest(bufio.NewReader(conn)) req, err := http.ReadRequest(bufio.NewReader(conn))
if err != nil { if err != nil {
log.Logf("[sni] %s - %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err) log.Logf("[sni] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
return return
} }
if !req.URL.IsAbs() { if !req.URL.IsAbs() {
...@@ -84,40 +86,79 @@ func (h *sniHandler) Handle(conn net.Conn) { ...@@ -84,40 +86,79 @@ func (h *sniHandler) Handle(conn net.Conn) {
b, host, err := readClientHelloRecord(conn, "", false) b, host, err := readClientHelloRecord(conn, "", false)
if err != nil { if err != nil {
log.Log("[sni]", err) log.Logf("[sni] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
return return
} }
addr := net.JoinHostPort(host, "443") host = net.JoinHostPort(host, "443")
if !Can("tcp", addr, h.options.Whitelist, h.options.Blacklist) { log.Logf("[ss] %s -> %s -> %s",
log.Logf("[sni] Unauthorized to tcp connect to %s", addr) conn.RemoteAddr(), h.options.Node.String(), host)
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[sni] %s -> %s : Unauthorized to tcp connect to %s",
conn.RemoteAddr(), conn.LocalAddr(), host)
return return
} }
if h.options.Bypass.Contains(addr) { if h.options.Bypass.Contains(host) {
log.Log("[sni] [bypass]", addr) log.Log("[sni] %s - %s bypass %s",
conn.RemoteAddr(), conn.LocalAddr(), host)
return return
} }
cc, err := h.options.Chain.Dial(addr, retries := 1
RetryChainOption(h.options.Retries), if h.options.Chain != nil && h.options.Chain.Retries > 0 {
TimeoutChainOption(h.options.Timeout), retries = h.options.Chain.Retries
HostsChainOption(h.options.Hosts), }
ResolverChainOption(h.options.Resolver), if h.options.Retries > 0 {
) retries = h.options.Retries
}
var cc net.Conn
var route *Chain
for i := 0; i < retries; i++ {
route, err = h.options.Chain.selectRouteFor(host)
if err != nil {
log.Logf("[sni] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
continue
}
buf := bytes.Buffer{}
fmt.Fprintf(&buf, "%s -> %s -> ",
conn.RemoteAddr(), h.options.Node.String())
for _, nd := range route.route {
fmt.Fprintf(&buf, "%d@%s -> ", nd.ID, nd.String())
}
fmt.Fprintf(&buf, "%s", host)
log.Log("[route]", buf.String())
cc, err = route.Dial(host,
TimeoutChainOption(h.options.Timeout),
HostsChainOption(h.options.Hosts),
ResolverChainOption(h.options.Resolver),
)
if err == nil {
break
}
log.Logf("[sni] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
}
if err != nil { if err != nil {
log.Logf("[sni] %s -> %s : %s", conn.RemoteAddr(), addr, err)
return return
} }
defer cc.Close() defer cc.Close()
if _, err := cc.Write(b); err != nil { if _, err := cc.Write(b); err != nil {
log.Logf("[sni] %s -> %s : %s", conn.RemoteAddr(), addr, err) log.Logf("[sni] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
} }
log.Logf("[sni] %s <-> %s", cc.LocalAddr(), addr) log.Logf("[sni] %s <-> %s", cc.LocalAddr(), host)
transport(conn, cc) transport(conn, cc)
log.Logf("[sni] %s >-< %s", cc.LocalAddr(), addr) log.Logf("[sni] %s >-< %s", cc.LocalAddr(), host)
} }
// sniSniffConn is a net.Conn that reads from r, fails on Writes, // sniSniffConn is a net.Conn that reads from r, fails on Writes,
......
This diff is collapsed.
...@@ -125,49 +125,84 @@ func (h *shadowHandler) Handle(conn net.Conn) { ...@@ -125,49 +125,84 @@ func (h *shadowHandler) Handle(conn net.Conn) {
} }
cipher, err := ss.NewCipher(method, password) cipher, err := ss.NewCipher(method, password)
if err != nil { if err != nil {
log.Log("[ss]", err) log.Logf("[ss] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
return return
} }
conn = &shadowConn{conn: ss.NewConn(conn, cipher)} conn = &shadowConn{conn: ss.NewConn(conn, cipher)}
log.Logf("[ss] %s - %s", conn.RemoteAddr(), conn.LocalAddr())
conn.SetReadDeadline(time.Now().Add(ReadTimeout)) conn.SetReadDeadline(time.Now().Add(ReadTimeout))
addr, err := h.getRequest(conn) host, err := h.getRequest(conn)
if err != nil { if err != nil {
log.Logf("[ss] %s - %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err) log.Logf("[ss] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
return return
} }
// clear timer // clear timer
conn.SetReadDeadline(time.Time{}) conn.SetReadDeadline(time.Time{})
log.Logf("[ss] %s -> %s", conn.RemoteAddr(), addr) log.Logf("[ss] %s -> %s -> %s",
conn.RemoteAddr(), h.options.Node.String(), host)
if !Can("tcp", addr, h.options.Whitelist, h.options.Blacklist) { if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[ss] Unauthorized to tcp connect to %s", addr) log.Logf("[ss] %s - %s : Unauthorized to tcp connect to %s",
conn.RemoteAddr(), conn.LocalAddr(), host)
return return
} }
if h.options.Bypass.Contains(addr) { if h.options.Bypass.Contains(host) {
log.Logf("[ss] [bypass] %s", addr) log.Logf("[ss] %s - %s : Bypass %s",
conn.RemoteAddr(), conn.LocalAddr(), host)
return return
} }
cc, err := h.options.Chain.Dial(addr, retries := 1
RetryChainOption(h.options.Retries), if h.options.Chain != nil && h.options.Chain.Retries > 0 {
TimeoutChainOption(h.options.Timeout), retries = h.options.Chain.Retries
HostsChainOption(h.options.Hosts), }
ResolverChainOption(h.options.Resolver), if h.options.Retries > 0 {
) retries = h.options.Retries
}
var cc net.Conn
var route *Chain
for i := 0; i < retries; i++ {
route, err = h.options.Chain.selectRouteFor(host)
if err != nil {
log.Logf("[ss] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
continue
}
buf := bytes.Buffer{}
fmt.Fprintf(&buf, "%s -> %s -> ",
conn.RemoteAddr(), h.options.Node.String())
for _, nd := range route.route {
fmt.Fprintf(&buf, "%d@%s -> ", nd.ID, nd.String())
}
fmt.Fprintf(&buf, "%s", host)
log.Log("[route]", buf.String())
cc, err = route.Dial(host,
TimeoutChainOption(h.options.Timeout),
HostsChainOption(h.options.Hosts),
ResolverChainOption(h.options.Resolver),
)
if err == nil {
break
}
log.Logf("[ss] %s -> %s : %s",
conn.RemoteAddr(), conn.LocalAddr(), err)
}
if err != nil { if err != nil {
log.Logf("[ss] %s -> %s : %s", conn.RemoteAddr(), addr, err)
return return
} }
defer cc.Close() defer cc.Close()
log.Logf("[ss] %s <-> %s", conn.RemoteAddr(), addr) log.Logf("[ss] %s <-> %s", conn.RemoteAddr(), host)
transport(conn, cc) transport(conn, cc)
log.Logf("[ss] %s >-< %s", conn.RemoteAddr(), addr) log.Logf("[ss] %s >-< %s", conn.RemoteAddr(), host)
} }
const ( const (
......
...@@ -444,15 +444,15 @@ func (h *sshForwardHandler) Init(options ...HandlerOption) { ...@@ -444,15 +444,15 @@ func (h *sshForwardHandler) Init(options ...HandlerOption) {
func (h *sshForwardHandler) Handle(conn net.Conn) { func (h *sshForwardHandler) Handle(conn net.Conn) {
sshConn, chans, reqs, err := ssh.NewServerConn(conn, h.config) sshConn, chans, reqs, err := ssh.NewServerConn(conn, h.config)
if err != nil { if err != nil {
log.Logf("[ssh-forward] %s -> %s : %s", conn.RemoteAddr(), h.options.Addr, err) log.Logf("[ssh-forward] %s -> %s : %s", conn.RemoteAddr(), h.options.Node.Addr, err)
conn.Close() conn.Close()
return return
} }
defer sshConn.Close() defer sshConn.Close()
log.Logf("[ssh-forward] %s <-> %s", conn.RemoteAddr(), h.options.Addr) log.Logf("[ssh-forward] %s <-> %s", conn.RemoteAddr(), h.options.Node.Addr)
h.handleForward(sshConn, chans, reqs) h.handleForward(sshConn, chans, reqs)
log.Logf("[ssh-forward] %s >-< %s", conn.RemoteAddr(), h.options.Addr) log.Logf("[ssh-forward] %s >-< %s", conn.RemoteAddr(), h.options.Node.Addr)
} }
func (h *sshForwardHandler) handleForward(conn ssh.Conn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) { func (h *sshForwardHandler) handleForward(conn ssh.Conn, chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) {
...@@ -506,7 +506,7 @@ func (h *sshForwardHandler) handleForward(conn ssh.Conn, chans <-chan ssh.NewCha ...@@ -506,7 +506,7 @@ func (h *sshForwardHandler) handleForward(conn ssh.Conn, chans <-chan ssh.NewCha
func (h *sshForwardHandler) directPortForwardChannel(channel ssh.Channel, raddr string) { func (h *sshForwardHandler) directPortForwardChannel(channel ssh.Channel, raddr string) {
defer channel.Close() defer channel.Close()
log.Logf("[ssh-tcp] %s - %s", h.options.Addr, raddr) log.Logf("[ssh-tcp] %s - %s", h.options.Node.Addr, raddr)
if !Can("tcp", raddr, h.options.Whitelist, h.options.Blacklist) { if !Can("tcp", raddr, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[ssh-tcp] Unauthorized to tcp connect to %s", raddr) log.Logf("[ssh-tcp] Unauthorized to tcp connect to %s", raddr)
...@@ -525,14 +525,14 @@ func (h *sshForwardHandler) directPortForwardChannel(channel ssh.Channel, raddr ...@@ -525,14 +525,14 @@ func (h *sshForwardHandler) directPortForwardChannel(channel ssh.Channel, raddr
ResolverChainOption(h.options.Resolver), ResolverChainOption(h.options.Resolver),
) )
if err != nil { if err != nil {
log.Logf("[ssh-tcp] %s - %s : %s", h.options.Addr, raddr, err) log.Logf("[ssh-tcp] %s - %s : %s", h.options.Node.Addr, raddr, err)
return return
} }
defer conn.Close() defer conn.Close()
log.Logf("[ssh-tcp] %s <-> %s", h.options.Addr, raddr) log.Logf("[ssh-tcp] %s <-> %s", h.options.Node.Addr, raddr)
transport(conn, channel) transport(conn, channel)
log.Logf("[ssh-tcp] %s >-< %s", h.options.Addr, raddr) log.Logf("[ssh-tcp] %s >-< %s", h.options.Node.Addr, raddr)
} }
// tcpipForward is structure for RFC 4254 7.1 "tcpip-forward" request // tcpipForward is structure for RFC 4254 7.1 "tcpip-forward" request
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment