diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-06-01 00:52:06 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-06-01 00:52:13 +0200 |
commit | 47a7c12c47fa10728494623ea8f89beab8e5cd77 (patch) | |
tree | 2e37a6a55d169c96e9927c608a12f540e5cd0123 /src/identity/identity_api_lookup.c | |
parent | 09d0b535d3b5dc8798b18a4791d45b4a9c8ab529 (diff) | |
download | gnunet-47a7c12c47fa10728494623ea8f89beab8e5cd77.tar.gz gnunet-47a7c12c47fa10728494623ea8f89beab8e5cd77.zip |
stash
Diffstat (limited to 'src/identity/identity_api_lookup.c')
-rw-r--r-- | src/identity/identity_api_lookup.c | 173 |
1 files changed, 122 insertions, 51 deletions
diff --git a/src/identity/identity_api_lookup.c b/src/identity/identity_api_lookup.c index 40a22c262..56ebf6f47 100644 --- a/src/identity/identity_api_lookup.c +++ b/src/identity/identity_api_lookup.c | |||
@@ -26,8 +26,9 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_identity_service.h" | 28 | #include "gnunet_identity_service.h" |
29 | #include "identity.h" | ||
29 | 30 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__) | 31 | #define LOG(kind, ...) GNUNET_log_from (kind, "identity-api", __VA_ARGS__) |
31 | 32 | ||
32 | 33 | ||
33 | /** | 34 | /** |
@@ -37,9 +38,9 @@ struct GNUNET_IDENTITY_EgoLookup | |||
37 | { | 38 | { |
38 | 39 | ||
39 | /** | 40 | /** |
40 | * Handle to the identity service. | 41 | * Connection to service. |
41 | */ | 42 | */ |
42 | struct GNUNET_IDENTITY_Handle *identity; | 43 | struct GNUNET_MQ_Handle *mq; |
43 | 44 | ||
44 | /** | 45 | /** |
45 | * Name of the ego we are looking up. | 46 | * Name of the ego we are looking up. |
@@ -59,53 +60,103 @@ struct GNUNET_IDENTITY_EgoLookup | |||
59 | 60 | ||
60 | 61 | ||
61 | /** | 62 | /** |
62 | * Method called to inform about the egos of this peer. | 63 | * We received a result code from the service. Check the message |
64 | * is well-formed. | ||
63 | * | 65 | * |
64 | * When used with #GNUNET_IDENTITY_connect, this function is | 66 | * @param cls closure |
65 | * initially called for all egos and then again whenever a | 67 | * @param rcm result message received |
66 | * ego's name changes or if it is deleted. At the end of | 68 | * @return #GNUNET_OK if the message is well-formed |
67 | * the initial pass over all egos, the function is once called | 69 | */ |
68 | * with 'NULL' for @a ego. That does NOT mean that the callback won't | 70 | static int |
69 | * be invoked in the future or that there was an error. | 71 | check_identity_result_code (void *cls, const struct ResultCodeMessage *rcm) |
70 | * | 72 | { |
71 | * If the @a name matches the name from @a cls, we found the zone | 73 | if (sizeof (*rcm) != htons (rcm->header.size)) |
72 | * for our computation and will invoke the callback. | 74 | GNUNET_MQ_check_zero_termination (rcm); |
73 | * If we have iterated over all egos and not found the name, we | 75 | return GNUNET_OK; |
74 | * invoke the callback with NULL. | 76 | } |
77 | |||
78 | |||
79 | /** | ||
80 | * We received a result code from the service. | ||
75 | * | 81 | * |
76 | * @param cls closure with the `struct GNUNET_IDENTITY_EgoLookup` | 82 | * @param cls closure |
77 | * @param ego ego handle | 83 | * @param rcm result message received |
78 | * @param ctx context for application to store data for this ego | ||
79 | * (during the lifetime of this process, initially NULL) | ||
80 | * @param name name assigned by the user for this ego, | ||
81 | * NULL if the user just deleted the ego and it | ||
82 | * must thus no longer be used | ||
83 | */ | 84 | */ |
84 | static void | 85 | static void |
85 | identity_cb (void *cls, | 86 | handle_identity_result_code (void *cls, const struct ResultCodeMessage *rcm) |
86 | struct GNUNET_IDENTITY_Ego *ego, | ||
87 | void **ctx, | ||
88 | const char *name) | ||
89 | { | 87 | { |
90 | struct GNUNET_IDENTITY_EgoLookup *el = cls; | 88 | struct GNUNET_IDENTITY_EgoLookup *el = cls; |
91 | 89 | ||
92 | if ( (NULL != name) && | 90 | el->cb (el->cb_cls, NULL); |
93 | (0 == strcmp (name, | 91 | GNUNET_IDENTITY_ego_lookup_cancel (el); |
94 | el->name)) ) | 92 | } |
95 | { | 93 | |
96 | el->cb (el->cb_cls, | 94 | |
97 | ego); | 95 | /** |
98 | GNUNET_IDENTITY_ego_lookup_cancel (el); | 96 | * Check validity of identity update message. |
99 | return; | 97 | * |
100 | } | 98 | * @param cls closure |
101 | if (NULL == ego) | 99 | * @param um message received |
100 | * @return #GNUNET_OK if the message is well-formed | ||
101 | */ | ||
102 | static int | ||
103 | check_identity_update (void *cls, const struct UpdateMessage *um) | ||
104 | { | ||
105 | uint16_t size = ntohs (um->header.size); | ||
106 | uint16_t name_len = ntohs (um->name_len); | ||
107 | const char *str = (const char *) &um[1]; | ||
108 | |||
109 | if ((size != name_len + sizeof (struct UpdateMessage)) || | ||
110 | ((0 != name_len) && ('\0' != str[name_len - 1]))) | ||
102 | { | 111 | { |
103 | /* not found */ | 112 | GNUNET_break (0); |
104 | el->cb (el->cb_cls, | 113 | return GNUNET_SYSERR; |
105 | NULL); | ||
106 | GNUNET_IDENTITY_ego_lookup_cancel (el); | ||
107 | return; | ||
108 | } | 114 | } |
115 | return GNUNET_OK; | ||
116 | } | ||
117 | |||
118 | |||
119 | /** | ||
120 | * Handle identity update message. | ||
121 | * | ||
122 | * @param cls closure | ||
123 | * @param um message received | ||
124 | */ | ||
125 | static void | ||
126 | handle_identity_update (void *cls, const struct UpdateMessage *um) | ||
127 | { | ||
128 | struct GNUNET_IDENTITY_EgoLookup *el = cls; | ||
129 | uint16_t name_len = ntohs (um->name_len); | ||
130 | const char *str = (0 == name_len) ? NULL : (const char *) &um[1]; | ||
131 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
132 | struct GNUNET_HashCode id; | ||
133 | struct GNUNET_IDENTITY_Ego ego; | ||
134 | |||
135 | GNUNET_break (GNUNET_YES != ntohs (um->end_of_list)); | ||
136 | GNUNET_CRYPTO_ecdsa_key_get_public (&um->private_key, &pub); | ||
137 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id); | ||
138 | ego.pk = (struct GNUNET_CRYPTO_EcdsaPrivateKey *) &um->private_key; | ||
139 | ego.name = (char *) str; | ||
140 | ego.id = id; | ||
141 | el->cb (el->cb_cls, &ego); | ||
142 | GNUNET_IDENTITY_ego_lookup_cancel (el); | ||
143 | } | ||
144 | |||
145 | |||
146 | /** | ||
147 | * Generic error handler, called with the appropriate error code and | ||
148 | * the same closure specified at the creation of the message queue. | ||
149 | * Not every message queue implementation supports an error handler. | ||
150 | * | ||
151 | * @param cls closure with the `struct GNUNET_IDENTITY_EgoLookup *` | ||
152 | * @param error error code | ||
153 | */ | ||
154 | static void | ||
155 | mq_error_handler (void *cls, enum GNUNET_MQ_Error error) | ||
156 | { | ||
157 | struct GNUNET_IDENTITY_EgoLookup *el = cls; | ||
158 | |||
159 | el->cb (el->cb_cls, NULL); | ||
109 | } | 160 | } |
110 | 161 | ||
111 | 162 | ||
@@ -120,25 +171,45 @@ identity_cb (void *cls, | |||
120 | */ | 171 | */ |
121 | struct GNUNET_IDENTITY_EgoLookup * | 172 | struct GNUNET_IDENTITY_EgoLookup * |
122 | GNUNET_IDENTITY_ego_lookup (const struct GNUNET_CONFIGURATION_Handle *cfg, | 173 | GNUNET_IDENTITY_ego_lookup (const struct GNUNET_CONFIGURATION_Handle *cfg, |
123 | const char *name, | 174 | const char *name, |
124 | GNUNET_IDENTITY_EgoCallback cb, | 175 | GNUNET_IDENTITY_EgoCallback cb, |
125 | void *cb_cls) | 176 | void *cb_cls) |
126 | { | 177 | { |
127 | struct GNUNET_IDENTITY_EgoLookup *el; | 178 | struct GNUNET_IDENTITY_EgoLookup *el; |
179 | struct GNUNET_MQ_Envelope *env; | ||
180 | struct GNUNET_MessageHeader *req; | ||
181 | size_t nlen; | ||
128 | 182 | ||
183 | GNUNET_assert (NULL != cb); | ||
129 | el = GNUNET_new (struct GNUNET_IDENTITY_EgoLookup); | 184 | el = GNUNET_new (struct GNUNET_IDENTITY_EgoLookup); |
130 | el->name = GNUNET_strdup (name); | ||
131 | el->cb = cb; | 185 | el->cb = cb; |
132 | el->cb_cls = cb_cls; | 186 | el->cb_cls = cb_cls; |
133 | el->identity = GNUNET_IDENTITY_connect (cfg, | ||
134 | &identity_cb, | ||
135 | el); | ||
136 | if (NULL == el->identity) | ||
137 | { | 187 | { |
138 | GNUNET_free (el->name); | 188 | struct GNUNET_MQ_MessageHandler handlers[] = |
189 | {GNUNET_MQ_hd_var_size (identity_result_code, | ||
190 | GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE, | ||
191 | struct ResultCodeMessage, | ||
192 | el), | ||
193 | GNUNET_MQ_hd_var_size (identity_update, | ||
194 | GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE, | ||
195 | struct UpdateMessage, | ||
196 | el), | ||
197 | GNUNET_MQ_handler_end ()}; | ||
198 | |||
199 | el->mq = | ||
200 | GNUNET_CLIENT_connect (cfg, "identity", handlers, &mq_error_handler, el); | ||
201 | } | ||
202 | if (NULL == el->mq) | ||
203 | { | ||
204 | GNUNET_break (0); | ||
139 | GNUNET_free (el); | 205 | GNUNET_free (el); |
140 | return NULL; | 206 | return NULL; |
141 | } | 207 | } |
208 | el->name = GNUNET_strdup (name); | ||
209 | nlen = strlen (name) + 1; | ||
210 | env = GNUNET_MQ_msg_extra (req, nlen, GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP); | ||
211 | memcpy (&req[1], name, nlen); | ||
212 | GNUNET_MQ_send (el->mq, env); | ||
142 | return el; | 213 | return el; |
143 | } | 214 | } |
144 | 215 | ||
@@ -151,7 +222,7 @@ GNUNET_IDENTITY_ego_lookup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
151 | void | 222 | void |
152 | GNUNET_IDENTITY_ego_lookup_cancel (struct GNUNET_IDENTITY_EgoLookup *el) | 223 | GNUNET_IDENTITY_ego_lookup_cancel (struct GNUNET_IDENTITY_EgoLookup *el) |
153 | { | 224 | { |
154 | GNUNET_IDENTITY_disconnect (el->identity); | 225 | GNUNET_MQ_destroy (el->mq); |
155 | GNUNET_free (el->name); | 226 | GNUNET_free (el->name); |
156 | GNUNET_free (el); | 227 | GNUNET_free (el); |
157 | } | 228 | } |