-
Notifications
You must be signed in to change notification settings - Fork 13
/
util.go
92 lines (80 loc) · 2.21 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main
import (
"log"
"net"
"net/http"
"strconv"
"strings"
"github.com/oftn-oswg/ipcat"
)
// ParseSocketName produces a struct suitable for net.Dial
// given a string representing a socket address to bind or connect to
func ParseSocketName(value string) (string, string) {
value = strings.TrimSpace(value)
// If value begins with "unix:" then we are a Unix domain socket
if strings.Index(value, "unix:") == 0 {
return "unix", strings.TrimSpace(value[5:])
}
// If value is a port number, prepend a colon
if _, err := strconv.Atoi(value); err == nil {
return "tcp", ":" + value
}
return "tcp", value
}
func getCloudflareSet() *ipcat.IntervalSet {
ipset := ipcat.NewIntervalSet(24)
cloudflareRanges, err := ipcat.DownloadCloudflare()
if err != nil {
log.Printf("Could not download Cloudflare ranges: %s", err)
return nil
}
if err := ipcat.UpdateCloudflare(ipset, cloudflareRanges); err != nil {
log.Printf("Could not update Cloudflare ranges: %s", err)
return nil
}
log.Printf("Loaded %d Cloudflare records\n", ipset.Len())
return ipset
}
var cloudflareSet = getCloudflareSet()
func peelRemoteIP(r *http.Request) net.IP {
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
// We could not parse the host and port.
// Assume this means local.
return net.IPv6loopback
}
return net.ParseIP(host)
}
func peelLocalProxy(ip net.IP, r *http.Request) net.IP {
if ip != nil {
// Local proxies only!
if ip.IsLoopback() {
if real := r.Header.Get("X-Real-IP"); real != "" {
headerip := net.ParseIP(real)
if headerip != nil {
return headerip
}
}
}
}
return ip
}
func peelCloudflare(ip net.IP, r *http.Request) net.IP {
if cloudflareSet != nil {
// Cloudflare proxy only!
record, err := cloudflareSet.Contains(ip.String())
if err == nil && record != nil {
// We are being served by Cloudflare
connectingIP := r.Header.Get("CF-Connecting-IP")
if connectingIP != "" {
return net.ParseIP(connectingIP)
}
}
}
return ip
}
// RealRemoteIP returns the value of the X-Real-IP header,
// or the RemoteAddr property if the header does not exist.
func RealRemoteIP(r *http.Request) net.IP {
return peelCloudflare(peelLocalProxy(peelRemoteIP(r), r), r)
}