Difference between NewChannel vs Request in ssh sftp server

Viewed 201

I'm looking at go sftp server example code

https://github.com/pkg/sftp/blob/master/examples/go-sftp-server/main.go

There are section of code which are unclear to me

_, chans, reqs, err := ssh.NewServerConn(nConn, config)
if err != nil {
    log.Fatal("failed to handshake", err)
}
fmt.Fprintf(debugStream, "SSH server established\n")

// The incoming Request channel must be serviced.
go ssh.DiscardRequests(reqs)

// Service the incoming Channel channel.
for newChannel := range chans {
    ...
}

First: With ssh.NewServerConn, if NewChannel(chans) represent new request to the channel what is Request reqs. So what is difference between chans and reqs here.

Second: Why is the need to ssh.DiscardRequests(reqs)

2 Answers

Looking at the documentation for ssh.NewServerConn it appears that it returns the following:

  1. *ServerConn
  2. <-chan NewChannel
  3. <-chan *Request
  4. error

The second returned value, NewChannel

represents an incoming request to a channel

The third returned value, Request

is a request sent outside of the normal stream of data

This doesn't really answer your questions but it does provide helpful clues as where to look.

So to answer you questions:

  1. chans receives connections that are new to the server. Using the received value from chans, you can either accept and communicate with that connection or just reject the connection. This can be thought of multiple people logging into a remote machine via ssh and handling multiple sessions.

    reqs holds global requests (which is defined here) sent to either the server or client that should not be sent to any specific channel. RFC4254 gives the example of a such a request as "start TCP/IP forwarding for a specific port".
    You can see the internal usage of how the ssh package uses the incomingRequests channel here.

  2. The documentation for ssh.NewServerConn explicitly states

    The Request and NewChannel channels must be serviced, or the connection will hang.

    In the event that this server does receive a global request it needs to be handled appropriately if the request is asking for a reply.

Apart from @will7200 answer I just want to add a couple of things which I found while my reading around this.

SSH has Global request called SSH_MESSAGE_GLOBAL_REQUEST and SSH_MESSAGE_CHANNEL_REQUEST or starts TCP/IP forwarding for a specific port

a channel is any specific terminal or how we see it when we send the data across the ssh server and client.

So reqs over here is the global request and all channel requests are wrapped inside the channel.

GLOBAL requests are requests that are not specific to a CHANNEL like TCPKeepAlive (as mention in ssh_config) or start TCP/IP forwarding for a specific port.

and DisdCardRequest essentially discard those request that does not want a reply

Related