code: func (s *Server) Announce(infoHash [20]byte, port int, impliedPort bool) (*Announce, error) {
  	startAddrs, err := s.traversalStartingNodes()
  	if err != nil {
  		return nil, err
  	}
  	a := &Announce{
  		Peers:               make(chan PeersValues, 100),
  		values:              make(chan PeersValues),
  		triedAddrs:          newBloomFilterForTraversal(),
  		server:              s,
  		infoHash:            int160FromByteArray(infoHash),
  		announcePort:        port,
  		announcePortImplied: impliedPort,
  		contactRateLimiter:  make(chan struct{}, 10),
  	}
  	a.ctx, a.cancel = context.WithCancel(context.Background())
  	a.stop = a.ctx.Done()
  	a.nodesPendingContact.target = int160FromByteArray(infoHash)
  	a.nodeContactorCond.L = &a.mu
  	go a.rateUnlimiter()
  	// Function ferries from values to Values until discovery is halted.
  	go func() {
  		defer close(a.Peers)
  		for {
  			select {
  			case psv := <-a.values:
  				select {
  				case a.Peers <- psv:
  				case <-a.stop:
  					return
  				}
  			case <-a.stop:
  				return
  			}
  		}
  	}()
  	for _, n := range startAddrs {
  		a.pendContact(n)
  	}
  	a.maybeClose()
  	go a.nodeContactor()
  	return a, nil
  }
docs: // This is kind of the main thing you want to do with DHT. It traverses the
  // graph toward nodes that store peers for the infohash, streaming them to the
  // caller, and announcing the local node to each node if allowed and
  // specified.