towards peerstore iterate
[oweals/gnunet.git] / src / peerstore / peerstore_common.c
1 /*
2       This file is part of GNUnet
3       (C) 2012-2013 Christian Grothoff (and other contributing authors)
4
5       GNUnet is free software; you can redistribute it and/or modify
6       it under the terms of the GNU General Public License as published
7       by the Free Software Foundation; either version 3, or (at your
8       option) any later version.
9
10       GNUnet is distributed in the hope that it will be useful, but
11       WITHOUT ANY WARRANTY; without even the implied warranty of
12       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13       General Public License for more details.
14
15       You should have received a copy of the GNU General Public License
16       along with GNUnet; see the file COPYING.  If not, write to the
17       Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18       Boston, MA 02111-1307, USA.
19  */
20 /**
21  * @file peerstore/peerstore_common.c
22  * @brief Helper peerstore functions
23  * @author Omar Tarabai
24  */
25
26 #include "peerstore_common.h"
27
28 /**
29  * Creates a record message ready to be sent
30  *
31  * @param sub_system sub system string
32  * @param peer Peer identity (can be NULL)
33  * @param key record key string (can be NULL)
34  * @param value record value BLOB (can be NULL)
35  * @param value_size record value size in bytes (set to 0 if value is NULL)
36  * @param expiry absolute time after which the record expires
37  * @param msg_type message type to be set in header
38  * @return pointer to record message struct
39  */
40 struct StoreRecordMessage *
41 PEERSTORE_create_record_message(const char *sub_system,
42     const struct GNUNET_PeerIdentity *peer,
43     const char *key,
44     const void *value,
45     size_t value_size,
46     struct GNUNET_TIME_Absolute expiry,
47     uint16_t msg_type)
48 {
49   struct StoreRecordMessage *srm;
50   size_t ss_size;
51   size_t key_size;
52   size_t request_size;
53   void *dummy;
54
55   ss_size = strlen(sub_system) + 1;
56   if(NULL == key)
57     key_size = 0;
58   else
59     key_size = strlen(key) + 1;
60   request_size = sizeof(struct StoreRecordMessage) +
61       ss_size +
62       key_size +
63       value_size;
64   srm = GNUNET_malloc(request_size);
65   srm->header.size = htons(request_size);
66   srm->header.type = htons(msg_type);
67   srm->key_size = htons(key_size);
68   srm->expiry = expiry;
69   if(NULL == peer)
70     srm->peer_set = htons(GNUNET_NO);
71   else
72   {
73     srm->peer_set = htons(GNUNET_YES);
74     srm->peer = *peer;
75   }
76   srm->sub_system_size = htons(ss_size);
77   srm->value_size = htons(value_size);
78   dummy = &srm[1];
79   memcpy(dummy, sub_system, ss_size);
80   dummy += ss_size;
81   memcpy(dummy, key, key_size);
82   dummy += key_size;
83   memcpy(dummy, value, value_size);
84   return srm;
85
86 }
87
88 /**
89  * Parses a message carrying a record
90  *
91  * @param message the actual message
92  * @return Pointer to record or NULL if error
93  */
94 struct GNUNET_PEERSTORE_Record *
95 PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message)
96 {
97   struct StoreRecordMessage *srm;
98   struct GNUNET_PEERSTORE_Record *record;
99   uint16_t req_size;
100   uint16_t ss_size;
101   uint16_t key_size;
102   uint16_t value_size;
103   char *dummy;
104
105   req_size = ntohs(message->size);
106   if(req_size < sizeof(struct StoreRecordMessage))
107     return NULL;
108   srm = (struct StoreRecordMessage *)message;
109   ss_size = ntohs(srm->sub_system_size);
110   key_size = ntohs(srm->key_size);
111   value_size = ntohs(srm->value_size);
112   if(ss_size + key_size + value_size + sizeof(struct StoreRecordMessage)
113         != req_size)
114     return NULL;
115   record = GNUNET_new(struct GNUNET_PEERSTORE_Record);
116   if(GNUNET_YES == ntohs(srm->peer_set))
117   {
118     record->peer = GNUNET_new(struct GNUNET_PeerIdentity);
119     memcpy(record->peer, &srm->peer, sizeof(struct GNUNET_PeerIdentity));
120   }
121   record->expiry = srm->expiry;
122   dummy = (char *)&srm[1];
123   if(ss_size > 0)
124   {
125     record->sub_system = GNUNET_strdup(dummy);
126     dummy += ss_size;
127   }
128   if(key_size > 0)
129   {
130     record->key = GNUNET_strdup(dummy);
131     dummy += key_size;
132   }
133   if(value_size > 0)
134   {
135     record->value = GNUNET_malloc(value_size);
136     memcpy(record->value, dummy, value_size);
137   }
138   record->value_size = value_size;
139
140   return record;
141 }