@@ -139,6 +139,66 @@ func getAllTaskContextsFromDisk(sess *core.Session, task *core.Task) (*clientpb.
139139 }, nil
140140}
141141
142+ // getTaskContextFromDB fetches task context from DB + disk when session is not in memory.
143+ func getTaskContextFromDB (sessionID string , taskID uint32 , index int32 ) (* clientpb.TaskContext , error ) {
144+ dbSess , err := db .FindSession (sessionID )
145+ if err != nil || dbSess == nil {
146+ return nil , types .ErrNotFoundSession
147+ }
148+ dbTask , err := db .GetTaskBySessionAndSeq (sessionID , taskID )
149+ if err != nil {
150+ return nil , types .ErrNotFoundTask
151+ }
152+ entries , err := readTaskSpitesFromDisk (sessionID , dbTask .Seq )
153+ if err != nil || len (entries ) == 0 {
154+ return nil , types .ErrNotFoundTaskContent
155+ }
156+ var spite * implantpb.Spite
157+ if index == - 1 {
158+ spite = entries [len (entries )- 1 ].Spite
159+ } else {
160+ for _ , e := range entries {
161+ if e .Index == int (index ) {
162+ spite = e .Spite
163+ break
164+ }
165+ }
166+ }
167+ if spite == nil {
168+ return nil , types .ErrNotFoundTaskContent
169+ }
170+ return & clientpb.TaskContext {
171+ Task : dbTask .ToProtobuf (),
172+ Session : dbSess .ToProtobuf (),
173+ Spite : spite ,
174+ }, nil
175+ }
176+
177+ // getAllTaskContextFromDB fetches all task contexts from DB + disk when session is not in memory.
178+ func getAllTaskContextFromDB (sessionID string , taskID uint32 ) (* clientpb.TaskContexts , error ) {
179+ dbSess , err := db .FindSession (sessionID )
180+ if err != nil || dbSess == nil {
181+ return nil , types .ErrNotFoundSession
182+ }
183+ dbTask , err := db .GetTaskBySessionAndSeq (sessionID , taskID )
184+ if err != nil {
185+ return nil , types .ErrNotFoundTask
186+ }
187+ entries , err := readTaskSpitesFromDisk (sessionID , dbTask .Seq )
188+ if err != nil || len (entries ) == 0 {
189+ return nil , types .ErrNotFoundTaskContent
190+ }
191+ spites := make ([]* implantpb.Spite , 0 , len (entries ))
192+ for _ , e := range entries {
193+ spites = append (spites , e .Spite )
194+ }
195+ return & clientpb.TaskContexts {
196+ Task : dbTask .ToProtobuf (),
197+ Session : dbSess .ToProtobuf (),
198+ Spites : spites ,
199+ }, nil
200+ }
201+
142202func getTaskContext (sess * core.Session , task * core.Task , index int32 ) (* clientpb.TaskContext , error ) {
143203 var msg * implantpb.Spite
144204 var ok bool
@@ -174,7 +234,12 @@ func (rpc *Server) GetTasks(ctx context.Context, req *clientpb.TaskRequest) (*cl
174234 } else {
175235 sess , err := core .Sessions .Get (req .SessionId )
176236 if err != nil {
177- return nil , types .ErrNotFoundSession
237+ // Fallback to DB when session is not in memory (e.g., dead session)
238+ modelTasks , dbErr := db .ListTasksBySession (req .SessionId )
239+ if dbErr != nil {
240+ return nil , types .ErrNotFoundSession
241+ }
242+ return modelTasks .ToProtobuf (), nil
178243 }
179244 return sess .Tasks .ToProtobuf (), nil
180245 }
@@ -198,7 +263,7 @@ func (rpc *Server) GetTaskContent(ctx context.Context, req *clientpb.Task) (*cli
198263 }
199264 sess , err := core .Sessions .Get (req .SessionId )
200265 if err != nil {
201- return nil , types . ErrNotFoundSession
266+ return getTaskContextFromDB ( req . SessionId , req . TaskId , req . Need )
202267 }
203268 task := sess .Tasks .GetOrRecover (sess , req .TaskId )
204269 if task == nil {
@@ -217,7 +282,8 @@ func (rpc *Server) WaitTaskContent(ctx context.Context, req *clientpb.Task) (*cl
217282 }
218283 sess , err := core .Sessions .Get (req .SessionId )
219284 if err != nil {
220- return nil , types .ErrNotFoundSession
285+ // Session not in memory (dead), try DB+disk directly
286+ return getTaskContextFromDB (req .SessionId , req .TaskId , req .Need )
221287 }
222288 task := sess .Tasks .GetOrRecover (sess , req .TaskId )
223289 if task == nil {
@@ -269,7 +335,8 @@ func (rpc *Server) WaitTaskFinish(ctx context.Context, req *clientpb.Task) (*cli
269335 }
270336 sess , err := core .Sessions .Get (req .SessionId )
271337 if err != nil {
272- return nil , types .ErrNotFoundSession
338+ // Session not in memory (dead), try DB+disk directly
339+ return getTaskContextFromDB (req .SessionId , req .TaskId , - 1 )
273340 }
274341 task := sess .Tasks .GetOrRecover (sess , req .TaskId )
275342 if task == nil {
@@ -309,7 +376,7 @@ func (rpc *Server) GetAllTaskContent(ctx context.Context, req *clientpb.Task) (*
309376 }
310377 sess , err := core .Sessions .Get (req .SessionId )
311378 if err != nil {
312- return nil , types . ErrNotFoundSession
379+ return getAllTaskContextFromDB ( req . SessionId , req . TaskId )
313380 }
314381 task := sess .Tasks .GetOrRecover (sess , req .TaskId )
315382 if task == nil {
0 commit comments