From 2cb4d347d04242be04383433771626bd8ca26129 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Wed, 1 Jun 2016 17:44:53 +0200
Subject: [PATCH] make the local tracer more robust

if a read from the remote tracer's socket fails, let's smash
the socket and wait for another remote tracer
---
 common/utils/T/local_tracer.c | 58 +++++++++++++++++++++++++++--------
 1 file changed, 46 insertions(+), 12 deletions(-)

diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c
index fb4cbd9a3e..c7247e980b 100644
--- a/common/utils/T/local_tracer.c
+++ b/common/utils/T/local_tracer.c
@@ -131,35 +131,69 @@ process:
 
 static void *forward_remote_messages(void *_f)
 {
+#define PUT(x) do { \
+    if (bufsize == bufmaxsize) { \
+      bufmaxsize += 4096; \
+      buf = realloc(buf, bufmaxsize); \
+      if (buf == NULL) abort(); \
+    } \
+    buf[bufsize] = x; \
+    bufsize++; \
+  } while (0)
+#define PUT_BUF(x, l) do { \
+    char *zz = (char *)(x); \
+    int len = l; \
+    while (len) { PUT(*zz); zz++; len--; } \
+  } while (0)
+
   forward_data *f = _f;
   int from;
   int to;
   int l, len;
   char *b;
-  char buf[1024];
+  char *buf = NULL;
+  int bufsize = 0;
+  int bufmaxsize = 0;
+  char t;
 
 again:
 
-  /* Note: if the remote socket dies while a transfer is running
-   *       then the state of the tracer will be totally messed up.
-   * If that ever happens, things are messed up anyway, so no big
-   * deal... (TODO: to be refined at some point, maybe)
-   */
   while (1) {
     from = f->socket_remote;
     to = f->socket_local;
-    len = read(from, buf, 1024);
-    if (len <= 0) break;
-    b = buf;
 
-    while (len) {
-      l = write(to, b, len);
+    bufsize = 0;
+
+    /* let's read and process messages */
+    len = read(from, &t, 1); if (len <= 0) goto dead;
+    PUT(t);
+
+    switch (t) {
+    case 0:
+    case 1:
+      /* message 0 and 1: get a length and then 'length' numbers */
+      if (read(from, &len, sizeof(int)) != sizeof(int)) goto dead;
+      PUT_BUF(&len, 4);
+      while (len) {
+        if (read(from, &l, sizeof(int)) != sizeof(int)) goto dead;
+        PUT_BUF(&l, 4);
+        len--;
+      }
+      break;
+
+    case 2: break;
+    }
+
+    b = buf;
+    while (bufsize) {
+      l = write(to, b, bufsize);
       if (l <= 0) abort();
-      len -= l;
+      bufsize -= l;
       b += l;
     }
   }
 
+dead:
   /* socket died, let's stop all traces and wait for another tracer */
   buf[0] = 1;
   if (write(to, buf, 1) != 1) abort();
-- 
GitLab