From 76c68a53b51383f353332ac404706d7d6546089b Mon Sep 17 00:00:00 2001 From: Justin Li Date: Wed, 23 Jul 2014 14:00:17 -0400 Subject: [PATCH] Add RealIPHeader configuration, and move network conf to its own struct --- config/config.go | 24 ++++++++++++++------ example.json | 1 + http/query/query.go | 53 ++++++++++++++++++++------------------------- http/tracker.go | 2 +- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/config/config.go b/config/config.go index 4267740..beb1bfa 100644 --- a/config/config.go +++ b/config/config.go @@ -40,6 +40,17 @@ type DriverConfig struct { Params map[string]string `json:"params,omitempty"` } +// NetConfig is the configuration used to tune networking behaviour. +type NetConfig struct { + AllowIPSpoofing bool `json:"allow_ip_spoofing"` + DualStackedPeers bool `json:"dual_stacked_peers"` + RealIPHeader string `json:"real_ip_header"` + + PreferredSubnet bool `json:"preferred_subnet,omitempty"` + PreferredIPv4Subnet int `json:"preferred_ipv4_subnet,omitempty"` + PreferredIPv6Subnet int `json:"preferred_ipv6_subnet,omitempty"` +} + // Config is a configuration for a Server. type Config struct { Addr string `json:"addr"` @@ -50,17 +61,13 @@ type Config struct { Freeleech bool `json:"freeleech"` Whitelist bool `json:"whitelist"` PurgeInactiveTorrents bool `json:"purge_inactive_torrents"` - AllowIPSpoofing bool `json:"allow_ip_spoofing"` - DualStackedPeers bool `json:"dual_stacked_peers"` Announce Duration `json:"announce"` MinAnnounce Duration `json:"min_announce"` RequestTimeout Duration `json:"request_timeout"` NumWantFallback int `json:"default_num_want"` - PreferredSubnet bool `json:"preferred_subnet,omitempty"` - PreferredIPv4Subnet int `json:"preferred_ipv4_subnet,omitempty"` - PreferredIPv6Subnet int `json:"preferred_ipv6_subnet,omitempty"` + NetConfig } // DefaultConfig is a configuration that can be used as a fallback value. @@ -79,13 +86,16 @@ var DefaultConfig = Config{ Freeleech: false, Whitelist: false, PurgeInactiveTorrents: true, - AllowIPSpoofing: true, - DualStackedPeers: true, Announce: Duration{30 * time.Minute}, MinAnnounce: Duration{15 * time.Minute}, RequestTimeout: Duration{10 * time.Second}, NumWantFallback: 50, + + NetConfig: NetConfig{ + AllowIPSpoofing: true, + DualStackedPeers: true, + }, } // Open is a shortcut to open a file, read it, and generate a Config. diff --git a/example.json b/example.json index 103abac..e74aee5 100644 --- a/example.json +++ b/example.json @@ -15,6 +15,7 @@ "whitelist": false, "purge_inactive_torrents": true, "allow_ip_spoofing": true, + "dual_stacked_peers": true, "announce": "30m", "min_announce": "15m", diff --git a/http/query/query.go b/http/query/query.go index 7776765..5e28852 100644 --- a/http/query/query.go +++ b/http/query/query.go @@ -12,6 +12,8 @@ import ( "net/url" "strconv" "strings" + + "github.com/chihaya/chihaya/config" ) // Query represents a parsed URL.Query. @@ -121,7 +123,7 @@ func (q Query) RequestedPeerCount(fallback int) int { return fallback } -func getIPs(ipstr string, ipv4, ipv6 net.IP, dualStacked bool) (net.IP, net.IP, bool) { +func getIPs(ipstr string, ipv4, ipv6 net.IP, cfg *config.NetConfig) (net.IP, net.IP, bool) { var done bool if ip := net.ParseIP(ipstr); ip != nil { @@ -134,7 +136,7 @@ func getIPs(ipstr string, ipv4, ipv6 net.IP, dualStacked bool) (net.IP, net.IP, } } - if dualStacked { + if cfg.DualStackedPeers { done = ipv4 != nil && ipv6 != nil } else { done = ipv4 != nil || ipv6 != nil @@ -144,54 +146,47 @@ func getIPs(ipstr string, ipv4, ipv6 net.IP, dualStacked bool) (net.IP, net.IP, } // RequestedIP returns the requested IP address from a Query. -func (q Query) RequestedIP(r *http.Request, allowSpoofing, dualStacked bool) (v4, v6 net.IP, err error) { +func (q Query) RequestedIP(r *http.Request, cfg *config.NetConfig) (v4, v6 net.IP, err error) { var done bool - var ds = dualStacked - if allowSpoofing { + if cfg.AllowIPSpoofing { if str, ok := q.Params["ip"]; ok { - if v4, v6, done = getIPs(str, v4, v6, ds); done { + if v4, v6, done = getIPs(str, v4, v6, cfg); done { return } } if str, ok := q.Params["ipv4"]; ok { - if v4, v6, done = getIPs(str, v4, v6, ds); done { + if v4, v6, done = getIPs(str, v4, v6, cfg); done { return } } if str, ok := q.Params["ipv6"]; ok { - if v4, v6, done = getIPs(str, v4, v6, ds); done { + if v4, v6, done = getIPs(str, v4, v6, cfg); done { return } } } - if xRealIPs, ok := q.Params["x-real-ip"]; ok { - if v4, v6, done = getIPs(string(xRealIPs[0]), v4, v6, ds); done { + if cfg.RealIPHeader != "" { + if xRealIPs, ok := q.Params[cfg.RealIPHeader]; ok { + if v4, v6, done = getIPs(string(xRealIPs[0]), v4, v6, cfg); done { + return + } + } + } else { + if r.RemoteAddr == "" { + if v4 == nil { + v4 = net.ParseIP("127.0.0.1") + } return } - } - if r.RemoteAddr == "" { - if v4 == nil { - v4 = net.ParseIP("127.0.0.1") - } - return - } - - portIndex := len(r.RemoteAddr) - 1 - for ; portIndex >= 0; portIndex-- { - if r.RemoteAddr[portIndex] == ':' { - break - } - } - - if portIndex != -1 { - str := r.RemoteAddr[0:portIndex] - if v4, v6, done = getIPs(str, v4, v6, ds); done { - return + if idx := strings.LastIndex(r.RemoteAddr, ":"); idx != -1 { + if v4, v6, done = getIPs(r.RemoteAddr[0:idx], v4, v6, cfg); done { + return + } } } diff --git a/http/tracker.go b/http/tracker.go index 444e114..b319c1c 100644 --- a/http/tracker.go +++ b/http/tracker.go @@ -35,7 +35,7 @@ func NewAnnounce(cfg *config.Config, r *http.Request, p httprouter.Params) (*mod return nil, models.ErrMalformedRequest } - ipv4, ipv6, err := q.RequestedIP(r, cfg.AllowIPSpoofing, cfg.DualStackedPeers) + ipv4, ipv6, err := q.RequestedIP(r, &cfg.NetConfig) if err != nil { return nil, models.ErrMalformedRequest }