Просмотр исходного кода

Fix: more robust EADDRINUSE error detection; now works on Windows

Rod Hynes 11 лет назад
Родитель
Сommit
b8e923fbe4
3 измененных файлов с 18 добавлено и 5 удалено
  1. 1 1
      psiphon/httpProxy.go
  2. 1 1
      psiphon/socksProxy.go
  3. 16 3
      psiphon/utils.go

+ 1 - 1
psiphon/httpProxy.go

@@ -44,7 +44,7 @@ func NewHttpProxy(config *Config, tunneler Tunneler) (proxy *HttpProxy, err erro
 	listener, err := net.Listen(
 		"tcp", fmt.Sprintf("127.0.0.1:%d", config.LocalHttpProxyPort))
 	if err != nil {
-		if IsNetworkBindError(err) {
+		if IsAddressInUseError(err) {
 			NoticeHttpProxyPortInUse(config.LocalSocksProxyPort)
 		}
 		return nil, ContextError(err)

+ 1 - 1
psiphon/socksProxy.go

@@ -46,7 +46,7 @@ func NewSocksProxy(config *Config, tunneler Tunneler) (proxy *SocksProxy, err er
 	listener, err := socks.ListenSocks(
 		"tcp", fmt.Sprintf("127.0.0.1:%d", config.LocalSocksProxyPort))
 	if err != nil {
-		if IsNetworkBindError(err) {
+		if IsAddressInUseError(err) {
 			NoticeSocksProxyPortInUse(config.LocalSocksProxyPort)
 		}
 		return nil, ContextError(err)

+ 16 - 3
psiphon/utils.go

@@ -141,7 +141,20 @@ func ContextError(err error) error {
 	return fmt.Errorf("%s#%d: %s", funcName, line, err)
 }
 
-// IsNetworkBindError returns true when the err is due to EADDRINUSE.
-func IsNetworkBindError(err error) bool {
-	return strings.Contains(err.Error(), "bind: address already in use")
+// IsAddressInUseError returns true when the err is due to EADDRINUSE/WSAEADDRINUSE.
+func IsAddressInUseError(err error) bool {
+	if err, ok := err.(*net.OpError); ok {
+		if err, ok := err.Err.(*os.SyscallError); ok {
+			if err.Err == syscall.EADDRINUSE {
+				return true
+			}
+			// Special case for Windows (WSAEADDRINUSE = 10048)
+			if errno, ok := err.Err.(syscall.Errno); ok {
+				if 10048 == int(errno) {
+					return true
+				}
+			}
+		}
+	}
+	return false
 }