summaryrefslogtreecommitdiffstats
path: root/internal/nym/client.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/nym/client.go')
-rw-r--r--internal/nym/client.go45
1 files changed, 22 insertions, 23 deletions
diff --git a/internal/nym/client.go b/internal/nym/client.go
index 89fcf52..e0b14d2 100644
--- a/internal/nym/client.go
+++ b/internal/nym/client.go
@@ -1,8 +1,7 @@
package nym
import (
- "encoding/base64"
- "encoding/json"
+ "encoding/binary"
"fmt"
"io"
"io/fs"
@@ -18,6 +17,7 @@ import (
// Client sends payloads through the Nym mixnet via an embedded nym-client subprocess.
type Client struct {
journalistAddr string
+ recipient []byte // parsed 96-byte wire form of journalistAddr
wsPort int
dryRun bool
process *exec.Cmd
@@ -26,8 +26,12 @@ type Client struct {
configDir string
}
-func New(journalistAddr string, binFS fs.FS) *Client {
- return &Client{journalistAddr: journalistAddr, wsPort: 1978, binFS: binFS}
+func New(journalistAddr string, binFS fs.FS) (*Client, error) {
+ recipient, err := ParseRecipient(journalistAddr)
+ if err != nil {
+ return nil, fmt.Errorf("parse journalist nym address: %w", err)
+ }
+ return &Client{journalistAddr: journalistAddr, recipient: recipient, wsPort: 1978, binFS: binFS}, nil
}
func NewDryRun(journalistAddr string) *Client {
@@ -75,31 +79,26 @@ func (c *Client) Start() error {
return fmt.Errorf("nym-client websocket did not start in time")
}
-type sendMsg struct {
- Type string `json:"type"`
- Message string `json:"message"`
- Recipient string `json:"recipient"`
- WithReplySurb bool `json:"withReplySurb"`
-}
-
-// Send delivers payload to the journalist's Nym address through the mixnet.
+// Send delivers payload to the journalist's Nym address through the mixnet
+// using nym-client's binary websocket protocol (tag || recipient || conn_id ||
+// data_len || data). This avoids the JSON+base64 wrapping of the old text
+// protocol, which inflated every payload by ~4/3 before it ever reached the
+// nym-client's own 16MB hardcoded websocket message limit.
func (c *Client) Send(payload []byte) error {
if c.dryRun {
fmt.Printf("[dry-run] payload received: %d bytes — would send to %s\n",
len(payload), c.journalistAddr)
return nil
}
- msg := sendMsg{
- Type: "send",
- Message: base64.StdEncoding.EncodeToString(payload),
- Recipient: c.journalistAddr,
- WithReplySurb: false,
- }
- raw, err := json.Marshal(msg)
- if err != nil {
- return fmt.Errorf("marshal: %w", err)
- }
- if err := websocket.Message.Send(c.ws, string(raw)); err != nil {
+
+ req := make([]byte, 0, 1+len(c.recipient)+8+8+len(payload))
+ req = append(req, ReqSend)
+ req = append(req, c.recipient...)
+ req = binary.BigEndian.AppendUint64(req, 0) // connection_id: none
+ req = binary.BigEndian.AppendUint64(req, uint64(len(payload)))
+ req = append(req, payload...)
+
+ if err := websocket.Message.Send(c.ws, req); err != nil {
return fmt.Errorf("ws send: %w", err)
}
return nil