@@ -95,12 +95,11 @@ type sshSmartSubtransport struct {
9595}
9696
9797type connection struct {
98- conn net.Conn
9998 client * ssh.Client
10099 session * ssh.Session
101100 currentStream * sshSmartSubtransportStream
102101 connected bool
103- m sync.Mutex
102+ m sync.RWMutex
104103}
105104
106105func (t * sshSmartSubtransport ) Action (transportOptionsURL string , action git2go.SmartServiceAction ) (git2go.SmartSubtransportStream , error ) {
@@ -155,11 +154,6 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
155154 return nil , fmt .Errorf ("unexpected action: %v" , action )
156155 }
157156
158- if t .con .connected {
159- // Disregard errors from previous stream, futher details inside Close().
160- _ = t .Close ()
161- }
162-
163157 port := "22"
164158 if u .Port () != "" {
165159 port = u .Port ()
@@ -189,13 +183,18 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
189183 return nil
190184 }
191185
186+ t .con .m .RLock ()
187+ if t .con .connected == true {
188+ // The connection is no longer shared across actions, so ensures
189+ // all has been released before starting a new connection.
190+ _ = t .Close ()
191+ }
192+ t .con .m .RUnlock ()
193+
192194 err = t .createConn (t .addr , sshConfig )
193195 if err != nil {
194196 return nil , err
195197 }
196- t .con .m .Lock ()
197- t .con .connected = true
198- t .con .m .Unlock ()
199198
200199 traceLog .Info ("[ssh]: creating new ssh session" )
201200 if t .con .session , err = t .con .client .NewSession (); err != nil {
@@ -244,12 +243,12 @@ func (t *sshSmartSubtransport) Action(transportOptionsURL string, action git2go.
244243 return nil
245244
246245 default :
247- t .con .m .Lock ()
246+ t .con .m .RLock ()
248247 if ! t .con .connected {
249- t .con .m .Unlock ()
248+ t .con .m .RUnlock ()
250249 return nil
251250 }
252- t .con .m .Unlock ()
251+ t .con .m .RUnlock ()
253252
254253 _ , err := io .Copy (w , reader )
255254 if err != nil {
@@ -286,8 +285,10 @@ func (t *sshSmartSubtransport) createConn(addr string, sshConfig *ssh.ClientConf
286285 return err
287286 }
288287
289- t .con .conn = conn
288+ t .con .m .Lock ()
289+ t .con .connected = true
290290 t .con .client = ssh .NewClient (c , chans , reqs )
291+ t .con .m .Unlock ()
291292
292293 return nil
293294}
@@ -309,29 +310,24 @@ func (t *sshSmartSubtransport) Close() error {
309310 if t .con .client != nil && t .stdin != nil {
310311 _ = t .stdin .Close ()
311312 }
312- t .con . client = nil
313+ t .stdin = nil
313314
314315 if t .con .session != nil {
315316 traceLog .Info ("[ssh]: session.Close()" , "server" , t .addr )
316317 _ = t .con .session .Close ()
317318 }
318319 t .con .session = nil
319320
320- return nil
321- }
322-
323- func (t * sshSmartSubtransport ) Free () {
324- traceLog .Info ("[ssh]: sshSmartSubtransport.Free()" )
325321 if t .con .client != nil {
326322 _ = t .con .client .Close ()
327323 }
328324
329- if t .con .conn != nil {
330- _ = t .con .conn .Close ()
331- }
332- t .con .m .Lock ()
333325 t .con .connected = false
334- t .con .m .Unlock ()
326+
327+ return nil
328+ }
329+
330+ func (t * sshSmartSubtransport ) Free () {
335331}
336332
337333type sshSmartSubtransportStream struct {
0 commit comments