To this I would like to add a third option: direct connection over UDP. For this we will need:

A NAT-2-NAT connection initator, as described in my earlier entry. This is coordinated over Jabber (working out both parties' IP, synchronizing the start of the connection attempts, password transfers).

A stream-over-UDP protocol. Possibly Airhook, though this has some problems (doesn't support packet reordering). I also have a mostly complete reliable messaging over UDP protocol of my own (source available on request), that could be trivially used for streaming data.

While we're reimplementing TCP, we may as well do it right. My UDP messaging protocol is designed for long fat pipes. None of this windowing nonsense as in TCP, each packet is ACKed (twice if doing so is cheap). An arbitrary number of messages may be in flight at once. Loosing a packet does not cause a resend of a whole chunk of packets, just the one that was lost.

Implementing NAT-2-NAT like this means we don't have to reinvent the wheel: Don't have to worry about the higher level negotiations of "I want to send you this file.", "Ok, go ahead", etc, as we would in a separate application. As Jabber adds capabilities like audio links, we get these for free too.