ipc, worker: dial and bind through netaddr (V-484)
Five hardcoded transports, three in internal/ipc and two in internal/worker, all now go through the seam address. The unix perms logic moved into netaddr, so the two copies of parentDir and the umask dance are gone. peerCaller already returned ok=false for a non-unix conn, so the SO_PEERCRED path degrades correctly on tcp with no change.
This commit is contained in:
+24
-13
@@ -8,13 +8,15 @@ import (
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kami/maven/internal/netaddr"
|
||||
)
|
||||
|
||||
// Client — the module side of the boundary. Wraps a unix-socket connection
|
||||
// and satisfies CoreAPI, so a module imports ipc, holds a CoreAPI, and is
|
||||
// agnostic to whether it's been wired in-process (tests / daemon-embedded)
|
||||
// or over this socket (full topology). The swappability is the seam auth
|
||||
// will insert into without touching module code.
|
||||
// Client — the module side of the boundary. Wraps a connection to core and
|
||||
// satisfies CoreAPI, so a module imports ipc, holds a CoreAPI, and is
|
||||
// agnostic to whether it's been wired in-process (tests / daemon-embedded),
|
||||
// over a local unix socket, or over tcp to another host. The swappability is
|
||||
// the seam auth will insert into without touching module code.
|
||||
//
|
||||
// One Client ⇒ one conn ⇒ one concurrent request at a time. A module that
|
||||
// wants parallel requests opens one Client per goroutine; the store is the
|
||||
@@ -22,7 +24,8 @@ import (
|
||||
// per-Client lock keeps frame interleaving impossible by construction.
|
||||
type Client struct {
|
||||
conn net.Conn
|
||||
path string // kept so a dropped conn can be re-dialed (core restart)
|
||||
path string // the address as configured, kept for errors and logs
|
||||
addr netaddr.Addr // parsed, so a dropped conn can be re-dialed (core restart)
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
@@ -81,14 +84,22 @@ var readOnlyMethods = map[Method]bool{
|
||||
MethodPing: true,
|
||||
}
|
||||
|
||||
// Dial connects to a core socket at path and returns a Client. The module
|
||||
// owns its Client lifecycle; Close on shutdown.
|
||||
// Dial connects to core at path and returns a Client. The module owns its
|
||||
// Client lifecycle; Close on shutdown.
|
||||
//
|
||||
// path is a netaddr seam address: a bare path is the unix socket it has
|
||||
// always been, and "tcp://host:port?token=..." reaches a core on another
|
||||
// host. See internal/netaddr.
|
||||
func Dial(path string) (*Client, error) {
|
||||
c, err := net.Dial("unix", path)
|
||||
addr, err := netaddr.Parse(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ipc: dial %s: %w", path, err)
|
||||
return nil, err
|
||||
}
|
||||
return &Client{conn: c, path: path}, nil
|
||||
c, err := netaddr.Dial(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ipc: dial %s: %w", addr, err)
|
||||
}
|
||||
return &Client{conn: c, path: path, addr: addr}, nil
|
||||
}
|
||||
|
||||
func (c *Client) Close() error {
|
||||
@@ -189,9 +200,9 @@ func (c *Client) call(ctx context.Context, m Method, params, result any) error {
|
||||
// re-dials clean. Caller holds c.mu.
|
||||
func (c *Client) roundtrip(m Method, raw json.RawMessage, resp *Response) error {
|
||||
if c.conn == nil {
|
||||
conn, err := net.Dial("unix", c.path)
|
||||
conn, err := netaddr.Dial(c.addr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: dial %s: %v", errWriteLost, c.path, err)
|
||||
return fmt.Errorf("%w: dial %s: %v", errWriteLost, c.addr, err)
|
||||
}
|
||||
c.conn = conn
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user