-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from Snawoot/localaddr_hint
Localaddr hint
- Loading branch information
Showing
7 changed files
with
198 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -194,6 +194,8 @@ Usage of /home/user/go/bin/dumbproxy: | |
colon-separated list of enabled ciphers | ||
-disable-http2 | ||
disable HTTP2 | ||
-ip-hints value | ||
a comma-separated list of source addresses to use on dial attempts. Example: "10.0.0.1,fe80::2,0.0.0.0,::" | ||
-key string | ||
key for TLS certificate | ||
-list-ciphers | ||
|
@@ -206,6 +208,8 @@ Usage of /home/user/go/bin/dumbproxy: | |
upstream proxy URL. Can be repeated multiple times to chain proxies. Examples: socks5h://127.0.0.1:9050; https://user:[email protected]:443 | ||
-timeout duration | ||
timeout for network operations (default 10s) | ||
-user-ip-hints | ||
allow IP hints to be specified by user in X-Src-IP-Hints header | ||
-verbosity int | ||
logging verbosity (10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical) (default 20) | ||
-version | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"net" | ||
|
||
"github.com/hashicorp/go-multierror" | ||
) | ||
|
||
var ( | ||
ErrNoSuitableAddress = errors.New("no suitable address") | ||
ErrBadIPAddressLength = errors.New("bad IP address length") | ||
ErrUnknownNetwork = errors.New("unknown network") | ||
) | ||
|
||
type BoundDialerContextKey struct{} | ||
|
||
type BoundDialerDefaultSink interface { | ||
DialContext(ctx context.Context, network, address string) (net.Conn, error) | ||
} | ||
|
||
type BoundDialer struct { | ||
defaultDialer BoundDialerDefaultSink | ||
defaultHints []net.IP | ||
} | ||
|
||
func NewBoundDialer(defaultDialer BoundDialerDefaultSink, defaultHints []net.IP) *BoundDialer { | ||
if defaultDialer == nil { | ||
defaultDialer = &net.Dialer{} | ||
} | ||
return &BoundDialer{ | ||
defaultDialer: defaultDialer, | ||
defaultHints: defaultHints, | ||
} | ||
} | ||
|
||
func (d *BoundDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { | ||
hints := d.defaultHints | ||
if hintsOverride := ctx.Value(BoundDialerContextKey{}); hintsOverride != nil { | ||
if hintsOverrideValue, ok := hintsOverride.([]net.IP); ok { | ||
hints = hintsOverrideValue | ||
} | ||
} | ||
|
||
if len(hints) == 0 { | ||
return d.defaultDialer.DialContext(ctx, network, address) | ||
} | ||
|
||
var netBase string | ||
switch network { | ||
case "tcp", "tcp4", "tcp6": | ||
netBase = "tcp" | ||
case "udp", "udp4", "udp6": | ||
netBase = "udp" | ||
case "ip", "ip4", "ip6": | ||
netBase = "ip" | ||
default: | ||
return d.defaultDialer.DialContext(ctx, network, address) | ||
} | ||
|
||
var resErr error | ||
for _, lIP := range hints { | ||
lAddr, restrictedNetwork, err := ipToLAddr(netBase, lIP) | ||
if err != nil { | ||
resErr = multierror.Append(resErr, fmt.Errorf("ipToLAddr(%q) failed: %w", lIP.String(), err)) | ||
continue | ||
} | ||
if network != netBase && network != restrictedNetwork { | ||
continue | ||
} | ||
|
||
conn, err := (&net.Dialer{ | ||
LocalAddr: lAddr, | ||
}).DialContext(ctx, restrictedNetwork, address) | ||
if err != nil { | ||
resErr = multierror.Append(resErr, fmt.Errorf("dial failed: %w", err)) | ||
} else { | ||
return conn, nil | ||
} | ||
} | ||
|
||
if resErr == nil { | ||
resErr = ErrNoSuitableAddress | ||
} | ||
return nil, resErr | ||
} | ||
|
||
func (d *BoundDialer) Dial(network, address string) (net.Conn, error) { | ||
return d.DialContext(context.Background(), network, address) | ||
} | ||
|
||
func ipToLAddr(network string, ip net.IP) (net.Addr, string, error) { | ||
v6 := true | ||
if ip4 := ip.To4(); len(ip4) == net.IPv4len { | ||
ip = ip4 | ||
v6 = false | ||
} else if len(ip) != net.IPv6len { | ||
return nil, "", ErrBadIPAddressLength | ||
} | ||
|
||
var lAddr net.Addr | ||
var lNetwork string | ||
switch network { | ||
case "tcp", "tcp4", "tcp6": | ||
lAddr = &net.TCPAddr{ | ||
IP: ip, | ||
} | ||
if v6 { | ||
lNetwork = "tcp6" | ||
} else { | ||
lNetwork = "tcp4" | ||
} | ||
case "udp", "udp4", "udp6": | ||
lAddr = &net.UDPAddr{ | ||
IP: ip, | ||
} | ||
if v6 { | ||
lNetwork = "udp6" | ||
} else { | ||
lNetwork = "udp4" | ||
} | ||
case "ip", "ip4", "ip6": | ||
lAddr = &net.IPAddr{ | ||
IP: ip, | ||
} | ||
if v6 { | ||
lNetwork = "ip6" | ||
} else { | ||
lNetwork = "ip4" | ||
} | ||
default: | ||
return nil, "", ErrUnknownNetwork | ||
} | ||
|
||
return lAddr, lNetwork, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters