예제 #1
0
파일: ssh.go 프로젝트: simudream/duplex
func (c *ssh_channel) WriteTrailers(trailers []string) error {
	if ok, err := c.SendRequest("trailers", true, ssh.Marshal(ssh_trailerPayload{
		Trailers: trailers,
	})); err != nil || !ok {
		return errors.New("unable to set trailers")
	}
	c.ssh_channelData.Trailers = trailers
	return nil
}
예제 #2
0
파일: ssh.go 프로젝트: simudream/duplex
func ssh_handleConn(conn net.Conn, config *ssh.ServerConfig, peer *Peer) {
	defer conn.Close()
	sshConn, chans, reqs, err := ssh.NewServerConn(conn, config)
	if err != nil {
		debug("failed to handshake:", err)
		return
	}
	endpoint := conn.RemoteAddr().Network() + "://" + conn.RemoteAddr().String()
	if conn.RemoteAddr().Network() == "unix" && conn.RemoteAddr().String() == "" {
		// is it normal to not have a remote address with unix sockets?
		// because we need a unique endpoint for peer.conns, we use the
		// peer name when we don't have a remote address.
		endpoint = conn.RemoteAddr().Network() + "://" + sshConn.User()
	}
	pc := &ssh_peerConnection{
		endpoint:   endpoint,
		remote:     sshConn.User(),
		conn:       sshConn,
		local:      peer.GetOption(OptName).(string),
		attachedCh: make(map[uint32]chan interface{}),
	}
	peer.Lock()
	peer.conns[endpoint] = pc
	peer.Unlock()
	go func() {
		sshConn.Wait()
		//debug("server disconnection: ", err)
		// TODO: handle unexpected disconnect
	}()
	go ssh.DiscardRequests(reqs)
	ok, _, err := sshConn.SendRequest("@duplex-greeting", true,
		ssh.Marshal(&ssh_greetingPayload{peer.GetOption(OptName).(string)}))
	if err != nil || !ok {
		if err != io.EOF {
			debug("failed to greet:", err)
		}
		return
	}
	ssh_acceptChannels(chans, pc, peer)
}
예제 #3
0
파일: ssh.go 프로젝트: simudream/duplex
func ssh_openChannel(peerConn *ssh_peerConnection, service string, headers []string, attached bool, attach uint32) (Channel, error) {
	meta := ssh_channelData{
		Service:      service,
		Headers:      headers,
		FlagAttached: attached,
		Attach:       attach,
	}
	ch, reqs, err := peerConn.conn.OpenChannel("@duplex", ssh.Marshal(meta))
	if err != nil {
		return nil, err
	}
	peerConn.attachedCh[ch.LocalID()] = make(chan interface{}, 1024)
	channel := &ssh_channel{
		Channel:         ch,
		ssh_channelData: meta,
		peerConn:        peerConn,
	}

	go channel.handleRequests(reqs)

	return channel, nil
}