Add RealIPHeader configuration, and move network conf to its own struct

This commit is contained in:
Justin Li 2014-07-23 14:00:17 -04:00
parent 8369bbbcd8
commit 76c68a53b5
4 changed files with 43 additions and 37 deletions

View file

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

View file

@ -15,6 +15,7 @@
"whitelist": false,
"purge_inactive_torrents": true,
"allow_ip_spoofing": true,
"dual_stacked_peers": true,
"announce": "30m",
"min_announce": "15m",

View file

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

View file

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