Assemble partial received frames.

Apparently both native and flash WebSockets implementations can send
partial packets.
This commit is contained in:
Joel Martin 2010-04-16 15:53:59 -05:00
parent 89fbd66fa9
commit af7a319387
2 changed files with 74 additions and 30 deletions

View File

@ -35,6 +35,7 @@
var host = null, port = null, sendDelay = 0;
var ws = null, update_ref = null, send_ref = null;
var sent = 0, received = 0, errors = 0;
var max_send = 2000;
Array.prototype.pushStr = function (str) {
var n = str.length;
@ -51,8 +52,21 @@
function check_respond(data) {
//console.log(">> check_respond");
var decoded, str, length, chksum, nums, arr;
var decoded, first, last, str, length, chksum, nums, arr;
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) {
return String.fromCharCode(num);
} ).join('').split(':');
@ -77,14 +91,14 @@
}
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 = [];
for (var i=0; i < length; i++) {
numlist.push( Math.floor(Math.random()*10) );
}
chksum = numlist.reduce(add);
var nums = numlist.join('');
arr.pushStr(length + ":" + chksum + ":" + nums)
arr.pushStr("^" + length + ":" + chksum + ":" + nums + "$")
ws.send(Base64.encode(arr));
sent++;
}

View File

@ -36,41 +36,56 @@ def traffic(token="."):
sys.stdout.flush()
def check(buf):
try:
data = b64decode(buf[1:-1])
except:
print "\n<BOF>" + repr(buf) + "<EOF>"
return "Failed to decode"
try:
length, chksum, nums = data.split(':')
length = int(length)
chksum = int(chksum)
except:
return "Invalid data format"
chunks = data.count('$')
if chunks > 1:
traffic(str(chunks))
if len(nums) != length:
return "Real length %d is not %d" % (len(nums), length)
for chunk in data.split("$"):
if not chunk: continue
inv = nums.translate(None, "0123456789")
if inv:
return "Invalid characters found: %s" % inv
if chunk[0] != "^":
return "buf did not start with '^'"
real_chksum = 0
for num in nums:
real_chksum += int(num)
try:
length, chksum, nums = chunk[1:].split(':')
length = int(length)
chksum = int(chksum)
except:
print "\n<BOF>" + repr(data) + "<EOF>"
return "Invalid data format"
if real_chksum != chksum:
return "Real checksum %d is not %d" % (real_chksum, chksum)
if len(nums) != length:
return "Real length %d is not %d" % (len(nums), length)
inv = nums.translate(None, "0123456789")
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():
length = random.randint(10, 2000)
numlist = []
for i in range(0, length):
numlist.append(random.randint(0, 9))
length = random.randint(10, 10000)
numlist = rand_array[10000-length:]
# Error in length
#numlist.append(5)
chksum = sum(numlist)
# Error in checksum
#numlist[0] = 5
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"
return buf
@ -78,6 +93,7 @@ def generate():
def responder(client, delay=500):
global errors
cqueue = []
cpartial = ""
socks = [client]
last_send = time.time() * 1000
@ -89,13 +105,21 @@ def responder(client, delay=500):
buf = client.recv(buffer_size)
if len(buf) == 0: raise Exception("Client closed")
#print "Client recv: %s (%d)" % (repr(buf[1:-1]), len(buf))
err = check(buf)
if err:
traffic("}")
errors = errors + 1
print err
if buf[-1] == '\xff':
if cpartial:
err = check(cpartial + buf)
cpartial = ""
else:
err = check(buf)
if err:
traffic("}")
errors = errors + 1
print err
else:
traffic(">")
else:
traffic(">")
traffic(".>")
cpartial = cpartial + buf
now = time.time() * 1000
if client in outs and now > (last_send + delay):
@ -139,4 +163,10 @@ if __name__ == '__main__':
except:
print "Usage: <listen_port> [delay_ms]"
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)