Merge pull request #109 from Snawoot/dp_export

DP export
This commit is contained in:
Vladislav Yarmak
2025-11-20 01:03:14 +02:00
committed by GitHub
2 changed files with 67 additions and 12 deletions
+1
View File
@@ -101,6 +101,7 @@ eu3.sec-tunnel.com,77.111.244.22,443
| cafile | String | use custom CA certificate bundle file |
| certchain-workaround | Boolean | add bundled cross-signed intermediate cert to certchain to make it check out on old systems (default true) |
| country | String | desired proxy location (default "EU") |
| dp-export | - | export configuration for dumbproxy |
| fake-SNI | String | domain name to use as SNI in communications with servers |
| init-retries | Number | number of attempts for initialization steps, zero for unlimited retry |
| init-retry-interval | Duration | delay between initialization retries (default 5s) |
+66 -12
View File
@@ -16,6 +16,7 @@ import (
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
@@ -102,6 +103,7 @@ type CLIArgs struct {
country string
listCountries bool
listProxies bool
dpExport bool
bindAddress string
socksMode bool
verbosity int
@@ -150,6 +152,7 @@ func parse_args() *CLIArgs {
flag.StringVar(&args.country, "country", "EU", "desired proxy location")
flag.BoolVar(&args.listCountries, "list-countries", false, "list available countries and exit")
flag.BoolVar(&args.listProxies, "list-proxies", false, "output proxy list and exit")
flag.BoolVar(&args.dpExport, "dp-export", false, "export configuration for dumbproxy")
flag.StringVar(&args.bindAddress, "bind-address", "127.0.0.1:18080", "proxy listen address")
flag.BoolVar(&args.socksMode, "socks-mode", false, "listen for SOCKS requests instead of HTTP")
flag.IntVar(&args.verbosity, "verbosity", 20, "logging verbosity "+
@@ -188,8 +191,8 @@ func parse_args() *CLIArgs {
if args.country == "" {
arg_fail("Country can't be empty string.")
}
if args.listCountries && args.listProxies {
arg_fail("list-countries and list-proxies flags are mutually exclusive")
if args.listCountries && args.listProxies || args.listCountries && args.dpExport || args.listProxies && args.dpExport {
arg_fail("mutually exclusive output arguments were provided")
}
return args
}
@@ -338,6 +341,31 @@ func run() int {
return printCountries(try, mainLogger, args.timeout, seclient)
}
var ips []se.SEIPEntry
if args.listProxies || args.dpExport {
err = try("discover", func() error {
ctx, cl := context.WithTimeout(context.Background(), args.timeout)
defer cl()
ips, err = seclient.Discover(ctx, fmt.Sprintf("\"%s\",,", args.country))
if err != nil {
return err
}
if len(ips) == 0 {
return errors.New("empty endpoints list!")
}
return nil
})
if err != nil {
return 12
}
if args.listProxies {
return printProxies(ips, seclient)
}
if args.dpExport {
return dpExport(ips, seclient)
}
}
handlerDialerFactory := func(endpointAddr string) dialer.ContextDialer {
return dialer.NewProxyDialer(
dialer.WrapStringToCb(endpointAddr),
@@ -351,10 +379,9 @@ func run() int {
d)
}
var ips []se.SEIPEntry
var handlerDialer dialer.ContextDialer
if args.overrideProxyAddress == "" || args.listProxies {
if args.overrideProxyAddress == "" {
err = try("discover", func() error {
ctx, cl := context.WithTimeout(context.Background(), args.timeout)
defer cl()
@@ -365,10 +392,6 @@ func run() int {
if len(res) == 0 {
return errors.New("empty endpoints list!")
}
if args.listProxies {
ips = res
return nil
}
mainLogger.Info("Discovered endpoints: %v. Starting server selection routine %q.", res, args.serverSelection.value)
var ss dialer.SelectionFunc
@@ -414,10 +437,6 @@ func run() int {
mainLogger.Info("Endpoint override: %s", sanitizedEndpoint)
}
if args.listProxies {
return printProxies(ips, seclient)
}
clock.RunTicker(context.Background(), args.refresh, args.refreshRetry, func(ctx context.Context) error {
mainLogger.Info("Refreshing login...")
reqCtx, cl := context.WithTimeout(ctx, args.timeout)
@@ -503,6 +522,41 @@ func printProxies(ips []se.SEIPEntry, seclient *se.SEClient) int {
return 0
}
func dpExport(ips []se.SEIPEntry, seclient *se.SEClient) int {
wr := csv.NewWriter(os.Stdout)
wr.Comma = ' '
defer wr.Flush()
creds := url.UserPassword(seclient.GetProxyCredentials())
var gotOne bool
for i, ip := range ips {
if len(ip.Ports) == 0 {
continue
}
u := url.URL{
Scheme: "https",
User: creds,
Host: net.JoinHostPort(
ip.IP,
strconv.Itoa(int(ip.Ports[0])),
),
RawQuery: url.Values{
"sni": []string{""},
"peername": []string{fmt.Sprintf("%s%d.%s", strings.ToLower(ip.Geo.CountryCode), i, PROXY_SUFFIX)},
}.Encode(),
}
key := "proxy"
if gotOne {
key = "#proxy"
}
wr.Write([]string{
key,
u.String(),
})
gotOne = true
}
return 0
}
func sanitizeFixedProxyAddress(addr string) string {
if _, _, err := net.SplitHostPort(addr); err == nil {
return addr