/* read a packet ID acknowledgement record from buf into ack */ bool reliable_ack_read(struct reliable_ack *ack, struct buffer *buf, const struct session_id *sid) { struct gc_arena gc = gc_new(); int i; uint8_t count; packet_id_type net_pid; packet_id_type pid; struct session_id session_id_remote; if (!buf_read(buf, &count, sizeof(count))) { goto error; } for (i = 0; i < count; ++i) { if (!buf_read(buf, &net_pid, sizeof(net_pid))) { goto error; } if (ack->len >= RELIABLE_ACK_SIZE) { goto error; } pid = ntohpid(net_pid); ack->packet_id[ack->len++] = pid; } if (count) { if (!session_id_read(&session_id_remote, buf)) { goto error; } if (!session_id_defined(&session_id_remote) || !session_id_equal(&session_id_remote, sid)) { dmsg(D_REL_LOW, "ACK read BAD SESSION-ID FROM REMOTE, local=%s, remote=%s", session_id_print(sid, &gc), session_id_print(&session_id_remote, &gc)); goto error; } } gc_free(&gc); return true; error: gc_free(&gc); return false; }
/* print a reliable ACK record coming off the wire */ const char * reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc) { int i; uint8_t n_ack; struct session_id sid_ack; packet_id_type pid; struct buffer out = alloc_buf_gc (256, gc); buf_printf (&out, "["); if (!buf_read (buf, &n_ack, sizeof (n_ack))) goto done; for (i = 0; i < n_ack; ++i) { if (!buf_read (buf, &pid, sizeof (pid))) goto done; pid = ntohpid (pid); buf_printf (&out, " " packet_id_format, (packet_id_print_type)pid); } if (n_ack) { if (!session_id_read (&sid_ack, buf)) goto done; if (verbose) buf_printf (&out, " sid=%s", session_id_print (&sid_ack, gc)); } done: buf_printf (&out, " ]"); return BSTR (&out); }