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: krpc.go Project: hlandau/dht
// Read a message from the connection.
func Read(conn denet.UDPConn) (msg *Message, remoteAddr *net.UDPAddr, err error) {
	buf, remoteAddr, err := denet.ReadDatagramFromUDP(conn)
	if err != nil {
		return
	}

	msg, err = Decode(buf)
	return
}
Example #3
0
func (c *client) recvLoop() {
	for {
		buf, _, err := net.ReadDatagramFromUDP(c.conn)
		if err != nil {
			return
		}

		rbio := bufio.NewReader(bytes.NewReader(buf))
		res, err := http.ReadResponse(rbio, nil)
		if err == nil {
			c.handleResponse(res)
		}
	}
}
Example #4
0
func makeRequest(dst gnet.IP, opcode opcodeNo, data []byte) ([]byte, error) {
	conn, err := gnet.DialUDP("udp", nil, &gnet.UDPAddr{dst, hostToGatewayPort, ""})
	if err != nil {
		return nil, err
	}

	defer conn.Close()

	msg := make([]byte, 2)
	msg[0] = version0     // Version 0
	msg[1] = byte(opcode) // Opcode
	msg = append(msg, data...)

	rconf := backoff
	rconf.Reset()

	for {
		// here we use the 'delay' as the timeout
		maxtime := rconf.NextDelay()
		if maxtime == 0 {
			// max tries reached
			break
		}

		err = conn.SetDeadline(time.Now().Add(maxtime))
		if err != nil {
			return nil, err
		}

		_, err = conn.Write(msg)
		if err != nil {
			return nil, err
		}

		var res []byte
		var uaddr *gnet.UDPAddr
		res, uaddr, err = net.ReadDatagramFromUDP(conn)
		if err != nil {
			if err.(gnet.Error).Timeout() {
				// try again
				continue
			}
			return nil, err
		}

		if !uaddr.IP.Equal(dst) || uaddr.Port != hostToGatewayPort {
			continue
		}

		if len(res) < 4 {
			continue
		}

		if res[0] != 0 || res[1] != (0x80|byte(opcode)) {
			continue
		}

		rc := binary.BigEndian.Uint16(res[2:])

		if rc != 0 {
			return nil, fmt.Errorf("NAT-PMP: default gateway responded with nonzero error code %d", rc)
		}

		return res[4:], nil
	}

	return nil, natpmpErrTimeout
}