Projects STRLCPY prox5 Commits 144fe6b3
🤬
  • ■ ■ ■ ■
    conductor.go
    skipped 2 lines
    3 3  import (
    4 4   "context"
    5 5   "errors"
     6 + "strings"
    6 7   "sync/atomic"
    7 8  )
    8 9   
    skipped 30 lines
    39 40   return errors.New("not running")
    40 41   }
    41 42   
    42  - pe.dbgPrint("pausing...")
     43 + buf := copABuffer.Get().(*strings.Builder)
     44 + buf.WriteString("pausing...")
     45 + pe.dbgPrint(buf)
    43 46   
    44 47   pe.quit()
    45 48   
    skipped 28 lines
  • ■ ■ ■ ■ ■ ■
    daemons.go
    skipped 2 lines
    3 3  import (
    4 4   "errors"
    5 5   "strconv"
     6 + "strings"
    6 7   "sync"
    7 8   "sync/atomic"
    8 9   "time"
    skipped 67 lines
    76 77   pe.pool.Reboot()
    77 78   }
    78 79   
    79  - pe.dbgPrint("map builder started")
     80 + pe.dbgPrint(simpleString("map builder started"))
    80 81   
    81 82   go func() {
    82  - defer pe.dbgPrint("map builder paused")
     83 + defer pe.dbgPrint(simpleString("map builder paused"))
    83 84   for {
    84 85   select {
    85 86   case <-pe.ctx.Done():
    skipped 42 lines
    128 129   pe.pool.Reboot()
    129 130   }
    130 131   
    131  - pe.dbgPrint("job spawner started")
    132  - defer pe.dbgPrint("job spawner paused")
     132 + pe.dbgPrint(simpleString("job spawner started"))
     133 + defer pe.dbgPrint(simpleString("job spawner paused"))
    133 134   
    134 135   q := make(chan bool)
    135 136   
    skipped 6 lines
    142 143   return
    143 144   case sock := <-pe.Pending:
    144 145   if err := pe.pool.Submit(sock.validate); err != nil {
    145  - pe.dbgPrint(err.Error())
     146 + pe.dbgPrint(simpleString(err.Error()))
    146 147   }
    147 148   default:
    148 149   time.Sleep(25 * time.Millisecond)
    149 150   count := pe.recycling()
    150  - pe.dbgPrint("recycled " + strconv.Itoa(count) + " proxies from our map")
     151 + buf := copABuffer.Get().(*strings.Builder)
     152 + buf.WriteString("recycled ")
     153 + buf.WriteString(strconv.Itoa(count))
     154 + buf.WriteString(" proxies from our map")
     155 + pe.dbgPrint(buf)
    151 156   }
    152 157   }
    153 158   }()
    skipped 6 lines
  • ■ ■ ■ ■ ■
    debug.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "fmt"
     5 + "strings"
    5 6   "sync"
    6 7  )
    7 8   
    skipped 55 lines
    63 64   pe.swampopt.debug = false
    64 65  }
    65 66   
    66  -func (pe *ProxyEngine) dbgPrint(str string) {
     67 +func simpleString(s string) *strings.Builder {
     68 + buf := copABuffer.Get().(*strings.Builder)
     69 + buf.WriteString(s)
     70 + return buf
     71 +}
     72 + 
     73 +func (pe *ProxyEngine) dbgPrint(builder *strings.Builder) {
     74 + defer discardBuffer(builder)
    67 75   if !pe.swampopt.debug {
    68 76   return
    69 77   }
    70 78   if !useDebugChannel {
    71  - pe.Debug.Print(str)
     79 + pe.Debug.Print(builder.String())
    72 80   return
    73 81   }
    74 82   select {
    75  - case debugChan <- str:
     83 + case debugChan <- builder.String():
    76 84   return
    77 85   default:
    78  - pe.Debug.Print("overflow: " + str)
     86 + buf := copABuffer.Get().(*strings.Builder)
     87 + buf.WriteString("overflow: ")
     88 + buf.WriteString(builder.String())
     89 + pe.Debug.Print(buf.String())
     90 + discardBuffer(buf)
    79 91   }
    80 92  }
    81 93   
  • ■ ■ ■ ■ ■
    defs.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "context"
     5 + "strings"
    5 6   "sync"
    6 7   "sync/atomic"
    7 8   "time"
    skipped 182 lines
    190 191   }))
    191 192   
    192 193   if err != nil {
    193  - pe.dbgPrint("CRITICAL: " + err.Error())
     194 + buf := copABuffer.Get().(*strings.Builder)
     195 + buf.WriteString("CRITICAL: ")
     196 + buf.WriteString(err.Error())
     197 + pe.dbgPrint(buf)
    194 198   panic(err)
    195 199   }
    196 200   
    skipped 40 lines
  • ■ ■ ■ ■ ■
    dispense.go
    1 1  package prox5
    2 2   
    3 3  import (
     4 + "strings"
    4 5   "sync/atomic"
    5 6   "time"
    6 7   
    skipped 96 lines
    103 104   defer atomic.StoreUint32(&sock.lock, stateUnlocked)
    104 105   
    105 106   if atomic.LoadInt64(&sock.timesBad) > int64(pe.GetRemoveAfter()) && pe.GetRemoveAfter() != -1 {
    106  - pe.dbgPrint("deleting from map (too many failures): " + sock.Endpoint)
     107 + buf := copABuffer.Get().(*strings.Builder)
     108 + buf.WriteString("deleting from map (too many failures): ")
     109 + buf.WriteString(sock.Endpoint)
     110 + pe.dbgPrint(buf)
    107 111   if err := pe.swampmap.delete(sock.Endpoint); err != nil {
    108  - pe.dbgPrint(err.Error())
     112 + pe.dbgPrint(simpleString(err.Error()))
    109 113   }
    110 114   }
    111 115   
    112 116   if pe.badProx.Peek(sock) {
    113  - pe.dbgPrint("badProx dial ratelimited: " + sock.Endpoint)
     117 + buf := copABuffer.Get().(*strings.Builder)
     118 + buf.WriteString("badProx dial ratelimited: ")
     119 + buf.WriteString(sock.Endpoint)
     120 + pe.dbgPrint(buf)
    114 121   return false
    115 122   }
    116 123   
    117 124   if time.Since(sock.lastValidated) > pe.swampopt.stale {
    118  - pe.dbgPrint("proxy stale: " + sock.Endpoint)
     125 + buf := copABuffer.Get().(*strings.Builder)
     126 + buf.WriteString("proxy stale: ")
     127 + buf.WriteString(sock.Endpoint)
     128 + pe.dbgPrint(buf)
    119 129   go pe.stats.stale()
    120 130   return false
    121 131   }
    skipped 4 lines
  • ■ ■ ■ ■ ■ ■
    example/go.mod
     1 +module p5example
     2 + 
     3 +go 1.18
     4 + 
     5 +require (
     6 + git.tcp.direct/kayos/prox5 v0.5.3-0.20220709184754-7ecedfdd0c63
     7 + github.com/haxii/socks5 v1.0.0
     8 + github.com/mattn/go-tty v0.0.4
     9 +)
     10 + 
     11 +require (
     12 + git.tcp.direct/kayos/common v0.7.0 // indirect
     13 + git.tcp.direct/kayos/go-socks5 v1.0.1 // indirect
     14 + github.com/mattn/go-isatty v0.0.14 // indirect
     15 + github.com/miekg/dns v1.1.50 // indirect
     16 + github.com/panjf2000/ants/v2 v2.5.0 // indirect
     17 + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
     18 + github.com/yunginnanet/Rate5 v1.0.1 // indirect
     19 + go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
     20 + go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
     21 + golang.org/x/mod v0.4.2 // indirect
     22 + golang.org/x/net v0.0.0-20220630215102-69896b714898 // indirect
     23 + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
     24 + golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
     25 + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
     26 + h12.io/socks v1.0.3 // indirect
     27 + inet.af/netaddr v0.0.0-20220617031823-097006376321 // indirect
     28 + nullprogram.com/x/rng v1.1.0 // indirect
     29 +)
     30 + 
  • ■ ■ ■ ■ ■ ■
    example/go.sum
     1 +git.tcp.direct/kayos/common v0.7.0 h1:KZDwoCzUiwQaYSWESr080N8wUVyLD27QYgzXgc7LiAQ=
     2 +git.tcp.direct/kayos/common v0.7.0/go.mod h1:7tMZBVNPLFSZk+JXTA6pgXWpf/XHqYRfT7Q3OziI++Y=
     3 +git.tcp.direct/kayos/go-socks5 v1.0.1 h1:Pe9PlSXofibIJyWkrr9rwWcgyfUxSdUcDCQ//6fAi0U=
     4 +git.tcp.direct/kayos/go-socks5 v1.0.1/go.mod h1:I9xU/uzFAZKukMJgEgWPrfC6rDlcPQe8wXMibF3qvhE=
     5 +git.tcp.direct/kayos/prox5 v0.5.3-0.20220709184754-7ecedfdd0c63 h1:eidAXI7o5gIf4linhOIFEtSiYQQOsqHLcMqhBrF9vgA=
     6 +git.tcp.direct/kayos/prox5 v0.5.3-0.20220709184754-7ecedfdd0c63/go.mod h1:/44/UlcKPOXZ/jr+NdftkZvLkW0k4QokPXqAdQ2O3BQ=
     7 +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
     8 +github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
     9 +github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI=
     10 +github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c=
     11 +github.com/haxii/socks5 v1.0.0 h1:78BIzd4lHibdRNOKdMwKCnnsgYLW9SeotqU+nMhWSSo=
     12 +github.com/haxii/socks5 v1.0.0/go.mod h1:6O9Ba2yrLlvuSe/L1e84eZI8cPw6H+q1Ilr4hjgm4uY=
     13 +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
     14 +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
     15 +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
     16 +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
     17 +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
     18 +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
     19 +github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
     20 +github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
     21 +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
     22 +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
     23 +github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q=
     24 +github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
     25 +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
     26 +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
     27 +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
     28 +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
     29 +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
     30 +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
     31 +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
     32 +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
     33 +github.com/yunginnanet/Rate5 v1.0.1 h1:OePwNrj9/A/flmhyr/gKI5RYgrW6d1oWCqrZRXUev3k=
     34 +github.com/yunginnanet/Rate5 v1.0.1/go.mod h1:f0r66kVQZojRqUgVdLC/CKexMlF0nUDAmd01tBeF4Ms=
     35 +go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE=
     36 +go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
     37 +go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
     38 +go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 h1:FyBZqvoA/jbNzuAWLQE2kG820zMAkcilx6BMjGbL/E4=
     39 +go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
     40 +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
     41 +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
     42 +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
     43 +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     44 +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
     45 +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
     46 +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
     47 +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
     48 +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
     49 +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
     50 +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
     51 +golang.org/x/net v0.0.0-20220630215102-69896b714898 h1:K7wO6V1IrczY9QOQ2WkVpw4JQSwCd52UsxVEirZUfiw=
     52 +golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
     53 +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     54 +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     55 +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
     56 +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
     57 +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
     58 +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
     59 +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     60 +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     61 +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     62 +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     63 +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     64 +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     65 +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     66 +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
     67 +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
     68 +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
     69 +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
     70 +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
     71 +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
     72 +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
     73 +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
     74 +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
     75 +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
     76 +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
     77 +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
     78 +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
     79 +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
     80 +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     81 +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     82 +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
     83 +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
     84 +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
     85 +h12.io/socks v1.0.3 h1:Ka3qaQewws4j4/eDQnOdpr4wXsC//dXtWvftlIcCQUo=
     86 +h12.io/socks v1.0.3/go.mod h1:AIhxy1jOId/XCz9BO+EIgNL2rQiPTBNnOfnVnQ+3Eck=
     87 +inet.af/netaddr v0.0.0-20220617031823-097006376321 h1:B4dC8ySKTQXasnjDTMsoCMf1sQG4WsMej0WXaHxunmU=
     88 +inet.af/netaddr v0.0.0-20220617031823-097006376321/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k=
     89 +nullprogram.com/x/rng v1.1.0 h1:SMU7DHaQSWtKJNTpNFIFt8Wd/KSmOuSDPXrMFp/UMro=
     90 +nullprogram.com/x/rng v1.1.0/go.mod h1:glGw6V87vyfawxCzqOABL3WfL95G65az9Z2JZCylCkg=
     91 + 
  • ■ ■ ■ ■ ■
    example/main.go
    skipped 5 lines
    6 6   "strconv"
    7 7   "time"
    8 8   
     9 + "git.tcp.direct/kayos/prox5"
     10 + "github.com/haxii/socks5"
    9 11   "github.com/mattn/go-tty"
     12 +)
    10 13   
    11  - "git.tcp.direct/kayos/prox5"
     14 +var (
     15 + swamp *prox5.ProxyEngine
     16 + quit chan bool
     17 + t *tty.TTY
    12 18  )
    13 19   
    14  -var swamp *prox5.ProxyEngine
    15  -var quit chan bool
    16  -var t *tty.TTY
     20 +type socksLogger struct{}
     21 + 
     22 +var socklog = socksLogger{}
     23 + 
     24 +// Printf is used to handle socks server logging.
     25 +func (s socksLogger) Printf(format string, a ...interface{}) {
     26 + println(fmt.Sprintf(format, a))
     27 +}
     28 + 
     29 +func StartUpstreamProxy(listen string) {
     30 + conf := &socks5.Config{Dial: swamp.DialContext, Logger: socklog}
     31 + server, err := socks5.New(conf)
     32 + if err != nil {
     33 + println(err.Error())
     34 + return
     35 + }
     36 + 
     37 + socklog.Printf("starting proxy server on %s", listen)
     38 + if err := server.ListenAndServe("tcp", listen); err != nil {
     39 + println(err.Error())
     40 + return
     41 + }
     42 +}
    17 43   
    18 44  func init() {
    19 45   quit = make(chan bool)
    20 46   swamp = prox5.NewProxyEngine()
    21 47   swamp.SetMaxWorkers(5)
    22 48   swamp.EnableDebug()
     49 + go StartUpstreamProxy("127.0.0.1:1555")
    23 50   
    24 51   count := swamp.LoadProxyTXT(os.Args[1])
    25 52   if count < 1 {
    skipped 105 lines
  • ■ ■ ■ ■ ■ ■
    getters.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "strconv"
     5 + "strings"
    5 6   "sync/atomic"
    6 7   "time"
    7 8   
    skipped 3 lines
    11 12  // GetProto retrieves the known protocol value of the Proxy.
    12 13  func (sock *Proxy) GetProto() ProxyProtocol {
    13 14   return sock.proto
     15 +}
     16 + 
     17 +// GetProto safely retrieves the protocol value of the Proxy.
     18 +func (sock *Proxy) String() string {
     19 + tout := ""
     20 + if sock.parent.GetServerTimeoutStr() != "-1" {
     21 + tbuf := copABuffer.Get().(*strings.Builder)
     22 + tbuf.WriteString("?timeout=")
     23 + tbuf.WriteString(sock.parent.GetServerTimeoutStr())
     24 + tbuf.WriteString("s")
     25 + tout = tbuf.String()
     26 + discardBuffer(tbuf)
     27 + }
     28 + buf := copABuffer.Get().(*strings.Builder)
     29 + buf.WriteString("socks")
     30 + buf.WriteString(getProtoStr(sock.GetProto()))
     31 + buf.WriteString("://")
     32 + buf.WriteString(sock.Endpoint)
     33 + if tout != "" {
     34 + buf.WriteString(tout)
     35 + }
     36 + out := buf.String()
     37 + discardBuffer(buf)
     38 + return out
    14 39  }
    15 40   
    16 41  // GetStatistics returns all current statistics.
    skipped 109 lines
  • ■ ■ ■ ■ ■ ■
    go.mod
    skipped 2 lines
    3 3  go 1.18
    4 4   
    5 5  require (
    6  - git.tcp.direct/kayos/common v0.6.0
     6 + git.tcp.direct/kayos/common v0.7.0
    7 7   git.tcp.direct/kayos/go-socks5 v1.0.1
    8  - github.com/mattn/go-tty v0.0.4
    9 8   github.com/miekg/dns v1.1.50
    10 9   github.com/panjf2000/ants/v2 v2.5.0
    11 10   github.com/yunginnanet/Rate5 v1.0.1
    skipped 2 lines
    14 13  )
    15 14   
    16 15  require (
    17  - github.com/mattn/go-isatty v0.0.10 // indirect
    18 16   github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
    19 17   go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
    20 18   go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
    21 19   golang.org/x/mod v0.4.2 // indirect
    22 20   golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 // indirect
    23  - golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
     21 + golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
    24 22   golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
    25 23   golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
    26 24   nullprogram.com/x/rng v1.1.0 // indirect
    skipped 2 lines
  • ■ ■ ■ ■ ■
    go.sum
    1  -git.tcp.direct/kayos/common v0.6.0 h1:x3qXJxGalhv3y4bX191Lx8R73Se1UzPgAP3fL2gqhyA=
    2  -git.tcp.direct/kayos/common v0.6.0/go.mod h1:jG1yXbN+5PrRZwGe32qIGWgLC4x5JWdyNBbMj1gIWB0=
     1 +git.tcp.direct/kayos/common v0.7.0 h1:KZDwoCzUiwQaYSWESr080N8wUVyLD27QYgzXgc7LiAQ=
     2 +git.tcp.direct/kayos/common v0.7.0/go.mod h1:7tMZBVNPLFSZk+JXTA6pgXWpf/XHqYRfT7Q3OziI++Y=
    3 3  git.tcp.direct/kayos/go-socks5 v1.0.1 h1:Pe9PlSXofibIJyWkrr9rwWcgyfUxSdUcDCQ//6fAi0U=
    4 4  git.tcp.direct/kayos/go-socks5 v1.0.1/go.mod h1:I9xU/uzFAZKukMJgEgWPrfC6rDlcPQe8wXMibF3qvhE=
    5 5  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
    6 6  github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
    7 7  github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI=
    8 8  github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c=
    9  -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
    10  -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
    11  -github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
    12  -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
    13  -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
    14  -github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
    15  -github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
    16 9  github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
    17 10  github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
    18 11  github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q=
    skipped 30 lines
    49 42  golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
    50 43  golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
    51 44  golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
    52  -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
    53 45  golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    54  -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    55  -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    56 46  golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    57 47  golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    58 48  golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    skipped 1 lines
    60 50  golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
    61 51  golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
    62 52  golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
    63  -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
    64  -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
     53 +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
     54 +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
    65 55  golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
    66 56  golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
    67 57  golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
    skipped 18 lines
  • ■ ■ ■ ■ ■ ■
    list_management.go
    skipped 95 lines
    96 96  func (pe *ProxyEngine) LoadProxyTXT(seedFile string) (count int) {
    97 97   f, err := os.Open(seedFile)
    98 98   if err != nil {
    99  - pe.dbgPrint(err.Error())
     99 + pe.dbgPrint(simpleString(err.Error()))
    100 100   return 0
    101 101   }
    102 102   
    103 103   defer func() {
    104 104   if err := f.Close(); err != nil {
    105  - pe.dbgPrint(err.Error())
     105 + pe.dbgPrint(simpleString(err.Error()))
    106 106   }
    107 107   }()
    108 108   
    109 109   bs, err := io.ReadAll(f)
    110 110   if err != nil {
    111  - pe.dbgPrint(err.Error())
     111 + pe.dbgPrint(simpleString(err.Error()))
    112 112   return 0
    113 113   }
    114 114   sockstr := string(bs)
    skipped 42 lines
  • ■ ■ ■ ■ ■
    mystery_dialer.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "context"
    5  - "errors"
     5 + "fmt"
    6 6   "net"
    7  - "strconv"
     7 + "strings"
     8 + "sync"
    8 9   "sync/atomic"
     10 + "time"
    9 11   
    10 12   "h12.io/socks"
    11 13  )
    12 14   
    13  -// DialContext is a simple stub adapter to implement a net.Dialer.
    14  -func (s *ProxyEngine) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
    15  - return s.MysteryDialer(ctx, network, addr)
     15 +var copABuffer = &sync.Pool{New: func() interface{} { return &strings.Builder{} }}
     16 + 
     17 +func discardBuffer(buf *strings.Builder) {
     18 + buf.Reset()
     19 + copABuffer.Put(buf)
    16 20  }
    17 21   
    18 22  // DialContext is a simple stub adapter to implement a net.Dialer.
    19  -func (s *ProxyEngine) Dial(network, addr string) (net.Conn, error) {
    20  - return s.DialContext(context.Background(), network, addr)
     23 +func (pe *ProxyEngine) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
     24 + return pe.MysteryDialer(ctx, network, addr)
     25 +}
     26 + 
     27 +// Dial is a simple stub adapter to implement a net.Dialer.
     28 +func (pe *ProxyEngine) Dial(network, addr string) (net.Conn, error) {
     29 + return pe.MysteryDialer(context.Background(), network, addr)
     30 +}
     31 + 
     32 +// DialTimeout is a simple stub adapter to implement a net.Dialer with a timeout.
     33 +func (pe *ProxyEngine) DialTimeout(network, addr string, timeout time.Duration) (net.Conn, error) {
     34 + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(timeout))
     35 + go func() {
     36 + select {
     37 + case <-ctx.Done():
     38 + cancel()
     39 + }
     40 + }()
     41 + return pe.MysteryDialer(ctx, network, addr)
    21 42  }
    22 43   
    23 44  // MysteryDialer is a dialer function that will use a different proxy for every request.
    skipped 3 lines
    27 48   count int
    28 49   )
    29 50   // pull down proxies from channel until we get a proxy good enough for our spoiled asses
     51 + 
    30 52   for {
    31 53   max := pe.GetDialerBailout()
    32 54   if count > max {
    33  - return nil, errors.New("giving up after " + strconv.Itoa(max) + " tries")
     55 + return nil, fmt.Errorf("giving up after %d tries", max)
    34 56   }
    35 57   if err := ctx.Err(); err != nil {
    36  - return nil, err
     58 + return nil, fmt.Errorf("context error: %v", err)
    37 59   }
    38 60   var sock *Proxy
     61 + popSockAndLockIt:
    39 62   for {
    40 63   sock = pe.GetAnySOCKS(false)
    41  - if !atomic.CompareAndSwapUint32(&sock.lock, stateUnlocked, stateLocked) {
    42  - continue
     64 + socksString = sock.String()
     65 + select {
     66 + case <-ctx.Done():
     67 + return nil, fmt.Errorf("context done: %v", ctx.Err())
     68 + default:
     69 + buf := copABuffer.Get().(*strings.Builder)
     70 + if atomic.CompareAndSwapUint32(&sock.lock, stateUnlocked, stateLocked) {
     71 + buf.WriteString("got lock for ")
     72 + buf.WriteString(socksString)
     73 + break popSockAndLockIt
     74 + }
     75 + select {
     76 + case pe.Pending <- sock:
     77 + buf.WriteString("can't get lock, putting back ")
     78 + buf.WriteString(socksString)
     79 + pe.dbgPrint(buf)
     80 + continue
     81 + default:
     82 + buf.WriteString("can't get lock, can't put back ")
     83 + buf.WriteString(socksString)
     84 + continue
     85 + }
    43 86   }
    44  - break
    45 87   }
    46  - pe.dbgPrint("dialer trying: " + sock.Endpoint + "...")
    47  - tout := ""
     88 + buf := copABuffer.Get().(*strings.Builder)
     89 + buf.WriteString("try dial with: ")
     90 + buf.WriteString(sock.Endpoint)
     91 + pe.dbgPrint(buf)
    48 92   if pe.GetServerTimeoutStr() != "-1" {
    49  - tout = "?timeout=" + pe.GetServerTimeoutStr() + "s"
     93 + tout := copABuffer.Get().(*strings.Builder)
     94 + tout.WriteString("?timeout=")
     95 + tout.WriteString(pe.GetServerTimeoutStr())
     96 + tout.WriteRune('s')
    50 97   }
    51  - socksString = "socks" + getProtoStr(sock.proto) + "://" + sock.Endpoint + tout
    52 98   var ok bool
    53 99   if sock, ok = pe.dispenseMiddleware(sock); !ok {
    54  - pe.dbgPrint("failed middleware check, " + socksString + ", cycling...")
     100 + buf := copABuffer.Get().(*strings.Builder)
     101 + buf.WriteString("failed middleware check, ")
     102 + buf.WriteString(sock.String())
     103 + buf.WriteString(", cycling...")
     104 + pe.dbgPrint(buf)
    55 105   continue
    56 106   }
    57 107   atomic.StoreUint32(&sock.lock, stateUnlocked)
    skipped 1 lines
    59 109   conn, err := dialSocks(network, addr)
    60 110   if err != nil {
    61 111   count++
    62  - pe.dbgPrint("unable to reach [redacted] with " + socksString + ", cycling...")
     112 + buf := copABuffer.Get().(*strings.Builder)
     113 + buf.WriteString("unable to reach [redacted] with ")
     114 + buf.WriteString(socksString)
     115 + buf.WriteString(", cycling...")
     116 + pe.dbgPrint(buf)
    63 117   continue
    64 118   }
    65  - pe.dbgPrint("MysteryDialer using socks: " + socksString)
     119 + buf = copABuffer.Get().(*strings.Builder)
     120 + buf.WriteString("MysteryDialer using socks: ")
     121 + buf.WriteString(socksString)
     122 + pe.dbgPrint(buf)
    66 123   return conn, nil
    67 124   }
    68 125  }
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    socks5_server.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "fmt"
    5  - 
    6 5   "git.tcp.direct/kayos/go-socks5"
     6 + "strings"
    7 7  )
    8 8   
    9 9  type socksLogger struct {
    skipped 2 lines
    12 12   
    13 13  // Printf is used to handle socks server logging.
    14 14  func (s socksLogger) Printf(format string, a ...interface{}) {
    15  - s.parent.dbgPrint(fmt.Sprintf(format, a...))
     15 + buf := copABuffer.Get().(*strings.Builder)
     16 + buf.WriteString(fmt.Sprintf(format, a...))
     17 + s.parent.dbgPrint(buf)
    16 18  }
    17 19   
    18 20  type socksCreds struct {
    skipped 21 lines
    40 42   Dial: pe.MysteryDialer,
    41 43   }
    42 44   
    43  - pe.dbgPrint("listening for SOCKS5 connections on " + listen)
     45 + buf := copABuffer.Get().(*strings.Builder)
     46 + buf.WriteString("listening for SOCKS5 connections on ")
     47 + buf.WriteString(listen)
     48 + pe.dbgPrint(buf)
    44 49   
    45 50   server, err := socks5.New(conf)
    46 51   if err != nil {
    skipped 6 lines
  • ■ ■ ■ ■ ■
    validator_engine.go
    skipped 155 lines
    156 156   
    157 157   // determined as bad, won't try again until it expires from that cache
    158 158   if s.badProx.Peek(sock) {
    159  - s.dbgPrint("badProx ratelimited: " + sock.Endpoint)
     159 + buf := copABuffer.Get().(*strings.Builder)
     160 + buf.WriteString("badProx ratelimited: ")
     161 + buf.WriteString(sock.Endpoint)
     162 + s.dbgPrint(buf)
    160 163   return
    161 164   }
    162 165   
    skipped 16 lines
    179 182   
    180 183   switch sock.proto {
    181 184   case ProtoSOCKS4, ProtoSOCKS4a, ProtoSOCKS5, ProtoHTTP:
    182  - s.dbgPrint("verified " + sock.Endpoint + " as SOCKS" + getProtoStr(sock.proto))
     185 + buf := copABuffer.Get().(*strings.Builder)
     186 + buf.WriteString("verified ")
     187 + buf.WriteString(sock.Endpoint)
     188 + buf.WriteString(" as SOCKS")
     189 + buf.WriteString(getProtoStr(sock.proto))
     190 + s.dbgPrint(buf)
    183 191   break
    184 192   default:
    185  - s.dbgPrint("failed to verify: " + sock.Endpoint)
     193 + buf := copABuffer.Get().(*strings.Builder)
     194 + buf.WriteString("failed to verify: ")
     195 + buf.WriteString(sock.Endpoint)
     196 + s.dbgPrint(buf)
    186 197   sock.bad()
    187 198   s.badProx.Check(sock)
    188 199   return
    skipped 25 lines
Please wait...
Page is in error, reload to recover