Well, fair enough. Let me explain a bit how it would be done. Finding the "first packets" is not as easy as you may think.
The two fields in the network protocol that matter are the destination address (DST) and the endpoint ID (EID). These identify the flow uniquely. I'll write this header as DST:EID.
So you find some packet that has, let's say 1000:100 as the header. Now, that flow was established at some point in the past with two packets, that are sent between components called the flow allocators. Flow allocator packets are all sent to a fixed EID, 1. So there will have been an exchange in the network of a packet with 1000:1, and a packet send back from 1000 to the source, SRC:1 (you don't know the source yet).
The contents of the first packet will be (relevant fields only)
1000:1:SRC:X
with SRC the source address, and X an endpoint ID chosen by the source. When the destination receives this, it generates its EID=100 and sends the following information to the source's flow allocator:
SRC:1:X:100
The source knows from X that the message is from 1000. This is enough information for both endpoints to know the <ADDR, EID> pair of their peers. An interceptor doesn't know SRC or X. You could look for all packets and find that "100" field, but how do you know it was sent by 1000?
It will take quite some traffic flow analysis to match these two packets. Probably it will be easier to try to match the actual data flows.
Now take into account that networks have multiple layers, and all flows are established this way.
It's definitely not impossible. But it's harder than just reading the first X bytes off a packet.
In most of our Ouroboros deployments (meaning: in the lab) we did just that. We use a raw packet interface (bpf on mac, raw sockets on linux) and send Ouroboros traffic on top of Ethernet.
The fun thing is that when we compared throughput to UDP/IP, Ouroboros is a bit slower for packets below 1460 bytes, because the NIC has something called "Generic Segment Offload (GSO)" which cheats a bit and send UDP traffic as larger chunks over the kernel boundary. We have no such optimization (yet). But when we started sending jumbo frames, Ouroboros was faster than UDP/IP over Ethernet because the GSO wasn't implemented for UDP jumbo frames (not pointing fingers, nobody does that).
And this brings me to another thing. Nitpicking of course. But that is what Ouroboros is about. Picking all the nits we could find. It's one for the connoisseurs.
Ethernet has a minimum frame size that is dictated by Layer 1 and has to do with collision detection and the transmission delay/cable length. For good ol' 10 base-T it's 64 bytes. For GbE the minimum frame size for Ethernet is 512 bytes. Small Ethernet frames under 64 bytes are called runt frames. Ethernet has a length field to allow for padding.
Now the interesting part in the standards. Ethernet frames are padded to 64 bytes. But GbE ethernet frames are not padded to 512 bytes. They use something called carrier extension (and frame bursting, but let's not complicate things too much).
So there is a Layer 1 problem (minimum frame size because of cable length). The original Ethernet "fixed" this with a LENGTH field in Layer 2. While the receiver was reading the correct amount of received bytes, if it was 64, it could mean a padded Ethernet frame. Ethernet II (DIX) made things worse. The Ethernet length field is now interpreted as an EtherType, indicating the Layer 3 protocol. And the layer 3 protocol now has to have a length field to fix the Layer 1 problem. Sigh.
GbE solves it right here, right now. It does carrier extension and reports the correct amount of bytes to layer 2. But it pads to 64 bytes for compatibility.
Ouroboros' protocols have no length field. Read the details on the heartbleed bug if you want to know why this matters.
I'm one of the developers. Thank you all for your interest in this project. This website is still under construction, and we're well aware that it's severely lacking in information, I'll try to find some time to update everything. Unfortunately marketing is not one of my skills.
The cleaner architecture is the whole point of the exercise.
I'm trying to avoid arguments why this would be "better" than anything else. Just some examples of things that I personally don't like about IP, and that Ouroboros does differently. These points may not matter to you, and that is perfectly fine. I'm not a salesman trying to make a sell.
1) IP (and Ethernet etc) has source addresses in every packet. Ouroboros negotiates them at the start of the communication, and only has the destination address in the packets. This improves end-user privacy a great deal.
2) The Ouroboros end-to-end protocol, (which has the RTT estimator and retransmisison timeout (RTO) timer), runs in the library between the actual server and client programs. It runs at sub-millisecond accuracy. If there is an underestimation of RTT, at worst it retransmits a few extra packets (See 3). But these improve the RTT estimate.
3) Default TCP congestion control doesn't play nice in lossy situations, having severe issues with throughput because of AIMD. Ouroboros completely splits the network and end-to-end protocol. Therefore the architecture only allows congestion control using Forward ECN at the network protocol (and only the network protocol). This is similar to the operation of DCTCP, but DCTCP has the ECN in the network protocol (IP), and the notification in the end-to-end protocol (TCP). I'm not fond of that as a solution (however, if I would run a commercial datacenter, I would run DCTCP, no doubt about that).
4) The Ouroboros end-to-end protocol is based on Delta-t, which doesn't require the 3-way handshake of TCP. It does have a two-way handshake (called flow allocation) to negotiate endpoints and the peer addresses (as to avoid sending src in every packet). But it can also do a ECDHE key exchange at that time. So it can establish an encrypted end-to-end connection in 1 RTT. The implementation still does it in 2 phases, (it's on my to-do list to piggyback the public keys).
5) Ouroboros has 2 types of layers, one for unicast and one for broadcast. This is where I think it really shines. The broadcast layer allows easy implementation of what is known as a "multicast service". A PoC is in the obc program.
Some of this may still seem nebulous, and I apologize. It's an unfunded pet project. But if I find interested people that ask interested questions, it will help me to update the documentation and make things more digestible/palatable.
Sorry, my response was rather cryptic. I was more referring to the interface having both an L2 and L3 address. From an academic perspective, I agree with OP that assigning the L3 address to the interface probably causes more problems than it solves. MPTCP provides workaround over L4 to what is essentially an L3 problem. But it would take a huge architectural change to go back to assigning addresses to L3 hosts.
Just to provide my 2 cents on the issue:
There are a lot of things at play... Rekhter's law ("Addressing can follow topology or topology can follow addressing. Choose one.") doesn't combine well with the fact that it's not desirable to have end-hosts participate in routing updates. When these two are taken together, they have implications on scalability of any routing solution, especially in the cases of end-host mobility and multihoming.
When the "topology follows addressing" (like TCP/IP), the constraint of not wanting to advertise the end-host address (as someone mentioned, no ISP will accept your /32 on BGP) assigning the end-host a different address per attached network is the simplest solution. This indeed boils down to the assigning L3 addresses to the interface. The TCP connection problem can be handled by tunnels (as is the case in Mobile IP or LISP) but tunnels are rather expensive since the tunnel endpoint in the network has to maintain al lot of state.
In the case of "addressing follows topology", changes in topology, when taking the constraint of not advertising end-hosts via routing, requires address renumbering of the network elements.
So, when taken as a pure L3 problem, it boils down to choosing which problem to solve: constantly tracking the end-hosts, or constantly renumbering the network.
The latter, when used in combination with recursive network layering, shows quite some promise. It requires less addresses, but I know from experience that it's not the easiest idea to sell.
MPTCP provides a pragmatic workaround on top of L4 that doesn't require tunnels. It's a shame that it's not completely transparent to the applications (it requires explicit code changes to enable).I agree with a lot of the concerns of getting this upstream in the kernel. I tried to play around with it a couple of times, but the distribution as a full kernel was a bit of a roadblock. Would be easier if it was distributed as a kernel patch. And it seems perfectly doable to implement it in user space, that might further speed up adoption.
https://ouroboros.rocks/docs/overview/