aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-12-21 15:42:09 -0500
committerRob Austein <sra@hactrn.net>2016-12-21 15:42:09 -0500
commita86b6d255187a0a6a91916c14b0da49210fbed91 (patch)
tree192c4e84901fd02a34425ca82a6e9a556367d3cf
parentd492caaf91d37d7623a57e2d77d3d61fd8ffbda0 (diff)
Rewrite core upload loop to simplify and fix race conditions.
The main loop in cryptech_upload:send_file() was much more complicated than necessary, and also contained some hidden assumptions about serial I/O timing which happened to fail on the first two machines I tested. We already had a perfectly good buffered-input function, so rewrote to use that, and simplified control structure in the process. In theory, the new code should work in any environment where the old one did, but this has not yet been confirmed.
-rwxr-xr-xprojects/hsm/cryptech_upload23
1 files changed, 7 insertions, 16 deletions
diff --git a/projects/hsm/cryptech_upload b/projects/hsm/cryptech_upload
index 17395ce..b41f25b 100755
--- a/projects/hsm/cryptech_upload
+++ b/projects/hsm/cryptech_upload
@@ -191,33 +191,24 @@ def send_file(src, size, args, dst):
return False
# 2. Write file contents while calculating CRC-32
- while True:
+ chunks = int((size + chunk_size - 1) / chunk_size)
+ for counter in xrange(chunks):
data = src.read(chunk_size)
- if not data:
- break
dst.write(data)
dst.flush()
- print("Wrote {!s} bytes (chunk {!s}/{!s})".format(len(data), counter, int(size / chunk_size)))
+ print("Wrote {!s} bytes (chunk {!s}/{!s})".format(len(data), counter + 1, chunks))
# read ACK (a counter of number of 4k chunks received)
- while True:
- ack_bytes = dst.read(4)
- if len(ack_bytes) == 4:
- break
- print("ERROR: Did not receive an ACK, got {!r}".format(ack_bytes))
- dst.write("\r") # eventually get back to the CLI prompt
- dst.flush()
- ack = struct.unpack("<I", ack_bytes)[0]
+ ack_bytes = ""
+ while len(ack_bytes) < 4:
+ ack_bytes += _read(dst)
+ ack = struct.unpack("<I", ack_bytes[:4])[0]
if ack != counter + 1:
print("ERROR: Did not receive the expected counter as ACK (got {!r}/{!r}, not {!r})".format(ack, ack_bytes, counter))
- flush = dst.read(100)
- print("FLUSH data: {!r}".format(flush))
return False
counter += 1
crc = crc32(data, crc) & 0xffffffff
- _read(dst)
-
# 3. Write CRC-32 (4 bytes)
_write(dst, struct.pack("<I", crc))
response = _read(dst)