diff options
Diffstat (limited to 'src/transport/transport_api_get_hello.c')
-rw-r--r-- | src/transport/transport_api_get_hello.c | 199 |
1 files changed, 158 insertions, 41 deletions
diff --git a/src/transport/transport_api_get_hello.c b/src/transport/transport_api_get_hello.c index 8087159c6..9a65616a9 100644 --- a/src/transport/transport_api_get_hello.c +++ b/src/transport/transport_api_get_hello.c | |||
@@ -34,25 +34,20 @@ | |||
34 | 34 | ||
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Linked list of functions to call whenever our HELLO is updated. | 37 | * Functions to call with this peer's HELLO. |
38 | */ | 38 | */ |
39 | struct GNUNET_TRANSPORT_GetHelloHandle | 39 | struct GNUNET_TRANSPORT_GetHelloHandle |
40 | { | 40 | { |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * This is a doubly linked list. | 43 | * Our configuration. |
44 | */ | 44 | */ |
45 | struct GNUNET_TRANSPORT_GetHelloHandle *next; | 45 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
46 | |||
47 | /** | ||
48 | * This is a doubly linked list. | ||
49 | */ | ||
50 | struct GNUNET_TRANSPORT_GetHelloHandle *prev; | ||
51 | 46 | ||
52 | /** | 47 | /** |
53 | * Transport handle. | 48 | * Transport handle. |
54 | */ | 49 | */ |
55 | struct GNUNET_TRANSPORT_Handle *handle; | 50 | struct GNUNET_MQ_Handle *mq; |
56 | 51 | ||
57 | /** | 52 | /** |
58 | * Callback to call once we got our HELLO. | 53 | * Callback to call once we got our HELLO. |
@@ -60,34 +55,158 @@ struct GNUNET_TRANSPORT_GetHelloHandle | |||
60 | GNUNET_TRANSPORT_HelloUpdateCallback rec; | 55 | GNUNET_TRANSPORT_HelloUpdateCallback rec; |
61 | 56 | ||
62 | /** | 57 | /** |
58 | * Closure for @e rec. | ||
59 | */ | ||
60 | void *rec_cls; | ||
61 | |||
62 | /** | ||
63 | * Task for calling the HelloUpdateCallback when we already have a HELLO | 63 | * Task for calling the HelloUpdateCallback when we already have a HELLO |
64 | */ | 64 | */ |
65 | struct GNUNET_SCHEDULER_Task *notify_task; | 65 | struct GNUNET_SCHEDULER_Task *notify_task; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * Closure for @e rec. | 68 | * ID of the task trying to reconnect to the service. |
69 | */ | 69 | */ |
70 | void *rec_cls; | 70 | struct GNUNET_SCHEDULER_Task *reconnect_task; |
71 | |||
72 | /** | ||
73 | * Delay until we try to reconnect. | ||
74 | */ | ||
75 | struct GNUNET_TIME_Relative reconnect_delay; | ||
71 | 76 | ||
72 | }; | 77 | }; |
73 | 78 | ||
74 | 79 | ||
80 | /** | ||
81 | * Function we use for checking incoming HELLO messages. | ||
82 | * | ||
83 | * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *` | ||
84 | * @param msg message received | ||
85 | * @return #GNUNET_OK if message is well-formed | ||
86 | */ | ||
87 | static int | ||
88 | check_hello (void *cls, | ||
89 | const struct GNUNET_MessageHeader *msg) | ||
90 | { | ||
91 | struct GNUNET_PeerIdentity me; | ||
92 | |||
93 | if (GNUNET_OK != | ||
94 | GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg, | ||
95 | &me)) | ||
96 | { | ||
97 | GNUNET_break (0); | ||
98 | return GNUNET_SYSERR; | ||
99 | } | ||
100 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
101 | "Receiving (my own) HELLO message (%u bytes), I am `%s'.\n", | ||
102 | (unsigned int) ntohs (msg->size), | ||
103 | GNUNET_i2s (&me)); | ||
104 | return GNUNET_OK; | ||
105 | } | ||
106 | |||
75 | 107 | ||
76 | /** | 108 | /** |
77 | * Task to call the HelloUpdateCallback of the GetHelloHandle | 109 | * Function we use for handling incoming HELLO messages. |
78 | * | 110 | * |
79 | * @param cls the `struct GNUNET_TRANSPORT_GetHelloHandle` | 111 | * @param cls closure, a `struct GNUNET_TRANSPORT_GetHelloHandle *` |
112 | * @param msg message received | ||
80 | */ | 113 | */ |
81 | static void | 114 | static void |
82 | call_hello_update_cb_async (void *cls) | 115 | handle_hello (void *cls, |
116 | const struct GNUNET_MessageHeader *msg) | ||
83 | { | 117 | { |
84 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls; | 118 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls; |
85 | 119 | ||
86 | GNUNET_assert (NULL != ghh->handle->my_hello); | ||
87 | GNUNET_assert (NULL != ghh->notify_task); | ||
88 | ghh->notify_task = NULL; | ||
89 | ghh->rec (ghh->rec_cls, | 120 | ghh->rec (ghh->rec_cls, |
90 | ghh->handle->my_hello); | 121 | msg); |
122 | } | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Function that will schedule the job that will try | ||
127 | * to connect us again to the client. | ||
128 | * | ||
129 | * @param ghh transport service to reconnect | ||
130 | */ | ||
131 | static void | ||
132 | schedule_reconnect (struct GNUNET_TRANSPORT_GetHelloHandle *ghh); | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Generic error handler, called with the appropriate | ||
137 | * error code and the same closure specified at the creation of | ||
138 | * the message queue. | ||
139 | * Not every message queue implementation supports an error handler. | ||
140 | * | ||
141 | * @param cls closure with the `struct GNUNET_TRANSPORT_Handle *` | ||
142 | * @param error error code | ||
143 | */ | ||
144 | static void | ||
145 | mq_error_handler (void *cls, | ||
146 | enum GNUNET_MQ_Error error) | ||
147 | { | ||
148 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls; | ||
149 | |||
150 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
151 | "Error receiving from transport service, disconnecting temporarily.\n"); | ||
152 | GNUNET_MQ_destroy (ghh->mq); | ||
153 | ghh->mq = NULL; | ||
154 | schedule_reconnect (ghh); | ||
155 | } | ||
156 | |||
157 | |||
158 | /** | ||
159 | * Try again to connect to transport service. | ||
160 | * | ||
161 | * @param cls the handle to the transport service | ||
162 | */ | ||
163 | static void | ||
164 | reconnect (void *cls) | ||
165 | { | ||
166 | GNUNET_MQ_hd_var_size (hello, | ||
167 | GNUNET_MESSAGE_TYPE_HELLO, | ||
168 | struct GNUNET_MessageHeader); | ||
169 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls; | ||
170 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
171 | make_hello_handler (ghh), | ||
172 | GNUNET_MQ_handler_end () | ||
173 | }; | ||
174 | struct GNUNET_MQ_Envelope *env; | ||
175 | struct StartMessage *s; | ||
176 | |||
177 | ghh->reconnect_task = NULL; | ||
178 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
179 | "Connecting to transport service.\n"); | ||
180 | GNUNET_assert (NULL == ghh->mq); | ||
181 | ghh->mq = GNUNET_CLIENT_connecT (ghh->cfg, | ||
182 | "transport", | ||
183 | handlers, | ||
184 | &mq_error_handler, | ||
185 | ghh); | ||
186 | if (NULL == ghh->mq) | ||
187 | return; | ||
188 | env = GNUNET_MQ_msg (s, | ||
189 | GNUNET_MESSAGE_TYPE_TRANSPORT_START); | ||
190 | s->options = htonl (0); | ||
191 | GNUNET_MQ_send (ghh->mq, | ||
192 | env); | ||
193 | } | ||
194 | |||
195 | |||
196 | /** | ||
197 | * Function that will schedule the job that will try | ||
198 | * to connect us again to the client. | ||
199 | * | ||
200 | * @param ghh transport service to reconnect | ||
201 | */ | ||
202 | static void | ||
203 | schedule_reconnect (struct GNUNET_TRANSPORT_GetHelloHandle *ghh) | ||
204 | { | ||
205 | ghh->reconnect_task = | ||
206 | GNUNET_SCHEDULER_add_delayed (ghh->reconnect_delay, | ||
207 | &reconnect, | ||
208 | ghh); | ||
209 | ghh->reconnect_delay = GNUNET_TIME_STD_BACKOFF (ghh->reconnect_delay); | ||
91 | } | 210 | } |
92 | 211 | ||
93 | 212 | ||
@@ -95,7 +214,7 @@ call_hello_update_cb_async (void *cls) | |||
95 | * Obtain the HELLO message for this peer. The callback given in this function | 214 | * Obtain the HELLO message for this peer. The callback given in this function |
96 | * is never called synchronously. | 215 | * is never called synchronously. |
97 | * | 216 | * |
98 | * @param handle connection to transport service | 217 | * @param cfg configuration |
99 | * @param rec function to call with the HELLO, sender will be our peer | 218 | * @param rec function to call with the HELLO, sender will be our peer |
100 | * identity; message and sender will be NULL on timeout | 219 | * identity; message and sender will be NULL on timeout |
101 | * (handshake with transport service pending/failed). | 220 | * (handshake with transport service pending/failed). |
@@ -104,23 +223,23 @@ call_hello_update_cb_async (void *cls) | |||
104 | * @return handle to cancel the operation | 223 | * @return handle to cancel the operation |
105 | */ | 224 | */ |
106 | struct GNUNET_TRANSPORT_GetHelloHandle * | 225 | struct GNUNET_TRANSPORT_GetHelloHandle * |
107 | GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, | 226 | GNUNET_TRANSPORT_get_hello (const struct GNUNET_CONFIGURATION_Handle *cfg, |
108 | GNUNET_TRANSPORT_HelloUpdateCallback rec, | 227 | GNUNET_TRANSPORT_HelloUpdateCallback rec, |
109 | void *rec_cls) | 228 | void *rec_cls) |
110 | { | 229 | { |
111 | struct GNUNET_TRANSPORT_GetHelloHandle *hwl; | 230 | struct GNUNET_TRANSPORT_GetHelloHandle *ghh; |
112 | 231 | ||
113 | hwl = GNUNET_new (struct GNUNET_TRANSPORT_GetHelloHandle); | 232 | ghh = GNUNET_new (struct GNUNET_TRANSPORT_GetHelloHandle); |
114 | hwl->rec = rec; | 233 | ghh->rec = rec; |
115 | hwl->rec_cls = rec_cls; | 234 | ghh->rec_cls = rec_cls; |
116 | hwl->handle = handle; | 235 | ghh->cfg = cfg; |
117 | GNUNET_CONTAINER_DLL_insert (handle->hwl_head, | 236 | reconnect (ghh); |
118 | handle->hwl_tail, | 237 | if (NULL == ghh->mq) |
119 | hwl); | 238 | { |
120 | if (NULL != handle->my_hello) | 239 | GNUNET_free (ghh); |
121 | hwl->notify_task = GNUNET_SCHEDULER_add_now (&call_hello_update_cb_async, | 240 | return NULL; |
122 | hwl); | 241 | } |
123 | return hwl; | 242 | return ghh; |
124 | } | 243 | } |
125 | 244 | ||
126 | 245 | ||
@@ -132,15 +251,13 @@ GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, | |||
132 | void | 251 | void |
133 | GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh) | 252 | GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh) |
134 | { | 253 | { |
135 | struct GNUNET_TRANSPORT_Handle *handle = ghh->handle; | 254 | if (NULL != ghh->mq) |
136 | 255 | { | |
137 | if (NULL != ghh->notify_task) | 256 | GNUNET_MQ_destroy (ghh->mq); |
138 | GNUNET_SCHEDULER_cancel (ghh->notify_task); | 257 | ghh->mq = NULL; |
139 | GNUNET_CONTAINER_DLL_remove (handle->hwl_head, | 258 | } |
140 | handle->hwl_tail, | ||
141 | ghh); | ||
142 | GNUNET_free (ghh); | 259 | GNUNET_free (ghh); |
143 | } | 260 | } |
144 | 261 | ||
145 | 262 | ||
146 | /* end of transport_api_hello.c */ | 263 | /* end of transport_api_get_hello.c */ |