Connection reset detection on Windows XP.

This commit is contained in:
Chen Yufei
2013-01-30 20:36:20 +08:00
parent ecedab9cad
commit 08f748dc72
6 changed files with 48 additions and 28 deletions

View File

@@ -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)

View File

@@ -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",

View File

@@ -20,6 +20,7 @@ var directDomainList = []string{
"baidu.com",
"bankcomm.com",
"bankofchina.com",
"bdstatic.com",
"bing.com",
"bing.com.cn",
"boc.cn",

View File

@@ -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"

15
proxy_unix.go Normal file
View File

@@ -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
}

20
proxy_windows.go Normal file
View File

@@ -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
}