package main import ( "encoding/json" "errors" "flag" "fmt" "io" "os" "time" "git.virebent.art/virebent/yamnweb/katzenpost/dispatcher" "github.com/katzenpost/hpqc/hash" clientconfig "github.com/katzenpost/katzenpost/client/config" "github.com/katzenpost/katzenpost/client/thin" ) const capability = "yamn-dispatch-v1" func run() error { var configPath string var settle time.Duration flag.StringVar(&configPath, "config", "thinclient.toml", "thin-client configuration") flag.DurationVar(&settle, "settle", 2*time.Second, "time allowed for kpclientd to queue frames") flag.Parse() input, err := io.ReadAll(io.LimitReader(os.Stdin, dispatcher.MaxEnvelopeBytes*2)) if err != nil { return fmt.Errorf("read envelope: %w", err) } var envelope dispatcher.Envelope if err := json.Unmarshal(input, &envelope); err != nil { return errors.New("invalid envelope input") } encoded, err := dispatcher.EncodeEnvelope(envelope) if err != nil { return err } frames, err := dispatcher.SplitEnvelope(encoded) if err != nil { return err } config, err := thin.LoadFile(configPath) if err != nil { return fmt.Errorf("load thin-client config: %w", err) } client := thin.NewThinClient(config, &clientconfig.Logging{Level: "ERROR", Disable: true}) defer client.Close() if err := client.Dial(); err != nil { return fmt.Errorf("connect to kpclientd: %w", err) } service, err := client.GetService(capability) if err != nil { return fmt.Errorf("find dispatcher service: %w", err) } destination := hash.Sum256(service.MixDescriptor.IdentityKey) for _, frame := range frames { if err := client.SendMessageWithoutReply(frame, &destination, service.RecipientQueueID); err != nil { return fmt.Errorf("send frame: %w", err) } } time.Sleep(settle) fmt.Fprintln(os.Stdout, "accepted") return nil } func main() { if err := run(); err != nil { fmt.Fprintf(os.Stderr, "submission failed: %v\n", err) os.Exit(1) } }