示例#1
0
// ParseAnnounce parses an AnnounceRequest from a UDP request.
//
// If allowIPSpoofing is true, IPs provided via params will be used.
//
// If v6 is true the announce will be parsed as an IPv6 announce "the
// opentracker way", see
// http://opentracker.blog.h3q.com/2007/12/28/the-ipv6-situation/
func ParseAnnounce(r Request, allowIPSpoofing, v6 bool) (*bittorrent.AnnounceRequest, error) {
	ipEnd := 84 + net.IPv4len
	if v6 {
		ipEnd = 84 + net.IPv6len
	}

	if len(r.Packet) < ipEnd+10 {
		return nil, errMalformedPacket
	}

	infohash := r.Packet[16:36]
	peerID := r.Packet[36:56]
	downloaded := binary.BigEndian.Uint64(r.Packet[56:64])
	left := binary.BigEndian.Uint64(r.Packet[64:72])
	uploaded := binary.BigEndian.Uint64(r.Packet[72:80])

	eventID := int(r.Packet[83])
	if eventID >= len(eventIDs) {
		return nil, errMalformedEvent
	}

	ip := r.IP
	ipbytes := r.Packet[84:ipEnd]
	if allowIPSpoofing {
		// Make sure the bytes are copied to a new slice.
		copy(ip, net.IP(ipbytes))
	}
	if !allowIPSpoofing && r.IP == nil {
		// We have no IP address to fallback on.
		return nil, errMalformedIP
	}

	numWant := binary.BigEndian.Uint32(r.Packet[ipEnd+4 : ipEnd+8])
	port := binary.BigEndian.Uint16(r.Packet[ipEnd+8 : ipEnd+10])

	params, err := handleOptionalParameters(r.Packet[ipEnd+10:])
	if err != nil {
		return nil, err
	}

	return &bittorrent.AnnounceRequest{
		Event:      eventIDs[eventID],
		InfoHash:   bittorrent.InfoHashFromBytes(infohash),
		NumWant:    uint32(numWant),
		Left:       left,
		Downloaded: downloaded,
		Uploaded:   uploaded,
		Peer: bittorrent.Peer{
			ID:   bittorrent.PeerIDFromBytes(peerID),
			IP:   ip,
			Port: port,
		},
		Params: params,
	}, nil
}
示例#2
0
// ParseScrape parses a ScrapeRequest from a UDP request.
func ParseScrape(r Request) (*bittorrent.ScrapeRequest, error) {
	// If a scrape isn't at least 36 bytes long, it's malformed.
	if len(r.Packet) < 36 {
		return nil, errMalformedPacket
	}

	// Skip past the initial headers and check that the bytes left equal the
	// length of a valid list of infohashes.
	r.Packet = r.Packet[16:]
	if len(r.Packet)%20 != 0 {
		return nil, errMalformedPacket
	}

	// Allocate a list of infohashes and append it to the list until we're out.
	var infohashes []bittorrent.InfoHash
	for len(r.Packet) >= 20 {
		infohashes = append(infohashes, bittorrent.InfoHashFromBytes(r.Packet[:20]))
		r.Packet = r.Packet[20:]
	}

	return &bittorrent.ScrapeRequest{
		InfoHashes: infohashes,
	}, nil
}