Allow sepcify which IP version (IPv4 or IPv6) should be returned

Creates go.mod

Signed-off-by: p4u <p4u@dabax.net>
This commit is contained in:
iomete 2019-09-20 00:56:16 +02:00
parent 9a19400b08
commit 51489f170e
4 changed files with 78 additions and 23 deletions

View File

@ -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() {

View File

@ -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 <nil> 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{
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 <nil>.
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
}

12
go.mod Normal file
View File

@ -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
)

21
go.sum Normal file
View File

@ -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=