mirror of
https://github.com/nadoo/glider.git
synced 2025-02-24 01:45:39 +08:00
forwarder: add the ability to specify local ip. #48
This commit is contained in:
parent
205b4efac7
commit
39ccbc5adf
5
conf.go
5
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, " Examples:\n")
|
fmt.Fprintf(os.Stderr, " e.g.:\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