DownloadPoint Routing & Transit Proposal
DRAFT DOCUMENT
This proposal is a draft document generated by AI and may not have been reviewed for accuracy. The technical details, implementation estimates, and architectural decisions described herein should be validated by experienced developers familiar with FidoNet protocols and the BinktermPHP codebase before implementation.
Overview
This document outlines the requirements and implementation plan for adding point node support and mail transit capabilities to BinktermPHP.
Current State
The system currently operates as an endpoint - it only processes mail addressed to/from its own node address. Mail destined for other addresses is not handled.
What Transit Would Add
1. Point Node Support
Points are subordinate nodes with addresses like 1:153/149.1, 1:153/149.2 (boss node address + point number).
Required Components:
- Point registration system (which points belong to your node)
- Authentication for point connections
- Point-specific routing rules
- Mail queueing for offline points
2. Routing Engine
New Components:
PacketRouter class:
- analyzeDestination(address) - determine if mail is for you, a point, or transit
- getRoute(address) - figure out which uplink/downlink should receive it
- canRoute(address) - check if you're authorized to route to this destination
- queueForTransit(packet, destination) - hold mail for forwarding
Database Changes:
-- Points registered under this node
CREATE TABLE points (
id SERIAL PRIMARY KEY,
point_number INTEGER NOT NULL,
full_address VARCHAR(50) NOT NULL,
boss_address VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
owner_name VARCHAR(100),
enabled BOOLEAN DEFAULT true,
last_connection TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(full_address)
);
-- Mail awaiting transit/forwarding
CREATE TABLE transit_queue (
id SERIAL PRIMARY KEY,
packet_data BYTEA NOT NULL,
from_address VARCHAR(50) NOT NULL,
to_address VARCHAR(50) NOT NULL,
destination_address VARCHAR(50) NOT NULL, -- Where to forward it
message_type VARCHAR(20), -- netmail, echomail
priority INTEGER DEFAULT 5,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
forwarded_at TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending' -- pending, sent, failed
);
-- Custom routing rules (optional, for advanced routing)
CREATE TABLE routing_rules (
id SERIAL PRIMARY KEY,
address_pattern VARCHAR(50) NOT NULL, -- e.g., "1:153/149." or "1:153/"
route_via VARCHAR(50) NOT NULL, -- Which uplink/point to send through
priority INTEGER DEFAULT 5,
enabled BOOLEAN DEFAULT true,
notes TEXT
);
3. Packet Processing Changes
Current Flow: Inbound packet ? Parse ? If for me: store in DB ? Done
With Transit: Inbound packet ? Parse ? Route decision:
?? For me ? Store in messages DB
?? For my point ? Store in transit_queue
?? For other system ? Route to uplink (if transit allowed)
?? Unknown destination ? Bounce/return to sender or hold
Implementation:
class PacketProcessor {
public function processMessage($message) {
$destination = $message['to_address'];
// Check if it's for this system
if ($this->isForMe($destination)) {
$this->storeLocalMessage($message);
return;
}
// Check if it's for one of our points
if ($this->isMyPoint($destination)) {
$this->queueForPoint($message, $destination);
return;
}
// Check if we allow transit routing
if ($this->config->allow_full_routing) {
$route = $this->router->getRoute($destination);
if ($route) {
$this->queueForTransit($message, $route);
return;
}
}
// Destination unknown or not routable
$this->handleUnroutable($message);
}
}
4. Binkp Server Updates
New Functionality:
// In binkp_server.php
// Authenticate points (not just uplinks)
function authenticatePoint($address, $password) {
// Check points table
// Verify password matches
// Return point configuration
}
// Send outbound mail for specific points when they connect
function getOutboundForPoint($pointAddress) {
// Query transit_queue for mail to this point
// Bundle into packets
// Return list of files to send
}
// Accept inbound mail destined for points
function processInboundForPoints($packet) {
// Parse packet
// Route messages to transit_queue if for other points
}
// Handle point-specific flags (CM, ICM, etc.)
function handlePointCapabilities($point, $capabilities) {
// Points may have limited connectivity
// Adjust session behavior accordingly
}
5. Mail Bundling for Points
New Script: scripts/bundle_point_mail.php
// Check transit_queue for mail to each point
// Create .pkt files for each point
// Archive into .su0, .mo0, etc. bundles based on day
// Flag as "ready to send" when point connects
// Clean up old sent bundles
Example:
- Point 1:153/149.1 has 5 netmails waiting
- Create 00010001.pkt with those messages
- Bundle into 00010001.su0 (Saturday)
- Store in data/outbound/point.1/
- When point connects, send the bundle
6. Security & Policy
Critical Decisions:
-
Routing Scope
- Points only (safest)
- Full transit for specific networks
- Open relay (not recommended)
-
Authentication
- Session passwords for points
- Address verification
- Maximum failed login attempts
-
Resource Limits
- Bandwidth per point
- Maximum queue size per point
- Maximum message size
- Maximum age for queued mail
-
Error Handling
- Bounce undeliverable mail vs. hold
- Notify sender of routing failures
- Loop detection (don't route mail in circles)
7. Configuration
New Config File: config/transit.json
{
"allow_transit": true,
"allow_points": true,
"allow_full_routing": false,
"max_point_number": 999,
"max_queue_age_days": 30,
"max_queue_size_mb": 100,
"bounce_unroutable": true,
"points": [
{
"address": "1:153/149.1",
"password": "secret123",
"owner": "Alice Smith",
"enabled": true,
"max_queue_mb": 10,
"notes": "Alice's home system"
},
{
"address": "1:153/149.2",
"password": "secret456",
"owner": "Bob Jones",
"enabled": true,
"max_queue_mb": 10,
"notes": "Bob's BBS"
}
],
"routing_rules": [
{
"pattern": "1:153/149.*",
"action": "queue_for_point",
"enabled": true
},
{
"pattern": "1:153/*",
"action": "forward_to_hub",
"hub_address": "1:153/0",
"enabled": false
}
]
}
8. Implementation Files
New Files:
- src/BinkP/PacketRouter.php - Core routing engine
- src/BinkP/PointManager.php - Point registration/management
- src/BinkP/TransitQueue.php - Transit queue operations
- scripts/bundle_point_mail.php - Create outbound bundles for points
- scripts/cleanup_transit.php - Remove old/sent transit mail
- config/transit.json - Transit configuration
Modified Files:
- scripts/binkp_server.php - Add point authentication and routing
- src/BinkP/BinkPSession.php - Handle point-specific sessions
- src/BinkP/PacketProcessor.php - Add routing logic to message processing
- src/BinkP/BinkPMailer.php - Support point-specific outbound queues
Database Migrations:
- database/migrations/v1.x.x_add_points_table.sql
- database/migrations/v1.x.x_add_transit_queue.sql
- database/migrations/v1.x.x_add_routing_rules.sql
9. Complexity & Effort Estimate
Complexity Level: Medium (3/5)
Estimated Effort:
- Point-only mode: 1 week
- Full transit with routing: 2 weeks
- Testing & debugging: 1 week
Risk Assessment:
- Medium Risk: Routing errors could result in lost or misrouted mail
- Mitigation: Extensive logging, test mode, mail backup before routing
Dependencies:
- Existing packet processing must be stable
- Database performance for queue operations
- Understanding of FidoNet routing semantics
Implementation Approaches
Approach A: Point-Only Mode (Recommended)
Scope:
- Only route for your own points (e.g., 1:153/149.x)
- Don't route for other nodes
- Simpler security model
- Less risk of mail loss
Advantages:
- 40% of the development effort
- Covers most common use case
- Lower risk
- Easier to test
Use Cases:
- Users want to run a point off your BBS
- Family/friends want FidoNet addresses under your node
- Testing/development points
Approach B: Full Transit Capability
Scope:
- Route for points AND other systems
- Configurable routing rules
- Support for complex network topologies
- Hub/gateway functionality
Advantages:
- Full FidoNet routing capabilities
- Can act as regional hub
- Supports complex network configurations
Disadvantages:
- More complex
- Higher risk
- Requires deep FidoNet routing knowledge
- More configuration required
Next Steps
-
Decision Required:
- Point-only or full transit?
- Timeline and priority
-
Design Phase:
- Finalize database schema
- Design routing algorithm
- Security model review
-
Implementation Phase:
- Database migrations
- Core routing engine
- BinkP server integration
- Bundling scripts
-
Testing Phase:
- Unit tests for routing logic
- Integration tests with real points
- Error handling and edge cases
-
Documentation:
- Point setup guide
- Routing configuration guide
- Troubleshooting guide
References
-
FTS-0001: Basic FidoNet Technical Standard
-
FTS-0005: The distribution nodelist
-
FidoNet routing best practices
-
Existing implementations (Binkd, Argus, etc.)
Questions for Consideration
-
Should points have web UI access or BinkP-only?
-
How do we handle echomail for points? (Subscribe independently or inherit from boss?)
-
What happens when a point is unreachable for extended periods?
-
Should points have message quotas?
-
Do we need a point administration UI for users?
Document Status: Draft Proposal
Last Updated: 2026-01-30
Author: AI-Generated (Requires Review)
|