mirror of
https://github.com/zhigang1992/cow.git
synced 2026-01-12 17:12:57 +08:00
Connection reset detection on Windows XP.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -20,6 +20,7 @@ var directDomainList = []string{
|
||||
"baidu.com",
|
||||
"bankcomm.com",
|
||||
"bankofchina.com",
|
||||
"bdstatic.com",
|
||||
"bing.com",
|
||||
"bing.com.cn",
|
||||
"boc.cn",
|
||||
|
||||
30
proxy.go
30
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"
|
||||
|
||||
15
proxy_unix.go
Normal file
15
proxy_unix.go
Normal 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
20
proxy_windows.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user