diff --git a/go.mod b/go.mod index 8bc73f9..9779c57 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,9 @@ require ( github.com/google/gopacket v1.1.19 github.com/oschwald/maxminddb-golang v1.10.0 github.com/spf13/viper v1.15.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.4 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 + github.com/tsosunchia/powclient v0.1.0 golang.org/x/net v0.10.0 golang.org/x/sync v0.2.0 ) diff --git a/go.sum b/go.sum index d26a859..c403423 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= @@ -199,6 +200,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tsosunchia/powclient v0.1.0 h1:yUCa1Zd0KENOCiWJ3NOYhV1uVWUjy1ujy4w8gap3j4M= +github.com/tsosunchia/powclient v0.1.0/go.mod h1:Pm4MP3QqN74SfNskPpFIEyT+NQrcABGoXkkeRwjlMEE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/pow/factorization.go b/pow/factorization.go deleted file mode 100644 index 44dc6a5..0000000 --- a/pow/factorization.go +++ /dev/null @@ -1,45 +0,0 @@ -package pow - -import ( - "math/big" -) - -func gcd(a, b *big.Int) *big.Int { - return new(big.Int).GCD(nil, nil, a, b) -} - -func abs(a *big.Int) *big.Int { - return new(big.Int).Abs(a) -} - -func rho(N *big.Int) *big.Int { - two := big.NewInt(2) - if new(big.Int).Mod(N, two).Cmp(big.NewInt(0)) == 0 { - return two - } - - x := big.NewInt(0).Set(N) - y := big.NewInt(0).Set(N) - c := big.NewInt(1) - g := big.NewInt(1) - - for g.Cmp(big.NewInt(1)) == 0 { - x.Mul(x, x).Add(x, c).Mod(x, N) - y.Mul(y, y).Add(y, c).Mod(y, N) - y.Mul(y, y).Add(y, c).Mod(y, N) - g = gcd(abs(new(big.Int).Sub(x, y)), N) - } - return g -} - -func factors(N *big.Int) []*big.Int { - one := big.NewInt(1) - if N.Cmp(one) == 0 { - return []*big.Int{} - } - factor := rho(N) - if factor.Cmp(N) == 0 { - return []*big.Int{N} - } - return append(factors(factor), factors(new(big.Int).Div(N, factor))...) -} diff --git a/pow/factorization_test.go b/pow/factorization_test.go deleted file mode 100644 index eea5dba..0000000 --- a/pow/factorization_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package pow - -import ( - "fmt" - "math/big" - "strings" - "testing" - "time" -) - -func TestFactors(t *testing.T) { - p1 := big.NewInt(24801309629) - p2 := big.NewInt(34244502967) - input := (new(big.Int).Mul(p1, p2)).String() - input = strings.TrimSuffix(input, "\n") - - N := new(big.Int) - N.SetString(input, 10) - // Start timer - start := time.Now() - // Calculation - factorsList := factors(N) - // End timer - elapsed := time.Since(start) - // Output results - for _, factor := range factorsList { - fmt.Println(factor) - } - fmt.Printf("Elapsed time: %s\n", elapsed) - - expected := []*big.Int{ - p1, - p2, - } - - if !equalSlices(factorsList, expected) { - t.Errorf("factorsList does not match expected values") - } -} - -func equalSlices(slice1, slice2 []*big.Int) bool { - if len(slice1) != len(slice2) { - return false - } - for i := range slice1 { - if slice1[i].Cmp(slice2[i]) != 0 { - return false - } - } - return true -} diff --git a/pow/pow.go b/pow/pow.go index a06788f..5100d96 100644 --- a/pow/pow.go +++ b/pow/pow.go @@ -2,6 +2,7 @@ package pow import ( "fmt" + "github.com/tsosunchia/powclient" "github.com/xgadget-lab/nexttrace/config" "net/url" "os" @@ -13,7 +14,7 @@ const ( ) func GetToken(fastIp string, host string, port string) (string, error) { - getTokenParams := NewGetTokenParams() + getTokenParams := powclient.NewGetTokenParams() u := url.URL{Scheme: "https", Host: fastIp + ":" + port, Path: baseURL} getTokenParams.BaseUrl = u.String() getTokenParams.SNI = host @@ -22,7 +23,7 @@ func GetToken(fastIp string, host string, port string) (string, error) { var err error // 尝试三次RetToken,如果都失败了,异常退出 for i := 0; i < 3; i++ { - token, err := RetToken(getTokenParams) + token, err := powclient.RetToken(getTokenParams) if err != nil { continue } diff --git a/pow/pow_client.go b/pow/pow_client.go deleted file mode 100644 index f1b54f0..0000000 --- a/pow/pow_client.go +++ /dev/null @@ -1,185 +0,0 @@ -package pow - -import ( - "bytes" - "crypto/tls" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "math/big" - "net/http" - "time" -) - -//TODO: 在这里要实现优选IP - -type Challenge struct { - RequestID string `json:"request_id"` - Challenge string `json:"challenge"` -} - -type RequestResponse struct { - Challenge Challenge `json:"challenge"` - RequestTime int64 `json:"request_time"` -} - -type SubmitRequest struct { - Challenge Challenge `json:"challenge"` - Answer []string `json:"answer"` - RequestTime int64 `json:"request_time"` -} - -type SubmitResponse struct { - Token string `json:"token"` -} - -type GetTokenParams struct { - TimeoutSec time.Duration - BaseUrl string - RequestPath string - SubmitPath string - UserAgent string - SNI string - Host string -} - -func NewGetTokenParams() *GetTokenParams { - return &GetTokenParams{ - TimeoutSec: 5 * time.Second, // 你的默认值 - BaseUrl: "http://127.0.0.1:55000", - RequestPath: "/request_challenge", - SubmitPath: "/submit_answer", - UserAgent: "POW client", - SNI: "", - Host: "", - } -} - -func RetToken(getTokenParams *GetTokenParams) (string, error) { - // Get challenge - challengeResponse, err := requestChallenge(getTokenParams) - if err != nil { - return "", err - } - //fmt.Println(challengeResponse.Challenge.Challenge) - - // Solve challenge and submit answer - token, err := submitAnswer(getTokenParams, challengeResponse) - if err != nil { - return "", err - } - - return token, nil -} - -func requestChallenge(getTokenParams *GetTokenParams) (*RequestResponse, error) { - client := &http.Client{ - Timeout: getTokenParams.TimeoutSec, - } - if getTokenParams.SNI != "" { - client = &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - ServerName: getTokenParams.SNI, - }, - }, - } - } - req, err := http.NewRequest("GET", getTokenParams.BaseUrl+getTokenParams.RequestPath, nil) - if err != nil { - return nil, err - } - req.Header.Add("User-Agent", getTokenParams.UserAgent) - //req.Header.Add("Host", getTokenParams.Host) - req.Host = getTokenParams.Host - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - fmt.Println(err) - } - }(resp.Body) - var challengeResponse RequestResponse - err = json.NewDecoder(resp.Body).Decode(&challengeResponse) - if err != nil { - return nil, err - } - - return &challengeResponse, nil -} - -func submitAnswer(getTokenParams *GetTokenParams, challengeResponse *RequestResponse) (string, error) { - client := &http.Client{ - Timeout: getTokenParams.TimeoutSec, - } - if getTokenParams.SNI != "" { - client = &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - ServerName: getTokenParams.SNI, - }, - }, - } - } - requestTime := challengeResponse.RequestTime - challenge := challengeResponse.Challenge.Challenge - requestId := challengeResponse.Challenge.RequestID - N := new(big.Int) - N.SetString(challenge, 10) - factorsList := factors(N) - if len(factorsList) != 2 { - return "", errors.New("factors function did not return exactly two factors") - } - p1 := factorsList[0] - p2 := factorsList[1] - if p1.Cmp(p2) > 0 { // if p1 > p2 - p1, p2 = p2, p1 // swap p1 and p2 - } - submitRequest := SubmitRequest{ - Challenge: Challenge{RequestID: requestId}, - Answer: []string{p1.String(), p2.String()}, - RequestTime: requestTime, - } - requestBody, err := json.Marshal(submitRequest) - if err != nil { - return "", err - } - - req, err := http.NewRequest("POST", getTokenParams.BaseUrl+getTokenParams.SubmitPath, bytes.NewBuffer(requestBody)) - if err != nil { - return "", err - } - req.Header.Set("Content-Type", "application/json") - req.Header.Add("User-Agent", getTokenParams.UserAgent) - //req.Header.Add("Host", getTokenParams.Host) - req.Host = getTokenParams.Host - - resp, err := client.Do(req) - if err != nil { - return "", err - } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - fmt.Println(err) - } - }(resp.Body) - - if resp.StatusCode != http.StatusOK { - bodyBytes, _ := ioutil.ReadAll(resp.Body) - return "", errors.New(string(bodyBytes)) - } - - var submitResponse SubmitResponse - err = json.NewDecoder(resp.Body).Decode(&submitResponse) - if err != nil { - return "", err - } - - return submitResponse.Token, nil -}