         self.recvAllocator = recvAllocator
         self._pipeline = ChannelPipeline(channel: self)
         // As the socket may already be connected we should ensure we start with the correct addresses cached.
-        self.localAddressCached.store(Box(try? socket.localAddress()))
-        self.remoteAddressCached.store(Box(try? socket.remoteAddress()))
+        self.addressesCached.store(Box((local: try? socket.localAddress(), remote: try? socket.remoteAddress())))
     }
 
     deinit {


    // This is `Channel` API so must be thread-safe.
    public final var localAddress: SocketAddress? {
        return self.localAddressCached.load().value
    }

    // This is `Channel` API so must be thread-safe.
    public final var remoteAddress: SocketAddress? {
        return self.remoteAddressCached.load().value
    }

    /// `false` if the whole `Channel` is closed and so no more IO operation can be done.


    internal final func updateCachedAddressesFromSocket(updateLocal: Bool = true, updateRemote: Bool = true) {
        assert(self.eventLoop.inEventLoop)
        assert(updateLocal || updateRemote)
        let cached = addressesCached.load().value
        let local = updateLocal ? try? self.localAddress0() : cached.local
        let remote = updateRemote ? try? self.remoteAddress0() : cached.remote
        self.addressesCached.store(Box((local: local, remote: remote)))
    }

    internal final func unsetCachedAddressesFromSocket() {
        assert(self.eventLoop.inEventLoop)
        self.addressesCached.store(Box((local: nil, remote: nil)))
    }

    public final func connect0(to address: SocketAddress, promise: EventLoopPromise<Void>?) {
