     
     fileprivate func bailOn(socket: GCDAsyncSocket?, peer: BPPeer) {
         peer.state = .notConnected
+        peer.announced = false
         socket?.synchronouslySetDelegate(nil)
         socket?.disconnect()
         peer.socket = nil

            peer.announced = true
        }
        
        self.dispatch_on_delegate_queue({
            delegate.browserFoundPeer?(role, peer: peer, customData: (customData.isEmpty ? nil : customData), inviteBlock: { (timeoutForInvite) in
                do {
                    // pick the address to connect to INSIDE the block, because more addresses may have been added between announcement and inviteBlock being executed
                    guard let hhaddresses = peer.dnsService?.resolvedAddressInfo, hhaddresses.count > 0, var chosenAddress = hhaddresses.filter({ $0.isCandidateAddress(bluetoothOnly: limitToBluetooth) }).first else {
                        DLog("BluepeerObject inviteBlock: no resolvedAddresses or candidates after invite accepted/rejected, BAILING")
                        return
                    }
                    
                    // if we can use wifi, then use wifi if possible
                    if !self.bluetoothOnly && !chosenAddress.isWifiInterface() {
                        let wifiCandidates = hhaddresses.filter({ $0.isCandidateAddress(bluetoothOnly: self.bluetoothOnly) && $0.isWifiInterface() })
                        if wifiCandidates.count > 0 {
                            chosenAddress = wifiCandidates.first!
                        }
                    }
                    
                    DLog("BluepeerObject inviteBlock: peer has \(hhaddresses.count) addresses, chose \(chosenAddress.addressAndPortString) on interface \(chosenAddress.interfaceName)")
                    let sockdata = chosenAddress.socketAsData()

                    // TODO: when migrating Wifibooth, blueprint: make sure browserFoundPeer calls stopBrowsing()!
                    // 1.1: don't stop browsing automatically, delegate must do that now
//                    self.stopBrowsing() // stop browsing once user has done something. Destroys all HHService except this one!
                    
                    if let oldSocket = peer.socket {
                        DLog("**** BluepeerObject: PEER ALREADY HAD SOCKET, DESTROYING...")
                        oldSocket.synchronouslySetDelegate(nil)
                        oldSocket.disconnect()
                        peer.socket = nil
                    }
                    
                    peer.socket = GCDAsyncSocket.init(delegate: self, delegateQueue: self.socketQueue)
                    peer.socket?.isIPv4PreferredOverIPv6 = false
                    peer.state = .connecting
                    try peer.socket?.connect(toAddress: sockdata, viaInterface: chosenAddress.interfaceName, withTimeout: timeoutForInvite)
                } catch {
                    DLog("BluepeerObject: could not connect.")
                }
            })
        })
    }
    

            name = name!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) // sender pads with spaces to 32 bytes
            peer.displayName = self.sanitizeCharsToDNSChars(str: name!) // probably unnecessary but need to be safe
            
            // we're the server. If we are advertising and browsing for the same serviceType, there might be a duplicate peer situation to take care of -- one created by browsing, one when socket was accepted. Remedy: kill old one, keep this one
            for existingPeer in self.peers.filter({ $0.displayName == peer.displayName && $0 != peer }) {
                if let indexOfPeer = self.peers.index(of: existingPeer) {
                    DLog("BluepeerObject: removing dupe peer \(self.peers[indexOfPeer].displayName) from index \(indexOfPeer), had socket: \(self.peers[indexOfPeer].socket != nil ? "ACTIVE" : "nil"). Peers(n=\(self.peers.count)) after adding:")
                    DLog(self.peers)
                    
                    self.peers.remove(at: indexOfPeer)
                }
                self.bailOn(socket: existingPeer.socket, peer: existingPeer)
