_onConnection (conn, type) {
    const self = this

    // If the connection has already been closed before the `connect` event is fired,
    // then `remoteAddress` will not be available, and we can't use this connection.
    // - Node.js issue: https://github.com/nodejs/node-v0.x-archive/issues/7566
    // - WebTorrent issue: https://github.com/webtorrent/webtorrent/issues/398
    if (!conn.remoteAddress) {
      conn.on('error', noop)
      conn.destroy()
      return
    }

    self._pendingConns.add(conn)
    conn.once('close', cleanupPending)

    const peer = type === 'utp'
      ? Peer.createUTPIncomingPeer(conn, this._client.throttleGroups)
      : Peer.createTCPIncomingPeer(conn, this._client.throttleGroups)

    const wire = peer.wire
    wire.once('pe3', onPe3)
    wire.once('handshake', onHandshake)

    async function onPe3 (infoHashHash) {
      const torrent = await self._client._getByHash(infoHashHash)
      if (torrent) {
        peer.swarm = torrent
        torrent._addIncomingPeer(peer)
        peer.onPe3(infoHashHash)
      } else {
        peer.destroy(new Error(`Unexpected info hash hash ${infoHashHash} from incoming peer ${peer.id}`))
      }
    }

    async function onHandshake (infoHash, peerId) {
      cleanupPending()

      const torrent = await self._client.get(infoHash)
      // only add incoming peer if didn't already do so in protocol encryption handshake
      if (torrent) {
        if (!peer.swarm) {
          peer.swarm = torrent
          torrent._addIncomingPeer(peer)
        }
        peer.onHandshake(infoHash, peerId)
      } else {
        const err = new Error(
          `Unexpected info hash ${infoHash} from incoming peer ${peer.id}`
        )
        peer.destroy(err)
      }
    }

    function cleanupPending () {
      conn.removeListener('close', cleanupPending)
      wire.removeListener('handshake', onHandshake)
      if (self._pendingConns) {
        self._pendingConns.delete(conn)
      }
    }
  }
On incoming connections, we expect the remote peer to send a handshake first. Based
on the infoHash in that handshake, route the peer to the right swarm.