diff --git a/domainset.go b/domainset.go index e3f4ddd..99b49a4 100644 --- a/domainset.go +++ b/domainset.go @@ -154,8 +154,7 @@ func (ds *DomainSet) isHostChouFeng(host string) bool { func (ds *DomainSet) addChouHost(host string) bool { dm := host2Domain(host) - if ds.isHostAlwaysDirect(host) || dm == "localhost" || - hostIsIP(host) || ds.chouSet.has(dm) { + if ds.isHostAlwaysDirect(host) || dm == "localhost" || hostIsIP(host) { return false } ds.chouSet.add(dm) @@ -170,9 +169,12 @@ func (ds *DomainSet) addBlockedHost(host string) bool { } dm := host2Domain(host) if ds.isHostAlwaysDirect(host) || ds.chou.has(dm) || dm == "localhost" || - hostIsIP(host) || ds.blocked.has(dm) { + hostIsIP(host) { return false } + if ds.blocked.has(dm) { + return true + } ds.blocked.add(dm) ds.blockedChanged = true debug.Printf("%s added to blocked list\n", dm) diff --git a/domainset_blocked.go b/domainset_blocked.go index 7d2d8a1..f7e1b8a 100644 --- a/domainset_blocked.go +++ b/domainset_blocked.go @@ -9,10 +9,10 @@ var blockedDomainList = []string{ "feedburner.com", "facebook.net", "facebook.com", - "golang.org", "t.co", "twimg.com", "twitpic.com", + "twitter.com", "wordpress.com", "youtu.be", "youtube.com", diff --git a/domainset_direct.go b/domainset_direct.go index 6b730b8..944b8ff 100644 --- a/domainset_direct.go +++ b/domainset_direct.go @@ -20,6 +20,7 @@ var directDomainList = []string{ "baidu.com", "bankcomm.com", "bankofchina.com", + "bdstatic.com", "bing.com", "bing.com.cn", "boc.cn", diff --git a/proxy.go b/proxy.go index 0dd829f..c70642c 100644 --- a/proxy.go +++ b/proxy.go @@ -379,7 +379,7 @@ func (c *clientConn) handleBlockedRequest(r *Request, err error, msg string) err } else if domainSet.isHostChouFeng(r.URL.Host) || config.AutoRetry { // err must be timeout here // Domain in chou domain set is likely to be blocked, should automatically - // restart request using parent proxy. + // retry request using parent proxy. // If autoRetry is enabled, treat timeout domain as chou and retry. if domainSet.addChouHost(r.URL.Host) { return errRetry @@ -414,14 +414,8 @@ func (c *clientConn) handleServerReadError(r *Request, sv *serverConn, err error return errShouldClose } errMsg = genErrMsg(r, msg) - if sv.maybeFake() || isErrConnReset(err) { - // GFW may connection reset when reading from server, may also make - // it time out. But timeout is also normal if network condition is - // bad, so should treate timeout separately. - if maybeBlocked(err) { - return c.handleBlockedRequest(r, err, errMsg) - } - // fall through to send general error message + if sv.maybeFake() && maybeBlocked(err) { + return c.handleBlockedRequest(r, err, errMsg) } if r.responseNotSent() { sendErrorPage(c, "502 read error", err.Error(), errMsg) @@ -451,7 +445,7 @@ func (c *clientConn) handleClientReadError(r *Request, err error, msg string) er debug.Printf("%s client closed connection", msg) } else if ne, ok := err.(*net.OpError); ok { if debug { - if ne.Err == syscall.ECONNRESET { + if isErrConnReset(err) { debug.Printf("%s connection reset", msg) } else if ne.Timeout() { debug.Printf("%s client read timeout, maybe has closed\n", msg) @@ -470,7 +464,7 @@ func (c *clientConn) handleClientWriteError(r *Request, err error, msg string) e if debug { if ne.Err == syscall.EPIPE { debug.Printf("%s broken pipe %v\n", msg, r) - } else if ne.Err == syscall.ECONNRESET { + } else if isErrConnReset(err) { debug.Println("%s connection reset %v\n", msg, r) } } @@ -577,14 +571,6 @@ func createctDirectConnection(host string) (conn, error) { return conn{c, ctDirectConn}, nil } -func isErrConnReset(err error) bool { - ne, ok := err.(*net.OpError) - if ok { - return ne.Err == syscall.ECONNRESET - } - return false -} - func isErrTimeout(err error) bool { ne, ok := err.(*net.OpError) if ok { @@ -594,11 +580,7 @@ func isErrTimeout(err error) bool { } func maybeBlocked(err error) bool { - ne, ok := err.(*net.OpError) - if ok { - return ne.Timeout() || ne.Err == syscall.ECONNRESET - } - return false + return isErrTimeout(err) || isErrConnReset(err) } const connFailedErrCode = "504 Connection failed" diff --git a/proxy_unix.go b/proxy_unix.go new file mode 100644 index 0000000..efef3ac --- /dev/null +++ b/proxy_unix.go @@ -0,0 +1,15 @@ +// +build darwin freebsd linux netbsd openbsd + +package main + +import ( + "net" + "syscall" +) + +func isErrConnReset(err error) bool { + if ne, ok := err.(*net.OpError); ok { + return ne.Err == syscall.ECONNRESET + } + return false +} diff --git a/proxy_windows.go b/proxy_windows.go new file mode 100644 index 0000000..8337816 --- /dev/null +++ b/proxy_windows.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "net" + "syscall" +) + +var _ = fmt.Print + +func isErrConnReset(err error) bool { + if ne, ok := err.(*net.OpError); ok { + if errno, enok := ne.Err.(syscall.Errno); enok { + // I got these number by print. Only tested on XP. + // fmt.Println("network errno:", errno) + return errno == 64 || errno == 10054 + } + } + return false +}