Repository : ssh://git@open-mesh.org/alfred
On branch : master
commit fcfe26c690ce59cbcab63ffa720b42f5e1737e24 Author: Sven Eckelmann sven@open-mesh.com Date: Fri Jan 11 20:07:56 2013 +0100
alfred: Add transaction management block to push_data
The transactions over the network should be secured using transactions based on the packet count and transaction id. As first step each alfred_push_data packet has to transport the current identifier of the transaction and the sequence number of the current packet.
Signed-off-by: Sven Eckelmann sven@open-mesh.com
fcfe26c690ce59cbcab63ffa720b42f5e1737e24 alfred.h | 2 ++ client.c | 4 +++- main.c | 2 ++ packet.h | 12 ++++++++++++ recv.c | 1 + send.c | 13 +++++++++++-- unix_sock.c | 11 ++++++++++- util.c | 25 +++++++++++++++++++++++++ 8 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/alfred.h b/alfred.h index 21f0078..e885e2a 100644 --- a/alfred.h +++ b/alfred.h @@ -126,3 +126,5 @@ int netsock_close(int sock); /* util.c */ int time_diff(struct timeval *tv1, struct timeval *tv2, struct timeval *tvdiff); +void time_random_seed(void); +uint16_t get_random_id(void); diff --git a/client.c b/client.c index f1629ab..7c7cb4d 100644 --- a/client.c +++ b/client.c @@ -124,7 +124,9 @@ int alfred_client_set_data(struct globals *globals)
push->header.type = ALFRED_PUSH_DATA; push->header.version = ALFRED_VERSION; - push->header.length = htons(len - sizeof(*push)); + push->header.length = htons(len - sizeof(push->header)); + push->tx.id = get_random_id(); + push->tx.seqno = htons(0);
/* we leave data->source "empty" */ memset(data->source, 0, sizeof(data->source)); diff --git a/main.c b/main.c index 43a6069..3ec38c0 100644 --- a/main.c +++ b/main.c @@ -81,6 +81,8 @@ static struct globals *alfred_init(int argc, char *argv[]) globals->clientmode_version = 0; globals->mesh_iface = "bat0";
+ time_random_seed(); + while ((opt = getopt_long(argc, argv, "ms:r:hi:b:vV:", long_options, &opt_ind)) != -1) { switch (opt) { diff --git a/packet.h b/packet.h index 3579a3d..a01015d 100644 --- a/packet.h +++ b/packet.h @@ -52,6 +52,16 @@ struct alfred_data { } __packed;
/** + * struct alfred_transaction_mgmt - Transaction Mgmt block for multiple packets + * @id: random identificator used for this transaction + * @seqno: Number of packet inside a transaction + */ +struct alfred_transaction_mgmt { + uint16_t id; + uint16_t seqno; +} __packed; + +/** * enum alfred_packet_type - Types of packet stored in the main alfred_tlv * @ALFRED_PUSH_DATA: Packet is an alfred_push_data_v* * @ALFRED_ANNOUNCE_MASTER: Packet is an alfred_announce_master_v* @@ -68,6 +78,7 @@ enum alfred_packet_type { /** * struct alfred_push_data_v0 - Packet to push data blocks to another * @header: TLV header describing the complete packet + * @tx: Transaction identificator and sequence number of packet * @data: multiple "alfred_data" blocks of arbitrary size (accumulated size * stored in "header.length") * @@ -75,6 +86,7 @@ enum alfred_packet_type { */ struct alfred_push_data_v0 { struct alfred_tlv header; + struct alfred_transaction_mgmt tx; /* flexible data block */ __extension__ struct alfred_data data[0]; } __packed; diff --git a/recv.c b/recv.c index 7d4d4bf..20da0ee 100644 --- a/recv.c +++ b/recv.c @@ -49,6 +49,7 @@ static int process_alfred_push_data(struct globals *globals, goto err;
len = ntohs(push->header.length); + len -= sizeof(*push) - sizeof(push->header); pos = (uint8_t *)push->data;
while (len > (int)sizeof(*data)) { diff --git a/send.c b/send.c index 01bc592..e378ed4 100644 --- a/send.c +++ b/send.c @@ -55,10 +55,13 @@ int push_data(struct globals *globals, struct in6_addr *destination, struct alfred_push_data_v0 *push; struct alfred_data *data; uint16_t total_length = 0; + size_t tlv_length; + uint16_t seqno = 0;
push = (struct alfred_push_data_v0 *)buf; push->header.type = ALFRED_PUSH_DATA; push->header.version = ALFRED_VERSION; + push->tx.id = get_random_id();
while (NULL != (hashit = hash_iterate(globals->data_hash, hashit))) { struct dataset *dataset = hashit->bucket->data; @@ -74,7 +77,10 @@ int push_data(struct globals *globals, struct in6_addr *destination, * first */ if (total_length + dataset->data.header.length + sizeof(*data) > MAX_PAYLOAD - sizeof(*push)) { - push->header.length = htons(total_length); + tlv_length = total_length; + tlv_length += sizeof(*push) - sizeof(push->header); + push->header.length = htons(tlv_length); + push->tx.seqno = htons(seqno++); send_alfred_packet(globals, destination, push, sizeof(*push) + total_length); total_length = 0; @@ -90,7 +96,10 @@ int push_data(struct globals *globals, struct in6_addr *destination, } /* send the final packet */ if (total_length) { - push->header.length = htons(total_length); + tlv_length = total_length; + tlv_length += sizeof(*push) - sizeof(push->header); + push->header.length = htons(tlv_length); + push->tx.seqno = htons(seqno++); send_alfred_packet(globals, destination, push, sizeof(*push) + total_length); } diff --git a/unix_sock.c b/unix_sock.c index 27dee54..fc50436 100644 --- a/unix_sock.c +++ b/unix_sock.c @@ -99,7 +99,13 @@ static int unix_sock_add_data(struct globals *globals,
len = ntohs(push->header.length);
- if (len < (int)sizeof(*data)) + if (len < (int)(sizeof(*push) + sizeof(push->header))) + return -1; + + /* subtract rest of push header */ + len -= sizeof(*push) - sizeof(push->header); + + if (len < (int)(sizeof(*data))) return -1;
data = push->data; @@ -151,6 +157,7 @@ static int unix_sock_req_data(struct globals *globals, int ret, len; uint8_t buf[MAX_PAYLOAD]; struct alfred_push_data_v0 *push; + uint16_t seqno = 0;
len = ntohs(request->header.length);
@@ -199,6 +206,7 @@ send_reply: push = (struct alfred_push_data_v0 *)buf; push->header.type = ALFRED_PUSH_DATA; push->header.version = ALFRED_VERSION; + push->tx.id = get_random_id();
while (NULL != (hashit = hash_iterate(globals->data_hash, hashit))) { struct dataset *dataset = hashit->bucket->data; @@ -214,6 +222,7 @@ send_reply:
len = dataset->data.header.length + sizeof(*data); push->header.length = htons(len); + push->tx.seqno = htons(seqno++);
write(client_sock, buf, sizeof(*push) + len); } diff --git a/util.c b/util.c index 0d026b1..ffb7aca 100644 --- a/util.c +++ b/util.c @@ -20,6 +20,9 @@ */
#include <sys/time.h> +#include <time.h> +#include <stdint.h> +#include <stdlib.h>
int time_diff(struct timeval *tv1, struct timeval *tv2, struct timeval *tvdiff) { @@ -33,3 +36,25 @@ int time_diff(struct timeval *tv1, struct timeval *tv2,
return (tvdiff->tv_sec >= 0); } + +void time_random_seed(void) +{ + struct timespec now; + uint8_t *c = (uint8_t *)&now; + size_t i; + unsigned int s = 0; + + clock_gettime(CLOCK_REALTIME, &now); + + for (i = 0; i < sizeof(now); i++) { + s *= 127u; + s += c[i]; + } + + srand(s); +} + +uint16_t get_random_id(void) +{ + return random(); +}