Skip to content

Commit 954daad

Browse files
authored
Merge pull request #300 from ellemouton/revokeExpiredSessions
multi: revoke expired sessions
2 parents 2c446cd + 7a0a18d commit 954daad

File tree

3 files changed

+75
-7
lines changed

3 files changed

+75
-7
lines changed

session/server.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,14 @@ type GRPCServerCreator func(opts ...grpc.ServerOption) *grpc.Server
1919
type mailboxSession struct {
2020
server *grpc.Server
2121

22-
wg sync.WaitGroup
22+
wg sync.WaitGroup
23+
quit chan struct{}
24+
}
25+
26+
func newMailboxSession() *mailboxSession {
27+
return &mailboxSession{
28+
quit: make(chan struct{}),
29+
}
2330
}
2431

2532
func (m *mailboxSession) start(session *Session,
@@ -62,6 +69,7 @@ func (m *mailboxSession) run(mailboxServer *mailbox.Server) {
6269

6370
func (m *mailboxSession) stop() {
6471
m.server.Stop()
72+
close(m.quit)
6573
m.wg.Wait()
6674
}
6775

@@ -82,7 +90,9 @@ func NewServer(serverCreator GRPCServerCreator) *Server {
8290
}
8391
}
8492

85-
func (s *Server) StartSession(session *Session, authData []byte) error {
93+
func (s *Server) StartSession(session *Session, authData []byte) (chan struct{},
94+
error) {
95+
8696
s.activeSessionsMtx.Lock()
8797
defer s.activeSessionsMtx.Unlock()
8898

@@ -91,11 +101,13 @@ func (s *Server) StartSession(session *Session, authData []byte) error {
91101

92102
_, ok := s.activeSessions[id]
93103
if ok {
94-
return fmt.Errorf("session %x is already active", id[:])
104+
return nil, fmt.Errorf("session %x is already active", id[:])
95105
}
96106

97-
s.activeSessions[id] = &mailboxSession{}
98-
return s.activeSessions[id].start(session, s.serverCreator, authData)
107+
sess := newMailboxSession()
108+
s.activeSessions[id] = sess
109+
110+
return sess.quit, sess.start(session, s.serverCreator, authData)
99111
}
100112

101113
func (s *Server) StopSession(localPublicKey *btcec.PublicKey) error {

session_rpcserver.go

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"strings"
7+
"sync"
78
"time"
89

910
"github.com/btcsuite/btcd/btcec"
@@ -20,6 +21,18 @@ type sessionRpcServer struct {
2021

2122
db *session.DB
2223
sessionServer *session.Server
24+
25+
quit chan struct{}
26+
wg sync.WaitGroup
27+
stopOnce sync.Once
28+
}
29+
30+
// stop cleans up any sessionRpcServer resources.
31+
func (s *sessionRpcServer) stop() {
32+
s.stopOnce.Do(func() {
33+
close(s.quit)
34+
s.wg.Wait()
35+
})
2336
}
2437

2538
// AddSession adds and starts a new Terminal Connect session.
@@ -72,6 +85,9 @@ func (s *sessionRpcServer) AddSession(_ context.Context,
7285
// resumeSession tries to start an existing session if it is not expired, not
7386
// revoked and a LiT session.
7487
func (s *sessionRpcServer) resumeSession(sess *session.Session) error {
88+
pubKey := sess.LocalPublicKey
89+
pubKeyBytes := pubKey.SerializeCompressed()
90+
7591
// We only start non-revoked, non-expired LiT sessions. Everything else
7692
// we just skip.
7793
if sess.State != session.StateInUse &&
@@ -88,12 +104,50 @@ func (s *sessionRpcServer) resumeSession(sess *session.Session) error {
88104
}
89105
if sess.Expiry.Before(time.Now()) {
90106
log.Debugf("Not resuming session %x with expiry %s",
91-
sess.LocalPublicKey.SerializeCompressed(), sess.Expiry)
107+
pubKeyBytes, sess.Expiry)
108+
109+
if err := s.db.RevokeSession(pubKey); err != nil {
110+
return fmt.Errorf("error revoking session: %v", err)
111+
}
112+
92113
return nil
93114
}
94115

95116
authData := []byte("Authorization: Basic " + s.basicAuth)
96-
return s.sessionServer.StartSession(sess, authData)
117+
sessionClosedSub, err := s.sessionServer.StartSession(sess, authData)
118+
if err != nil {
119+
return err
120+
}
121+
122+
s.wg.Add(1)
123+
go func() {
124+
defer s.wg.Done()
125+
126+
ticker := time.NewTimer(time.Until(sess.Expiry))
127+
defer ticker.Stop()
128+
129+
select {
130+
case <-s.quit:
131+
case <-sessionClosedSub:
132+
case <-ticker.C:
133+
log.Debugf("Stopping expired session %x with "+
134+
"type %d", pubKeyBytes, sess.Type)
135+
136+
err = s.sessionServer.StopSession(pubKey)
137+
if err != nil {
138+
log.Debugf("Error stopping session: "+
139+
"%v", err)
140+
}
141+
142+
err = s.db.RevokeSession(pubKey)
143+
if err != nil {
144+
log.Debugf("error revoking session: "+
145+
"%v", err)
146+
}
147+
}
148+
}()
149+
150+
return err
97151
}
98152

99153
// ListSessions returns all sessions known to the session store.

terminal.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ func (g *LightningTerminal) Run() error {
227227
basicAuth: g.rpcProxy.basicAuth,
228228
db: g.sessionDB,
229229
sessionServer: g.sessionServer,
230+
quit: make(chan struct{}),
230231
}
231232

232233
// Now start up all previously created sessions.
@@ -838,6 +839,7 @@ func (g *LightningTerminal) shutdown() error {
838839
}
839840
}
840841

842+
g.sessionRpcServer.stop()
841843
if err := g.sessionDB.Close(); err != nil {
842844
log.Errorf("Error closing session DB: %v", err)
843845
returnErr = err

0 commit comments

Comments
 (0)