http: stop using remote http port

The remote port used to send the announce has nothing to do with the
port being listened to for the torrent client protocol.
This commit is contained in:
Jimmy Zelinskie 2015-08-20 00:17:00 -04:00
parent 97cb3c7cb6
commit c8e8b95bfe

View file

@ -44,32 +44,18 @@ func (s *Server) newAnnounce(r *http.Request, p httprouter.Params) (*models.Anno
} }
left, err := q.Uint64("left") left, err := q.Uint64("left")
ipv4, ipv6, err := requestedEndpoint(q, r, &s.config.NetConfig)
if err != nil { if err != nil {
return nil, models.ErrMalformedRequest return nil, models.ErrMalformedRequest
} }
var ipv4Endpoint, ipv6Endpoint models.Endpoint ipv4, ipv6, err := requestedIP(q, r, &s.config.NetConfig)
if ipv4 != nil {
ipv4Endpoint = *ipv4
// If the port we couldn't get the port before, fallback to the port param.
if ipv4Endpoint.Port == uint16(0) {
ipv4Endpoint.Port = uint16(port)
}
}
if ipv6 != nil {
ipv6Endpoint = *ipv6
// If the port we couldn't get the port before, fallback to the port param.
if ipv6Endpoint.Port == uint16(0) {
ipv6Endpoint.Port = uint16(port)
}
}
if err != nil { if err != nil {
return nil, models.ErrMalformedRequest return nil, models.ErrMalformedRequest
} }
ipv4Endpoint := models.Endpoint{ipv4, uint16(port)}
ipv6Endpoint := models.Endpoint{ipv6, uint16(port)}
downloaded, err := q.Uint64("downloaded") downloaded, err := q.Uint64("downloaded")
if err != nil { if err != nil {
return nil, models.ErrMalformedRequest return nil, models.ErrMalformedRequest
@ -132,26 +118,26 @@ func requestedPeerCount(q *query.Query, fallback int) int {
return fallback return fallback
} }
// requestedEndpoint returns the IP address and port pairs for a request. If // requestedIP returns the IP address for a request. If there are multiple in
// there are multiple in the request, one IPv4 and one IPv6 will be returned. // the request, one IPv4 and one IPv6 will be returned.
func requestedEndpoint(q *query.Query, r *http.Request, cfg *config.NetConfig) (v4, v6 *models.Endpoint, err error) { func requestedIP(q *query.Query, r *http.Request, cfg *config.NetConfig) (v4, v6 net.IP, err error) {
var done bool var done bool
if cfg.AllowIPSpoofing { if cfg.AllowIPSpoofing {
if str, ok := q.Params["ip"]; ok { if str, ok := q.Params["ip"]; ok {
if v4, v6, done = getEndpoints(str, v4, v6, cfg); done { if v4, v6, done = getIPs(str, v4, v6, cfg); done {
return return
} }
} }
if str, ok := q.Params["ipv4"]; ok { if str, ok := q.Params["ipv4"]; ok {
if v4, v6, done = getEndpoints(str, v4, v6, cfg); done { if v4, v6, done = getIPs(str, v4, v6, cfg); done {
return return
} }
} }
if str, ok := q.Params["ipv6"]; ok { if str, ok := q.Params["ipv6"]; ok {
if v4, v6, done = getEndpoints(str, v4, v6, cfg); done { if v4, v6, done = getIPs(str, v4, v6, cfg); done {
return return
} }
} }
@ -159,18 +145,18 @@ func requestedEndpoint(q *query.Query, r *http.Request, cfg *config.NetConfig) (
if cfg.RealIPHeader != "" { if cfg.RealIPHeader != "" {
if xRealIPs, ok := r.Header[cfg.RealIPHeader]; ok { if xRealIPs, ok := r.Header[cfg.RealIPHeader]; ok {
if v4, v6, done = getEndpoints(string(xRealIPs[0]), v4, v6, cfg); done { if v4, v6, done = getIPs(string(xRealIPs[0]), v4, v6, cfg); done {
return return
} }
} }
} else { } else {
if r.RemoteAddr == "" && v4 == nil { if r.RemoteAddr == "" && v4 == nil {
if v4, v6, done = getEndpoints("127.0.0.1", v4, v6, cfg); done { if v4, v6, done = getIPs("127.0.0.1", v4, v6, cfg); done {
return return
} }
} }
if v4, v6, done = getEndpoints(r.RemoteAddr, v4, v6, cfg); done { if v4, v6, done = getIPs(r.RemoteAddr, v4, v6, cfg); done {
return return
} }
} }
@ -182,22 +168,18 @@ func requestedEndpoint(q *query.Query, r *http.Request, cfg *config.NetConfig) (
return return
} }
func getEndpoints(ipstr string, ipv4, ipv6 *models.Endpoint, cfg *config.NetConfig) (*models.Endpoint, *models.Endpoint, bool) { func getIPs(ipstr string, ipv4, ipv6 net.IP, cfg *config.NetConfig) (net.IP, net.IP, bool) {
host, port, err := net.SplitHostPort(ipstr) host, _, err := net.SplitHostPort(ipstr)
if err != nil { if err != nil {
host = ipstr host = ipstr
} }
// We can ignore this error, because ports that are 0 are assumed to be the
// port parameter provided in the "port" param of the announce request.
parsedPort, _ := strconv.ParseUint(port, 10, 16)
if ip := net.ParseIP(host); ip != nil { if ip := net.ParseIP(host); ip != nil {
ipTo4 := ip.To4() ipTo4 := ip.To4()
if ipv4 == nil && ipTo4 != nil { if ipv4 == nil && ipTo4 != nil {
ipv4 = &models.Endpoint{ipTo4, uint16(parsedPort)} ipv4 = ipTo4
} else if ipv6 == nil && ipTo4 == nil { } else if ipv6 == nil && ipTo4 == nil {
ipv6 = &models.Endpoint{ip, uint16(parsedPort)} ipv6 = ip
} }
} }