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.
7487func (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.
0 commit comments