// Package transport provides an abstraction layer for different network transports package transport import ( "fmt" "net" "sync" ) // TransportType represents the type of network transport type TransportType int const ( TransportTor TransportType = iota TransportMesh TransportDirect ) // String returns string representation of transport type func (t TransportType) String() string { switch t { case TransportTor: return "Tor" case TransportMesh: return "Mesh" case TransportDirect: return "Direct" default: return "Unknown" } } // Transport defines the interface for network transports type Transport interface { // Connect establishes a connection to a remote peer Connect(address string) (net.Conn, error) // Listen starts listening for incoming connections Listen(address string) (net.Listener, error) // Type returns the transport type Type() TransportType // Close closes the transport Close() error } // TransportManager manages multiple transports type TransportManager struct { transports map[TransportType]Transport mu sync.RWMutex closed bool } // NewTransportManager creates a new transport manager func NewTransportManager() *TransportManager { return &TransportManager{ transports: make(map[TransportType]Transport), } } // RegisterTransport registers a new transport func (tm *TransportManager) RegisterTransport(transport Transport) error { tm.mu.Lock() defer tm.mu.Unlock() if tm.closed { return fmt.Errorf("transport manager is closed") } transportType := transport.Type() if _, exists := tm.transports[transportType]; exists { return fmt.Errorf("transport %s already registered", transportType) } tm.transports[transportType] = transport return nil } // GetTransport retrieves a transport by type func (tm *TransportManager) GetTransport(transportType TransportType) (Transport, error) { tm.mu.RLock() defer tm.mu.RUnlock() if tm.closed { return nil, fmt.Errorf("transport manager is closed") } transport, exists := tm.transports[transportType] if !exists { return nil, fmt.Errorf("transport %s not registered", transportType) } return transport, nil } // Connect connects using the specified transport func (tm *TransportManager) Connect(transportType TransportType, address string) (net.Conn, error) { transport, err := tm.GetTransport(transportType) if err != nil { return nil, err } return transport.Connect(address) } // Listen starts listening on the specified transport func (tm *TransportManager) Listen(transportType TransportType, address string) (net.Listener, error) { transport, err := tm.GetTransport(transportType) if err != nil { return nil, err } return transport.Listen(address) } // ListTransports returns all registered transport types func (tm *TransportManager) ListTransports() []TransportType { tm.mu.RLock() defer tm.mu.RUnlock() types := make([]TransportType, 0, len(tm.transports)) for transportType := range tm.transports { types = append(types, transportType) } return types } // Close closes all transports func (tm *TransportManager) Close() error { tm.mu.Lock() defer tm.mu.Unlock() if tm.closed { return nil } var lastErr error for transportType, transport := range tm.transports { if err := transport.Close(); err != nil { lastErr = fmt.Errorf("failed to close %s transport: %w", transportType, err) } } tm.transports = make(map[TransportType]Transport) tm.closed = true return lastErr } // Count returns the number of registered transports func (tm *TransportManager) Count() int { tm.mu.RLock() defer tm.mu.RUnlock() return len(tm.transports) } // String returns a string representation func (tm *TransportManager) String() string { tm.mu.RLock() defer tm.mu.RUnlock() return fmt.Sprintf("TransportManager(transports=%d, closed=%v)", len(tm.transports), tm.closed) }