Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.go 1.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package cli
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "net/http"
  7. "strings"
  8. "github.com/9seconds/mtg/v2/essentials"
  9. "github.com/9seconds/mtg/v2/mtglib"
  10. )
  11. // publicIPEndpoints are tried in order. Each must return the client's public
  12. // IP as a single address in the plain-text response body.
  13. var publicIPEndpoints = []string{
  14. "https://ifconfig.co",
  15. "https://icanhazip.com",
  16. "https://ifconfig.me",
  17. }
  18. func getIP(ntw mtglib.Network, protocol string) net.IP {
  19. dialer := ntw.NativeDialer()
  20. client := ntw.MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error) {
  21. conn, err := dialer.DialContext(ctx, protocol, address)
  22. if err != nil {
  23. return nil, err
  24. }
  25. return essentials.WrapNetConn(conn), err
  26. })
  27. for _, endpoint := range publicIPEndpoints {
  28. if ip := fetchPublicIP(client, endpoint); ip != nil {
  29. return ip
  30. }
  31. }
  32. return nil
  33. }
  34. func fetchPublicIP(client *http.Client, endpoint string) net.IP {
  35. req, err := http.NewRequest(http.MethodGet, endpoint, nil) //nolint: noctx
  36. if err != nil {
  37. return nil
  38. }
  39. req.Header.Set("Accept", "text/plain")
  40. req.Header.Set("User-Agent", "curl/8")
  41. resp, err := client.Do(req)
  42. if err != nil {
  43. return nil
  44. }
  45. defer func() {
  46. io.Copy(io.Discard, resp.Body) //nolint: errcheck
  47. resp.Body.Close() //nolint: errcheck
  48. }()
  49. if resp.StatusCode != http.StatusOK {
  50. return nil
  51. }
  52. data, err := io.ReadAll(resp.Body)
  53. if err != nil {
  54. return nil
  55. }
  56. return net.ParseIP(strings.TrimSpace(string(data)))
  57. }