OSDN Git Service

new repo
[bytom/vapor.git] / p2p / public_ip.go
1 package p2p
2
3 import (
4         "io/ioutil"
5         "net"
6         "net/http"
7         "strings"
8         "time"
9 )
10
11 var ipCheckServices = []string{
12         "http://members.3322.org/dyndns/getip",
13         "http://ifconfig.me/",
14         "http://icanhazip.com/",
15         "http://ifconfig.io/ip",
16         "http://ident.me/",
17         "http://whatismyip.akamai.com/",
18         "http://myip.dnsomatic.com/",
19         "http://diagnostic.opendns.com/myip",
20         "http://myexternalip.com/raw",
21 }
22
23 // IPResult is the ip check response
24 type IPResult struct {
25         Success bool
26         IP      string
27 }
28
29 var timeout = time.Duration(5)
30
31 // GetIP return the ip of the current host
32 func GetIP() *IPResult {
33         resultCh := make(chan *IPResult, 1)
34         for _, s := range ipCheckServices {
35                 go ipAddress(s, resultCh)
36         }
37
38         for {
39                 select {
40                 case result := <-resultCh:
41                         return result
42                 case <-time.After(time.Second * timeout):
43                         return &IPResult{false, ""}
44                 }
45         }
46 }
47
48 func ipAddress(service string, done chan<- *IPResult) {
49         client := http.Client{Timeout: time.Duration(timeout * time.Second)}
50         resp, err := client.Get(service)
51         if err != nil {
52                 return
53         }
54
55         defer resp.Body.Close()
56         data, err := ioutil.ReadAll(resp.Body)
57         if err != nil {
58                 return
59         }
60
61         address := strings.TrimSpace(string(data))
62         if ip := net.ParseIP(address); ip != nil && ip.To4() != nil {
63                 select {
64                 case done <- &IPResult{true, address}:
65                         return
66                 default:
67                         return
68                 }
69         }
70 }