code: def _do_query(self, query, iph, eth, in_port, msg):
          
          datapath = msg.datapath
          dpid = datapath.id
          ofproto = datapath.ofproto
          parser = datapath.ofproto_parser
  
          # learn the querier.
          self._to_querier[dpid] = {
              'port': in_port,
              'ip': iph.src,
              'mac': eth.src
          }
  
          # set the timeout time.
          timeout = igmp.QUERY_RESPONSE_INTERVAL
          if query.maxresp:
              timeout = query.maxresp / 10
  
          self._to_hosts.setdefault(dpid, {})
          if query.address == '0.0.0.0':
              # general query. reset all reply status.
              for group in self._to_hosts[dpid].values():
                  group['replied'] = False
                  group['leave'] = None
          else:
              # specific query. reset the reply status of the specific
              # group.
              group = self._to_hosts[dpid].get(query.address)
              if group:
                  group['replied'] = False
                  group['leave'] = None
  
          actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]
          self._do_packet_out(
              datapath, msg.data, in_port, actions)
  
          # wait for REPORT messages.
          hub.spawn(self._do_timeout_for_query, timeout, datapath)
docs: the process when the snooper received a QUERY message.