mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 07:40:56 +08:00 
			
		
		
		
	支持PROXY Protocol/修复UDP源站无法修改的问题
This commit is contained in:
		
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							@@ -23,6 +23,7 @@ require (
 | 
				
			|||||||
	github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
 | 
						github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
 | 
				
			||||||
	github.com/mattn/go-sqlite3 v2.0.3+incompatible
 | 
						github.com/mattn/go-sqlite3 v2.0.3+incompatible
 | 
				
			||||||
	github.com/mssola/user_agent v0.5.2
 | 
						github.com/mssola/user_agent v0.5.2
 | 
				
			||||||
 | 
						github.com/pires/go-proxyproto v0.6.1
 | 
				
			||||||
	github.com/shirou/gopsutil v3.21.5+incompatible
 | 
						github.com/shirou/gopsutil v3.21.5+incompatible
 | 
				
			||||||
	github.com/tklauser/go-sysconf v0.3.6 // indirect
 | 
						github.com/tklauser/go-sysconf v0.3.6 // indirect
 | 
				
			||||||
	golang.org/x/image v0.0.0-20190802002840-cff245a6509b
 | 
						golang.org/x/image v0.0.0-20190802002840-cff245a6509b
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@@ -110,6 +110,8 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
 | 
				
			|||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 | 
					github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 | 
				
			||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 | 
					github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 | 
				
			||||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 | 
					github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 | 
				
			||||||
 | 
					github.com/pires/go-proxyproto v0.6.1 h1:EBupykFmo22SDjv4fQVQd2J9NOoLPmyZA/15ldOGkPw=
 | 
				
			||||||
 | 
					github.com/pires/go-proxyproto v0.6.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
					github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
					github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,10 +6,12 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
				
			||||||
 | 
						"github.com/pires/go-proxyproto"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -37,7 +39,7 @@ func NewHTTPClientPool() *HTTPClientPool {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Client 根据地址获取客户端
 | 
					// Client 根据地址获取客户端
 | 
				
			||||||
func (this *HTTPClientPool) Client(req *http.Request, origin *serverconfigs.OriginConfig, originAddr string) (rawClient *http.Client, err error) {
 | 
					func (this *HTTPClientPool) Client(req *HTTPRequest, origin *serverconfigs.OriginConfig, originAddr string, proxyProtocol *serverconfigs.ProxyProtocolConfig) (rawClient *http.Client, err error) {
 | 
				
			||||||
	if origin.Addr == nil {
 | 
						if origin.Addr == nil {
 | 
				
			||||||
		return nil, errors.New("origin addr should not be empty (originId:" + strconv.FormatInt(origin.Id, 10) + ")")
 | 
							return nil, errors.New("origin addr should not be empty (originId:" + strconv.FormatInt(origin.Id, 10) + ")")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -105,7 +107,7 @@ func (this *HTTPClientPool) Client(req *http.Request, origin *serverconfigs.Orig
 | 
				
			|||||||
				for i := 1; i <= retries; i++ {
 | 
									for i := 1; i <= retries; i++ {
 | 
				
			||||||
					port := int(toaConfig.RandLocalPort())
 | 
										port := int(toaConfig.RandLocalPort())
 | 
				
			||||||
					// TODO 思考是否支持X-Real-IP/X-Forwarded-IP
 | 
										// TODO 思考是否支持X-Real-IP/X-Forwarded-IP
 | 
				
			||||||
					err := sharedTOAManager.SendMsg("add:" + strconv.Itoa(port) + ":" + req.RemoteAddr)
 | 
										err := sharedTOAManager.SendMsg("add:" + strconv.Itoa(port) + ":" + req.requestRemoteAddr(true))
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						remotelogs.Error("TOA", "add failed: "+err.Error())
 | 
											remotelogs.Error("TOA", "add failed: "+err.Error())
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
@@ -126,10 +128,43 @@ func (this *HTTPClientPool) Client(req *http.Request, origin *serverconfigs.Orig
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// 普通的连接
 | 
								// 普通的连接
 | 
				
			||||||
			return (&net.Dialer{
 | 
								conn, err := (&net.Dialer{
 | 
				
			||||||
				Timeout:   connectionTimeout,
 | 
									Timeout:   connectionTimeout,
 | 
				
			||||||
				KeepAlive: 1 * time.Minute,
 | 
									KeepAlive: 1 * time.Minute,
 | 
				
			||||||
			}).DialContext(ctx, network, originAddr)
 | 
								}).DialContext(ctx, network, originAddr)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if proxyProtocol != nil && proxyProtocol.IsOn && (proxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || proxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
 | 
				
			||||||
 | 
									var remoteAddr = req.requestRemoteAddr(true)
 | 
				
			||||||
 | 
									var transportProtocol = proxyproto.TCPv4
 | 
				
			||||||
 | 
									if strings.Contains(remoteAddr, ":") {
 | 
				
			||||||
 | 
										transportProtocol = proxyproto.TCPv6
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									var destAddr = conn.RemoteAddr()
 | 
				
			||||||
 | 
									var reqConn = req.RawReq.Context().Value(HTTPConnContextKey)
 | 
				
			||||||
 | 
									if reqConn != nil {
 | 
				
			||||||
 | 
										destAddr = reqConn.(net.Conn).LocalAddr()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									header := proxyproto.Header{
 | 
				
			||||||
 | 
										Version:           byte(proxyProtocol.Version),
 | 
				
			||||||
 | 
										Command:           proxyproto.PROXY,
 | 
				
			||||||
 | 
										TransportProtocol: transportProtocol,
 | 
				
			||||||
 | 
										SourceAddr: &net.TCPAddr{
 | 
				
			||||||
 | 
											IP:   net.ParseIP(remoteAddr),
 | 
				
			||||||
 | 
											Port: req.requestRemotePort(),
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										DestinationAddr: destAddr,
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									_, err = header.WriteTo(conn)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										_ = conn.Close()
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return conn, nil
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		MaxIdleConns:          0,
 | 
							MaxIdleConns:          0,
 | 
				
			||||||
		MaxIdleConnsPerHost:   idleConns,
 | 
							MaxIdleConnsPerHost:   idleConns,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,14 +21,14 @@ func TestHTTPClientPool_Client(t *testing.T) {
 | 
				
			|||||||
			t.Fatal(err)
 | 
								t.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			client, err := pool.Client(nil, origin, origin.Addr.PickAddress())
 | 
								client, err := pool.Client(nil, origin, origin.Addr.PickAddress(), nil)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			t.Log("client:", client)
 | 
								t.Log("client:", client)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for i := 0; i < 10; i++ {
 | 
							for i := 0; i < 10; i++ {
 | 
				
			||||||
			client, err := pool.Client(nil, origin, origin.Addr.PickAddress())
 | 
								client, err := pool.Client(nil, origin, origin.Addr.PickAddress(), nil)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -53,7 +53,7 @@ func TestHTTPClientPool_cleanClients(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < 10; i++ {
 | 
						for i := 0; i < 10; i++ {
 | 
				
			||||||
		t.Log("get", i)
 | 
							t.Log("get", i)
 | 
				
			||||||
		_, _ = pool.Client(nil, origin, origin.Addr.PickAddress())
 | 
							_, _ = pool.Client(nil, origin, origin.Addr.PickAddress(), nil)
 | 
				
			||||||
		time.Sleep(1 * time.Second)
 | 
							time.Sleep(1 * time.Second)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -73,6 +73,6 @@ func BenchmarkHTTPClientPool_Client(b *testing.B) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	pool := NewHTTPClientPool()
 | 
						pool := NewHTTPClientPool()
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		_, _ = pool.Client(nil, origin, origin.Addr.PickAddress())
 | 
							_, _ = pool.Client(nil, origin, origin.Addr.PickAddress(), nil)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -145,7 +145,7 @@ func (this *HTTPRequest) doReverseProxy() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 获取请求客户端
 | 
						// 获取请求客户端
 | 
				
			||||||
	client, err := SharedHTTPClientPool.Client(this.RawReq, origin, originAddr)
 | 
						client, err := SharedHTTPClientPool.Client(this, origin, originAddr, this.reverseProxy.ProxyProtocol)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		remotelogs.Error("HTTP_REQUEST_REVERSE_PROXY", err.Error())
 | 
							remotelogs.Error("HTTP_REQUEST_REVERSE_PROXY", err.Error())
 | 
				
			||||||
		this.write50x(err, http.StatusBadGateway)
 | 
							this.write50x(err, http.StatusBadGateway)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,9 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/stats"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/stats"
 | 
				
			||||||
 | 
						"github.com/pires/go-proxyproto"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,6 +85,31 @@ func (this *TCPListener) handleConn(conn net.Conn) error {
 | 
				
			|||||||
		_ = originConn.Close()
 | 
							_ = originConn.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// PROXY Protocol
 | 
				
			||||||
 | 
						if firstServer.ReverseProxy != nil &&
 | 
				
			||||||
 | 
							firstServer.ReverseProxy.ProxyProtocol != nil &&
 | 
				
			||||||
 | 
							firstServer.ReverseProxy.ProxyProtocol.IsOn &&
 | 
				
			||||||
 | 
							(firstServer.ReverseProxy.ProxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || firstServer.ReverseProxy.ProxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
 | 
				
			||||||
 | 
							var remoteAddr = conn.RemoteAddr()
 | 
				
			||||||
 | 
							var transportProtocol = proxyproto.TCPv4
 | 
				
			||||||
 | 
							if strings.Contains(remoteAddr.String(), "[") {
 | 
				
			||||||
 | 
								transportProtocol = proxyproto.TCPv6
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							header := proxyproto.Header{
 | 
				
			||||||
 | 
								Version:           byte(firstServer.ReverseProxy.ProxyProtocol.Version),
 | 
				
			||||||
 | 
								Command:           proxyproto.PROXY,
 | 
				
			||||||
 | 
								TransportProtocol: transportProtocol,
 | 
				
			||||||
 | 
								SourceAddr:        remoteAddr,
 | 
				
			||||||
 | 
								DestinationAddr:   conn.LocalAddr(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_, err = header.WriteTo(originConn)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								closer()
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 从源站读取
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		originBuffer := bytePool32k.Get()
 | 
							originBuffer := bytePool32k.Get()
 | 
				
			||||||
		defer func() {
 | 
							defer func() {
 | 
				
			||||||
@@ -107,6 +134,7 @@ func (this *TCPListener) handleConn(conn net.Conn) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 从客户端读取
 | 
				
			||||||
	clientBuffer := bytePool32k.Get()
 | 
						clientBuffer := bytePool32k.Get()
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		bytePool32k.Put(clientBuffer)
 | 
							bytePool32k.Put(clientBuffer)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ import (
 | 
				
			|||||||
func TestListener_Listen(t *testing.T) {
 | 
					func TestListener_Listen(t *testing.T) {
 | 
				
			||||||
	listener := NewListener()
 | 
						listener := NewListener()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	group := serverconfigs.NewServerGroup("http://:1234")
 | 
						group := serverconfigs.NewServerAddressGroup("https://:1234")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	listener.Reload(group)
 | 
						listener.Reload(group)
 | 
				
			||||||
	err := listener.Listen()
 | 
						err := listener.Listen()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,9 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/stats"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/stats"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/utils"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/utils"
 | 
				
			||||||
 | 
						"github.com/pires/go-proxyproto"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -19,6 +21,8 @@ type UDPListener struct {
 | 
				
			|||||||
	connMap    map[string]*UDPConn
 | 
						connMap    map[string]*UDPConn
 | 
				
			||||||
	connLocker sync.Mutex
 | 
						connLocker sync.Mutex
 | 
				
			||||||
	connTicker *utils.Ticker
 | 
						connTicker *utils.Ticker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reverseProxy *serverconfigs.ReverseProxyConfig
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *UDPListener) Serve() error {
 | 
					func (this *UDPListener) Serve() error {
 | 
				
			||||||
@@ -26,8 +30,9 @@ func (this *UDPListener) Serve() error {
 | 
				
			|||||||
	if firstServer == nil {
 | 
						if firstServer == nil {
 | 
				
			||||||
		return errors.New("no server available")
 | 
							return errors.New("no server available")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if firstServer.ReverseProxy == nil {
 | 
						this.reverseProxy = firstServer.ReverseProxy
 | 
				
			||||||
		return errors.New("no ReverseProxy configured for the server")
 | 
						if this.reverseProxy == nil {
 | 
				
			||||||
 | 
							return errors.New("no ReverseProxy configured for the server '" + firstServer.Name + "'")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.connMap = map[string]*UDPConn{}
 | 
						this.connMap = map[string]*UDPConn{}
 | 
				
			||||||
@@ -50,7 +55,7 @@ func (this *UDPListener) Serve() error {
 | 
				
			|||||||
				ok = false
 | 
									ok = false
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if !ok {
 | 
								if !ok {
 | 
				
			||||||
				originConn, err := this.connectOrigin(firstServer.ReverseProxy, "")
 | 
									originConn, err := this.connectOrigin(this.reverseProxy, addr)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					remotelogs.Error("UDP_LISTENER", "unable to connect to origin server: "+err.Error())
 | 
										remotelogs.Error("UDP_LISTENER", "unable to connect to origin server: "+err.Error())
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
@@ -87,9 +92,16 @@ func (this *UDPListener) Close() error {
 | 
				
			|||||||
func (this *UDPListener) Reload(group *serverconfigs.ServerAddressGroup) {
 | 
					func (this *UDPListener) Reload(group *serverconfigs.ServerAddressGroup) {
 | 
				
			||||||
	this.Group = group
 | 
						this.Group = group
 | 
				
			||||||
	this.Reset()
 | 
						this.Reset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 重置配置
 | 
				
			||||||
 | 
						firstServer := this.Group.FirstServer()
 | 
				
			||||||
 | 
						if firstServer == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.reverseProxy = firstServer.ReverseProxy
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *UDPListener) connectOrigin(reverseProxy *serverconfigs.ReverseProxyConfig, remoteAddr string) (conn net.Conn, err error) {
 | 
					func (this *UDPListener) connectOrigin(reverseProxy *serverconfigs.ReverseProxyConfig, remoteAddr net.Addr) (conn net.Conn, err error) {
 | 
				
			||||||
	if reverseProxy == nil {
 | 
						if reverseProxy == nil {
 | 
				
			||||||
		return nil, errors.New("no reverse proxy config")
 | 
							return nil, errors.New("no reverse proxy config")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -100,11 +112,34 @@ func (this *UDPListener) connectOrigin(reverseProxy *serverconfigs.ReverseProxyC
 | 
				
			|||||||
		if origin == nil {
 | 
							if origin == nil {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		conn, err = OriginConnect(origin, remoteAddr)
 | 
							conn, err = OriginConnect(origin, remoteAddr.String())
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			remotelogs.Error("UDP_LISTENER", "unable to connect origin: "+origin.Addr.Host+":"+origin.Addr.PortRange+": "+err.Error())
 | 
								remotelogs.Error("UDP_LISTENER", "unable to connect origin: "+origin.Addr.Host+":"+origin.Addr.PortRange+": "+err.Error())
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
								// PROXY Protocol
 | 
				
			||||||
 | 
								if reverseProxy != nil &&
 | 
				
			||||||
 | 
									reverseProxy.ProxyProtocol != nil &&
 | 
				
			||||||
 | 
									reverseProxy.ProxyProtocol.IsOn &&
 | 
				
			||||||
 | 
									(reverseProxy.ProxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || reverseProxy.ProxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
 | 
				
			||||||
 | 
									var transportProtocol = proxyproto.UDPv4
 | 
				
			||||||
 | 
									if strings.Contains(remoteAddr.String(), "[") {
 | 
				
			||||||
 | 
										transportProtocol = proxyproto.UDPv6
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									header := proxyproto.Header{
 | 
				
			||||||
 | 
										Version:           byte(reverseProxy.ProxyProtocol.Version),
 | 
				
			||||||
 | 
										Command:           proxyproto.PROXY,
 | 
				
			||||||
 | 
										TransportProtocol: transportProtocol,
 | 
				
			||||||
 | 
										SourceAddr:        remoteAddr,
 | 
				
			||||||
 | 
										DestinationAddr:   this.Listener.LocalAddr(),
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									_, err = header.WriteTo(conn)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										_ = conn.Close()
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user