Description
Runs provider-neutral TLS sessions over Flyology socket readiness.
A Connection provides ordinary synchronous Ada operations. Lightweight tasks suspend on WANT_READ or WANT_WRITE; native tasks block their pthread. The selected provider performs TLS and cryptography outside this package.
Example:
Take (OpenSSL, Socket, Client, "example.com", Secure);
Handshake (Secure, Timeout => 5.0);
Close
procedure Close (Item : in out Connection)
Cancel an active operation, destroy provider state, and close the socket. Provider state is destroyed before the descriptor. Concurrent callers wait for the same close. Closing a closed Item is harmless.
Parameters
- Item
Connection whose ownership is released
Raised exceptions
- Flyology
.IO.Sockets.Socket_Error The descriptor close fails
- TLS_Error
A downstream session violates the non-raising finalization contract; descriptor cleanup still completes
- Program_Error
Internal controller cleanup fails after the connection has been made unusable
Connection
type Connection is new Ada.Finalization.Limited_Controlled with private;
Sole closing owner of one connected socket and one provider session. Take transfers ownership. Finalize calls Close. Handshake, Receive, Send_All, and Shutdown are serialized. Close may run concurrently: it wakes the active operation, waits for it to release provider state, destroys the TLS session, then closes the descriptor. Other concurrent operations wait their turn. Take is the only non-concurrent operation: callers must give it exclusive access to a closed Connection. Operations queued behind an active provider call recheck cancellation and their original deadline at intervals of at most 10 milliseconds.
Create_Session
function Create_Session
(Item : in out Provider;
FD : Descriptor;
Side : Role;
Server_Name : String) return Session_Access
Create a nonblocking session borrowing FD. A client implementation must apply Server_Name to both SNI and certificate hostname verification. The session does not own or close FD. This factory must not perform network I/O or depend on FD already being in nonblocking mode.
Parameters
- Item
Initialized provider
- FD
Borrowed connected descriptor
- Side
Client or server role
- Server_Name
Verified DNS name for clients; empty for servers
Return value
Newly allocated provider session
Raised exceptions
- TLS_Error
Provider setup fails
Error_Message
function Error_Message (Item : Session) return String
Return the diagnostic for the most recent Failed result. The returned String owns its Ada value and remains valid across later provider calls.
Parameters
- Item
Failed session
Return value
Provider-specific diagnostic
Handshake
procedure Handshake
(Item : in out Connection;
Timeout : Duration := Infinite;
Token : access Flyology.Cancellation.Token := null)
Complete the TLS handshake. Negative Timeout means no limit and zero is an immediate poll. One monotonic deadline spans every provider retry. A lightweight caller suspends its task; a native caller blocks its pthread. Cancellation never destroys a session until the provider call has returned.
Parameters
- Item
Open TLS connection
- Timeout
Shared handshake deadline in seconds
- Token
Optional one-shot token that must outlive this call
Raised exceptions
- Operation_Cancelled
Token or concurrent Close interrupts
- Timeout_Error
The shared deadline expires
- Device_Error
Readiness polling fails
- TLS_Error
The provider rejects the handshake or peer
- Program_Error
Item is closed
Handshake_Step
function Handshake_Step
(Item : in out Session) return Step_Status
Execute one handshake step. Complete finishes the handshake; Want_Read and Want_Write request readiness; Failed supplies a provider diagnostic; Peer_Closed reports that the peer closed before completion.
Parameters
- Item
Session to advance
Return value
Provider progress state
Is_Available
function Is_Available (Item : Provider) return Boolean
Report whether provider code and configuration are ready for sessions.
Parameters
- Item
Provider to inspect
Return value
True when Create_Session can be attempted
Is_Open
function Is_Open (Item : Connection) return Boolean
Report whether Item owns a session and descriptor and is not closing.
Parameters
- Item
Connection to inspect
Return value
True while Item is usable
Name
function Name (Item : Provider) return String
Return a short stable provider name for diagnostics.
Parameters
- Item
Provider to identify
Return value
Provider name
Operation_Cancelled
Operation_Cancelled : exception renames
Flyology.Cancellation.Operation_Cancelled;
Raised when a token or concurrent Close interrupts an operation.
Provider
type Provider is limited interface;
Factory for provider sessions. Provider objects are initialized once and may create sessions concurrently. Provider finalization must serialize with Name, Is_Available, and Create_Session. A created Session must remain usable after the Provider object is finalized. Create_Session initializes protocol state but must not perform network I/O; descriptor operations begin only through the step functions after Take succeeds.
Receive
procedure Receive
(Item : in out Connection;
Data : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset;
Timeout : Duration := Infinite;
Token : access Flyology.Cancellation.Token := null)
Receive one decrypted chunk. Last is Data'First - 1 after an orderly close_notify. One deadline spans WANT_READ and WANT_WRITE retries. Lane, cancellation, and serialization behavior match Handshake.
Parameters
- Item
Handshaken TLS connection
- Data
Destination buffer
- Last
Last element received, or Data'First - 1 on close_notify
- Timeout
Shared operation deadline in seconds
- Token
Optional one-shot token that must outlive this call
Raised exceptions
- Operation_Cancelled
Token or concurrent Close interrupts
- Timeout_Error
The shared deadline expires
- Device_Error
Readiness polling fails
- TLS_Error
The provider reports protocol or transport failure
- Program_Error
Item is closed
Receive_Exactly
procedure Receive_Exactly
(Item : in out Connection;
Data : out Ada.Streams.Stream_Element_Array;
Timeout : Duration := Infinite;
Token : access Flyology.Cancellation.Token := null)
Fill Data under one deadline. An orderly close before Data is full is a TLS_Error. Lane and cancellation behavior match Handshake.
Parameters
- Item
Handshaken TLS connection
- Data
Destination buffer to fill
- Timeout
Shared sequence deadline in seconds
- Token
Optional one-shot token that must outlive this call
Raised exceptions
- Operation_Cancelled
Token or concurrent Close interrupts
- Timeout_Error
The shared deadline expires
- Device_Error
Readiness polling fails
- TLS_Error
The peer closes early or the provider fails
- Program_Error
Item is closed
Receive_Step
function Receive_Step
(Item : in out Session;
Data : out Ada.Streams.Stream_Element_Array;
Last : in out Ada.Streams.Stream_Element_Offset) return Step_Status
Execute one decrypted receive step. All Step_Status values are valid. Complete must return at least one byte; Peer_Closed represents close_notify. Want_Read, Want_Write, Peer_Closed, and Failed consume no buffer and leave Last unchanged.
Parameters
- Item
Session to read
- Data
Destination buffer
- Last
Last element produced, if any
Return value
Provider progress state
Role
type Role is (Client, Server);
TLS endpoint role.
Enumeration literals
- Client
Initiates a handshake and verifies Server_Name
- Server
Accepts a handshake using configured credentials
Send_All
procedure Send_All
(Item : in out Connection;
Data : Ada.Streams.Stream_Element_Array;
Timeout : Duration := Infinite;
Token : access Flyology.Cancellation.Token := null)
Encrypt and send all Data under one deadline. Partial provider progress and all WANT retries share that deadline. Lane, cancellation, and serialization behavior match Handshake.
Parameters
- Item
Handshaken TLS connection
- Data
Source buffer sent completely
- Timeout
Shared sequence deadline in seconds
- Token
Optional one-shot token that must outlive this call
Raised exceptions
- Operation_Cancelled
Token or concurrent Close interrupts
- Timeout_Error
The shared deadline expires
- Device_Error
Readiness polling fails
- TLS_Error
The provider or peer fails
- Program_Error
Item is closed
Send_Step
function Send_Step
(Item : in out Session;
Data : Ada.Streams.Stream_Element_Array;
Last : in out Ada.Streams.Stream_Element_Offset) return Step_Status
Execute one encrypted send step. All Step_Status values are valid; Peer_Closed means the peer closed before the send completed. Complete consumes at least one byte. Want_Read, Want_Write, Peer_Closed, and Failed consume no bytes, leave Last unchanged, and require the identical Data slice on retry.
Parameters
- Item
Session to write
- Data
Source buffer
- Last
Last element consumed, if any
Return value
Provider progress state
Session
type Session is abstract new Ada.Finalization.Limited_Controlled with
null record;
One provider-owned TLS session. Implementations must not perform a blocking descriptor operation: every would-block condition is returned as Want_Read or Want_Write. Operations on one Session are serialized by Flyology. Finalization must release provider state but must not close the borrowed descriptor or propagate an exception.
Session_Access
type Session_Access is access all Session'Class;
Owning access to one provider session; Flyology deallocates it after the active operation has drained and before closing the socket.
Shutdown
procedure Shutdown
(Item : in out Connection;
Timeout : Duration := Infinite;
Token : access Flyology.Cancellation.Token := null)
Exchange TLS close_notify alerts without closing the owned socket. One deadline spans the complete bidirectional shutdown and all WANT retries. A peer transport close without close_notify raises TLS_Error. Repeating Shutdown after success is harmless.
Parameters
- Item
Open TLS connection
- Timeout
Shared shutdown deadline in seconds
- Token
Optional one-shot token that must outlive this call
Raised exceptions
- Operation_Cancelled
Token or concurrent Close interrupts
- Timeout_Error
The shared deadline expires
- Device_Error
Readiness polling fails
- TLS_Error
The provider or peer fails shutdown
- Program_Error
Item is closed
Shutdown_Step
function Shutdown_Step
(Item : in out Session) return Step_Status
Execute one bidirectional close_notify step. Complete finishes shutdown; Want_Read and Want_Write request readiness; Failed supplies a provider diagnostic; Peer_Closed reports transport closure before the TLS shutdown completed.
Parameters
- Item
Session to shut down
Return value
Provider progress state
Step_Status
type Step_Status is
(Complete, Want_Read, Want_Write, Peer_Closed, Failed);
Result of one nonblocking provider operation.
Enumeration literals
- Complete
The operation completed, possibly with transferred bytes
- Want_Read
Retry after descriptor read readiness
- Want_Write
Retry after descriptor write readiness
- Peer_Closed
A valid TLS close_notify was received
- Failed
The session diagnostic describes a fatal failure
Take
procedure Take
(Backend : in out Provider'Class;
Socket : in out Flyology.IO.Sockets.Socket_Type;
Side : Role;
Server_Name : String;
Item : in out Connection)
Create a provider session and transfer Socket's sole closing ownership to Item. Socket becomes closed only after successful setup. Client sessions require a nonempty Server_Name so providers can perform SNI and hostname verification. Provider libraries are selected by Backend and may differ between connections. If setup fails, Socket keeps ownership, but its descriptor may already have been changed to nonblocking mode. Take must not run concurrently with any other operation on Item.
Parameters
- Backend
Initialized TLS provider
- Socket
Connected socket transferred on success
- Side
Client or server handshake role
- Server_Name
DNS name verified by a client; empty for a server
- Item
Closed connection that receives the socket and session
Raised exceptions
- TLS_Error
Provider setup fails or Backend is unavailable
- Flyology
.IO.Sockets.Socket_Error Preparing socket mode fails
- Program_Error
Item is open, Socket is invalid, or arguments do not match Side
TLS_Error
TLS_Error : exception;
Raised when a provider rejects configuration, a handshake, a record, or an alert. Exception messages contain the provider name and diagnostic.