init v0.1.0
This commit is contained in:
137
cmd/client/client.go
Normal file
137
cmd/client/client.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sudo-Ivan/reticulum-go/internal/config"
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/common"
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/identity"
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/transport"
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/destination"
|
||||
)
|
||||
|
||||
var (
|
||||
configPath = flag.String("config", "", "Path to config file")
|
||||
targetHash = flag.String("target", "", "Target destination hash")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var cfg *common.ReticulumConfig
|
||||
var err error
|
||||
|
||||
if *configPath == "" {
|
||||
cfg, err = config.InitConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize config: %v", err)
|
||||
}
|
||||
} else {
|
||||
cfg, err = config.LoadConfig(*configPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Enable transport by default for client
|
||||
cfg.EnableTransport = true
|
||||
|
||||
// Initialize transport
|
||||
transport, err := transport.NewTransport(cfg)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize transport: %v", err)
|
||||
}
|
||||
defer transport.Close()
|
||||
|
||||
// If target specified, establish connection
|
||||
if *targetHash != "" {
|
||||
destHash, err := identity.HashFromHex(*targetHash)
|
||||
if err != nil {
|
||||
log.Fatalf("Invalid destination hash: %v", err)
|
||||
}
|
||||
|
||||
// Request path if needed
|
||||
if !transport.HasPath(destHash) {
|
||||
fmt.Println("Requesting path to destination...")
|
||||
if err := transport.RequestPath(destHash, "", nil, true); err != nil {
|
||||
log.Fatalf("Failed to request path: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get destination identity
|
||||
destIdentity, err := identity.Recall(destHash)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to recall identity: %v", err)
|
||||
}
|
||||
|
||||
// Create destination
|
||||
dest, err := destination.New(
|
||||
destIdentity,
|
||||
destination.OUT,
|
||||
destination.SINGLE,
|
||||
"client",
|
||||
"direct",
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create destination: %v", err)
|
||||
}
|
||||
|
||||
// Enable and configure ratchets
|
||||
dest.SetRetainedRatchets(destination.RATCHET_COUNT)
|
||||
dest.SetRatchetInterval(destination.RATCHET_INTERVAL)
|
||||
dest.EnforceRatchets()
|
||||
|
||||
// Create link
|
||||
link := transport.NewLink(dest.Hash(), func() {
|
||||
fmt.Println("Link established")
|
||||
}, func() {
|
||||
fmt.Println("Link closed")
|
||||
})
|
||||
|
||||
defer link.Teardown()
|
||||
|
||||
// Set packet callback
|
||||
link.SetPacketCallback(func(data []byte) {
|
||||
fmt.Printf("Received: %s\n", string(data))
|
||||
})
|
||||
|
||||
// Start interactive loop
|
||||
go interactiveLoop(link)
|
||||
} else {
|
||||
fmt.Println("No target specified. Use -target <hash> to connect to a destination")
|
||||
return
|
||||
}
|
||||
|
||||
// Wait for interrupt
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigChan
|
||||
}
|
||||
|
||||
func interactiveLoop(link *transport.Link) {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
fmt.Print("> ")
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
fmt.Printf("Error reading input: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
input = strings.TrimSpace(input)
|
||||
if input == "quit" || input == "exit" {
|
||||
return
|
||||
}
|
||||
|
||||
if err := link.Send([]byte(input)); err != nil {
|
||||
fmt.Printf("Failed to send: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
117
cmd/reticulum/main.go
Normal file
117
cmd/reticulum/main.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sudo-Ivan/reticulum-go/internal/config"
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/transport"
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/interfaces"
|
||||
)
|
||||
|
||||
type Reticulum struct {
|
||||
config *config.ReticulumConfig
|
||||
transport *transport.Transport
|
||||
}
|
||||
|
||||
func NewReticulum(cfg *config.ReticulumConfig) (*Reticulum, error) {
|
||||
if cfg == nil {
|
||||
cfg = config.DefaultConfig()
|
||||
}
|
||||
|
||||
// Initialize transport
|
||||
t, err := transport.NewTransport(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Reticulum{
|
||||
config: cfg,
|
||||
transport: t,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *Reticulum) Start() error {
|
||||
// Initialize interfaces based on config
|
||||
for _, ifaceConfig := range r.config.Interfaces {
|
||||
var iface interfaces.Interface
|
||||
|
||||
switch ifaceConfig.Type {
|
||||
case "tcp":
|
||||
client, err := interfaces.NewTCPClient(
|
||||
ifaceConfig.Name,
|
||||
ifaceConfig.Address,
|
||||
ifaceConfig.Port,
|
||||
ifaceConfig.KISSFraming,
|
||||
ifaceConfig.I2PTunneled,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create TCP interface %s: %v", ifaceConfig.Name, err)
|
||||
continue
|
||||
}
|
||||
iface = client
|
||||
|
||||
case "tcpserver":
|
||||
server, err := interfaces.NewTCPServer(
|
||||
ifaceConfig.Name,
|
||||
ifaceConfig.Address,
|
||||
ifaceConfig.Port,
|
||||
ifaceConfig.PreferIPv6,
|
||||
ifaceConfig.I2PTunneled,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create TCP server interface %s: %v", ifaceConfig.Name, err)
|
||||
continue
|
||||
}
|
||||
iface = server
|
||||
|
||||
default:
|
||||
log.Printf("Unknown interface type: %s", ifaceConfig.Type)
|
||||
continue
|
||||
}
|
||||
|
||||
// Set packet callback to transport
|
||||
iface.SetPacketCallback(r.transport.HandlePacket)
|
||||
}
|
||||
|
||||
log.Printf("Reticulum initialized with config at: %s", r.config.ConfigPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Reticulum) Stop() error {
|
||||
if err := r.transport.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Initialize configuration
|
||||
cfg, err := config.InitConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize config: %v", err)
|
||||
}
|
||||
|
||||
// Create new reticulum instance
|
||||
r, err := NewReticulum(cfg)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create Reticulum instance: %v", err)
|
||||
}
|
||||
|
||||
// Start reticulum
|
||||
if err := r.Start(); err != nil {
|
||||
log.Fatalf("Failed to start Reticulum: %v", err)
|
||||
}
|
||||
|
||||
// Wait for interrupt signal
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigChan
|
||||
|
||||
// Clean shutdown
|
||||
if err := r.Stop(); err != nil {
|
||||
log.Printf("Error during shutdown: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user