While supporting the same UGI interface, each Horus layer runs a different protocol. Applications may specify at run-time what stack (or stacks) of layers they wish to use (see figure 1). If an application wishes to use unreliable ATM communication, it specifies the COM:atm stack. If instead it wishes to use totally ordered UDP communication, it would specify the TOTAL:MBRSHIP:FRAG:NAK:COM:udp stack (these layers will be explained shortly).
As another example, a single test program can be used to test the functioning and performance of any set of layers, without recompilation or linking, but by changing a run-time argument. To test the performance of the FC:STABLE:MBRSHIP:FRAG:NAK:COM:atm stack it could be invoked as:
horus_test -s FC:STABLE:MBRSHIP:FRAG:NAK:COM:atmSuch a test program would create a Horus socket and use the ioctl system call to push the desired layering onto the socket (much like protocol modules on a System V stream). Horus allows parameters to be passed to layers. For example, if messages have to be fragmented to 1024 byte packets, an application specifies MBRSHIP:FRAG(size=1024):NAK:COM:atm.
Although Horus allows layers to be stacked in any order (and even multiple times), most layers require certain semantics from layers below it, imposing a partial order on the stacking. We will now describe some of the most important Horus layers roughly in the partial order from the lowest to the highest.