peerstore API now uses MQ
[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  * Creates a MQ envelope for a single record
90  *
91  * @param sub_system sub system string
92  * @param peer Peer identity (can be NULL)
93  * @param key record key string (can be NULL)
94  * @param value record value BLOB (can be NULL)
95  * @param value_size record value size in bytes (set to 0 if value is NULL)
96  * @param expiry time after which the record expires
97  * @param msg_type message type to be set in header
98  * @return pointer to record message struct
99  */
100 struct GNUNET_MQ_Envelope *
101 PEERSTORE_create_record_mq_envelope(const char *sub_system,
102     const struct GNUNET_PeerIdentity *peer,
103     const char *key,
104     const void *value,
105     size_t value_size,
106     struct GNUNET_TIME_Absolute expiry,
107     uint16_t msg_type)
108 {
109   struct StoreRecordMessage *srm;
110   struct GNUNET_MQ_Envelope *ev;
111   size_t ss_size;
112   size_t key_size;
113   size_t msg_size;
114   void *dummy;
115
116   ss_size = strlen(sub_system) + 1;
117   if(NULL == key)
118     key_size = 0;
119   else
120     key_size = strlen(key) + 1;
121   msg_size = ss_size +
122       key_size +
123       value_size;
124   ev = GNUNET_MQ_msg_extra(srm, msg_size, msg_type);
125   srm->key_size = htons(key_size);
126   srm->expiry = expiry;
127   if(NULL == peer)
128     srm->peer_set = htons(GNUNET_NO);
129   else
130   {
131     srm->peer_set = htons(GNUNET_YES);
132     srm->peer = *peer;
133   }
134   srm->sub_system_size = htons(ss_size);
135   srm->value_size = htons(value_size);
136   dummy = &srm[1];
137   memcpy(dummy, sub_system, ss_size);
138   dummy += ss_size;
139   memcpy(dummy, key, key_size);
140   dummy += key_size;
141   memcpy(dummy, value, value_size);
142
143   return ev;
144 }
145
146 /**
147  * Parses a message carrying a record
148  *
149  * @param message the actual message
150  * @return Pointer to record or NULL if error
151  */
152 struct GNUNET_PEERSTORE_Record *
153 PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message)
154 {
155   struct StoreRecordMessage *srm;
156   struct GNUNET_PEERSTORE_Record *record;
157   uint16_t req_size;
158   uint16_t ss_size;
159   uint16_t key_size;
160   uint16_t value_size;
161   char *dummy;
162
163   req_size = ntohs(message->size);
164   if(req_size < sizeof(struct StoreRecordMessage))
165     return NULL;
166   srm = (struct StoreRecordMessage *)message;
167   ss_size = ntohs(srm->sub_system_size);
168   key_size = ntohs(srm->key_size);
169   value_size = ntohs(srm->value_size);
170   if(ss_size + key_size + value_size + sizeof(struct StoreRecordMessage)
171         != req_size)
172     return NULL;
173   record = GNUNET_new(struct GNUNET_PEERSTORE_Record);
174   if(GNUNET_YES == ntohs(srm->peer_set))
175   {
176     record->peer = GNUNET_new(struct GNUNET_PeerIdentity);
177     memcpy(record->peer, &srm->peer, sizeof(struct GNUNET_PeerIdentity));
178   }
179   record->expiry = GNUNET_new(struct GNUNET_TIME_Absolute);
180   *(record->expiry) = srm->expiry;
181   dummy = (char *)&srm[1];
182   if(ss_size > 0)
183   {
184     record->sub_system = GNUNET_strdup(dummy);
185     dummy += ss_size;
186   }
187   if(key_size > 0)
188   {
189     record->key = GNUNET_strdup(dummy);
190     dummy += key_size;
191   }
192   if(value_size > 0)
193   {
194     record->value = GNUNET_malloc(value_size);
195     memcpy(record->value, dummy, value_size);
196   }
197   record->value_size = value_size;
198
199   return record;
200 }