Can cryptography be used to hide routing information from the router? If Alice wants to talk to Bob and she has to involve a third party system run by Carol to establish, and possibly maintain, communications, then Carol knows that Alice and Bob communicated with each other.

Chuck sneaks into Carol's exchange, and now knows that Alice and Bob are talking to each other.

Carol decides to start a new exchange with new technology, with the primary purpose of never knowing who is talking to who, and she needs to figure out how to do this.

If Carol runs an exchange that is unlimited communications (meaning no per-transaction billing) then she has no business need to know who talked to who, or for how long, as long as both ends are authenticated to her servers.

So the question is:

Is there a way for Carol to design her new network/exchange/endpoints so that her equipment can route and connect two individuals on that service without knowing who is talking to who?

Obviously the service would need to be handling a lot of traffic, and the traffic would need small random delays so you couldn't simply watch the time that Alice puts in a request to the time another request is output and assume that's her outgoing connection.

But I still don't see a way to handle the actual routing and call connection in a way that prevents anyone from seeing who is communicating to whom.

I'm wondering if there's some cryptographic principle or method that might help with this.  So far all my attempts result in one point in the process where both the sender and recipient are known.
The solution is called onion routing; the gist of it is that there are a number of anonymising servers; when Alice wants to send a message to Bob, she picks a random route through a number of the servers; she then repeatedly encrypts the message for each hop, and sends the encrypted message (which states only the first hop in the clear) to the first server.

The first server then decrypts the message, which reveals the second hop.  It then sends the message to the second hop (batching it with a number of other messages, so someone cannot correlate incoming and outgoing messages).

The second server, again, decrypts the message, which reveals the third hop; and then batch-forwards it to the third hop.

This continues until we get to the last server, which decrypts the message, which reveals the actual destination (Bob) it then batch-forwards it to B0b.

Bob then decrypts the message, this reveals the message that Alice originally sent.

There are a number of subtle points; these points are well studied in the literature.

Now, because of all the above 'batch-forwarding', this doesn't work for real-time communication; for messages that don't mind some unpredictable delay, it's workable.