1111#include "packet_encryption.h"
1212#include "pivot_packet_dispatch.h"
1313
14+ // Async mode helpers (defined in core_async.c)
15+ extern BOOL async_in_work_hours (HttpTransportContext * ctx );
16+ extern DWORD async_calculate_sleep_ms (HttpTransportContext * ctx );
17+
1418/*!
1519 * @brief Prepare a winHTTP request with the given context.
1620 * @param ctx Pointer to the HTTP transport context to prepare the request from.
@@ -675,6 +679,24 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread)
675679 break ;
676680 }
677681
682+ // Async mode: wait until inside business hours before polling
683+ if (ctx -> async_mode && (ctx -> async_work_start != ctx -> async_work_end ) && !async_in_work_hours (ctx ))
684+ {
685+ dprintf ("[DISPATCH] Outside business hours, sleeping 60s before re-check" );
686+ if (ctx -> async_wake_event )
687+ {
688+ WaitForSingleObject (ctx -> async_wake_event , 60000 );
689+ }
690+ else
691+ {
692+ Sleep (60000 );
693+ }
694+ // Keep comms timestamp fresh so the timeout check doesn't
695+ // kill the transport during intentional out-of-hours sleep
696+ transport -> comms_last_packet = current_unix_timestamp ();
697+ continue ;
698+ }
699+
678700 dprintf ("[DISPATCH] Reading data from the remote side..." );
679701 result = packet_receive_http (remote , & packet );
680702
@@ -684,6 +706,24 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread)
684706 if (result == ERROR_EMPTY )
685707 {
686708 transport -> comms_last_packet = current_unix_timestamp ();
709+
710+ // In async mode, sleep for the configured poll interval on empty responses
711+ if (ctx -> async_mode && ctx -> async_poll_interval > 0 )
712+ {
713+ DWORD asyncDelay = async_calculate_sleep_ms (ctx );
714+ dprintf ("[DISPATCH] Async mode: no commands, sleeping for %ums" , asyncDelay );
715+ if (ctx -> async_wake_event )
716+ {
717+ WaitForSingleObject (ctx -> async_wake_event , asyncDelay );
718+ }
719+ else
720+ {
721+ Sleep (asyncDelay );
722+ }
723+ // Refresh timestamp so comms timeout doesn't fire after the async sleep
724+ transport -> comms_last_packet = current_unix_timestamp ();
725+ continue ;
726+ }
687727 }
688728 else if (result == ERROR_WINHTTP_CANNOT_CONNECT )
689729 {
@@ -802,6 +842,10 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread)
802842 {
803843 dprintf ("[DISPATCH] Packet was NULL, this indicates that it was a pivot packet" );
804844 }
845+
846+ // In async mode, do NOT sleep after handling a command — immediately
847+ // poll again to drain any remaining queued commands. The sleep only
848+ // happens on empty responses (no commands available).
805849 }
806850 }
807851
0 commit comments