     }
 
     func socketDidClose(socket: TSTCPSocket) {
-        delegateCall {
+        queueCall {
             self.delegate?.didDisconnect(self)
+            self.delegate = nil
         }
     }
 
     func didReadData(data: NSData, from: TSTCPSocket) {
-        delegateCall {
+        queueCall {
             self.pendingReadData.appendData(data)
             self.checkReadData()
         }
     }
 
     func didWriteData(length: Int, from: TSTCPSocket) {
-        delegateCall {
+        queueCall {
             self.remainWriteLength -= length
             if self.remainWriteLength <= 0 {
 

import Foundation
import tun2socks

class TUNTCPSocket: RawTCPSocketProtocol, TSTCPSocketDelegate {
    let tsSocket: TSTCPSocket
    var readTag: Int?
    var pendingReadData: NSMutableData = NSMutableData()
    var writeTag: Int!
    var remainWriteLength: Int = 0
    var closeAfterWriting = false

    var sourceIPAddress: IPv4Address? {
        return IPv4Address(fromInAddr: tsSocket.sourceAddress.s_addr)
    }

    var sourcePort: Port? {
        return Port(port: tsSocket.sourcePort)
    }

    var destinationIPAddress: IPv4Address? {
        return IPv4Address(fromInAddr: tsSocket.destinationAddress.s_addr)
    }

    var destinationPort: Port? {
        return Port(port: tsSocket.destinationPort)
    }

    init(socket: TSTCPSocket) {
        tsSocket = socket
        tsSocket.delegate = self
    }

    private func delegateCall(block: ()->()) {
        dispatch_async(queue, block)
    }

    private func checkReadData() {
        if pendingReadData.length > 0 {
            delegateCall {
                // the didReadData might change the readTag
                guard let tag = self.readTag else {
                    return

            forceDisconnect()
        }
    }

    // MARK: TSTCPSocketDelegate implemention
    // The local stop sending anything.
