9 // streamLocalChannelOpenDirectMsg is a struct used for SSH_MSG_CHANNEL_OPEN message
10 // with "direct-streamlocal@openssh.com" string.
12 // See openssh-portable/PROTOCOL, section 2.4. connection: Unix domain socket forwarding
13 // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL#L235
14 type streamLocalChannelOpenDirectMsg struct {
20 // forwardedStreamLocalPayload is a struct used for SSH_MSG_CHANNEL_OPEN message
21 // with "forwarded-streamlocal@openssh.com" string.
22 type forwardedStreamLocalPayload struct {
27 // streamLocalChannelForwardMsg is a struct used for SSH2_MSG_GLOBAL_REQUEST message
28 // with "streamlocal-forward@openssh.com"/"cancel-streamlocal-forward@openssh.com" string.
29 type streamLocalChannelForwardMsg struct {
33 // ListenUnix is similar to ListenTCP but uses a Unix domain socket.
34 func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
35 c.handleForwardsOnce.Do(c.handleForwards)
36 m := streamLocalChannelForwardMsg{
40 ok, _, err := c.SendRequest("streamlocal-forward@openssh.com", true, Marshal(&m))
45 return nil, errors.New("ssh: streamlocal-forward@openssh.com request denied by peer")
47 ch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: "unix"})
49 return &unixListener{socketPath, c, ch}, nil
52 func (c *Client) dialStreamLocal(socketPath string) (Channel, error) {
53 msg := streamLocalChannelOpenDirectMsg{
54 socketPath: socketPath,
56 ch, in, err := c.OpenChannel("direct-streamlocal@openssh.com", Marshal(&msg))
60 go DiscardRequests(in)
64 type unixListener struct {
71 // Accept waits for and returns the next connection to the listener.
72 func (l *unixListener) Accept() (net.Conn, error) {
77 ch, incoming, err := s.newCh.Accept()
81 go DiscardRequests(incoming)
96 // Close closes the listener.
97 func (l *unixListener) Close() error {
98 // this also closes the listener.
99 l.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: "unix"})
100 m := streamLocalChannelForwardMsg{
103 ok, _, err := l.conn.SendRequest("cancel-streamlocal-forward@openssh.com", true, Marshal(&m))
104 if err == nil && !ok {
105 err = errors.New("ssh: cancel-streamlocal-forward@openssh.com failed")
110 // Addr returns the listener's network address.
111 func (l *unixListener) Addr() net.Addr {
112 return &net.UnixAddr{