| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- package config
-
- import (
- "context"
- "fmt"
- "io"
- "io/ioutil"
- "net"
- "net/http"
- "strings"
- "time"
- )
-
- const (
- ifconfigAddress = "https://ifconfig.co/ip"
- ifconfigTimeout = 10 * time.Second
- )
-
- func getGlobalIPv4(ctx context.Context) (net.IP, error) {
- ip, err := fetchIP(ctx, "tcp4")
- if err != nil || ip.To4() == nil {
- return nil, fmt.Errorf("cannot find public ipv4 address: %w", err)
- }
-
- return ip, nil
- }
-
- func getGlobalIPv6(ctx context.Context) (net.IP, error) {
- ip, err := fetchIP(ctx, "tcp6")
- if err != nil || ip.To4() != nil {
- return nil, fmt.Errorf("cannot find public ipv6 address: %w", err)
- }
-
- return ip, nil
- }
-
- func fetchIP(ctx context.Context, network string) (net.IP, error) {
- dialer := &net.Dialer{FallbackDelay: -1}
- client := &http.Client{
- Jar: nil,
- Timeout: ifconfigTimeout,
- Transport: &http.Transport{
- DialContext: func(ctx context.Context, _, addr string) (net.Conn, error) {
- return dialer.DialContext(ctx, network, addr)
- },
- },
- }
-
- req, err := http.NewRequest("GET", ifconfigAddress, nil)
- if err != nil {
- return nil, fmt.Errorf("cannot create a request: %w", err)
- }
-
- resp, err := client.Do(req.WithContext(ctx))
- if err != nil {
- if resp != nil {
- io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
- }
-
- return nil, fmt.Errorf("cannot perform a request: %w", err)
- }
-
- defer resp.Body.Close() // nolint: errcheck
-
- respDataBytes, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, fmt.Errorf("cannot read response body: %w", err)
- }
-
- respData := strings.TrimSpace(string(respDataBytes))
-
- ip := net.ParseIP(respData)
- if ip == nil {
- return nil, fmt.Errorf("ifconfig.co returns incorrect IP %s", respData)
- }
-
- return ip, nil
- }
|