go-socks5
go-socks5 copied to clipboard
Issues with custom dialer
I want to customize the dialer so that it can dial outgoing connection using IPv6 address.
However, this library will prefer DNS resolution by default. In a dual-stack environment and the client use socks5h
(which means the hostname will not be resolved by the client), the resolved IP address might be IPv4, thus making the dialing failed.
Although I found a workaround that can pretend the name resolution success with empty result:
func (d YourResolver) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) {
return ctx, []byte{}, nil
}
And it can trick the address formatter to use the FQDN instead: https://github.com/things-go/go-socks5/blob/6191a3489f54e890dbaeafc168c470c9fb2135e4/statute/addr.go#L19-L26
It depends on the fallback of the error case, so it's not ideal to implement like this. Considering we need to have backwards compatibility, we also can't change the resolve logic here:
https://github.com/things-go/go-socks5/blob/6191a3489f54e890dbaeafc168c470c9fb2135e4/handle.go#L50-L65
So I'm creating an issue looking for ideas to solve this issue.
Maybe your question is to force your custom resolver to return an ipv6 address?
You can try net.ResolveIPAddr("ip6", name) or other go resolver, maybe like following:
func (d DNSResolver) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) {
addr, err := net.ResolveIPAddr("ip6", name)
if err != nil {
addr, err = net.ResolveIPAddr("ip4", name)
if err != nil {
return ctx, nil, err
}
return ctx, addr.IP, nil
}
return ctx, addr.IP, nil
}
Maybe your question is to force your custom resolver to return an ipv6 address?
You can try net.ResolveIPAddr("ip6", name) or other go resolver, maybe like following:
func (d DNSResolver) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) { addr, err := net.ResolveIPAddr("ip6", name) if err != nil { addr, err = net.ResolveIPAddr("ip4", name) if err != nil { return ctx, nil, err } return ctx, addr.IP, nil } return ctx, addr.IP, nil }
So what I'm trying to do is that, I want to use user a
for IPv4 outbound and b
for IPv6 outbound.
Although I can use ctx
for storing user information, it will be way easier if we have the option to skip the domain resolution.