github.com/devops-filetransfer/sshego@v7.0.4+incompatible/auto_test.go (about) 1 package sshego 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 //"strings" 8 "testing" 9 "time" 10 11 cv "github.com/glycerine/goconvey/convey" 12 ssh "github.com/glycerine/sshego/xendor/github.com/glycerine/xcryptossh" 13 ) 14 15 func Test060AutoRedialWithTricorder(t *testing.T) { 16 cv.Convey("sshego.Tricorder has auto-redial on disconnect capability.", t, func() { 17 18 // start a simple TCP server that is the target of the forward through the sshd, 19 // so we can confirm the client has made the connection. 20 21 // generate a random payload for the client to send to the server. 22 payloadByteCount := 50 23 confirmationPayload := RandomString(payloadByteCount) 24 confirmationReply := RandomString(payloadByteCount) 25 26 tcpSrvLsn, tcpSrvPort := GetAvailPort() 27 28 var nc net.Conn 29 tcpServerMgr := ssh.NewHalter() 30 StartBackgroundTestTcpServer( 31 tcpServerMgr, 32 payloadByteCount, 33 confirmationPayload, 34 confirmationReply, 35 tcpSrvLsn, 36 &nc) 37 38 s := MakeTestSshClientAndServer(true) 39 defer TempDirCleanup(s.SrvCfg.Origdir, s.SrvCfg.Tempdir) 40 41 dest := fmt.Sprintf("127.0.0.1:%v", tcpSrvPort) 42 tofu := true 43 dc := &DialConfig{ 44 ClientKnownHostsPath: s.CliCfg.ClientKnownHostsPath, 45 Mylogin: s.Mylogin, 46 RsaPath: s.RsaPath, 47 TotpUrl: s.Totp, 48 Pw: s.Pw, 49 Sshdhost: s.SrvCfg.EmbeddedSSHd.Host, 50 Sshdport: s.SrvCfg.EmbeddedSSHd.Port, 51 DownstreamHostPort: dest, 52 TofuAddIfNotKnown: tofu, 53 LocalNickname: "test060", 54 } 55 56 pp("060 1st time: tcpSrvPort = %v. dest='%v'", tcpSrvPort, dest) 57 58 var channelToTcpServer net.Conn 59 var err error 60 ctx := context.Background() 61 62 pp("making tri: s.CliCfg.LocalToRemote.Listen.Addr='%v'", 63 s.CliCfg.LocalToRemote.Listen.Addr) 64 65 tri, err := NewTricorder(dc, s.CliCfg.Halt, "test060") 66 panicOn(err) 67 bkg := context.Background() 68 channelToTcpServer, err = tri.SSHChannel(bkg, "direct-tcpip", dest) 69 70 cv.So(err, cv.ShouldBeNil) 71 cv.So(tri, cv.ShouldNotBeNil) 72 73 pp("fine with DialGetTricorder.") 74 75 <-tcpServerMgr.ReadyChan() 76 pp("060 1st time nc = '%#v'", nc) 77 pp("060 1st time nc.LocalAddr='%v'", nc.LocalAddr()) 78 79 checkReconNeeded := tri.cfg.ClientReconnectNeededTower.Subscribe(nil) 80 81 VerifyClientServerExchangeAcrossSshd(channelToTcpServer, confirmationPayload, confirmationReply, payloadByteCount) 82 83 tcpServerMgr.RequestStop() 84 <-tcpServerMgr.DoneChan() 85 86 nc.Close() 87 nc = nil 88 channelToTcpServer.Close() 89 90 pp("starting on 2nd confirmation") 91 92 s.SrvCfg.Halt.RequestStop() 93 <-s.SrvCfg.Halt.DoneChan() 94 95 // after killing remote sshd 96 97 var uhp2 *UHP 98 select { 99 case uhp2 = <-checkReconNeeded: 100 pp("good, 060 got needReconnectCh to '%#v'", uhp2) 101 102 case <-time.After(5 * time.Second): 103 panic("never received <-checkReconNeeded: timeout after 5 seconds") 104 } 105 106 cv.So(uhp2.User, cv.ShouldEqual, s.Mylogin) 107 destHostPort := fmt.Sprintf("%v:%v", s.SrvCfg.EmbeddedSSHd.Host, s.SrvCfg.EmbeddedSSHd.Port) 108 cv.So(uhp2.HostPort, cv.ShouldEqual, destHostPort) 109 110 // so restart the sshd server 111 112 pp("waiting for destHostPort='%v' to be availble", destHostPort) 113 panicOn(s.SrvCfg.Esshd.Stop()) 114 s.SrvCfg.Reset() 115 s.SrvCfg.NewEsshd() 116 s.SrvCfg.Esshd.Start(ctx) 117 118 serverDone2 := ssh.NewHalter() 119 confirmationPayload2 := RandomString(payloadByteCount) 120 confirmationReply2 := RandomString(payloadByteCount) 121 122 StartBackgroundTestTcpServer( 123 serverDone2, 124 payloadByteCount, 125 confirmationPayload2, 126 confirmationReply2, 127 tcpSrvLsn, &nc) 128 time.Sleep(time.Second) 129 130 // tri should automaticly re-Dial. 131 channelToTcpServer2, err := tri.SSHChannel(ctx, "direct-tcpip", dest) 132 133 panicOn(err) 134 135 <-serverDone2.ReadyChan() 136 pp("060 2nd time nc.LocalAddr='%v'", nc.LocalAddr()) 137 138 i := 0 139 for k, v := range tri.sshChannels { 140 pp("tri.sshChannels[%v]=%p -> %p", i, k, v) 141 i++ 142 } 143 144 VerifyClientServerExchangeAcrossSshd(channelToTcpServer2, confirmationPayload2, confirmationReply2, payloadByteCount) 145 146 // tcp-server should have exited because it got the expected 147 // message and replied with the agreed upon reply and then exited. 148 serverDone2.RequestStop() 149 <-serverDone2.DoneChan() 150 nc.Close() 151 152 // done with testing, cleanup 153 s.SrvCfg.Esshd.Stop() 154 <-s.SrvCfg.Esshd.Halt.DoneChan() 155 cv.So(true, cv.ShouldEqual, true) // we should get here. 156 }) 157 }