Beispiel #1
0
/* CLIENT */
func (n *Node) Dial(peerPubKey *rsa.PublicKey) (conn Conn, err error) {
	infoHash, err := pubKeyToInfoHash(peerPubKey)
	if err != nil {
		return
	}

	peerNotifications := make(chan string, peerChanBufferCapacity)
	n.dht.subscribeToInfoHash(dht.InfoHash(infoHash), peerNotifications)

	// ask for the infohash
	n.dht.PeersRequest(infoHash, false)

	connSuccessChan := make(chan interface{})

	for peerNotification := range peerNotifications {
		go func(peerNotification string) {

			// ASSUMPTION: peerNotifications doesn't yield duplicates.
			someConn, connErr := n.handlePotentialPeer(peerNotification, peerPubKey)

			if err != nil {
				Log(LOG_INFO, "Failed to connect to potential peer %s: %s", peerNotification, connErr)
			}

			connSuccessChan <- someConn
		}(peerNotification)
	}

	maybeConn, err := netutils.ReadWithTimeout(connSuccessChan, 30000)
	if err != nil {
		return
	}

	return maybeConn.(Conn), nil
}
Beispiel #2
0
// infohash used for this wherez lookup. This should be somewhat hard to guess
// but it's not exactly a secret.
func infoHash(passphrase []byte) (dht.InfoHash, error) {
	// SHA256 of the passphrase.
	h256 := sha256.New()
	h256.Write(passphrase)
	h := h256.Sum(nil)

	// Assuming perfect rainbow databases, it's better if the infohash does not
	// give out too much about the passphrase. Take half of this hash, then
	// generate a SHA1 hash from it.
	h2 := h[0 : sha256.Size/2]

	// Mainline DHT uses sha1.
	h160 := sha1.New()
	h160.Write(h2)
	h3 := h160.Sum(nil)
	return dht.InfoHash(h3[:]), nil
}
Beispiel #3
0
func TestReceivePeers(t *testing.T) {
	cleanupPeers()
	d := NewDHT(NewDHTConfig())
	peers := NewPeers(NewPeersConfig())
	peers.Init()
	m := make(map[dht.InfoHash][]string)
	ps := make([]string, 0)
	ps = append(ps, string([]byte{013, 026, 041, 054, 013, 013}))
	ps = append(ps, string([]byte{013, 026, 041, 055, 013, 013}))
	m[dht.InfoHash("")] = ps
	d.ReceivePeers(m, peers.Peers)
	assert.Equal(t, len(peers.Peers.Peerlist), 2)
	assert.NotNil(t, peers.Peers.Peerlist["11.22.33.45:2827"])
	assert.NotNil(t, peers.Peers.Peerlist["11.22.33.44:2827"])
	wait()
	d.Shutdown()
	wait()
}
Beispiel #4
0
func trackerHandler(w http.ResponseWriter, r *http.Request) {
	if r.FormValue("compact") != "1" {
		http.Error(w, "Only compact protocol supported.", 400)
		return
	}

	info_hash := dht.InfoHash(r.FormValue("info_hash"))
	if len(info_hash) != 20 {
		http.Error(w, "Bad info_hash.", 400)
		return
	}

	response := TrackerResponse{
		Interval:    300,
		MinInterval: 60,
	}

	peers, ok := peerCache.Get(info_hash)

	dhtNode.Find(info_hash)

	if !ok || len(peers) == 0 {
		response.Interval = 30
		response.MinInterval = 10

		time.Sleep(5 * time.Second)

		peers, ok = peerCache.Get(info_hash)
	}

	if ok && len(peers) > 0 {
		response.Incomplete = len(peers)
		response.Peers = strings.Join(peers, "")
	}

	w.Header().Set("Content-Type", "application/octet-stream")

	if err := bencode.Marshal(w, response); err != nil {
		http.Error(w, err.Error(), 500)
	}
}