Example #1
0
File: dht.go Project: hlandau/dht
// Reads datagrams from the connection and queues them for processing on the
// l-goroutine.
func (dht *DHT) readLoop() {
	for {
		b, addr, err := denet.ReadDatagramFromUDP(dht.conn)

		switch {
		// Successful receive.
		case err == nil:
			dht.rxChan <- packet{
				Data: b,
				Addr: *addr,
			}

			// An address was unreachable.
		case denet.ErrorIsPortUnreachable(err):
			dht.addrUnreachableChan <- *addr

			// Unless we are stopping, other errors should not occur.
		case atomic.LoadUint32(&dht.stopping) == 0:
			log.Errore(err, "unexpected error while receiving")

			// We are stopping.
		default:
			return
		}
	}
}
Example #2
0
File: dht.go Project: hlandauf/dht
func (d *DHT) sendMsg(conn *net.UDPConn, raddr net.UDPAddr, query interface{}) error {
	err := sendMsg(conn, raddr, query)
	if err != nil && denet.ErrorIsPortUnreachable(err) {
		d.processUnreachable(raddr)
	}
	return err
}
Example #3
0
func (dht *DHT) lTxQuery(n *node, method string, args interface{}) error {
	q, err := krpc.MakeQuery(method, args)
	if err != nil {
		return err
	}

	n.PendingQueries[q.TxID] = q
	err = krpc.Write(dht.conn, n.Addr, q)
	if err != nil && denet.ErrorIsPortUnreachable(err) {
		dht.lNodeUnreachable(n)
	}

	return nil
}
Example #4
0
File: krpc.go Project: hlandauf/dht
// sendMsg bencodes the data in 'query' and sends it to the remote node.
func sendMsg(conn *net.UDPConn, raddr net.UDPAddr, query interface{}) error {
	totalSent.Add(1)
	var b bytes.Buffer
	if err := bencode.Marshal(&b, query); err != nil {
		return err
	}
	if n, err := conn.WriteToUDP(b.Bytes(), &raddr); err != nil {
		if denet.ErrorIsPortUnreachable(err) {
			fmt.Println("DHT: port unreachable: ", err)
			return err
		}

		// all other errors are quashed
		//fmt.Println("DHT: node write failed:", err)
	} else {
		totalWrittenBytes.Add(int64(n))
	}
	return nil
}
Example #5
0
File: krpc.go Project: hlandauf/dht
// Read from UDP socket, writes slice of byte into channel.
func readFromSocket(socket *net.UDPConn,
	conChan chan packetType, unrChan chan net.UDPAddr, bytesArena arena, stop chan bool) {
	for {
		b := bytesArena.Pop()
		n, addr, err := socket.ReadFromUDP(b)
		b = b[0:n]
		if n == maxUDPPacketSize {
			// debug.Printf("DHT: Warning. Received packet with len >= %d, some data may have been discarded.\n", maxUDPPacketSize)
		}
		totalReadBytes.Add(int64(n))
		if n > 0 && err == nil {
			p := packetType{b, *addr}
			select {
			case conChan <- p:
				continue
			case <-stop:
				return
			}
		}

		if err != nil && denet.ErrorIsPortUnreachable(err) && addr != nil {
			fmt.Println("Marking unreachable: ", addr.String())
			unrChan <- *addr
		}

		// debug.Println("DHT: readResponse error:", err)

		// Do a non-blocking read of the stop channel and stop this goroutine if the channel
		// has been closed.
		select {
		case <-stop:
			return
		default:
		}
	}
}