aboutsummaryrefslogtreecommitdiff
path: root/src/mesh
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2012-11-22 18:02:19 +0000
committerBart Polot <bart@net.in.tum.de>2012-11-22 18:02:19 +0000
commit74e7bb910aef410888f92fdff592ebc592757c12 (patch)
tree19466d675f50b4ef7318fe7a08a047ded416da1f /src/mesh
parent3238f6daafe108e9faaa56df8bc4c10ff8af56c2 (diff)
downloadgnunet-74e7bb910aef410888f92fdff592ebc592757c12.tar.gz
gnunet-74e7bb910aef410888f92fdff592ebc592757c12.zip
- monitor tunnel inital implementation, WIP
Diffstat (limited to 'src/mesh')
-rw-r--r--src/mesh/gnunet-service-mesh.c202
-rw-r--r--src/mesh/mesh.h2
-rw-r--r--src/mesh/mesh_api.c79
3 files changed, 260 insertions, 23 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 097eca3b6..01f30156e 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1186,7 +1186,7 @@ tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer);
1186 * @return tunnel handler, NULL if doesn't exist. 1186 * @return tunnel handler, NULL if doesn't exist.
1187 */ 1187 */
1188static struct MeshTunnel * 1188static struct MeshTunnel *
1189tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid); 1189tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
1190 1190
1191 1191
1192/** 1192/**
@@ -3237,7 +3237,7 @@ tunnel_get_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid)
3237 * @return tunnel handler, NULL if doesn't exist 3237 * @return tunnel handler, NULL if doesn't exist
3238 */ 3238 */
3239static struct MeshTunnel * 3239static struct MeshTunnel *
3240tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid) 3240tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
3241{ 3241{
3242 return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid); 3242 return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid);
3243} 3243}
@@ -8066,6 +8066,7 @@ monitor_peers_iterator (void *cls,
8066} 8066}
8067 8067
8068 8068
8069
8069/** 8070/**
8070 * Iterator over all tunnels to send a monitoring client info about each tunnel. 8071 * Iterator over all tunnels to send a monitoring client info about each tunnel.
8071 * 8072 *
@@ -8076,44 +8077,44 @@ monitor_peers_iterator (void *cls,
8076 * @return GNUNET_YES, to keep iterating. 8077 * @return GNUNET_YES, to keep iterating.
8077 */ 8078 */
8078static int 8079static int
8079monitor_tunnel_iterator (void *cls, 8080monitor_all_tunnels_iterator (void *cls,
8080 const struct GNUNET_HashCode * key, 8081 const struct GNUNET_HashCode * key,
8081 void *value) 8082 void *value)
8082{ 8083{
8083 struct GNUNET_SERVER_Client *client = cls; 8084 struct GNUNET_SERVER_Client *client = cls;
8084 struct MeshTunnel *t = value; 8085 struct MeshTunnel *t = value;
8085 struct GNUNET_MESH_LocalMonitor *msg; 8086 struct GNUNET_MESH_LocalMonitor *msg;
8086 uint32_t npeers; 8087 uint32_t npeers;
8087 8088
8088 npeers = GNUNET_CONTAINER_multihashmap_size (t->peers); 8089 npeers = GNUNET_CONTAINER_multihashmap_size (t->peers);
8089 msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor) + 8090 msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor) +
8090 npeers * sizeof (struct GNUNET_PeerIdentity)); 8091 npeers * sizeof (struct GNUNET_PeerIdentity));
8091 GNUNET_PEER_resolve(t->id.oid, &msg->owner); 8092 GNUNET_PEER_resolve(t->id.oid, &msg->owner);
8092 msg->tunnel_id = htonl (t->id.tid); 8093 msg->tunnel_id = htonl (t->id.tid);
8093 msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor) + 8094 msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor) +
8094 npeers * sizeof (struct GNUNET_PeerIdentity)); 8095 npeers * sizeof (struct GNUNET_PeerIdentity));
8095 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR); 8096 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR);
8096 msg->npeers = 0; 8097 msg->npeers = 0;
8097 (void) GNUNET_CONTAINER_multihashmap_iterate (t->peers, 8098 (void) GNUNET_CONTAINER_multihashmap_iterate (t->peers,
8098 monitor_peers_iterator, 8099 monitor_peers_iterator,
8099 msg); 8100 msg);
8100 8101
8101 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 8102 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8102 "* sending info about tunnel %s [%u] (%u peers)\n", 8103 "* sending info about tunnel %s [%u] (%u peers)\n",
8103 GNUNET_i2s (&msg->owner), t->id.tid, npeers); 8104 GNUNET_i2s (&msg->owner), t->id.tid, npeers);
8104 8105
8105 if (msg->npeers != npeers) 8106 if (msg->npeers != npeers)
8106 { 8107 {
8107 GNUNET_break (0); 8108 GNUNET_break (0);
8108 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Monitor fail: size %u - iter %u\n", 8109 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Monitor fail: size %u - iter %u\n",
8109 npeers, msg->npeers); 8110 npeers, msg->npeers);
8110 } 8111 }
8111 8112
8112 msg->npeers = htonl (npeers); 8113 msg->npeers = htonl (npeers);
8113 GNUNET_SERVER_notification_context_unicast (nc, client, 8114 GNUNET_SERVER_notification_context_unicast (nc, client,
8114 &msg->header, 8115 &msg->header,
8115 GNUNET_NO); 8116 GNUNET_NO);
8116 return GNUNET_YES; 8117 return GNUNET_YES;
8117} 8118}
8118 8119
8119 8120
@@ -8142,7 +8143,7 @@ handle_local_monitor (void *cls, struct GNUNET_SERVER_Client *client,
8142 "Received monitor request from client %u\n", 8143 "Received monitor request from client %u\n",
8143 c->id); 8144 c->id);
8144 GNUNET_CONTAINER_multihashmap_iterate (tunnels, 8145 GNUNET_CONTAINER_multihashmap_iterate (tunnels,
8145 monitor_tunnel_iterator, 8146 monitor_all_tunnels_iterator,
8146 client); 8147 client);
8147 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 8148 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8148 "Monitor request from client %u completed\n", 8149 "Monitor request from client %u completed\n",
@@ -8152,6 +8153,170 @@ handle_local_monitor (void *cls, struct GNUNET_SERVER_Client *client,
8152 8153
8153 8154
8154/** 8155/**
8156 * Data needed to build a Monitor_Tunnel message.
8157 *
8158 * Both arrays can be combined to look up the position of the parent of
8159 * a peer: lookup[parent[peer]].
8160 */
8161struct MeshMonitorTunnelContext
8162{
8163 /**
8164 * Partial message, including peer count.
8165 */
8166 struct GNUNET_MESH_LocalMonitor *msg;
8167
8168 /**
8169 * Array with parents: peer->parent.
8170 */
8171 GNUNET_PEER_Id *parents;
8172
8173 /**
8174 * Array with positions: peer->position.
8175 */
8176 uint32_t *lookup;
8177
8178 /**
8179 * Size of the message so far.
8180 */
8181 size_t size;
8182
8183 /**
8184 * Client requesting the info.
8185 */
8186 struct MeshClient *c;
8187};
8188
8189
8190/**
8191 * Send a client a message about
8192 */
8193static void
8194send_client_monitor_tunnel (struct MeshMonitorTunnelContext *ctx)
8195{
8196 struct GNUNET_MESH_LocalMonitor *resp = ctx->msg;
8197 struct GNUNET_PeerIdentity *pid;
8198 unsigned int *parent;
8199 unsigned int i;
8200 size_t size;
8201
8202 size = sizeof (struct GNUNET_MESH_LocalMonitor);
8203 size += (sizeof (struct GNUNET_PeerIdentity) + sizeof (int)) * resp->npeers;
8204 resp->header.size = htons (size);
8205 pid = (struct GNUNET_PeerIdentity *) &resp[1];
8206 parent = (unsigned int *) &pid[resp->npeers];
8207 for (i = 0; i < resp->npeers; i++)
8208 parent[i] = htonl (ctx->lookup[ctx->parents[i]]);
8209 GNUNET_SERVER_notification_context_unicast (nc, ctx->c->handle,
8210 &resp->header, GNUNET_NO);
8211}
8212
8213/**
8214 * Iterator over a tunnel tree to build a message containing all peers
8215 * the in the tunnel, including relay nodes.
8216 *
8217 * @param cls Closure (pointer to pointer of message being built).
8218 * @param peer Short ID of a peer.
8219 * @param parent Short ID of the @c peer 's parent.
8220 *
8221 * FIXME: limit iterating to a message size / split if necessary
8222 */
8223static void
8224monitor_tunnel_iterator (void *cls,
8225 GNUNET_PEER_Id peer,
8226 GNUNET_PEER_Id parent)
8227{
8228 struct MeshMonitorTunnelContext *ctx = cls;
8229 struct GNUNET_MESH_LocalMonitor *msg = ctx->msg;
8230 struct GNUNET_PeerIdentity *pid;
8231
8232 msg = ctx->msg;
8233 pid = (struct GNUNET_PeerIdentity *) &msg[1];
8234 GNUNET_PEER_resolve(peer, &pid[msg->npeers]);
8235 ctx->parents[msg->npeers] = parent;
8236 ctx->lookup[peer] = msg->npeers;
8237 ctx->size += sizeof (struct GNUNET_PeerIdentity) * sizeof (uint32_t);
8238 msg->npeers++;
8239
8240 if ( (ctx->size + sizeof (struct GNUNET_PeerIdentity) * sizeof (uint32_t))
8241 > USHRT_MAX )
8242 {
8243 send_client_monitor_tunnel (ctx);
8244 ctx->size = sizeof (struct GNUNET_MESH_LocalMonitor);
8245 ctx->msg->npeers = 0;
8246 }
8247}
8248
8249
8250/**
8251 * Handler for client's MONITOR_TUNNEL request.
8252 *
8253 * @param cls Closure (unused).
8254 * @param client Identification of the client.
8255 * @param message The actual message.
8256 */
8257static void
8258handle_local_monitor_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
8259 const struct GNUNET_MessageHeader *message)
8260{
8261 const struct GNUNET_MESH_LocalMonitor *msg;
8262 struct GNUNET_MESH_LocalMonitor *resp;
8263 struct MeshMonitorTunnelContext ctx;
8264 struct MeshClient *c;
8265 struct MeshTunnel *t;
8266
8267 /* Sanity check for client registration */
8268 if (NULL == (c = client_get (client)))
8269 {
8270 GNUNET_break (0);
8271 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
8272 return;
8273 }
8274
8275 msg = (struct GNUNET_MESH_LocalMonitor *) message;
8276 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8277 "Received monitor tunnel request from client %u\n",
8278 c->id);
8279 t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id));
8280 if (NULL == t)
8281 {
8282 /* We don't know the tunnel */
8283 struct GNUNET_MESH_LocalMonitor warn;
8284
8285 warn = *msg;
8286 warn.npeers = htonl (UINT_MAX);
8287 GNUNET_SERVER_notification_context_unicast (nc, client,
8288 &warn.header,
8289 GNUNET_NO);
8290 GNUNET_SERVER_receive_done (client, GNUNET_OK);
8291 return;
8292 }
8293
8294 resp = GNUNET_malloc (USHRT_MAX); /* avoid realloc'ing on each step */
8295 *resp = *msg;
8296 resp->npeers = 0;
8297 ctx.msg = resp;
8298 ctx.parents = GNUNET_malloc (sizeof (GNUNET_PEER_Id) * 1024); /* hard limit anyway */
8299 ctx.lookup = GNUNET_malloc (sizeof (int) * 1024);
8300 ctx.size = sizeof (struct GNUNET_MESH_LocalMonitor);
8301 ctx.c = c;
8302
8303 tree_iterate_all (t->tree,
8304 monitor_tunnel_iterator,
8305 &ctx);
8306 send_client_monitor_tunnel (&ctx);
8307
8308 GNUNET_free (ctx.parents);
8309 GNUNET_free (ctx.lookup);
8310 GNUNET_free (resp);
8311
8312 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8313 "Monitor tunnel request from client %u completed\n",
8314 c->id);
8315 GNUNET_SERVER_receive_done (client, GNUNET_OK);
8316}
8317
8318
8319/**
8155 * Functions to handle messages from clients 8320 * Functions to handle messages from clients
8156 */ 8321 */
8157static struct GNUNET_SERVER_MessageHandler client_handlers[] = { 8322static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
@@ -8206,6 +8371,9 @@ static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
8206 {&handle_local_monitor, NULL, 8371 {&handle_local_monitor, NULL,
8207 GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR, 8372 GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR,
8208 sizeof (struct GNUNET_MessageHeader)}, 8373 sizeof (struct GNUNET_MessageHeader)},
8374 {&handle_local_monitor_tunnel, NULL,
8375 GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL,
8376 sizeof (struct GNUNET_MESH_LocalMonitor)},
8209 {NULL, NULL, 0, 0} 8377 {NULL, NULL, 0, 0}
8210}; 8378};
8211 8379
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h
index 68f163fa5..873b7f17a 100644
--- a/src/mesh/mesh.h
+++ b/src/mesh/mesh.h
@@ -305,7 +305,7 @@ struct GNUNET_MESH_LocalAck
305struct GNUNET_MESH_LocalMonitor 305struct GNUNET_MESH_LocalMonitor
306{ 306{
307 /** 307 /**
308 * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR 308 * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR[_TUNNEL]
309 */ 309 */
310 struct GNUNET_MessageHeader header; 310 struct GNUNET_MessageHeader header;
311 311
diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c
index f7aa6b9b1..9e55f2549 100644
--- a/src/mesh/mesh_api.c
+++ b/src/mesh/mesh_api.c
@@ -217,6 +217,16 @@ struct GNUNET_MESH_Handle
217 */ 217 */
218 void *monitor_cls; 218 void *monitor_cls;
219 219
220 /**
221 * Tunnel callback.
222 */
223 GNUNET_MESH_MonitorTunnelCB tunnel_cb;
224
225 /**
226 * Tunnel callback closure.
227 */
228 void *tunnel_cls;
229
220#if DEBUG_ACK 230#if DEBUG_ACK
221 unsigned int acks_sent; 231 unsigned int acks_sent;
222 unsigned int acks_recv; 232 unsigned int acks_recv;
@@ -1295,6 +1305,20 @@ process_monitor (struct GNUNET_MESH_Handle *h,
1295} 1305}
1296 1306
1297 1307
1308
1309/**
1310 * Process a local monitor_tunnel reply, pass info to the user.
1311 *
1312 * @param h Mesh handle.
1313 * @param message Message itself.
1314 */
1315static void
1316process_monitor_tunnel (struct GNUNET_MESH_Handle *h,
1317 const struct GNUNET_MessageHeader *message)
1318{
1319}
1320
1321
1298/** 1322/**
1299 * Function to process all messages received from the service 1323 * Function to process all messages received from the service
1300 * 1324 *
@@ -1345,11 +1369,14 @@ msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
1345 case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR: 1369 case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR:
1346 process_monitor (h, msg); 1370 process_monitor (h, msg);
1347 break; 1371 break;
1372 case GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL:
1373 process_monitor_tunnel (h, msg);
1374 break;
1348 default: 1375 default:
1349 /* We shouldn't get any other packages, log and ignore */ 1376 /* We shouldn't get any other packages, log and ignore */
1350 LOG (GNUNET_ERROR_TYPE_WARNING, 1377 LOG (GNUNET_ERROR_TYPE_WARNING,
1351 "unsolicited message form service (type %hu)\n", 1378 "unsolicited message form service (type %s)\n",
1352 ntohs (msg->type)); 1379 GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
1353 } 1380 }
1354 LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n"); 1381 LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n");
1355 if (GNUNET_YES == h->in_receive) 1382 if (GNUNET_YES == h->in_receive)
@@ -2202,15 +2229,23 @@ GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th)
2202 2229
2203/** 2230/**
2204 * Request information about the running mesh peer. 2231 * Request information about the running mesh peer.
2232 * The callback will be called for every tunnel known to the service,
2233 * listing all peers that blong to the tunnel (active only).
2234 *
2235 * If called again on the same handle, it will overwrite the previous
2236 * callback and cls. To retrieve the cls, monitor_cancel must be
2237 * called first.
2238 *
2239 * WARNING: unstable API, likely to change in the future!
2205 * 2240 *
2206 * @param h Handle to the mesh peer. 2241 * @param h Handle to the mesh peer.
2207 * @param callback Function to call with the requested data. 2242 * @param callback Function to call with the requested data.
2208 * @param monitor_cls Closure for @c callback. 2243 * @param callback_cls Closure for @c callback.
2209 */ 2244 */
2210void 2245void
2211GNUNET_MESH_monitor (struct GNUNET_MESH_Handle *h, 2246GNUNET_MESH_monitor (struct GNUNET_MESH_Handle *h,
2212 GNUNET_MESH_MonitorCB callback, 2247 GNUNET_MESH_MonitorCB callback,
2213 void *monitor_cls) 2248 void *callback_cls)
2214{ 2249{
2215 struct GNUNET_MessageHeader msg; 2250 struct GNUNET_MessageHeader msg;
2216 2251
@@ -2218,7 +2253,7 @@ GNUNET_MESH_monitor (struct GNUNET_MESH_Handle *h,
2218 msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR); 2253 msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR);
2219 send_packet (h, &msg, NULL); 2254 send_packet (h, &msg, NULL);
2220 h->monitor_cb = callback; 2255 h->monitor_cb = callback;
2221 h->monitor_cls = monitor_cls; 2256 h->monitor_cls = callback_cls;
2222 2257
2223 return; 2258 return;
2224} 2259}
@@ -2244,6 +2279,40 @@ GNUNET_MESH_monitor_cancel (struct GNUNET_MESH_Handle *h)
2244 2279
2245 2280
2246/** 2281/**
2282 * Request information about a specific tunnel of the running mesh peer.
2283 *
2284 * WARNING: unstable API, likely to change in the future!
2285 *
2286 * @param h Handle to the mesh peer.
2287 * @param initiator ID of the owner of the tunnel.
2288 * @param tunnel_number Tunnel number.
2289 * @param callback Function to call with the requested data.
2290 * @param callback_cls Closure for @c callback.
2291 */
2292void
2293GNUNET_MESH_monitor_tunnel (struct GNUNET_MESH_Handle *h,
2294 struct GNUNET_PeerIdentity *initiator,
2295 unsigned int tunnel_number,
2296 GNUNET_MESH_MonitorTunnelCB callback,
2297 void *callback_cls)
2298{
2299 struct GNUNET_MESH_LocalMonitor msg;
2300
2301 msg.header.size = htons (sizeof (msg));
2302 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR_TUNNEL);
2303 msg.npeers = htonl (0);
2304 msg.owner = *initiator;
2305 msg.tunnel_id = htonl (tunnel_number);
2306 msg.reserved = 0;
2307 send_packet (h, &msg.header, NULL);
2308 h->tunnel_cb = callback;
2309 h->tunnel_cls = callback_cls;
2310
2311 return;
2312}
2313
2314
2315/**
2247 * Transition API for tunnel ctx management 2316 * Transition API for tunnel ctx management
2248 */ 2317 */
2249void 2318void