peerstore helper file
[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 lifetime relative time after which the record expires
37  * @return pointer to record message struct
38  */
39 struct StoreRecordMessage *
40 PEERSTORE_create_record_message(const char *sub_system,
41     const struct GNUNET_PeerIdentity *peer,
42     const char *key,
43     const void *value,
44     size_t value_size,
45     struct GNUNET_TIME_Relative lifetime)
46 {
47   struct StoreRecordMessage *srm;
48   size_t ss_size;
49   size_t key_size;
50   size_t request_size;
51   void *dummy;
52
53   ss_size = strlen(sub_system) + 1;
54   if(NULL == key)
55     key_size = 0;
56   else
57     key_size = strlen(key) + 1;
58   request_size = sizeof(struct StoreRecordMessage) +
59       ss_size +
60       key_size +
61       value_size;
62   srm = GNUNET_malloc(request_size);
63   srm->header.size = htons(request_size);
64   srm->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
65   srm->key_size = htons(key_size);
66   srm->lifetime = lifetime;
67   if(NULL == peer)
68     srm->peer_set = htons(GNUNET_NO);
69   else
70   {
71     srm->peer_set = htons(GNUNET_YES);
72     srm->peer = *peer;
73   }
74   srm->sub_system_size = htons(ss_size);
75   srm->value_size = htons(value_size);
76   dummy = &srm[1];
77   memcpy(dummy, sub_system, ss_size);
78   dummy += ss_size;
79   memcpy(dummy, key, key_size);
80   dummy += key_size;
81   memcpy(dummy, value, value_size);
82   return srm;
83
84 }
85
86 /**
87  * Parses a message carrying a record
88  *
89  * @param message the actual message
90  * @return Pointer to record or NULL if error
91  */
92 struct GNUNET_PEERSTORE_Record *
93 PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message)
94 {
95   struct StoreRecordMessage *srm;
96   struct GNUNET_PEERSTORE_Record *record;
97   uint16_t req_size;
98   uint16_t ss_size;
99   uint16_t key_size;
100   uint16_t value_size;
101   char *dummy;
102
103   req_size = ntohs(message->size);
104   if(req_size < sizeof(struct StoreRecordMessage))
105     return NULL;
106   srm = (struct StoreRecordMessage *)message;
107   ss_size = ntohs(srm->sub_system_size);
108   key_size = ntohs(srm->key_size);
109   value_size = ntohs(srm->value_size);
110   if(ss_size + key_size + value_size + sizeof(struct StoreRecordMessage)
111         != req_size)
112     return NULL;
113   record = GNUNET_new(struct GNUNET_PEERSTORE_Record);
114   if(GNUNET_YES == ntohs(srm->peer_set))
115   {
116     record->peer = GNUNET_new(struct GNUNET_PeerIdentity);
117     memcpy(record->peer, &srm->peer, sizeof(struct GNUNET_PeerIdentity));
118   }
119   record->lifetime = srm->lifetime;
120   dummy = (char *)&srm[1];
121   if(ss_size > 0)
122   {
123     record->sub_system = GNUNET_strdup(dummy);
124     dummy += ss_size;
125   }
126   if(key_size > 0)
127   {
128     record->key = GNUNET_strdup(dummy);
129     dummy += key_size;
130   }
131   if(value_size > 0)
132   {
133     record->value = GNUNET_malloc(value_size);
134     memcpy(record->value, dummy, value_size);
135   }
136   record->value_size = value_size;
137
138   return record;
139 }