mirror of
https://github.com/Snawoot/hola-proxy.git
synced 2026-04-13 17:31:48 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
518606be42 | ||
|
|
25958fd032 | ||
|
|
822530392d | ||
|
|
971530e7ce |
21
README.md
21
README.md
@@ -9,27 +9,6 @@ Application is capable to forward traffic via proxies in datacenters (flag `-pro
|
|||||||
|
|
||||||
This alternative implementation ensures your internet connection is not shared with anyone else and everything is clean and safe.
|
This alternative implementation ensures your internet connection is not shared with anyone else and everything is clean and safe.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
:heart: :heart: :heart:
|
|
||||||
|
|
||||||
You can say thanks to the author by donations to these wallets:
|
|
||||||
|
|
||||||
- ETH: `0xB71250010e8beC90C5f9ddF408251eBA9dD7320e`
|
|
||||||
- BTC:
|
|
||||||
- Legacy: `1N89PRvG1CSsUk9sxKwBwudN6TjTPQ1N8a`
|
|
||||||
- Segwit: `bc1qc0hcyxc000qf0ketv4r44ld7dlgmmu73rtlntw`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Mirrors
|
|
||||||
|
|
||||||
IPFS git mirror:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://ipfs.io/ipns/k51qzi5uqu5dkrgx0hozpy1tlggw5o0whtquyrjlc6pprhvbmczr6qtj4ocrv0 hola-proxy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Cross-platform (Windows/Mac OS/Linux/Android (via shell)/\*BSD)
|
* Cross-platform (Windows/Mac OS/Linux/Android (via shell)/\*BSD)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -19,3 +19,5 @@ require (
|
|||||||
golang.org/x/crypto v0.42.0 // indirect
|
golang.org/x/crypto v0.42.0 // indirect
|
||||||
golang.org/x/sys v0.36.0 // indirect
|
golang.org/x/sys v0.36.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
retract [v0.0.0-0, v1.18.3]
|
||||||
|
|||||||
79
resolver.go
79
resolver.go
@@ -14,14 +14,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func FromURL(u string) (*net.Resolver, error) {
|
func FromURL(u string) (*net.Resolver, error) {
|
||||||
|
begin:
|
||||||
parsed, err := url.Parse(u)
|
parsed, err := url.Parse(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
host := parsed.Hostname()
|
host := parsed.Hostname()
|
||||||
port := parsed.Port()
|
port := parsed.Port()
|
||||||
switch strings.ToLower(parsed.Scheme) {
|
switch scheme := strings.ToLower(parsed.Scheme); scheme {
|
||||||
case "", "dns":
|
case "":
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(u, "//"):
|
||||||
|
u = "dns:" + u
|
||||||
|
default:
|
||||||
|
u = "dns://" + u
|
||||||
|
}
|
||||||
|
goto begin
|
||||||
|
case "udp", "dns":
|
||||||
if port == "" {
|
if port == "" {
|
||||||
port = "53"
|
port = "53"
|
||||||
}
|
}
|
||||||
@@ -31,12 +40,20 @@ func FromURL(u string) (*net.Resolver, error) {
|
|||||||
port = "53"
|
port = "53"
|
||||||
}
|
}
|
||||||
return NewTCPResolver(net.JoinHostPort(host, port)), nil
|
return NewTCPResolver(net.JoinHostPort(host, port)), nil
|
||||||
case "http", "https":
|
case "http", "https", "doh":
|
||||||
if port == "" {
|
if port == "" {
|
||||||
port = "443"
|
if scheme == "http" {
|
||||||
|
port = "80"
|
||||||
|
} else {
|
||||||
|
port = "443"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if scheme == "doh" {
|
||||||
|
parsed.Scheme = "https"
|
||||||
|
u = parsed.String()
|
||||||
}
|
}
|
||||||
return dns.NewDoHResolver(u, dns.DoHAddresses(net.JoinHostPort(host, port)))
|
return dns.NewDoHResolver(u, dns.DoHAddresses(net.JoinHostPort(host, port)))
|
||||||
case "tls":
|
case "tls", "dot":
|
||||||
if port == "" {
|
if port == "" {
|
||||||
port = "853"
|
port = "853"
|
||||||
}
|
}
|
||||||
@@ -55,12 +72,7 @@ type FastResolver struct {
|
|||||||
upstreams []LookupNetIPer
|
upstreams []LookupNetIPer
|
||||||
}
|
}
|
||||||
|
|
||||||
type lookupReply struct {
|
func FastResolverFromURLs(urls ...string) (LookupNetIPer, error) {
|
||||||
addrs []netip.Addr
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func FastResolverFromURLs(urls ...string) (*FastResolver, error) {
|
|
||||||
resolvers := make([]LookupNetIPer, 0, len(urls))
|
resolvers := make([]LookupNetIPer, 0, len(urls))
|
||||||
for i, u := range urls {
|
for i, u := range urls {
|
||||||
res, err := FromURL(u)
|
res, err := FromURL(u)
|
||||||
@@ -69,6 +81,9 @@ func FastResolverFromURLs(urls ...string) (*FastResolver, error) {
|
|||||||
}
|
}
|
||||||
resolvers = append(resolvers, res)
|
resolvers = append(resolvers, res)
|
||||||
}
|
}
|
||||||
|
if len(resolvers) == 1 {
|
||||||
|
return resolvers[0], nil
|
||||||
|
}
|
||||||
return NewFastResolver(resolvers...), nil
|
return NewFastResolver(resolvers...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,34 +95,38 @@ func NewFastResolver(resolvers ...LookupNetIPer) *FastResolver {
|
|||||||
|
|
||||||
func (r FastResolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
|
func (r FastResolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
|
||||||
ctx, cl := context.WithCancel(ctx)
|
ctx, cl := context.WithCancel(ctx)
|
||||||
drain := make(chan lookupReply, len(r.upstreams))
|
defer cl()
|
||||||
|
errors := make(chan error)
|
||||||
|
success := make(chan []netip.Addr)
|
||||||
for _, res := range r.upstreams {
|
for _, res := range r.upstreams {
|
||||||
go func(res LookupNetIPer) {
|
go func(res LookupNetIPer) {
|
||||||
addrs, err := res.LookupNetIP(ctx, network, host)
|
addrs, err := res.LookupNetIP(ctx, network, host)
|
||||||
drain <- lookupReply{addrs, err}
|
if err == nil {
|
||||||
|
select {
|
||||||
|
case success <- addrs:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
select {
|
||||||
|
case errors <- err:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
}
|
||||||
}(res)
|
}(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
|
||||||
var resAddrs []netip.Addr
|
|
||||||
var resErr error
|
var resErr error
|
||||||
for ; i < len(r.upstreams); i++ {
|
for _ = range r.upstreams {
|
||||||
pair := <-drain
|
select {
|
||||||
if pair.err != nil {
|
case <-ctx.Done():
|
||||||
resErr = multierror.Append(resErr, pair.err)
|
return nil, ctx.Err()
|
||||||
} else {
|
case resAddrs := <-success:
|
||||||
cl()
|
return resAddrs, nil
|
||||||
resAddrs = pair.addrs
|
case err := <-errors:
|
||||||
resErr = nil
|
resErr = multierror.Append(resErr, err)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
go func() {
|
return nil, resErr
|
||||||
for i = i + 1; i < len(r.upstreams); i++ {
|
|
||||||
<-drain
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return resAddrs, resErr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlainResolver(addr string) *net.Resolver {
|
func NewPlainResolver(addr string) *net.Resolver {
|
||||||
|
|||||||
Reference in New Issue
Block a user