Commit af7a3193 authored by Joel Martin's avatar Joel Martin

Assemble partial received frames.

Apparently both native and flash WebSockets implementations can send
partial packets.
parent 89fbd66f
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
var host = null, port = null, sendDelay = 0; var host = null, port = null, sendDelay = 0;
var ws = null, update_ref = null, send_ref = null; var ws = null, update_ref = null, send_ref = null;
var sent = 0, received = 0, errors = 0; var sent = 0, received = 0, errors = 0;
var max_send = 2000;
Array.prototype.pushStr = function (str) { Array.prototype.pushStr = function (str) {
var n = str.length; var n = str.length;
...@@ -51,8 +52,21 @@ ...@@ -51,8 +52,21 @@
function check_respond(data) { function check_respond(data) {
//console.log(">> check_respond"); //console.log(">> check_respond");
var decoded, str, length, chksum, nums, arr; var decoded, first, last, str, length, chksum, nums, arr;
decoded = Base64.decode(data); decoded = Base64.decode(data);
first = String.fromCharCode(decoded.shift());
last = String.fromCharCode(decoded.pop());
if (first != "^") {
console.error("Packet missing start char '^'");
errors++;
return;
}
if (last != "$") {
console.error("Packet missing end char '$'");
errors++;
return;
}
arr = decoded.map(function(num) { arr = decoded.map(function(num) {
return String.fromCharCode(num); return String.fromCharCode(num);
} ).join('').split(':'); } ).join('').split(':');
...@@ -77,14 +91,14 @@ ...@@ -77,14 +91,14 @@
} }
function send() { function send() {
var length = Math.floor(Math.random()*1991) + 10; // 10 - 2000 var length = Math.floor(Math.random()*(max_send-9)) + 10; // 10 - max_send
var numlist = [], arr = []; var numlist = [], arr = [];
for (var i=0; i < length; i++) { for (var i=0; i < length; i++) {
numlist.push( Math.floor(Math.random()*10) ); numlist.push( Math.floor(Math.random()*10) );
} }
chksum = numlist.reduce(add); chksum = numlist.reduce(add);
var nums = numlist.join(''); var nums = numlist.join('');
arr.pushStr(length + ":" + chksum + ":" + nums) arr.pushStr("^" + length + ":" + chksum + ":" + nums + "$")
ws.send(Base64.encode(arr)); ws.send(Base64.encode(arr));
sent++; sent++;
} }
......
...@@ -36,41 +36,56 @@ def traffic(token="."): ...@@ -36,41 +36,56 @@ def traffic(token="."):
sys.stdout.flush() sys.stdout.flush()
def check(buf): def check(buf):
try: try:
data = b64decode(buf[1:-1]) data = b64decode(buf[1:-1])
except: except:
print "\n<BOF>" + repr(buf) + "<EOF>"
return "Failed to decode" return "Failed to decode"
try: chunks = data.count('$')
length, chksum, nums = data.split(':') if chunks > 1:
length = int(length) traffic(str(chunks))
chksum = int(chksum)
except:
return "Invalid data format"
if len(nums) != length: for chunk in data.split("$"):
return "Real length %d is not %d" % (len(nums), length) if not chunk: continue
inv = nums.translate(None, "0123456789") if chunk[0] != "^":
if inv: return "buf did not start with '^'"
return "Invalid characters found: %s" % inv
try:
length, chksum, nums = chunk[1:].split(':')
length = int(length)
chksum = int(chksum)
except:
print "\n<BOF>" + repr(data) + "<EOF>"
return "Invalid data format"
real_chksum = 0 if len(nums) != length:
for num in nums: return "Real length %d is not %d" % (len(nums), length)
real_chksum += int(num)
if real_chksum != chksum: inv = nums.translate(None, "0123456789")
return "Real checksum %d is not %d" % (real_chksum, chksum) if inv:
return "Invalid characters found: %s" % inv
real_chksum = 0
for num in nums:
real_chksum += int(num)
if real_chksum != chksum:
return "Real checksum %d is not %d" % (real_chksum, chksum)
def generate(): def generate():
length = random.randint(10, 2000) length = random.randint(10, 10000)
numlist = [] numlist = rand_array[10000-length:]
for i in range(0, length): # Error in length
numlist.append(random.randint(0, 9)) #numlist.append(5)
chksum = sum(numlist) chksum = sum(numlist)
# Error in checksum
#numlist[0] = 5
nums = "".join( [str(n) for n in numlist] ) nums = "".join( [str(n) for n in numlist] )
data = "%d:%d:%s" % (length, chksum, nums) data = "^%d:%d:%s$" % (length, chksum, nums)
buf = "\x00" + b64encode(data) + "\xff" buf = "\x00" + b64encode(data) + "\xff"
return buf return buf
...@@ -78,6 +93,7 @@ def generate(): ...@@ -78,6 +93,7 @@ def generate():
def responder(client, delay=500): def responder(client, delay=500):
global errors global errors
cqueue = [] cqueue = []
cpartial = ""
socks = [client] socks = [client]
last_send = time.time() * 1000 last_send = time.time() * 1000
...@@ -89,13 +105,21 @@ def responder(client, delay=500): ...@@ -89,13 +105,21 @@ def responder(client, delay=500):
buf = client.recv(buffer_size) buf = client.recv(buffer_size)
if len(buf) == 0: raise Exception("Client closed") if len(buf) == 0: raise Exception("Client closed")
#print "Client recv: %s (%d)" % (repr(buf[1:-1]), len(buf)) #print "Client recv: %s (%d)" % (repr(buf[1:-1]), len(buf))
err = check(buf) if buf[-1] == '\xff':
if err: if cpartial:
traffic("}") err = check(cpartial + buf)
errors = errors + 1 cpartial = ""
print err else:
err = check(buf)
if err:
traffic("}")
errors = errors + 1
print err
else:
traffic(">")
else: else:
traffic(">") traffic(".>")
cpartial = cpartial + buf
now = time.time() * 1000 now = time.time() * 1000
if client in outs and now > (last_send + delay): if client in outs and now > (last_send + delay):
...@@ -139,4 +163,10 @@ if __name__ == '__main__': ...@@ -139,4 +163,10 @@ if __name__ == '__main__':
except: except:
print "Usage: <listen_port> [delay_ms]" print "Usage: <listen_port> [delay_ms]"
sys.exit(1) sys.exit(1)
print "Prepopulating random array"
rand_array = []
for i in range(0, 10000):
rand_array.append(random.randint(0, 9))
start_server(listen_port, delay=delay) start_server(listen_port, delay=delay)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment