def handlePacket_IQ(self, ad, data):
        # Initialization Request; someone else is trying to get online
        (kind, myip, port
         ) = self.decodePacket('!2s4sH', data)

        if port == 0:
            raise BadPacketError("Zero Port")

        # The IPPort which is allegedly mine
        my_ad = Ad().setRawIP(myip)
        my_ad.port = self.main.state.udp_port

        # src_ad is supposed to be the sender node's "true external IPPort"
        src_ad = Ad()
        src_ad.port = port

        if ad.isPrivate() and my_ad.auth('sx', self.main):
            # If the request came from a private IP address, but was sent
            # toward a public IP address, then assume the sender node also
            # has the same public IP address.
            src_ad.ip = my_ad.ip
        else:
            src_ad.ip = ad.ip

        if not src_ad.auth('sx', self.main):
            ip_code = CODE_IP_FOREIGN
        elif not src_ad.auth('b', self.main):
            ip_code = CODE_IP_BANNED
        else:
            ip_code = CODE_IP_OK

        osm = self.main.osm
        state = self.main.state

        # Provide a max of 48 addresses in a normal response,
        # 8 addresses in a little cache response
        IR_LEN = 48
        IC_LEN = 8

        # Lists of stuff
        node_ipps = []
        ir_nodes = []
        ir_peercache = []
        ic_peercache = []

        if ip_code != CODE_IP_OK:
            # For invalid IPs, send no neighbors, and a small peercache
            # just so they can try for a second opinion.
            IR_LEN = IC_LEN

        elif osm and osm.syncd:
            # Get a random sample of online nodes (plus me).
            indices = xrange(len(osm.nodes) + 1)
            try:
                indices = random.sample(indices, IR_LEN)
            except ValueError:
                pass

            # Remap the list of indices into a list of ipps.
            # For the one out-of-bounds index, fill in 'me'.
            def get_ipp(i):
                try:
                    return osm.nodes[i].ipp
                except IndexError:
                    return osm.me.ipp
            node_ipps = [get_ipp(i) for i in indices]

        elif osm:
            # Not syncd yet, don't add any online nodes
            pass

        elif (self.main.reconnect_dcall and self.main.accept_IQ_trigger
              and my_ad.auth('sx', self.main)):
            # If we've recently failed to connect, then go online
            # as the sole node on the network.  Then report our node ipp
            # so this other node can try to join us.

            self.main.addMyIPReport(src_ad, my_ad)
            self.main.startNodeSync(())

            osm = self.main.osm
            node_ipps = [osm.me.ipp]

        # Get my own IPP (if I know it)
        if osm:
            my_ipp = osm.me.ipp
        else:
            my_ipp = None

        now = time.time()

        # For each node, add its ip:port, and age.
        for ipp in node_ipps:
            if ipp == my_ipp:
                age = 0
            else:
                try:
                    age = max(now - state.peers[ipp], 0)
                except KeyError:
                    # If the entry has expired from the cache
                    # (not very likely), then assume 1 hour
                    age = 60*60

            ir_nodes.append(struct.pack('!6sI', ipp, int(age)))

        # Convert node_ipps into a set, for O(1) lookups
        node_ipps = set(node_ipps)

        # Grab the youngest peers in our cache.
        for when,ipp in state.getYoungestPeers(IR_LEN):

            # Add packet data to the outlist
            age = max(int(now - when), 0)

            pc_entry = struct.pack('!6sI', ipp, int(age))

            if (len(node_ipps) + len(ir_peercache) < IR_LEN and
                    ipp not in node_ipps):
                ir_peercache.append(pc_entry)

            if len(ic_peercache) < IC_LEN:
                ic_peercache.append(pc_entry)

        # === IC response packet ===
        packet = ['IC']

        # My IPPort
        packet.append(my_ad.getRawIPPort())

        # Add 4-byte sender's IP address
        packet.append(src_ad.getRawIP())

        # Add 1-byte flag: 1 if IP is invalid
        packet.append(struct.pack('!B', ip_code))

        # Add the peercache list
        packet.append(struct.pack('!B', len(ic_peercache)))
        packet.extend(ic_peercache)

        # Send IC packet to alternate port, undo NAT remapping
        if ad.orig_ip:
            ad.ip = ad.orig_ip
        self.sendPacket(''.join(packet), ad.getAddrTuple())


        # === IR response packet ===
        packet = ['IR']

        # My IPPort
        packet.append(my_ad.getRawIPPort())

        # Add to packet: 4-byte sender's IP address
        packet.append(src_ad.getRawIP())

        # Add 1-byte flag: 1 if IP is invalid
        packet.append(struct.pack('!B', ip_code))

        # Add the node list
        packet.append(struct.pack('!B', len(ir_nodes)))
        packet.extend(ir_nodes)

        # Now add the peercache list
        packet.append(struct.pack('!B', len(ir_peercache)))
        packet.extend(ir_peercache)

        # Send IR packet to dtella port
        self.sendPacket(''.join(packet), src_ad.getAddrTuple())

        # Update the sender in my peer cache (if valid)
        self.main.state.refreshPeer(src_ad, 0)