prox5/main.go

243 lines
5.3 KiB
Go
Raw Normal View History

2021-09-12 02:59:05 +00:00
package pxndscvm
import (
"bufio"
"bytes"
2021-09-12 04:55:36 +00:00
"context"
2021-09-12 02:59:05 +00:00
"crypto/tls"
2021-09-12 04:55:36 +00:00
"errors"
"io"
2021-09-12 02:59:05 +00:00
"io/ioutil"
"net"
"net/http"
"os"
"time"
"github.com/alitto/pond"
"github.com/rs/zerolog/log"
"golang.org/x/net/proxy"
"h12.io/socks"
)
const (
grn = "\033[32m"
red = "\033[31m"
rst = "\033[0m"
)
2021-09-12 04:55:36 +00:00
// LoadProxyTXT loads proxies from a given seed file and randomly feeds them to the workers.
2021-09-12 02:59:05 +00:00
// This fucntion has no real error handling, if the file can't be opened it's gonna straight up panic.
// TODO: make it more gooder.
func (s *Swamp) LoadProxyTXT(seedFile string) error {
s.dbgPrint("LoadProxyTXT start")
2021-09-12 02:59:05 +00:00
f, err := os.Open(seedFile)
if err != nil {
return err
2021-09-12 02:59:05 +00:00
}
scan := bufio.NewScanner(f)
if !s.started {
go s.tossUp()
}
2021-09-12 02:59:05 +00:00
for scan.Scan() {
2021-09-12 04:55:36 +00:00
s.scvm = append(s.scvm, scan.Text())
2021-09-12 02:59:05 +00:00
}
if !s.started {
go s.feed()
}
s.started = true
if err := f.Close(); err != nil {
s.dbgPrint(err.Error())
return err
}
return nil
}
func (s *Swamp) feed() {
s.dbgPrint("swamp feed start")
2021-09-12 02:59:05 +00:00
for {
select {
2021-09-12 04:55:36 +00:00
case s.Pending <- RandStrChoice(s.scvm):
2021-09-12 02:59:05 +00:00
//
default:
time.Sleep(1 * time.Second)
}
}
}
2021-09-12 04:55:36 +00:00
// MysteryDial will return a dialer that will use a different proxy for every request.
func (s *Swamp) MysteryDial(ctx context.Context, network, addr string) (net.Conn, error) {
2021-09-13 08:30:49 +00:00
var sock *Proxy
sock = &Proxy{Endpoint: ""}
2021-09-12 04:55:36 +00:00
// pull down proxies from channel until we get a proxy good enough for our spoiled asses
for {
if err := ctx.Err(); err != nil {
return nil, err
}
time.Sleep(10 * time.Millisecond)
2021-09-13 08:30:49 +00:00
candidate := s.getProxy()
if !s.stillGood(candidate) {
2021-09-12 04:55:36 +00:00
continue
}
sock = candidate
2021-09-13 08:30:49 +00:00
if sock.Endpoint != "" {
2021-09-12 04:55:36 +00:00
break
}
}
if err := ctx.Err(); err != nil {
return nil, err
}
2021-09-13 08:30:49 +00:00
var dialSocks = socks.Dial("socks" + sock.Proto + "://" + sock.Endpoint + "?timeout=3s")
2021-09-12 04:55:36 +00:00
2021-09-13 08:30:49 +00:00
return dialSocks(network, addr)
2021-09-12 02:59:05 +00:00
}
2021-09-13 08:30:49 +00:00
func (s *Swamp) proxyGETRequest(sock *Proxy) (string, error) {
2021-09-12 04:55:36 +00:00
s.mu.RLock()
defer s.mu.RUnlock()
2021-09-12 02:59:05 +00:00
req, err := http.NewRequest("GET", RandStrChoice(myipsites), bytes.NewBuffer([]byte("")))
if err != nil {
return "", err
}
headers := make(map[string]string)
// headers["Host"] = "wtfismyip.com"
2021-09-12 04:55:36 +00:00
headers["User-Agent"] = RandStrChoice(s.swampopt.UserAgents)
2021-09-12 02:59:05 +00:00
headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
headers["Accept-Language"] = "en-US,en;q=0.5"
headers["'Accept-Encoding'"] = "gzip, deflate, br"
headers["Connection"] = "keep-alive"
for header, value := range headers {
req.Header.Set(header, value)
}
2021-09-13 08:30:49 +00:00
var dialSocks = socks.Dial("socks" + sock.Proto + "://" + sock.Endpoint + "?timeout=4s")
2021-09-12 02:59:05 +00:00
var client *http.Client
2021-09-13 08:30:49 +00:00
if sock.Proto == "none" {
2021-09-12 02:59:05 +00:00
//goland:noinspection GoDeprecation
client = &http.Client{
Transport: &http.Transport{
Dial: proxy.Direct.Dial,
DisableKeepAlives: true,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
TLSHandshakeTimeout: time.Duration(4) * time.Second,
},
}
} else {
//goland:noinspection GoDeprecation
client = &http.Client{
Transport: &http.Transport{
Dial: dialSocks,
DisableKeepAlives: true,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
TLSHandshakeTimeout: time.Duration(4) * time.Second,
},
}
}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
panic(err)
}
}(resp.Body)
rbody, err := ioutil.ReadAll(resp.Body)
return string(rbody), err
2021-09-12 02:59:05 +00:00
}
2021-09-13 08:30:49 +00:00
func (s *Swamp) singleProxyCheck(sock *Proxy) error {
2021-09-12 04:55:36 +00:00
s.mu.RLock()
defer s.mu.RUnlock()
2021-09-13 08:30:49 +00:00
if _, err := net.DialTimeout("tcp", sock.Endpoint, 8*time.Second); err != nil {
badProx.Check(sock)
return err
2021-09-12 02:59:05 +00:00
}
2021-09-13 08:30:49 +00:00
resp, err := s.proxyGETRequest(sock)
2021-09-12 02:59:05 +00:00
if err != nil {
2021-09-13 08:30:49 +00:00
badProx.Check(sock)
return err
2021-09-12 02:59:05 +00:00
}
if newip := net.ParseIP(resp); newip == nil {
2021-09-13 08:30:49 +00:00
badProx.Check(sock)
return errors.New("nil response from http request")
2021-09-12 02:59:05 +00:00
}
2021-09-13 08:30:49 +00:00
return nil
2021-09-12 02:59:05 +00:00
}
2021-09-12 04:55:36 +00:00
func (s *Swamp) tossUp() {
s.dbgPrint("tossUp() proxy checking loop start")
var sversions = []string{"5", "4", "4a"}
2021-09-12 04:55:36 +00:00
s.Birthday = time.Now()
2021-09-12 02:59:05 +00:00
panicHandler := func(p interface{}) {
log.Error().Interface("panic", p).Msg("Task panicked")
}
pool := pond.New(100, 10000, pond.MinWorkers(100), pond.PanicHandler(panicHandler))
for {
pool.Submit(func() {
for {
2021-09-13 08:30:49 +00:00
sock := <-s.Pending
p := &Proxy{
Endpoint: sock,
}
// ratelimited
2021-09-13 08:30:49 +00:00
if useProx.Check(p) {
s.dbgPrint("useProx ratelimited: " + p.Endpoint)
2021-09-12 02:59:05 +00:00
continue
}
// determined as bad, won't try again until it expires from that cache
2021-09-13 08:30:49 +00:00
if badProx.Peek(p) {
s.dbgPrint("badProx ratelimited: " + p.Endpoint)
2021-09-12 02:59:05 +00:00
continue
}
// try to use the proxy with all 3 SOCKS versions
var good = false
for _, sver := range sversions {
p.Proto = sver
if err := s.singleProxyCheck(p); err == nil {
s.dbgPrint(grn+"verified " + p.Endpoint + " as SOCKS" + sver+rst)
good = true
break
2021-09-13 08:30:49 +00:00
}
2021-09-12 02:59:05 +00:00
}
if !good {
s.dbgPrint(red+"failed to verify " + p.Endpoint+rst)
badProx.Check(p)
continue
}
switch p.Proto {
case "4":
s.Stats.v4()
s.Socks4 <- p
case "4a":
s.Stats.v4a()
s.Socks4a <- p
case "5":
s.Stats.v5()
s.Socks5 <- p
}
2021-09-12 02:59:05 +00:00
}
})
time.Sleep(time.Duration(10) * time.Millisecond)
}
}