Эх сурвалжийг харах

Merge pull request #135 from efryntov/master

Meek proxy support for non-HTTP proxies, SOCKS4a extension for domain names support in upstreamproxy package
Rod Hynes 10 жил өмнө
parent
commit
0246d98e46

+ 2 - 1
psiphon/meekConn.go

@@ -30,6 +30,7 @@ import (
 	"net"
 	"net"
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
+	"strings"
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
@@ -173,7 +174,7 @@ func DialMeek(
 		// In the unfronted case, host is both what is dialed and what ends up in the HTTP Host header
 		// In the unfronted case, host is both what is dialed and what ends up in the HTTP Host header
 		host = fmt.Sprintf("%s:%d", serverEntry.IpAddress, serverEntry.MeekServerPort)
 		host = fmt.Sprintf("%s:%d", serverEntry.IpAddress, serverEntry.MeekServerPort)
 
 
-		if meekConfig.UpstreamProxyUrl != "" {
+		if strings.HasPrefix(meekConfig.UpstreamProxyUrl, "http://") {
 			// For unfronted meek, we let the http.Transport handle proxying, as the
 			// For unfronted meek, we let the http.Transport handle proxying, as the
 			// target server hostname has to be in the HTTP request line. Also, in this
 			// target server hostname has to be in the HTTP request line. Also, in this
 			// case, we don't require the proxy to support CONNECT and so we can work
 			// case, we don't require the proxy to support CONNECT and so we can work

+ 11 - 4
psiphon/upstreamproxy/proxy_socks4.go

@@ -96,13 +96,17 @@ func (s *socks4Proxy) Dial(network, addr string) (net.Conn, error) {
 	}
 	}
 
 
 	// Deal with the destination address/string.
 	// Deal with the destination address/string.
-	ipStr, portStr, err := net.SplitHostPort(addr)
+	hostStr, portStr, err := net.SplitHostPort(addr)
+	domainDest := ""
 	if err != nil {
 	if err != nil {
 		return nil, proxyError(fmt.Errorf("parsing destination address: %v", err))
 		return nil, proxyError(fmt.Errorf("parsing destination address: %v", err))
 	}
 	}
-	ip := net.ParseIP(ipStr)
+	ip := net.ParseIP(hostStr)
 	if ip == nil {
 	if ip == nil {
-		return nil, proxyError(fmt.Errorf("failed to parse destination IP"))
+		// hostStr is not representing an IP, probably a domain name
+		// try to put an invalid IP into DSTIP field and
+		// append domain name terminated by '\x00' at the end of request
+		ip = net.IPv4(0, 0, 0, 1)
 	}
 	}
 	ip4 := ip.To4()
 	ip4 := ip.To4()
 	if ip4 == nil {
 	if ip4 == nil {
@@ -133,6 +137,10 @@ func (s *socks4Proxy) Dial(network, addr string) (net.Conn, error) {
 		req = append(req, s.username...)
 		req = append(req, s.username...)
 	}
 	}
 	req = append(req, socks4Null)
 	req = append(req, socks4Null)
+	if domainDest != "" {
+		req = append(req, domainDest...)
+		req = append(req, socks4Null)
+	}
 	_, err = c.Write(req)
 	_, err = c.Write(req)
 	if err != nil {
 	if err != nil {
 		c.Close()
 		c.Close()
@@ -176,6 +184,5 @@ func socks4ErrorToString(code byte) string {
 }
 }
 
 
 func init() {
 func init() {
-	// Despite the scheme name, this really is SOCKS4.
 	proxy.RegisterDialerType("socks4a", newSOCKS4)
 	proxy.RegisterDialerType("socks4a", newSOCKS4)
 }
 }