Refactor writing peers & IPv6 Compact support. Closes #14.

This commit is contained in:
Jimmy Zelinskie
2014-06-28 20:44:43 -04:00
parent e0ead67737
commit 3999e35453
3 changed files with 159 additions and 79 deletions
+18 -14
View File
@@ -8,6 +8,7 @@ package models
import (
"errors"
"net"
"net/http"
"path"
"strconv"
@@ -29,7 +30,7 @@ type Peer struct {
UserID uint64 `json:"user_id"`
TorrentID uint64 `json:"torrent_id"`
IP string `json:"ip"`
IP net.IP `json:"ip"`
Port uint64 `json:"port"`
Uploaded uint64 `json:"uploaded"`
@@ -92,15 +93,15 @@ type Torrent struct {
}
// InSeederPool returns true if a peer is within a Torrent's pool of seeders.
func (t *Torrent) InSeederPool(p *Peer) bool {
_, exists := t.Seeders[p.Key()]
return exists
func (t *Torrent) InSeederPool(p *Peer) (exists bool) {
_, exists = t.Seeders[p.Key()]
return
}
// InLeecherPool returns true if a peer is within a Torrent's pool of leechers.
func (t *Torrent) InLeecherPool(p *Peer) bool {
_, exists := t.Leechers[p.Key()]
return exists
func (t *Torrent) InLeecherPool(p *Peer) (exists bool) {
_, exists = t.Leechers[p.Key()]
return
}
// User is a registered user for private trackers.
@@ -121,7 +122,7 @@ type Announce struct {
Compact bool `json:"compact"`
Downloaded uint64 `json:"downloaded"`
Event string `json:"event"`
IP string `json:"ip"`
IP net.IP `json:"ip"`
Infohash string `json:"infohash"`
Left uint64 `json:"left"`
NumWant int `json:"numwant"`
@@ -139,15 +140,18 @@ func NewAnnounce(r *http.Request, conf *config.Config) (*Announce, error) {
}
compact := q.Params["compact"] != "0"
downloaded, downloadedErr := q.Uint64("downloaded")
event, _ := q.Params["event"]
infohash, _ := q.Params["info_hash"]
ip, _ := q.RequestedIP(r)
left, leftErr := q.Uint64("left")
numWant := q.RequestedPeerCount(conf.NumWantFallback)
dir, _ := path.Split(r.URL.Path)
peerID, _ := q.Params["peer_id"]
dir, _ := path.Split(r.URL.Path)
numWant := q.RequestedPeerCount(conf.NumWantFallback)
ip, ipErr := q.RequestedIP(r)
port, portErr := q.Uint64("port")
left, leftErr := q.Uint64("left")
downloaded, downloadedErr := q.Uint64("downloaded")
uploaded, uploadedErr := q.Uint64("uploaded")
if downloadedErr != nil ||
@@ -156,7 +160,7 @@ func NewAnnounce(r *http.Request, conf *config.Config) (*Announce, error) {
peerID == "" ||
portErr != nil ||
uploadedErr != nil ||
ip == "" ||
ipErr != nil ||
len(dir) != 34 {
return nil, ErrMalformedRequest
}
+27 -9
View File
@@ -7,6 +7,7 @@ package query
import (
"errors"
"net"
"net/http"
"net/url"
"strconv"
@@ -120,21 +121,35 @@ func (q Query) RequestedPeerCount(fallback int) int {
}
// RequestedIP returns the requested IP address from a Query.
func (q Query) RequestedIP(r *http.Request) (string, error) {
if ip, ok := q.Params["ip"]; ok {
return ip, nil
func (q Query) RequestedIP(r *http.Request) (net.IP, error) {
if ipstr, ok := q.Params["ip"]; ok {
if ip := net.ParseIP(ipstr); ip != nil {
return ip, nil
}
}
if ip, ok := q.Params["ipv4"]; ok {
return ip, nil
if ipstr, ok := q.Params["ipv4"]; ok {
if ip := net.ParseIP(ipstr); ip != nil {
return ip, nil
}
}
if ipstr, ok := q.Params["ipv6"]; ok {
if ip := net.ParseIP(ipstr); ip != nil {
return ip, nil
}
}
if xRealIPs, ok := q.Params["X-Real-Ip"]; ok {
return string(xRealIPs[0]), nil
if ip := net.ParseIP(string(xRealIPs[0])); ip != nil {
return ip, nil
}
}
if r.RemoteAddr == "" {
return "127.0.0.1", nil
if ip := net.ParseIP("127.0.0.1"); ip != nil {
return ip, nil
}
}
portIndex := len(r.RemoteAddr) - 1
@@ -145,8 +160,11 @@ func (q Query) RequestedIP(r *http.Request) (string, error) {
}
if portIndex != -1 {
return r.RemoteAddr[0:portIndex], nil
ipstr := r.RemoteAddr[0:portIndex]
if ip := net.ParseIP(ipstr); ip != nil {
return ip, nil
}
}
return "", errors.New("failed to parse IP address")
return nil, errors.New("failed to parse IP address")
}