github.com/glycerine/xcryptossh@v7.0.4+incompatible/channel.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssh 6 7 import ( 8 "encoding/binary" 9 "errors" 10 "fmt" 11 "io" 12 "log" 13 "net" 14 "sync" 15 "sync/atomic" 16 "time" 17 ) 18 19 const ( 20 minPacketLength = 9 21 // channelMaxPacket contains the maximum number of bytes that will be 22 // sent in a single packet. As per RFC 4253, section 6.1, 32k is also 23 // the minimum. 24 channelMaxPacket = 1 << 15 25 // We follow OpenSSH here. 26 channelWindowSize = 64 * channelMaxPacket 27 ) 28 29 // verify interface satisfied. 30 var _ net.Conn = &channel{} 31 32 type HasTimeout interface { 33 timeout() 34 } 35 36 // NewChannel represents an incoming request to a channel. It must either be 37 // accepted for use by calling Accept, or rejected by calling Reject. 38 type NewChannel interface { 39 // Accept accepts the channel creation request. It returns the Channel 40 // and a Go channel containing SSH requests. The Go channel must be 41 // serviced otherwise the Channel will hang. 42 Accept() (Channel, <-chan *Request, error) 43 44 // Reject rejects the channel creation request. After calling 45 // this, no other methods on the Channel may be called. 46 Reject(reason RejectionReason, message string) error 47 48 // ChannelType returns the type of the channel, as supplied by the 49 // client. 50 ChannelType() string 51 52 // ExtraData returns the arbitrary payload for this channel, as supplied 53 // by the client. This data is specific to the channel type. 54 ExtraData() []byte 55 } 56 57 // A Channel is an ordered, reliable, flow-controlled, duplex stream 58 // that is multiplexed over an SSH connection. 59 type Channel interface { 60 // Read reads up to len(data) bytes from the channel. 61 Read(data []byte) (int, error) 62 63 // Write writes len(data) bytes to the channel. 64 Write(data []byte) (int, error) 65 66 // Close signals end of channel use. No data may be sent after this 67 // call. 68 Close() error 69 70 // CloseWrite signals the end of sending in-band 71 // data. Requests may still be sent, and the other side may 72 // still send data 73 CloseWrite() error 74 75 // SendRequest sends a channel request. If wantReply is true, 76 // it will wait for a reply and return the result as a 77 // boolean, otherwise the return value will be false. Channel 78 // requests are out-of-band messages so they may be sent even 79 // if the data stream is closed or blocked by flow control. 80 // If the channel is closed before a reply is returned, io.EOF 81 // is returned. 82 SendRequest(name string, wantReply bool, payload []byte) (bool, error) 83 84 // Stderr returns an io.ReadWriter that writes to this channel 85 // with the extended data type set to stderr. Stderr may 86 // safely be read and written from a different goroutine than 87 // Read and Write respectively. 88 Stderr() io.ReadWriter 89 90 // Done can be used to await connection shutdown. The 91 // returned channel will be closed when the Channel is closed. 92 Done() <-chan struct{} 93 94 // GetHalter returns the Channel specific Halter. 95 GetHalter() *Halter 96 97 // SetReadIdleTimeout starts an idle timer on 98 // Reads that will cause them to timeout after dur. 99 // A successful Read will bump the idle 100 // timeout into the future. 101 // 102 // Providing dur of 0 will disable the idle timeout. 103 // Zero is the default until SetReadIdleTimeout() is called. 104 // 105 // SetReadIdleTimeout() will always reset and 106 // clear any raised timeout left over from prior use. 107 // Any new timer (if dur > 0) begins from the return of 108 // the SetReadIdleTimeout() invocation. 109 // 110 // Idle timeouts are easier to use than deadlines, 111 // as they don't need to be refreshed after 112 // every read and write. Hence routines like io.Copy() 113 // that make many calls to Read() and Write() 114 // can be leveraged, while still having a timeout in 115 // the case of no activity. 116 // 117 // Moreover idle timeouts are more 118 // efficient because we don't guess at a 119 // deadline and then interrupt a perfectly 120 // good ongoing copy that happens to be 121 // taking a few seconds longer than our 122 // guesstimate. We avoid the pain of trying 123 // to restart long interrupted transfers that 124 // were making fine progress. 125 // 126 SetReadIdleTimeout(dur time.Duration) error 127 128 // SetWriteIdleTimeout is the same as SetReadIdleTimeout, 129 // but applies to writes rather than reads. 130 // Note that Write() to 131 // a Channel will "succeed" in the sense of 132 // returning a nil error long before they 133 // reach the remote end (or not). Writes 134 // are buffered internally. Hence the write 135 // idle timer may be less useful than 136 // the read timer. 137 SetWriteIdleTimeout(dur time.Duration) error 138 139 // SetIdleTimeout does both SetReadIdleTimeout 140 // and SetWriteIdleTimeout. 141 SetIdleTimeout(dur time.Duration) error 142 143 // GetReadIdleTimer allows monitoring of idle timeout 144 // by other parties. It doesn't disturb the 145 // timer if it happens to be running. 146 GetReadIdleTimer() *IdleTimer 147 148 // GetWriteIdleTimer allows monitoring of idle timeout 149 // by other parties. It doesn't disturb the 150 // timer if it happens to be running. 151 GetWriteIdleTimer() *IdleTimer 152 153 // SetReadDeadline sets the deadline for future Read calls 154 // and any currently-blocked Read call. 155 // A zero value for t means Read will not time out. 156 SetReadDeadline(t time.Time) error 157 158 // SetWriteDeadline sets the deadline for future Write calls 159 // and any currently-blocked Write call. 160 // A zero value for t means Write will not time out. 161 SetWriteDeadline(t time.Time) error 162 163 // SetDeadline sets the read and write deadlines. 164 SetDeadline(t time.Time) error 165 166 // Status lets clients query this Channel's lifecycle 167 // progress. 168 Status() *RunStatus 169 170 LocalAddr() net.Addr 171 RemoteAddr() net.Addr 172 } 173 174 // Request is a request sent outside of the normal stream of 175 // data. Requests can either be specific to an SSH channel, or they 176 // can be global. 177 type Request struct { 178 Type string 179 WantReply bool 180 Payload []byte 181 182 ch *channel 183 mux *mux 184 } 185 186 // Reply sends a response to a request. It must be called for all requests 187 // where WantReply is true and is a no-op otherwise. The payload argument is 188 // ignored for replies to channel-specific requests. 189 func (r *Request) Reply(ok bool, payload []byte) error { 190 if !r.WantReply { 191 return nil 192 } 193 194 if r.ch == nil { 195 return r.mux.ackRequest(ok, payload) 196 } 197 198 return r.ch.ackRequest(ok) 199 } 200 201 // RejectionReason is an enumeration used when rejecting channel creation 202 // requests. See RFC 4254, section 5.1. 203 type RejectionReason uint32 204 205 const ( 206 Prohibited RejectionReason = iota + 1 207 ConnectionFailed 208 UnknownChannelType 209 ResourceShortage 210 ) 211 212 // String converts the rejection reason to human readable form. 213 func (r RejectionReason) String() string { 214 switch r { 215 case Prohibited: 216 return "administratively prohibited" 217 case ConnectionFailed: 218 return "connect failed" 219 case UnknownChannelType: 220 return "unknown channel type" 221 case ResourceShortage: 222 return "resource shortage" 223 } 224 return fmt.Sprintf("unknown reason %d", int(r)) 225 } 226 227 func min(a uint32, b int) uint32 { 228 if a < uint32(b) { 229 return a 230 } 231 return uint32(b) 232 } 233 234 type channelDirection uint8 235 236 const ( 237 channelInbound channelDirection = iota 238 channelOutbound 239 ) 240 241 // channel is an implementation of the Channel interface that works 242 // with the mux class. 243 type channel struct { 244 // R/O after creation 245 chanType string 246 extraData []byte 247 localId, remoteId uint32 248 249 // maxIncomingPayload and maxRemotePayload are the maximum 250 // payload sizes of normal and extended data packets for 251 // receiving and sending, respectively. The wire packet will 252 // be 9 or 13 bytes larger (excluding encryption overhead). 253 maxIncomingPayload uint32 254 maxRemotePayload uint32 255 256 mux *mux 257 258 // decided is set to true if an accept or reject message has been sent 259 // (for outbound channels) or received (for inbound channels). 260 decided bool 261 262 // direction contains either channelOutbound, for channels created 263 // locally, or channelInbound, for channels created by the peer. 264 direction channelDirection 265 266 // Pending internal channel messages. 267 msg chan interface{} 268 269 // Since requests have no ID, there can be only one request 270 // with WantReply=true outstanding. This lock is held by a 271 // goroutine that has such an outgoing request pending. 272 sentRequestMu sync.Mutex 273 274 incomingRequests chan *Request 275 276 sentEOF bool 277 278 // thread-safe data 279 remoteWin window 280 pending *buffer 281 extPending *buffer 282 283 // windowMu protects myWindow, the flow-control window. 284 windowMu sync.Mutex 285 myWindow uint32 286 287 // writeMu serializes calls to mux.conn.writePacket() and 288 // protects sentClose and packetPool. This mutex must be 289 // different from windowMu, as writePacket can block if there 290 // is a key exchange pending. 291 writeMu sync.Mutex 292 sentClose bool 293 294 // packetPool has a buffer for each extended channel ID to 295 // save allocations during writes. 296 packetPool map[uint32][]byte 297 298 // hasClosed makes Close() idempotent. Only 299 // the first invocation of Close() has any 300 // effect; the result return nil immediately. 301 hasClosed int32 302 303 // idleR provides a means 304 // for ssh.Channel users to check how 305 // many nanoseconds have elapsed since the last 306 // error-free read. It is safe for 307 // use by multiple goroutines. Users 308 // should call SetIdleDur() and BeginAttempt() on it to before 309 // any subsequent calls to TimedOut(). 310 idleR *IdleTimer 311 312 // idleW is for writes, idleR is for reads. 313 idleW *IdleTimer 314 315 halt *Halter 316 } 317 318 // writePacket sends a packet. If the packet is a channel close, it updates 319 // sentClose. This method takes the lock c.writeMu. 320 func (c *channel) writePacket(packet []byte) error { 321 c.writeMu.Lock() 322 if c.sentClose { 323 c.writeMu.Unlock() 324 return io.EOF // TestClientWriteEOF depends on this being io.EOF 325 } 326 c.sentClose = (packet[0] == msgChannelClose) 327 err := c.mux.conn.writePacket(packet) 328 if err == nil { 329 c.idleW.AttemptOK() 330 } 331 c.writeMu.Unlock() 332 return err 333 } 334 335 func (c *channel) sendMessage(msg interface{}) error { 336 if debugMux { 337 log.Printf("send(%d): %#v", c.mux.chanList.offset, msg) 338 } 339 340 p := Marshal(msg) 341 binary.BigEndian.PutUint32(p[1:], c.remoteId) 342 return c.writePacket(p) 343 } 344 345 // WriteExtended writes data to a specific extended stream. These streams are 346 // used, for example, for stderr. 347 func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) { 348 c.idleW.BeginAttempt() 349 defer func() { 350 if err == nil { 351 c.idleW.AttemptOK() 352 } 353 }() 354 if c.sentEOF { 355 return 0, io.EOF 356 } 357 // 1 byte message type, 4 bytes remoteId, 4 bytes data length 358 opCode := byte(msgChannelData) 359 headerLength := uint32(9) 360 if extendedCode > 0 { 361 headerLength += 4 362 opCode = msgChannelExtendedData 363 } 364 365 c.writeMu.Lock() 366 packet := c.packetPool[extendedCode] 367 // We don't remove the buffer from packetPool, so 368 // WriteExtended calls from different goroutines will be 369 // flagged as errors by the race detector. 370 c.writeMu.Unlock() 371 372 for len(data) > 0 { 373 space := min(c.maxRemotePayload, len(data)) 374 if space, err = c.remoteWin.reserve(space); err != nil { 375 return n, err 376 } 377 c.idleW.AttemptOK() 378 if want := headerLength + space; uint32(cap(packet)) < want { 379 packet = make([]byte, want) 380 } else { 381 packet = packet[:want] 382 } 383 384 todo := data[:space] 385 386 packet[0] = opCode 387 binary.BigEndian.PutUint32(packet[1:], c.remoteId) 388 if extendedCode > 0 { 389 binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode)) 390 } 391 binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo))) 392 copy(packet[headerLength:], todo) 393 if err = c.writePacket(packet); err != nil { 394 return n, err 395 } 396 c.idleW.AttemptOK() 397 398 n += len(todo) 399 data = data[len(todo):] 400 } 401 402 c.writeMu.Lock() 403 c.packetPool[extendedCode] = packet 404 c.writeMu.Unlock() 405 406 return n, err 407 } 408 409 func (c *channel) handleData(packet []byte) error { 410 headerLen := 9 411 isExtendedData := packet[0] == msgChannelExtendedData 412 if isExtendedData { 413 headerLen = 13 414 } 415 if len(packet) < headerLen { 416 // malformed data packet 417 return parseError(packet[0]) 418 } 419 420 var extended uint32 421 if isExtendedData { 422 extended = binary.BigEndian.Uint32(packet[5:]) 423 } 424 425 length := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen]) 426 if length == 0 { 427 return nil 428 } 429 if length > c.maxIncomingPayload { 430 // TODO(hanwen): should send Disconnect? 431 return errors.New("ssh: incoming packet exceeds maximum payload size") 432 } 433 434 data := packet[headerLen:] 435 if length != uint32(len(data)) { 436 return errors.New("ssh: wrong packet length") 437 } 438 439 c.windowMu.Lock() 440 if c.myWindow < length { 441 c.windowMu.Unlock() 442 // TODO(hanwen): should send Disconnect with reason? 443 return errors.New("ssh: remote side wrote too much") 444 } 445 c.myWindow -= length 446 c.windowMu.Unlock() 447 448 if extended == 1 { 449 c.extPending.write(data) 450 } else if extended > 0 { 451 // discard other extended data. 452 } else { 453 c.pending.write(data) 454 } 455 return nil 456 } 457 458 func (c *channel) adjustWindow(n uint32) error { 459 c.windowMu.Lock() 460 // Since myWindow is managed on our side, and can never exceed 461 // the initial window setting, we don't worry about overflow. 462 c.myWindow += uint32(n) 463 c.windowMu.Unlock() 464 return c.sendMessage(windowAdjustMsg{ 465 AdditionalBytes: uint32(n), 466 }) 467 } 468 469 func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) { 470 c.idleR.BeginAttempt() 471 switch extended { 472 case 1: 473 n, err = c.extPending.Read(data) 474 case 0: 475 n, err = c.pending.Read(data) 476 default: 477 return 0, fmt.Errorf("ssh: extended code %d unimplemented", extended) 478 } 479 if err == nil { 480 c.idleR.AttemptOK() 481 } 482 483 if n > 0 { 484 err = c.adjustWindow(uint32(n)) 485 // sendWindowAdjust can return io.EOF if the remote 486 // peer has closed the connection, however we want to 487 // defer forwarding io.EOF to the caller of Read until 488 // the buffer has been drained. 489 if n > 0 && err == io.EOF { 490 err = nil 491 } 492 } 493 494 return n, err 495 } 496 497 func (c *channel) close() { 498 c.pending.eof() 499 c.extPending.eof() 500 close(c.msg) 501 close(c.incomingRequests) 502 c.writeMu.Lock() 503 // This is not necessary for a normal channel teardown, but if 504 // there was another error, it is. 505 c.sentClose = true 506 c.writeMu.Unlock() 507 // Unblock writers. 508 c.remoteWin.close() 509 c.halt.RequestStop() 510 c.halt.MarkDone() 511 c.idleR.Stop() 512 c.idleW.Stop() 513 } 514 515 func (c *channel) timeout() { 516 c.pending.timeout() 517 c.extPending.timeout() 518 // Unblock writers. 519 c.remoteWin.timeout() 520 mt, ok := c.mux.conn.(HasTimeout) 521 if ok { 522 mt.timeout() // unblock goroutines stuck in *memTransport 523 } 524 } 525 526 // responseMessageReceived is called when a success or failure message is 527 // received on a channel to check that such a message is reasonable for the 528 // given channel. 529 func (c *channel) responseMessageReceived() error { 530 if c.direction == channelInbound { 531 return errors.New("ssh: channel response message received on inbound channel") 532 } 533 if c.decided { 534 return errors.New("ssh: duplicate response received for channel") 535 } 536 c.decided = true 537 return nil 538 } 539 540 func (c *channel) handlePacket(packet []byte) error { 541 c.idleR.AttemptOK() 542 switch packet[0] { 543 case msgChannelData, msgChannelExtendedData: 544 return c.handleData(packet) 545 case msgChannelClose: 546 c.sendMessage(channelCloseMsg{PeersId: c.remoteId}) 547 c.mux.chanList.remove(c.localId) 548 c.close() 549 return nil 550 case msgChannelEOF: 551 // RFC 4254 is mute on how EOF affects dataExt messages but 552 // it is logical to signal EOF at the same time. 553 c.extPending.eof() 554 c.pending.eof() 555 return nil 556 } 557 558 decoded, err := decode(packet) 559 if err != nil { 560 return err 561 } 562 563 reqStopCh := c.halt.ReqStopChan() 564 var reqStopMux chan struct{} 565 if c.mux.halt != nil { 566 reqStopMux = c.mux.halt.ReqStopChan() 567 } 568 569 switch msg := decoded.(type) { 570 case *channelOpenFailureMsg: 571 if err := c.responseMessageReceived(); err != nil { 572 return err 573 } 574 c.mux.chanList.remove(msg.PeersId) 575 select { 576 case c.msg <- msg: 577 case <-reqStopMux: 578 return io.EOF 579 case <-reqStopCh: 580 return io.EOF 581 } 582 case *channelOpenConfirmMsg: 583 if err := c.responseMessageReceived(); err != nil { 584 return err 585 } 586 if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 { 587 return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize) 588 } 589 c.remoteId = msg.MyId 590 c.maxRemotePayload = msg.MaxPacketSize 591 c.remoteWin.add(msg.MyWindow) 592 select { 593 case c.msg <- msg: 594 case <-reqStopMux: 595 return io.EOF 596 case <-reqStopCh: 597 return io.EOF 598 } 599 case *windowAdjustMsg: 600 if !c.remoteWin.add(msg.AdditionalBytes) { 601 return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes) 602 } 603 case *channelRequestMsg: 604 req := Request{ 605 Type: msg.Request, 606 WantReply: msg.WantReply, 607 Payload: msg.RequestSpecificData, 608 ch: c, 609 } 610 select { 611 case c.incomingRequests <- &req: 612 case <-reqStopMux: 613 return io.EOF 614 case <-reqStopCh: 615 return io.EOF 616 } 617 default: 618 select { 619 case c.msg <- msg: 620 case <-reqStopMux: 621 return io.EOF 622 case <-reqStopCh: 623 return io.EOF 624 } 625 } 626 return nil 627 } 628 629 func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel { 630 idleR, idleW := NewIdleTimer(nil, 0), NewIdleTimer(nil, 0) 631 ch := &channel{ 632 remoteWin: window{Cond: newCond(), idle: idleR}, 633 myWindow: channelWindowSize, 634 pending: newBuffer(idleR), 635 extPending: newBuffer(idleR), 636 direction: direction, 637 incomingRequests: make(chan *Request, chanSize), 638 msg: make(chan interface{}, chanSize), 639 chanType: chanType, 640 extraData: extraData, 641 mux: m, 642 packetPool: make(map[uint32][]byte), 643 idleR: idleR, 644 idleW: idleW, 645 halt: NewHalter(), 646 } 647 idleR.AddTimeoutCallback(ch.timeout) 648 idleW.AddTimeoutCallback(ch.timeout) 649 ch.localId = m.chanList.add(ch) 650 return ch 651 } 652 653 var errUndecided = errors.New("ssh: must Accept or Reject channel") 654 var errDecidedAlready = errors.New("ssh: can call Accept or Reject only once") 655 656 type extChannel struct { 657 code uint32 658 ch *channel 659 } 660 661 func (e *extChannel) Write(data []byte) (n int, err error) { 662 return e.ch.WriteExtended(data, e.code) 663 } 664 665 func (e *extChannel) Read(data []byte) (n int, err error) { 666 return e.ch.ReadExtended(data, e.code) 667 } 668 669 func (c *channel) Accept() (Channel, <-chan *Request, error) { 670 if c.decided { 671 return nil, nil, errDecidedAlready 672 } 673 c.maxIncomingPayload = channelMaxPacket 674 confirm := channelOpenConfirmMsg{ 675 PeersId: c.remoteId, 676 MyId: c.localId, 677 MyWindow: c.myWindow, 678 MaxPacketSize: c.maxIncomingPayload, 679 } 680 c.decided = true 681 if err := c.sendMessage(confirm); err != nil { 682 return nil, nil, err 683 } 684 685 return c, c.incomingRequests, nil 686 } 687 688 func (ch *channel) Reject(reason RejectionReason, message string) error { 689 if ch.decided { 690 return errDecidedAlready 691 } 692 reject := channelOpenFailureMsg{ 693 PeersId: ch.remoteId, 694 Reason: reason, 695 Message: message, 696 Language: "en", 697 } 698 ch.decided = true 699 ch.idleR.Halt.RequestStop() 700 ch.idleW.Halt.RequestStop() 701 702 return ch.sendMessage(reject) 703 } 704 705 func (ch *channel) Read(data []byte) (int, error) { 706 if !ch.decided { 707 return 0, errUndecided 708 } 709 return ch.ReadExtended(data, 0) 710 } 711 712 func (ch *channel) Write(data []byte) (int, error) { 713 if !ch.decided { 714 return 0, errUndecided 715 } 716 return ch.WriteExtended(data, 0) 717 } 718 719 func (ch *channel) CloseWrite() error { 720 if !ch.decided { 721 return errUndecided 722 } 723 ch.sentEOF = true 724 return ch.sendMessage(channelEOFMsg{ 725 PeersId: ch.remoteId}) 726 } 727 728 func (ch *channel) Close() error { 729 if !atomic.CompareAndSwapInt32(&ch.hasClosed, 0, 1) { 730 // idempotent Close 731 return nil 732 } 733 ch.idleR.Halt.RequestStop() 734 ch.idleW.Halt.RequestStop() 735 ch.halt.RequestStop() 736 ch.halt.MarkDone() 737 738 if !ch.decided { 739 return errUndecided 740 } 741 742 return ch.sendMessage(channelCloseMsg{ 743 PeersId: ch.remoteId}) 744 } 745 746 // Extended returns an io.ReadWriter that sends and receives data on the given, 747 // SSH extended stream. Such streams are used, for example, for stderr. 748 func (ch *channel) Extended(code uint32) io.ReadWriter { 749 if !ch.decided { 750 return nil 751 } 752 return &extChannel{code, ch} 753 } 754 755 func (ch *channel) Stderr() io.ReadWriter { 756 return ch.Extended(1) 757 } 758 759 // Done returns the mux's halt.ReqStopChan(), so 760 // it lasts until the connection is lost. Use 761 // GetHalter() below to get a Channel specific 762 // done channel. 763 func (ch *channel) Done() <-chan struct{} { 764 if ch.mux.halt != nil { 765 return ch.mux.halt.ReqStopChan() 766 } 767 return nil 768 } 769 770 // GetHalter returns the channel ch specific Halter. 771 func (ch *channel) GetHalter() *Halter { 772 return ch.halt 773 } 774 775 func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) { 776 if !ch.decided { 777 return false, errUndecided 778 } 779 780 if wantReply { 781 ch.sentRequestMu.Lock() 782 defer ch.sentRequestMu.Unlock() 783 } 784 785 msg := channelRequestMsg{ 786 PeersId: ch.remoteId, 787 Request: name, 788 WantReply: wantReply, 789 RequestSpecificData: payload, 790 } 791 792 if err := ch.sendMessage(msg); err != nil { 793 return false, err 794 } 795 var reqStopMux chan struct{} 796 if ch.mux.halt != nil { 797 reqStopMux = ch.mux.halt.ReqStopChan() 798 } 799 reqStopCh := ch.halt.ReqStopChan() 800 801 if wantReply { 802 select { 803 case <-reqStopMux: 804 return false, io.EOF 805 case <-reqStopCh: 806 return false, io.EOF 807 case m, ok := (<-ch.msg): 808 if !ok { 809 return false, io.EOF 810 } 811 switch m.(type) { 812 case *channelRequestFailureMsg: 813 return false, nil 814 case *channelRequestSuccessMsg: 815 return true, nil 816 default: 817 return false, fmt.Errorf("ssh: unexpected response to channel request: %#v", m) 818 } 819 820 } 821 822 } 823 824 return false, nil 825 } 826 827 // ackRequest either sends an ack or nack to the channel request. 828 func (ch *channel) ackRequest(ok bool) error { 829 if !ch.decided { 830 return errUndecided 831 } 832 833 var msg interface{} 834 if !ok { 835 msg = channelRequestFailureMsg{ 836 PeersId: ch.remoteId, 837 } 838 } else { 839 msg = channelRequestSuccessMsg{ 840 PeersId: ch.remoteId, 841 } 842 } 843 return ch.sendMessage(msg) 844 } 845 846 func (ch *channel) ChannelType() string { 847 return ch.chanType 848 } 849 850 func (ch *channel) ExtraData() []byte { 851 return ch.extraData 852 } 853 854 // net.Conn compat: 855 856 type chanAddr struct { 857 name string 858 } 859 860 // name of the network (for example, "tcp", "udp") 861 func (c *chanAddr) Network() string { 862 return "ssh-channel" 863 } 864 865 // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") 866 func (c *chanAddr) String() string { 867 return c.name 868 } 869 870 var sshChanAddr chanAddr 871 872 // LocalAddr returns the local network address. 873 func (c *channel) LocalAddr() net.Addr { 874 return &sshChanAddr 875 } 876 877 // RemoteAddr returns the remote network address. 878 func (c *channel) RemoteAddr() net.Addr { 879 return &sshChanAddr 880 } 881 882 // SetReadIdleTimeout establishes a new timeout duration 883 // and starts the timing machinery off and running. 884 // A dur of zero will disable timeouts. 885 // 886 // SetReadIdleTimeout() will always reset and 887 // clear any raised timeout left over from prior use. 888 // Any new timer (if dur > 0) begins from the return of 889 // the SetReadIdleTimeout() invocation. 890 // 891 func (c *channel) SetReadIdleTimeout(dur time.Duration) error { 892 c.idleR.SetIdleTimeout(dur) 893 return nil 894 } 895 896 // SetWriteIdleTimeout establishes a new timeout duration 897 // and starts the timing machinery off and running. 898 // A dur of zero will disable timeouts. 899 // 900 // SetWriteIdleTimeout() will always reset and 901 // clear any raised timeout left over from prior use. 902 // Any new timer (if dur > 0) begins from the return of 903 // the SetWriteIdleTimeout() invocation. 904 // 905 func (c *channel) SetWriteIdleTimeout(dur time.Duration) error { 906 c.idleW.SetIdleTimeout(dur) 907 return nil 908 } 909 910 // SetIdleTimeout does both SetReadIdleTimeout and SetWriteIdleTimeout. 911 func (c *channel) SetIdleTimeout(dur time.Duration) error { 912 c.idleR.SetIdleTimeout(dur) 913 c.idleW.SetIdleTimeout(dur) 914 return nil 915 } 916 917 func (c *channel) SetReadDeadline(t time.Time) error { 918 return c.setDeadline(t, true) 919 } 920 921 func (c *channel) SetWriteDeadline(t time.Time) error { 922 return c.setDeadline(t, false) 923 } 924 925 func (c *channel) SetDeadline(t time.Time) error { 926 c.setDeadline(t, false) 927 return c.setDeadline(t, true) 928 } 929 930 func (c *channel) setDeadline(t time.Time, reads bool) error { 931 if t.IsZero() { 932 if reads { 933 c.idleR.SetOneshotIdleTimeout(0) 934 } else { 935 c.idleW.SetOneshotIdleTimeout(0) 936 } 937 } else { 938 var dur time.Duration 939 now := time.Now() 940 if !now.Before(t) { 941 // they are late, but they don't want to block, 942 // or they would have sent us a zero time. 943 // So set a minimal timeout that will unblock 944 // any reads immediately. 945 dur = time.Nanosecond 946 } else { 947 dur = t.Sub(now) 948 } 949 if reads { 950 c.idleR.SetOneshotIdleTimeout(dur) 951 } else { 952 c.idleW.SetOneshotIdleTimeout(dur) 953 } 954 } 955 return nil 956 } 957 958 func (c *channel) GetReadIdleTimer() *IdleTimer { 959 return c.idleR 960 } 961 962 func (c *channel) GetWriteIdleTimer() *IdleTimer { 963 return c.idleW 964 } 965 966 // Status observes the goroutine lifecycle. 967 func (c *channel) Status() (r *RunStatus) { 968 r = &RunStatus{} 969 r.Ready = c.idleR.Halt.IsReady() 970 r.StopRequested = c.idleR.Halt.IsStopRequested() 971 r.Done = c.idleR.Halt.IsDone() 972 if r.Done { 973 r.Err = c.idleR.Halt.Err() 974 } 975 r.DoneCh = c.idleR.Halt.DoneChan() 976 return 977 }