aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2012-06-24 22:01:52 +0000
committerBart Polot <bart@net.in.tum.de>2012-06-24 22:01:52 +0000
commit5920d1117915fdcfe9460ea04e7d61b7118038ed (patch)
tree107b83e18195d638c03aea296bc93912f44cab53
parent5e5ebac9bfdb28725e7ba1f32bc0482657ebc1fa (diff)
downloadgnunet-5920d1117915fdcfe9460ea04e7d61b7118038ed.tar.gz
gnunet-5920d1117915fdcfe9460ea04e7d61b7118038ed.zip
- more mesh/regex integration: basic announce completed, lookup started, wip
-rw-r--r--src/include/block_mesh.h70
-rw-r--r--src/include/gnunet_block_lib.h12
-rw-r--r--src/mesh/gnunet-service-mesh_new.c317
3 files changed, 369 insertions, 30 deletions
diff --git a/src/include/block_mesh.h b/src/include/block_mesh.h
index 6be5b1920..ef5979da2 100644
--- a/src/include/block_mesh.h
+++ b/src/include/block_mesh.h
@@ -46,4 +46,74 @@ struct PBlock
46 GNUNET_MESH_ApplicationType type; 46 GNUNET_MESH_ApplicationType type;
47}; 47};
48 48
49/**
50 * @brief A MeshRegexBlock contains one or more of this struct in the payload.
51 */
52struct MeshRegexEdge
53{
54 /**
55 * Destination of this edge.
56 */
57 struct GNUNET_HashCode key;
58
59 /**
60 * Length of the token towards the new state.
61 */
62 unsigned int n_token;
63
64 /* char token[n_token] */
65};
66
67/**
68 * @brief Block to announce a regex state.
69 */
70struct MeshRegexBlock
71{
72 /**
73 * The key of the state.
74 */
75 struct GNUNET_HashCode key;
76
77 /**
78 * Length of the proof regex string..
79 */
80 unsigned int n_proof;
81
82 /**
83 * Numer of edges parting from this state.
84 */
85 unsigned int n_edges;
86
87 /**
88 * Is this state an accepting state?
89 */
90 int accepting;
91
92 /* char proof[n_proof] */
93 /* struct MeshEdge edges[n_edges] */
94};
95
96/**
97 * @brief Block to announce a peer accepting a state.
98 */
99struct MeshRegexAccept
100{
101 /**
102 * The key of the state.
103 */
104 struct GNUNET_HashCode key;
105
106 /**
107 * Length of the proof regex string.
108 * FIXME necessary???
109 * already present in the leading MeshRegexBlock
110 */
111 // unsigned int n_proof;
112
113 /**
114 * The identity of the peer accepting the state
115 */
116 struct GNUNET_PeerIdentity id;
117
118};
49#endif \ No newline at end of file 119#endif \ No newline at end of file
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h
index 5498fe74d..90a3549b1 100644
--- a/src/include/gnunet_block_lib.h
+++ b/src/include/gnunet_block_lib.h
@@ -108,7 +108,17 @@ enum GNUNET_BLOCK_Type
108 /** 108 /**
109 * Block for finding peers by type 109 * Block for finding peers by type
110 */ 110 */
111 GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE = 21 111 GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE = 21,
112
113 /**
114 * Block to store a mesh regex state
115 */
116 GNUNET_BLOCK_TYPE_MESH_REGEX = 22,
117
118 /**
119 * Block to store a mesh regex accepting state
120 */
121 GNUNET_BLOCK_TYPE_MESH_REGEX_ACCEPT = 23
112}; 122};
113 123
114 124
diff --git a/src/mesh/gnunet-service-mesh_new.c b/src/mesh/gnunet-service-mesh_new.c
index c6ffa1402..86d0b4a09 100644
--- a/src/mesh/gnunet-service-mesh_new.c
+++ b/src/mesh/gnunet-service-mesh_new.c
@@ -68,7 +68,9 @@
68#define UNACKNOWLEDGED_WAIT GNUNET_TIME_relative_multiply(\ 68#define UNACKNOWLEDGED_WAIT GNUNET_TIME_relative_multiply(\
69 GNUNET_TIME_UNIT_SECONDS,\ 69 GNUNET_TIME_UNIT_SECONDS,\
70 2) 70 2)
71#define DEFAULT_TTL 64 71#define DEFAULT_TTL 64
72
73#define DHT_REPLICATION_LEVEL 10
72 74
73/* TODO END */ 75/* TODO END */
74 76
@@ -515,6 +517,32 @@ struct MeshClient
515}; 517};
516 518
517 519
520/**
521 * Struct to keep state of searches of services described by a regex
522 * using a user-provided string service description.
523 */
524struct MeshRegexSerachContext
525{
526 /**
527 * User provided description of the searched service.
528 */
529 char *description;
530
531 /**
532 * Part of the description already consumed by the search.
533 */
534 size_t position;
535
536 /**
537 * Running DHT GETs.
538 */
539 struct GNUNET_DHT_GetHandle **dht_get_handle;
540
541 /**
542 * Number of running DHT GETs.
543 */
544 unsigned int n_dht_gets;
545};
518 546
519/******************************************************************************/ 547/******************************************************************************/
520/************************ DEBUG FUNCTIONS ****************************/ 548/************************ DEBUG FUNCTIONS ****************************/
@@ -657,6 +685,109 @@ unsigned int next_client_id;
657 685
658/* FIXME move iterators here */ 686/* FIXME move iterators here */
659 687
688/**
689 * Regex callback iterator to store own service description in the DHT.
690 *
691 * @param cls closure.
692 * @param key hash for current state.
693 * @param proof proof for current state.
694 * @param accepting GNUNET_YES if this is an accepting state, GNUNET_NO if not.
695 * @param num_edges number of edges leaving current state.
696 * @param edges edges leaving current state.
697 */
698void
699regex_iterator (void *cls, const struct GNUNET_HashCode *key, const char *proof,
700 int accepting, unsigned int num_edges,
701 const struct GNUNET_REGEX_Edge *edges)
702{
703 struct MeshRegexBlock *block;
704 struct MeshRegexEdge *block_edge;
705 enum GNUNET_DHT_RouteOption opt;
706 size_t size;
707 size_t len;
708 unsigned int i;
709 char *aux;
710
711 opt = GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE;
712 if (GNUNET_YES == accepting)
713 {
714 struct MeshRegexAccept block;
715
716 size = sizeof (block);
717 block.key = *key;
718 block.id = my_full_id;
719 (void)
720 GNUNET_DHT_put(dht_handle, key,
721 DHT_REPLICATION_LEVEL,
722 opt | GNUNET_DHT_RO_RECORD_ROUTE,
723 GNUNET_BLOCK_TYPE_MESH_REGEX_ACCEPT,
724 size,
725 (char *) &block,
726 GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
727 APP_ANNOUNCE_TIME),
728 APP_ANNOUNCE_TIME,
729 NULL, NULL);
730 }
731 len = strlen(proof);
732 size = sizeof (struct MeshRegexBlock) + len;
733 block = GNUNET_malloc (size);
734
735 block->key = *key;
736 block->n_proof = htonl (len);
737 block->n_edges = htonl (num_edges);
738 block->accepting = htonl (accepting);
739
740 /* Store the proof at the end of the block. */
741 aux = (char *) &block[1];
742 memcpy (aux, proof, len);
743 aux = &aux[len];
744
745 /* Store each edge in a variable length MeshEdge struct at the
746 * very end of the MeshRegexBlock structure.
747 */
748 for (i = 0; i < num_edges; i++)
749 {
750 /* aux points at the end of the last block */
751 block_edge = (struct MeshRegexEdge *) aux;
752 len = strlen (edges[i].label);
753 size += sizeof (struct MeshRegexEdge) + len;
754 block = GNUNET_realloc (block, size);
755 block_edge->key = edges[i].destination;
756 block_edge->n_token = htonl (len);
757 aux = (char *) &block_edge[1];
758 memcpy (aux, edges[i].label, len);
759 aux = &aux[len];
760 }
761 (void)
762 GNUNET_DHT_put(dht_handle, key,
763 DHT_REPLICATION_LEVEL,
764 opt,
765 GNUNET_BLOCK_TYPE_MESH_REGEX, size,
766 (char *) block,
767 GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
768 APP_ANNOUNCE_TIME),
769 APP_ANNOUNCE_TIME,
770 NULL, NULL);
771 GNUNET_free (block);
772}
773
774
775/**
776 * Store the regular expression describing a local service into the DHT.
777 *
778 * @param regex The regular expresion.
779 */
780static void
781regex_put (const char *regex)
782{
783 struct GNUNET_REGEX_Automaton *dfa;
784
785 dfa = GNUNET_REGEX_construct_dfa (regex, strlen(regex));
786 GNUNET_REGEX_iterate_all_edges (dfa, &regex_iterator, NULL);
787 GNUNET_REGEX_automaton_destroy (dfa);
788
789}
790
660 791
661/******************************************************************************/ 792/******************************************************************************/
662/************************ PERIODIC FUNCTIONS ****************************/ 793/************************ PERIODIC FUNCTIONS ****************************/
@@ -689,7 +820,8 @@ announce_application (void *cls, const struct GNUNET_HashCode * key, void *value
689 block.type = htonl (block.type); 820 block.type = htonl (block.type);
690 /* FIXME are hashes in multihash map equal on all aquitectures? */ 821 /* FIXME are hashes in multihash map equal on all aquitectures? */
691 /* FIXME: keep return value of 'put' to possibly cancel!? */ 822 /* FIXME: keep return value of 'put' to possibly cancel!? */
692 GNUNET_DHT_put (dht_handle, key, 10, 823 GNUNET_DHT_put (dht_handle, key,
824 DHT_REPLICATION_LEVEL,
693 GNUNET_DHT_RO_RECORD_ROUTE | 825 GNUNET_DHT_RO_RECORD_ROUTE |
694 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 826 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
695 GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE, 827 GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
@@ -704,6 +836,40 @@ announce_application (void *cls, const struct GNUNET_HashCode * key, void *value
704 836
705/** 837/**
706 * Periodically announce what applications are provided by local clients 838 * Periodically announce what applications are provided by local clients
839 * (by regex)
840 *
841 * @param cls closure
842 * @param tc task context
843 */
844static void
845announce_regex (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
846{
847 struct MeshClient *c = cls;
848 unsigned int i;
849
850 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
851 {
852 c->regex_announce_task = GNUNET_SCHEDULER_NO_TASK;
853 return;
854 }
855
856 DEBUG_DHT ("Starting PUT for regex\n");
857
858 for (i = 0; i < c->n_regex; i++)
859 {
860 regex_put (c->regexes[i]);
861 }
862 c->regex_announce_task =
863 GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME, &announce_regex, cls);
864 DEBUG_DHT ("Finished PUT for regex\n");
865
866 return;
867}
868
869
870/**
871 * Periodically announce what applications are provided by local clients
872 * (by type)
707 * 873 *
708 * @param cls closure 874 * @param cls closure
709 * @param tc task context 875 * @param tc task context
@@ -756,7 +922,7 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
756 block.type = htonl (0); 922 block.type = htonl (0);
757 GNUNET_DHT_put (dht_handle, /* DHT handle */ 923 GNUNET_DHT_put (dht_handle, /* DHT handle */
758 &my_full_id.hashPubKey, /* Key to use */ 924 &my_full_id.hashPubKey, /* Key to use */
759 10, /* Replication level */ 925 DHT_REPLICATION_LEVEL, /* Replication level */
760 GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */ 926 GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
761 GNUNET_BLOCK_TYPE_MESH_PEER, /* Block type */ 927 GNUNET_BLOCK_TYPE_MESH_PEER, /* Block type */
762 sizeof (block), /* Size of the data */ 928 sizeof (block), /* Size of the data */
@@ -1557,7 +1723,7 @@ peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
1557 peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ 1723 peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
1558 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */ 1724 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
1559 &id.hashPubKey, /* key to search */ 1725 &id.hashPubKey, /* key to search */
1560 10, /* replication level */ 1726 DHT_REPLICATION_LEVEL, /* replication level */
1561 GNUNET_DHT_RO_RECORD_ROUTE | 1727 GNUNET_DHT_RO_RECORD_ROUTE |
1562 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 1728 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
1563 NULL, /* xquery */ // FIXME BLOOMFILTER 1729 NULL, /* xquery */ // FIXME BLOOMFILTER
@@ -2606,24 +2772,6 @@ tunnel_reset_timeout (struct MeshTunnel *t)
2606 (REFRESH_PATH_TIME, 4), &tunnel_timeout, t); 2772 (REFRESH_PATH_TIME, 4), &tunnel_timeout, t);
2607} 2773}
2608 2774
2609/**
2610 * Regex callback iterator to store own service description in the DHT.
2611 *
2612 * @param cls closure.
2613 * @param key hash for current state.
2614 * @param proof proof for current state.
2615 * @param accepting GNUNET_YES if this is an accepting state, GNUNET_NO if not.
2616 * @param num_edges number of edges leaving current state.
2617 * @param edges edges leaving current state.
2618 */
2619void
2620regex_iterator (void *cls, const struct GNUNET_HashCode *key, const char *proof,
2621 int accepting, unsigned int num_edges,
2622 const struct GNUNET_REGEX_Edge *edges)
2623{
2624
2625}
2626
2627 2775
2628/******************************************************************************/ 2776/******************************************************************************/
2629/**************** MESH NETWORK HANDLER HELPERS ***********************/ 2777/**************** MESH NETWORK HANDLER HELPERS ***********************/
@@ -3849,6 +3997,46 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
3849} 3997}
3850 3998
3851 3999
4000/**
4001 * Function to process DHT string to regex matching..
4002 * Called on each result obtained for the DHT search.
4003 *
4004 * @param cls closure (search context)
4005 * @param exp when will this value expire
4006 * @param key key of the result
4007 * @param get_path path of the get request (not used)
4008 * @param get_path_length lenght of get_path (not used)
4009 * @param put_path path of the put request (not used)
4010 * @param put_path_length length of the put_path (not used)
4011 * @param type type of the result
4012 * @param size number of bytes in data
4013 * @param data pointer to the result data
4014 *
4015 * TODO: re-issue the request after certain time? cancel after X results?
4016 */
4017static void
4018dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4019 const struct GNUNET_HashCode * key,
4020 const struct GNUNET_PeerIdentity *get_path,
4021 unsigned int get_path_length,
4022 const struct GNUNET_PeerIdentity *put_path,
4023 unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4024 size_t size, const void *data)
4025{
4026 const struct MeshRegexBlock *block = data;
4027 char *proof;
4028
4029 // FIXME: does proof have to be NULL terminated?
4030 proof = (char *) &block[1];
4031 if (GNUNET_OK != GNUNET_REGEX_check_proof (proof, key))
4032 {
4033 GNUNET_break_op (0);
4034 return;
4035 }
4036 // FIXME complete
4037 return;
4038}
4039
3852/******************************************************************************/ 4040/******************************************************************************/
3853/********************* MESH LOCAL HANDLES **************************/ 4041/********************* MESH LOCAL HANDLES **************************/
3854/******************************************************************************/ 4042/******************************************************************************/
@@ -4040,7 +4228,6 @@ static void
4040handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client, 4228handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
4041 const struct GNUNET_MessageHeader *message) 4229 const struct GNUNET_MessageHeader *message)
4042{ 4230{
4043 struct GNUNET_REGEX_Automaton *dfa;
4044 struct MeshClient *c; 4231 struct MeshClient *c;
4045 char *regex; 4232 char *regex;
4046 size_t len; 4233 size_t len;
@@ -4061,10 +4248,14 @@ handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
4061 memcpy (regex, &message[1], len); 4248 memcpy (regex, &message[1], len);
4062 regex[len] = '\0'; 4249 regex[len] = '\0';
4063 GNUNET_array_append (c->regexes, c->n_regex, regex); 4250 GNUNET_array_append (c->regexes, c->n_regex, regex);
4064 dfa = GNUNET_REGEX_construct_dfa (regex, len); 4251 if (GNUNET_SCHEDULER_NO_TASK == c->regex_announce_task)
4065 GNUNET_REGEX_iterate_all_edges (dfa, &regex_iterator, NULL); 4252 {
4066 4253 c->regex_announce_task = GNUNET_SCHEDULER_add_now(&announce_regex, c);
4067 GNUNET_REGEX_automaton_destroy (dfa); 4254 }
4255 else
4256 {
4257 regex_put(regex);
4258 }
4068 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4259 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex processed\n"); 4260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex processed\n");
4070} 4261}
@@ -4566,7 +4757,7 @@ handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
4566 GNUNET_DHT_get_start (dht_handle, 4757 GNUNET_DHT_get_start (dht_handle,
4567 GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE, 4758 GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
4568 &hash, 4759 &hash,
4569 10, 4760 DHT_REPLICATION_LEVEL,
4570 GNUNET_DHT_RO_RECORD_ROUTE | 4761 GNUNET_DHT_RO_RECORD_ROUTE |
4571 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 4762 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
4572 NULL, 0, 4763 NULL, 0,
@@ -4588,9 +4779,77 @@ static void
4588handle_local_connect_by_string (void *cls, struct GNUNET_SERVER_Client *client, 4779handle_local_connect_by_string (void *cls, struct GNUNET_SERVER_Client *client,
4589 const struct GNUNET_MessageHeader *message) 4780 const struct GNUNET_MessageHeader *message)
4590{ 4781{
4782 struct GNUNET_MESH_ConnectPeerByString *msg;
4783 struct MeshRegexSerachContext *ctx;
4784 struct GNUNET_HashCode key;
4785 struct MeshTunnel *t;
4786 struct MeshClient *c;
4787 MESH_TunnelNumber tid;
4788 const char *string;
4789 size_t size;
4790 size_t len;
4791
4591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string started\n"); 4792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string started\n");
4793 msg = (struct GNUNET_MESH_ConnectPeerByString *) message;
4794 size = htons (message->size);
4592 4795
4593 // FIXME complete 4796 /* Sanity check for client registration */
4797 if (NULL == (c = client_get (client)))
4798 {
4799 GNUNET_break (0);
4800 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4801 return;
4802 }
4803
4804 /* Message size sanity check */
4805 if (sizeof(struct GNUNET_MESH_ConnectPeerByString) >= size)
4806 {
4807 GNUNET_break (0);
4808 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4809 return;
4810 }
4811
4812 /* Tunnel exists? */
4813 tid = ntohl (msg->tunnel_id);
4814 t = tunnel_get_by_local_id (c, tid);
4815 if (NULL == t)
4816 {
4817 GNUNET_break (0);
4818 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4819 return;
4820 }
4821
4822 /* Does client own tunnel? */
4823 if (t->owner->handle != client)
4824 {
4825 GNUNET_break (0);
4826 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4827 return;
4828 }
4829
4830 /* Find string itself */
4831 len = size - sizeof(struct GNUNET_MESH_ConnectPeerByString);
4832 string = (const char *) &msg[1];
4833
4834 /* Initialize context */
4835 size = GNUNET_REGEX_get_first_key(string, len, &key);
4836 ctx = GNUNET_malloc (sizeof (struct MeshRegexSerachContext));
4837 ctx->position = size;
4838 ctx->description = GNUNET_malloc (len + 1);
4839 memcpy (ctx->description, string, len);
4840 ctx->description[len] = '\0';
4841 ctx->n_dht_gets = 1;
4842 ctx->dht_get_handle = GNUNET_malloc (sizeof(struct GNUNET_DHT_GetHandle *));
4843
4844 /* Start search in DHT */
4845 ctx->dht_get_handle[0] = GNUNET_DHT_get_start (dht_handle, /* handle */
4846 GNUNET_BLOCK_TYPE_MESH_REGEX, /* type */
4847 &key, /* key to search */
4848 DHT_REPLICATION_LEVEL, /* replication level */
4849 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
4850 NULL, /* xquery */ // FIXME BLOOMFILTER
4851 0, /* xquery bits */ // FIXME BLOOMFILTER SIZE
4852 &dht_get_string_handler, ctx);
4594 4853
4595 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4854 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string processed\n"); 4855 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string processed\n");