2022-05-23 01:05:50 +00:00
|
|
|
package prox5
|
2021-09-13 19:48:42 +00:00
|
|
|
|
|
|
|
import (
|
2021-09-14 01:50:39 +00:00
|
|
|
"context"
|
2021-09-18 08:33:40 +00:00
|
|
|
"fmt"
|
2021-09-13 19:48:42 +00:00
|
|
|
"net"
|
2021-10-23 14:58:03 +00:00
|
|
|
"sync/atomic"
|
2022-07-15 07:40:26 +00:00
|
|
|
"time"
|
2021-10-23 14:58:03 +00:00
|
|
|
|
2022-08-28 13:12:48 +00:00
|
|
|
"git.tcp.direct/kayos/socks"
|
2021-09-13 19:48:42 +00:00
|
|
|
)
|
|
|
|
|
2022-07-09 18:36:45 +00:00
|
|
|
// DialContext is a simple stub adapter to implement a net.Dialer.
|
2022-10-16 10:53:04 +00:00
|
|
|
func (p5 *ProxyEngine) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
2022-12-27 12:55:03 +00:00
|
|
|
return p5.mysteryDialer(ctx, network, addr)
|
2021-09-28 06:25:00 +00:00
|
|
|
}
|
|
|
|
|
2022-07-15 07:40:26 +00:00
|
|
|
// Dial is a simple stub adapter to implement a net.Dialer.
|
2022-10-16 10:53:04 +00:00
|
|
|
func (p5 *ProxyEngine) Dial(network, addr string) (net.Conn, error) {
|
2022-12-27 12:55:03 +00:00
|
|
|
return p5.mysteryDialer(context.Background(), network, addr)
|
2022-07-09 18:36:45 +00:00
|
|
|
}
|
|
|
|
|
2022-07-15 07:40:26 +00:00
|
|
|
// DialTimeout is a simple stub adapter to implement a net.Dialer with a timeout.
|
2022-10-16 10:53:04 +00:00
|
|
|
func (p5 *ProxyEngine) DialTimeout(network, addr string, timeout time.Duration) (net.Conn, error) {
|
2022-07-15 08:36:54 +00:00
|
|
|
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(timeout))
|
2022-07-25 07:14:26 +00:00
|
|
|
go func() { // this is a goroutine that calls cancel() upon the deadline expiring to avoid context leaks
|
|
|
|
<-ctx.Done()
|
|
|
|
cancel()
|
2022-07-25 06:23:12 +00:00
|
|
|
}()
|
2022-12-27 12:55:03 +00:00
|
|
|
return p5.mysteryDialer(ctx, network, addr)
|
2021-09-28 06:25:00 +00:00
|
|
|
}
|
|
|
|
|
2022-10-16 10:53:04 +00:00
|
|
|
func (p5 *ProxyEngine) addTimeout(socksString string) string {
|
2022-10-16 06:45:19 +00:00
|
|
|
tout := strs.Get()
|
|
|
|
tout.MustWriteString(socksString)
|
|
|
|
tout.MustWriteString("?timeout=")
|
|
|
|
tout.MustWriteString(p5.GetServerTimeoutStr())
|
|
|
|
_, _ = tout.WriteRune('s')
|
2022-07-25 07:14:26 +00:00
|
|
|
socksString = tout.String()
|
2022-10-16 06:45:19 +00:00
|
|
|
strs.MustPut(tout)
|
2022-07-25 07:14:26 +00:00
|
|
|
return socksString
|
|
|
|
}
|
|
|
|
|
2022-10-16 10:53:04 +00:00
|
|
|
func (p5 *ProxyEngine) popSockAndLockIt(ctx context.Context) (*Proxy, error) {
|
2022-09-22 23:48:08 +00:00
|
|
|
sock := p5.GetAnySOCKS()
|
2022-07-25 07:14:26 +00:00
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
return nil, fmt.Errorf("context done: %w", ctx.Err())
|
|
|
|
default:
|
|
|
|
if atomic.CompareAndSwapUint32(&sock.lock, stateUnlocked, stateLocked) {
|
2022-10-16 10:53:04 +00:00
|
|
|
// p5.msgGotLock(socksString)
|
2022-07-25 07:14:26 +00:00
|
|
|
return sock, nil
|
|
|
|
}
|
2022-07-25 06:24:06 +00:00
|
|
|
select {
|
2022-09-22 23:45:15 +00:00
|
|
|
case p5.Pending <- sock:
|
2022-10-16 10:53:04 +00:00
|
|
|
// p5.msgCantGetLock(socksString, true)
|
2022-07-25 07:14:26 +00:00
|
|
|
return nil, nil
|
|
|
|
default:
|
2022-10-16 10:53:04 +00:00
|
|
|
p5.msgCantGetLock(sock.String(), false)
|
2022-07-25 07:14:26 +00:00
|
|
|
return nil, nil
|
2022-07-25 06:24:06 +00:00
|
|
|
}
|
2022-07-25 07:14:26 +00:00
|
|
|
}
|
2022-07-15 07:40:26 +00:00
|
|
|
}
|
|
|
|
|
2022-12-27 12:55:03 +00:00
|
|
|
// mysteryDialer is a dialer function that will use a different proxy for every request.
|
|
|
|
// If you're looking for this function, it has been unexported. Use Dial, DialTimeout, or DialContext instead.
|
|
|
|
func (p5 *ProxyEngine) mysteryDialer(ctx context.Context, network, addr string) (net.Conn, error) {
|
2021-09-13 19:48:42 +00:00
|
|
|
// pull down proxies from channel until we get a proxy good enough for our spoiled asses
|
2022-08-28 13:12:48 +00:00
|
|
|
var count = 0
|
2021-09-13 19:48:42 +00:00
|
|
|
for {
|
2022-09-22 23:45:15 +00:00
|
|
|
max := p5.GetDialerBailout()
|
2021-09-29 08:31:19 +00:00
|
|
|
if count > max {
|
2022-07-25 06:23:12 +00:00
|
|
|
return nil, fmt.Errorf("giving up after %d tries", max)
|
2021-09-28 06:25:00 +00:00
|
|
|
}
|
2021-09-13 19:48:42 +00:00
|
|
|
if err := ctx.Err(); err != nil {
|
2022-07-25 07:14:26 +00:00
|
|
|
return nil, fmt.Errorf("context error: %w", err)
|
2021-09-13 19:48:42 +00:00
|
|
|
}
|
2022-10-16 10:53:04 +00:00
|
|
|
if p5.conCtx.Err() != nil {
|
|
|
|
return nil, fmt.Errorf("context closed")
|
|
|
|
}
|
2022-05-23 01:20:40 +00:00
|
|
|
var sock *Proxy
|
|
|
|
for {
|
2022-12-27 15:25:10 +00:00
|
|
|
if p5.scale() {
|
2022-12-27 15:31:28 +00:00
|
|
|
time.Sleep(1 * time.Millisecond)
|
2022-12-27 15:25:10 +00:00
|
|
|
}
|
2022-07-25 07:14:26 +00:00
|
|
|
var err error
|
2022-09-22 23:45:15 +00:00
|
|
|
sock, err = p5.popSockAndLockIt(ctx)
|
2022-07-25 07:14:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if sock != nil {
|
2021-10-23 14:58:03 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2022-08-28 13:12:48 +00:00
|
|
|
socksString := sock.String()
|
2022-05-23 01:20:40 +00:00
|
|
|
var ok bool
|
2022-09-22 23:45:15 +00:00
|
|
|
if sock, ok = p5.dispenseMiddleware(sock); !ok {
|
2022-08-28 13:12:48 +00:00
|
|
|
atomic.StoreUint32(&sock.lock, stateUnlocked)
|
2022-09-22 23:45:15 +00:00
|
|
|
p5.msgFailedMiddleware(socksString)
|
2021-10-23 14:58:03 +00:00
|
|
|
continue
|
|
|
|
}
|
2022-09-22 23:45:15 +00:00
|
|
|
p5.msgTry(socksString)
|
2021-10-23 14:58:03 +00:00
|
|
|
atomic.StoreUint32(&sock.lock, stateUnlocked)
|
2021-09-24 16:38:57 +00:00
|
|
|
dialSocks := socks.Dial(socksString)
|
2022-05-23 01:20:40 +00:00
|
|
|
conn, err := dialSocks(network, addr)
|
|
|
|
if err != nil {
|
2021-09-28 06:25:00 +00:00
|
|
|
count++
|
2022-09-22 23:45:15 +00:00
|
|
|
p5.msgUnableToReach(socksString, addr, err)
|
2021-09-24 16:38:57 +00:00
|
|
|
continue
|
|
|
|
}
|
2022-09-22 23:45:15 +00:00
|
|
|
p5.msgUsingProxy(socksString)
|
2022-10-19 12:36:31 +00:00
|
|
|
go func() {
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
_ = conn.Close()
|
|
|
|
case <-p5.conCtx.Done():
|
|
|
|
_ = conn.Close()
|
|
|
|
case <-p5.ctx.Done():
|
|
|
|
_ = conn.Close()
|
|
|
|
}
|
|
|
|
}()
|
2022-05-23 01:20:40 +00:00
|
|
|
return conn, nil
|
2021-09-13 19:48:42 +00:00
|
|
|
}
|
|
|
|
}
|