diff options
author | Rob Austein <sra@hactrn.net> | 2016-12-21 15:42:09 -0500 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2016-12-21 15:42:09 -0500 |
commit | a86b6d255187a0a6a91916c14b0da49210fbed91 (patch) | |
tree | 192c4e84901fd02a34425ca82a6e9a556367d3cf | |
parent | d492caaf91d37d7623a57e2d77d3d61fd8ffbda0 (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-x | projects/hsm/cryptech_upload | 23 |
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) |