Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
UppHub
Status & Roadmap
FAQ
Authors & License
Forums
Funding U++
Search on this site









SourceForge.net Logo

SourceForge.net Logo

GitHub Logo

Discord Logo

Design Notes


Table of Contents

 

1. Overview

2. Architectural Model

3. Execution Model

4. State Model

5. Error Handling Strategy

6. Threading Model

7. Memory Model

8.  Identity & RTTI

9. Subsystem Responsibilities

10. Design Principles

 


1. Overview

The SSH package is a layered, RAII-driven wrapper around libssh2, designed to integrate naturally with the U++ ecosystem.

Its goals:

Provide a unified object-oriented SSH abstraction

Preserve libssh2’s flexibility without exposing its procedural complexity

Support both GUI and console applications

Be cross-platform (POSIX + Windows)

Support multithreading

Follow U++ idioms (pick semantics, Event, RTTI, memory manager)

At the center of the architecture is the Ssh base class (the “core” abstraction).


2. Architectural Model

2.1 Layered Design

Ssh (Core)

├── SshSession

│    ├── SshChannel

│    │    ├── Scp

│    │    ├── SshExec

│    │    ├── SshShell

│    │    └── SshTunnel

│    └── SFtp

│         └── SFtpStream

└── SshHosts

2.2 Responsibilities by Layer

The Ssh class provides:

State machine

Error handling

Timeout handling

Abort support

Thread synchronization

Event-driven wait loop

Common diagnostics/tracing

Polymorphic base (RTTI-enabled)

It encapsulates:

LIBSSH2_SESSION*

Socket state

Timing state

Error state

Status flags (IDLE, WORKING, FAILED, ABORTED)

It does not represent a concrete SSH entity. It represents the execution model.


3. Execution Model

3.1 Cooperative Run Loop

Core execution is handled by:

bool Ssh::Run(Gate<>&& fn, bool abortable)

Design intent:

Wrap libssh2’s non-blocking behavior

Centralize timeout and abort checks

Serialize critical SSH operations

Ensure proper socket direction handling

Flow:

Set status = WORKING

Record start time

Repeatedly:

Validate timeout

Validate abort

Validate socket state

Lazily initialize session

Execute user-provided operation

Call Wait() if libssh2 indicates blocking

Transition to IDLE or FAILED

This abstracts libssh2’s EAGAIN-style state machine into a higher-level loop.

3.2 Wait Strategy

 

void Ssh::Wait()

Uses:

libssh2_session_block_directions()

SocketWaitEvent

WAIT_READ / WAIT_WRITE mask

Configurable wait step

Design goals:

Respect non-blocking semantics

Avoid busy looping

Integrate cleanly with U++ event loop

Support both console and GUI contexts


4. State Model

Core states:

IDLE

WORKING

FAILED

ABORTED

Transitions:

IDLE → WORKING (Run begins)

WORKING → IDLE (Success)

WORKING → FAILED (Error)

WORKING → ABORTED (User abort)

Abort is cooperative:

Sets status flag

Next Run iteration throws


5. Error Handling Strategy

Errors are captured via:

    struct Error : Exc

Properties:

Numeric error code

Descriptive message

Propagated via exceptions

Normalized into internal state via SetError()

This ensures:

Consistent error propagation

Clean user-facing API

libssh2 error translation

All public operations return status via operator bool(), IsError(), GetError(), GetErrorDesc()


6. Threading Model

Key aspects:

Static global mutex protects critical operations

Designed for multithreaded usage at object level

Internal operations are serialized

This design ensures:

No race conditions inside libssh2 calls

Controlled concurrency model

Predictable behavior under load


7. Memory Model

RAII-based lifecycle

Pick semantics supported

Compatible with U++ memory manager

Optional native malloc mode

Object lifetime is deterministic.

Resources (session, channel, socket) are released in destructors.


8. Identity & RTTI

Supports:

Polymorphic storage

Runtime casting via To<T>()

Type checking via Is<T>()

Design goal: safe polymorphism without losing performance.


 


9. Subsystem Responsibilities

SshSession

Authentication

Handshake

Agent support

Known hosts verification

Proxy support

SshChannel

Abstract channel handling

Shared channel lifecycle logic

Derived specializations:

Scp → file transfer

SshExec → command execution

SshShell → interactive shell + X11

SshTunnel → port forwarding

SFtp

Subsystem initialization

Directory traversal

File operations

Stream interface (SFtpStream)

SshHosts

Known host verification

Host fingerprint management


 


10. Design Principles

Non-blocking core wrapped in controlled blocking loop

RAII discipline

Clear separation of session vs channel vs subsystem

Cross-platform behavior abstraction

Debug traceability at object granularity

Avoid leaking libssh2 procedural complexity to users

Do you want to contribute?