OSDN Git Service

Merge pull request #935 from Bytom/dev
[bytom/bytom.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 type IpResult struct {
24         Success bool
25         Ip      string
26 }
27
28 var timeout = time.Duration(5)
29
30 func GetIP() *IpResult {
31         resultCh := make(chan *IpResult, 1)
32         for _, s := range ipCheckServices {
33                 go ipAddress(s, resultCh)
34         }
35
36         for {
37                 select {
38                 case result := <-resultCh:
39                         return result
40                 case <-time.After(time.Second * timeout):
41                         return &IpResult{false, ""}
42                 }
43         }
44 }
45
46 func ipAddress(service string, done chan<- *IpResult) {
47         client := http.Client{Timeout: time.Duration(timeout * time.Second)}
48         resp, err := client.Get(service)
49         if err != nil {
50                 return
51         }
52
53         defer resp.Body.Close()
54         data, err := ioutil.ReadAll(resp.Body)
55         if err != nil {
56                 return
57         }
58
59         address := strings.TrimSpace(string(data))
60         if net.ParseIP(address) != nil {
61                 select {
62                 case done <- &IpResult{true, address}:
63                         return
64                 default:
65                         return
66                 }
67         }
68 }