]> _ Git - remote-logging.git/commitdiff
server: Add retries with random backoff for file uploads
authormivirl <>
Sun, 3 Mar 2024 01:06:49 +0000 (19:06 -0600)
committermivirl <>
Sun, 3 Mar 2024 01:06:49 +0000 (19:06 -0600)
When binding a port on the server side, there's a chance that another
process has already bound the port. Retries a few times with a random
backoff to reduce the number of collisions

Future versions will reduce the number of ports used by the server,
and this change makes it possible with fewer issues.

src/client.pl
src/server.sh

index dfaa3c28c128dde7ca6aba684e6b4cee271abc0f..8e203771fd0d2e3113ce8968906e9f126dac9b3e 100644 (file)
@@ -243,9 +243,23 @@ sub send_file {
     $socket->send("file\n");
     $socket->send("$fileName\n");
     $socket->send("$fileHash\n");
-    sleep 2;
-    $socket->recv(my $port, 128);
-    ($port) = $port =~ m/(\d+)/;
+    $socket->recv(my $ignored, 128);
+    my $port = undef;
+    my $r;
+    my $sleeptime = 2;
+    my $attemptcount = 0;
+    while (! defined $port) {
+        sleep $sleeptime;
+        $sleeptime *= 2;
+        $sleeptime = 10 if ($sleeptime > 10);
+        $socket->recv($r, 128);
+        ($port) = $r =~ m/(\d+)/;
+        $attemptcount += 1;
+        if ($attemptcount >= 5) {
+            print_log "File: upload failure ($file)";
+            exit;
+        }
+    }
 
     # Send file once
     print_log "File: upload port is $port ($file)";
index 0a9bc89cda8978ba6ae00fedce7dcdad037c8d62..b6245d4f53894cbe216ba67c7084cbd83aec1ada 100644 (file)
@@ -118,14 +118,36 @@ while read -r COMMAND; do
             FILENAME="${FILENAME}_${SUFFIX}"
         fi
 
+        # Grab an open port and listen for file. Use netcat since sh can't
+        # handle binary data well
+        ATTEMPTCOUNT=0
+        SLEEPTIME=0
+        while true; do
+            sleep $(( RANDOM % (SLEEPTIME + 5) + 1 ))
+            PORT=$(( (RANDOM * 2 + RANDOM % 2) % 64511 + 1024 ))
+            nc -w 7 -l -p "$PORT" > "$FILENAME" 2>/dev/null &
+            NC_PID=$!
+            # Wait for nc to fail. There seems to be a bug with busybox sh where
+            # using the builtin sleep when following the backgrounded nc
+            # doesn't sleep, so calling the binary again
+            ../../../busybox sleep 1
+            if ps -o pid | grep -q -e $NC_PID ; then
+                break
+            fi
+            ATTEMPTCOUNT=$(( ATTEMPTCOUNT + 1 ))
+            SLEEPTIME=$(( SLEEPTIME + 2 ))
+            if [ $ATTEMPTCOUNT -gt 5 ]; then
+                echo "$CLIENTNAME: ($FILENAME) Failed to bind open port for file transfer, giving up" >&2
+                echo "[${FILERECVTIME}] File transfer failed: ${FILENAME}" >> _files.log
+                exit
+            fi
+        done
+        echo "$PORT"
+        wait $NC_PID
+
         FILERECVTIME="$(date '+%Y-%m-%d %H:%M:%S')"
         echo "[${FILERECVTIME}] File received: ${FILENAME}" >> _files.log
 
-        # Client should send with `cat file | nc ip port`
-        PORT=$(( (RANDOM * 2 + RANDOM % 2) % 64511 + 1024 ))
-        echo "$PORT"
-        nc -w 5 -l -p "$PORT" > "$FILENAME"
-
         HASH=$(md5sum "$FILENAME" | cut -d' ' -f1)
         if [ "$HASH" != "$TMPHASH" ]; then
             echo "Checksum error"