Skip to content

Commit 1faa547

Browse files
author
Paulo Gomes
authored
Merge pull request #775 from pjbgf/leak-conns
libgit2: dispose connections in SubTransport.Close
2 parents a00d0ed + bfa4e38 commit 1faa547

File tree

1 file changed

+21
-25
lines changed

1 file changed

+21
-25
lines changed

pkg/git/libgit2/managed/ssh.go

+21-25
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,11 @@ type sshSmartSubtransport struct {
9595
}
9696

9797
type 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

106105
func (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

337333
type sshSmartSubtransportStream struct {

0 commit comments

Comments
 (0)