// 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 } } }
// 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 }
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) } } }
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 }