A circuit is a two-way UDP connection between two nodes, be they the viewer and the simulator, two simulators, or the simulator and a utility server.
Two kinds of circuits exist, trusted and untrusted. Circuits are built with no custom session management, so endpoint processes can and do sometimes disappear and restart. Due to this fact, it cannot be accurately predicted if one node trusts another since it may have restarted since it was last contacted.
All circuits begin as untrusted circuits, and all viewer to simulator connections are made through untrusted circuits. In the message template, messages are flagged as either trusted or untrusted. Any trusted message going over an untrusted circuit will be discarded by the receiving node.
Trusted circuits only exist between simulators themselves and/or utility servers. These circuits are established in response to the DenyTrustedCircuit message, using the CreateTrustedCircuit message and a specialized handshake protocol.
As all circuits are handled by the message system, a circuit is established by calling the enableCircuit function. If a circuit has not already been established, this function is in charge of creating one. While establishment of trust is also a parameter in circuit creation function, a trusted circuit will not be created unless the CreateTrustedCircuit message is sent using the correct handshake protocol.
Circuits are established at multiple points during a viewer session lifetime, including login, creation of child agents, and transfers between simulators (teleports or region crosses). Each of these circuits has multiple methods to make sure the connection is alive, as well as that it is sending/receiving correct data, including:
- Packet ID Checking
- Each packet has a 32-bit packet ID number that is incremented each time either node sends a message. The circuit is in charge of making sure this number is correct, as it aids in establishing reliable packets over UDP
- Further covered in Packet_Accounting
- A ping ID generated by one node and sent to the other using the StartPingCheck message, and starts a timer.
- The receiving node, assuming it still sees the circuit as valid, will retrieve the ID of the last unacknowledged packet (see Packet Accounting for more information on Packet Acknowledgment). It sends this ID as well as the original ping ID back to the sender in a CompletePingCheck message.
- On receiving the CompletePingCheck message, the sender stops its ping timer, and adds the time to the ping delay array
- Pings are sent on a timed loop. The ping system can trigger a block on a circuit. If the number of pings the circuit has in transit exceeds a threshold, the circuit will be marked as blocked, and will remain blocked until the number of pings in transit drops below the aforementioned threshold.
- If the blocked circuits is a viewer<->simulator circuits, the simulator will put the agent in a Paused state.