From 51489f170e0ffe61f3f22338be9f4661e20d5a87 Mon Sep 17 00:00:00 2001 From: iomete Date: Fri, 20 Sep 2019 00:56:16 +0200 Subject: [PATCH] Allow sepcify which IP version (IPv4 or IPv6) should be returned Creates go.mod Signed-off-by: p4u --- cmd/exip/main.go | 8 ++++--- consensus.go | 60 ++++++++++++++++++++++++++++++++---------------- go.mod | 12 ++++++++++ go.sum | 21 +++++++++++++++++ 4 files changed, 78 insertions(+), 23 deletions(-) create mode 100644 go.mod create mode 100644 go.sum diff --git a/cmd/exip/main.go b/cmd/exip/main.go index c010340..33bf1c8 100644 --- a/cmd/exip/main.go +++ b/cmd/exip/main.go @@ -7,7 +7,7 @@ import ( "os" "time" - "github.com/glendc/go-external-ip" + externalip "gitlab.com/vocdoni/go-external-ip" ) // CLI Flags @@ -34,7 +34,8 @@ func main() { consensus := externalip.DefaultConsensus(cfg, logger) // retrieve the external ip - ip, err := consensus.ExternalIP() + ip4, err := consensus.ExternalIP(4) + ip6, err := consensus.ExternalIP(6) // simple error handling if err != nil { @@ -43,7 +44,8 @@ func main() { } // success, simply output the IP in string format - fmt.Println(ip.String()) + fmt.Println(ip4.String()) + fmt.Println(ip6.String()) } func init() { diff --git a/consensus.go b/consensus.go index 9b65b69..e61ceab 100644 --- a/consensus.go +++ b/consensus.go @@ -7,6 +7,9 @@ import ( "time" ) +const IPv6 = 6 +const IPv4 = 4 + // DefaultConsensusConfig returns the ConsensusConfig, // with the default values: // + Timeout: 30 seconds; @@ -24,17 +27,17 @@ func DefaultConsensus(cfg *ConsensusConfig, logger *log.Logger) *Consensus { consensus := NewConsensus(cfg, logger) // TLS-protected providers - consensus.AddVoter(NewHTTPSource("https://icanhazip.com/"), 3) - consensus.AddVoter(NewHTTPSource("https://myexternalip.com/raw"), 3) + consensus.AddVoter(NewHTTPSource("https://icanhazip.com/"), 3, IPv6) + consensus.AddVoter(NewHTTPSource("https://myexternalip.com/raw"), 3, IPv4) // Plain-text providers - consensus.AddVoter(NewHTTPSource("http://ifconfig.io/ip"), 1) - consensus.AddVoter(NewHTTPSource("http://checkip.amazonaws.com/"), 1) - consensus.AddVoter(NewHTTPSource("http://ident.me/"), 1) - consensus.AddVoter(NewHTTPSource("http://whatismyip.akamai.com/"), 1) - consensus.AddVoter(NewHTTPSource("http://tnx.nl/ip"), 1) - consensus.AddVoter(NewHTTPSource("http://myip.dnsomatic.com/"), 1) - consensus.AddVoter(NewHTTPSource("http://diagnostic.opendns.com/myip"), 1) + consensus.AddVoter(NewHTTPSource("http://ifconfig.io/ip"), 1, IPv6) + consensus.AddVoter(NewHTTPSource("http://checkip.amazonaws.com/"), 1, IPv4) + consensus.AddVoter(NewHTTPSource("http://ident.me/"), 1, IPv6) + consensus.AddVoter(NewHTTPSource("http://whatismyip.akamai.com/"), 1, IPv4) + consensus.AddVoter(NewHTTPSource("http://tnx.nl/ip"), 1, IPv6) + consensus.AddVoter(NewHTTPSource("http://myip.dnsomatic.com/"), 1, IPv4) + consensus.AddVoter(NewHTTPSource("http://diagnostic.opendns.com/myip"), 1, IPv6) return consensus } @@ -71,7 +74,8 @@ func (cfg *ConsensusConfig) WithTimeout(timeout time.Duration) *ConsensusConfig // Its `ExternalIP` method allows you to ask for your ExternalIP, // influenced by all its added voters. type Consensus struct { - voters []voter + voters4 []voter + voters6 []voter timeout time.Duration logger *log.Logger } @@ -79,7 +83,7 @@ type Consensus struct { // AddVoter adds a voter to this consensus. // The source cannot be and // the weight has to be of a value of 1 or above. -func (c *Consensus) AddVoter(source Source, weight uint) error { +func (c *Consensus) AddVoter(source Source, weight, ipversion uint) error { if source == nil { c.logger.Println("[ERROR] could not add voter: no source given") return ErrNoSource @@ -88,24 +92,37 @@ func (c *Consensus) AddVoter(source Source, weight uint) error { c.logger.Println("[ERROR] could not add voter: weight cannot be 0") return ErrInsufficientWeight } - - c.voters = append(c.voters, voter{ - source: source, - weight: weight, - }) + if ipversion == 4 { + c.voters4 = append(c.voters4, voter{ + source: source, + weight: weight, + }) + } + if ipversion == 6 { + c.voters6 = append(c.voters6, voter{ + source: source, + weight: weight, + }) + } return nil } // ExternalIP requests asynchronously the externalIP from all added voters, // returning the IP which received the most votes. // The returned IP will always be valid, in case the returned error is . -func (c *Consensus) ExternalIP() (net.IP, error) { +func (c *Consensus) ExternalIP(ipversion uint) (net.IP, error) { voteCollection := make(map[string]uint) var vlock sync.Mutex var wg sync.WaitGroup - + var thisVoters []voter + if ipversion == IPv4 { + thisVoters = c.voters4 + } + if ipversion == IPv6 { + thisVoters = c.voters6 + } // start all source Requests on a seperate goroutine - for _, v := range c.voters { + for _, v := range thisVoters { wg.Add(1) go func(v voter) { defer wg.Done() @@ -144,5 +161,8 @@ func (c *Consensus) ExternalIP() (net.IP, error) { // as the found IP was parsed previously, // we know it cannot be nil and is valid - return net.ParseIP(externalIP), nil + if ipversion == IPv4 { + return net.ParseIP(externalIP).To4(), nil + } + return net.ParseIP(externalIP).To16(), nil } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..53b3092 --- /dev/null +++ b/go.mod @@ -0,0 +1,12 @@ +module gitlab.com/vocdoni/go-external-ip + +go 1.12 + +require ( + github.com/google/pprof v0.0.0-20190908185732-236ed259b199 // indirect + github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 // indirect + golang.org/x/arch v0.0.0-20190919213554-7fe50f7625bd // indirect + golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 // indirect + golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 // indirect + golang.org/x/tools v0.0.0-20190919223014-db1d4edb4685 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..803f71c --- /dev/null +++ b/go.sum @@ -0,0 +1,21 @@ +github.com/google/pprof v0.0.0-20190908185732-236ed259b199 h1:sEyCq3pOT7tNC+3gcLI7sZkBDgntZ6wQJNmr9lmIjIc= +github.com/google/pprof v0.0.0-20190908185732-236ed259b199/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +golang.org/x/arch v0.0.0-20190919213554-7fe50f7625bd h1:IbZRdF+nCjC31g8APRj0sBwNe35VSPHNThzJKA0idTs= +golang.org/x/arch v0.0.0-20190919213554-7fe50f7625bd/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 h1:/zi0zzlPHWXYXrO1LjNRByFu8sdGgCkj2JLDdBIB84k= +golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190919223014-db1d4edb4685 h1:/6Ol4IqB+r3aIk191dJQFcnPHMW+pj8RzXAz3ddkmk4= +golang.org/x/tools v0.0.0-20190919223014-db1d4edb4685/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=