mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 15:52:38 +08:00 
			
		
		
		
	forwarder: add the ability to specify local ip. #48
This commit is contained in:
		
							parent
							
								
									205b4efac7
								
							
						
					
					
						commit
						39ccbc5adf
					
				
							
								
								
									
										7
									
								
								conf.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								conf.go
									
									
									
									
									
								
							@ -191,10 +191,9 @@ func usage() {
 | 
				
			|||||||
	fmt.Fprintf(os.Stderr, "  lha: Latency based High Availability mode\n")
 | 
						fmt.Fprintf(os.Stderr, "  lha: Latency based High Availability mode\n")
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "\n")
 | 
						fmt.Fprintf(os.Stderr, "\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "Forwarder option scheme: FORWARD_URL[#OPTIONS]\n")
 | 
						fmt.Fprintf(os.Stderr, "Forwarder option scheme: FORWARD_URL#OPTIONS\n")
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "  Available options for forwarders:\n")
 | 
						fmt.Fprintf(os.Stderr, "  priority: set the priority of that forwarder, default:0\n")
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "    priority: set the priority of that forwarder, default:0\n")
 | 
						fmt.Fprintf(os.Stderr, "  e.g.:\n")
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "  Examples:\n")
 | 
					 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "    socks5://1.1.1.1:1080#priority=100\n")
 | 
						fmt.Fprintf(os.Stderr, "    socks5://1.1.1.1:1080#priority=100\n")
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "    vmess://[security:]uuid@host:port?alterID=num#priority=200\n")
 | 
						fmt.Fprintf(os.Stderr, "    vmess://[security:]uuid@host:port?alterID=num#priority=200\n")
 | 
				
			||||||
	fmt.Fprintf(os.Stderr, "\n")
 | 
						fmt.Fprintf(os.Stderr, "\n")
 | 
				
			||||||
 | 
				
			|||||||
@ -129,7 +129,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (server
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// if we are resolving the dialer's domain, then use Direct to avoid denpency loop
 | 
						// if we are resolving the dialer's domain, then use Direct to avoid denpency loop
 | 
				
			||||||
	if strings.Contains(dialer.Addr(), qname) {
 | 
						if strings.Contains(dialer.Addr(), qname) {
 | 
				
			||||||
		dialer = proxy.Direct
 | 
							dialer = proxy.Default
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If client uses udp and no forwarders specified, use udp
 | 
						// If client uses udp and no forwarders specified, use udp
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,7 @@ func DialerFromURL(s string, dialer Dialer) (Dialer, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if dialer == nil {
 | 
						if dialer == nil {
 | 
				
			||||||
		dialer = Direct
 | 
							dialer = Default
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c, ok := dialerMap[strings.ToLower(u.Scheme)]
 | 
						c, ok := dialerMap[strings.ToLower(u.Scheme)]
 | 
				
			||||||
 | 
				
			|||||||
@ -6,20 +6,33 @@ import (
 | 
				
			|||||||
	"github.com/nadoo/glider/common/log"
 | 
						"github.com/nadoo/glider/common/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// direct proxy
 | 
					 | 
				
			||||||
type direct struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Direct proxy
 | 
					// Direct proxy
 | 
				
			||||||
var Direct = &direct{}
 | 
					type Direct struct {
 | 
				
			||||||
 | 
						*net.Dialer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *direct) Addr() string { return "DIRECT" }
 | 
					// Default dialer
 | 
				
			||||||
 | 
					var Default = &Direct{Dialer: &net.Dialer{}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *direct) Dial(network, addr string) (net.Conn, error) {
 | 
					// NewDirect returns a Direct dialer
 | 
				
			||||||
 | 
					func NewDirect(localip string) *Direct {
 | 
				
			||||||
 | 
						d := &net.Dialer{LocalAddr: &net.TCPAddr{
 | 
				
			||||||
 | 
							IP:   net.ParseIP(localip),
 | 
				
			||||||
 | 
							Port: 0,
 | 
				
			||||||
 | 
						}}
 | 
				
			||||||
 | 
						return &Direct{Dialer: d}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Addr returns forwarder's address
 | 
				
			||||||
 | 
					func (d *Direct) Addr() string { return "DIRECT" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Dial connects to the address addr on the network net
 | 
				
			||||||
 | 
					func (d *Direct) Dial(network, addr string) (net.Conn, error) {
 | 
				
			||||||
	if network == "uot" {
 | 
						if network == "uot" {
 | 
				
			||||||
		network = "udp"
 | 
							network = "udp"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c, err := net.Dial(network, addr)
 | 
						c, err := d.Dialer.Dial(network, addr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -31,8 +44,9 @@ func (d *direct) Dial(network, addr string) (net.Conn, error) {
 | 
				
			|||||||
	return c, err
 | 
						return c, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *direct) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
 | 
					// DialUDP connects to the given address
 | 
				
			||||||
	pc, err := net.ListenPacket(network, "")
 | 
					func (d *Direct) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
 | 
				
			||||||
 | 
						pc, err := net.ListenPacket(network, d.Dialer.LocalAddr.String())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.F("ListenPacket error: %s", err)
 | 
							log.F("ListenPacket error: %s", err)
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
@ -42,4 +56,5 @@ func (d *direct) DialUDP(network, addr string) (net.PacketConn, net.Addr, error)
 | 
				
			|||||||
	return pc, uAddr, err
 | 
						return pc, uAddr, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (d *direct) NextDialer(dstAddr string) Dialer { return d }
 | 
					// NextDialer returns the next dialer
 | 
				
			||||||
 | 
					func (d *Direct) NextDialer(dstAddr string) Dialer { return d }
 | 
				
			||||||
 | 
				
			|||||||
@ -19,12 +19,19 @@ type Forwarder struct {
 | 
				
			|||||||
	failures    uint32
 | 
						failures    uint32
 | 
				
			||||||
	MaxFailures uint32 //maxfailures to set to Disabled
 | 
						MaxFailures uint32 //maxfailures to set to Disabled
 | 
				
			||||||
	latency     int64
 | 
						latency     int64
 | 
				
			||||||
 | 
						localip     string // local ip address
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ForwarderFromURL parses `forward=` command value and returns a new forwarder
 | 
					// ForwarderFromURL parses `forward=` command value and returns a new forwarder
 | 
				
			||||||
func ForwarderFromURL(s string) (f *Forwarder, err error) {
 | 
					func ForwarderFromURL(s string) (f *Forwarder, err error) {
 | 
				
			||||||
 | 
						f = &Forwarder{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ss := strings.Split(s, "#")
 | 
						ss := strings.Split(s, "#")
 | 
				
			||||||
	var d Dialer
 | 
						if len(ss) > 1 {
 | 
				
			||||||
 | 
							err = f.parseOption(ss[1])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var d Dialer = NewDirect(f.localip)
 | 
				
			||||||
	for _, url := range strings.Split(ss[0], ",") {
 | 
						for _, url := range strings.Split(ss[0], ",") {
 | 
				
			||||||
		d, err = DialerFromURL(url, d)
 | 
							d, err = DialerFromURL(url, d)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -32,19 +39,12 @@ func ForwarderFromURL(s string) (f *Forwarder, err error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = NewForwarder(d)
 | 
						f.Dialer = d
 | 
				
			||||||
	if len(ss) > 1 {
 | 
						f.addr = d.Addr()
 | 
				
			||||||
		err = f.parseOption(ss[1])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return f, err
 | 
						return f, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewForwarder returns a new forwarder
 | 
					 | 
				
			||||||
func NewForwarder(dialer Dialer) *Forwarder {
 | 
					 | 
				
			||||||
	return &Forwarder{Dialer: dialer, addr: dialer.Addr()}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *Forwarder) parseOption(option string) error {
 | 
					func (f *Forwarder) parseOption(option string) error {
 | 
				
			||||||
	query, err := url.ParseQuery(option)
 | 
						query, err := url.ParseQuery(option)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@ -58,6 +58,8 @@ func (f *Forwarder) parseOption(option string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	f.Priority = int(priority)
 | 
						f.Priority = int(priority)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f.localip = query.Get("localip")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ func ServerFromURL(s string, dialer Dialer) (Server, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if dialer == nil {
 | 
						if dialer == nil {
 | 
				
			||||||
		dialer = Direct
 | 
							dialer = Default
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c, ok := serverMap[strings.ToLower(u.Scheme)]
 | 
						c, ok := serverMap[strings.ToLower(u.Scheme)]
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ func NewDialer(s []string, c *Config) proxy.Dialer {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(fwdrs) == 0 {
 | 
						if len(fwdrs) == 0 {
 | 
				
			||||||
		return proxy.Direct
 | 
							return proxy.Default
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(fwdrs) == 1 {
 | 
						if len(fwdrs) == 1 {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user