aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api_get_hello.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/transport_api_get_hello.c')
-rw-r--r--src/transport/transport_api_get_hello.c199
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 */
39struct GNUNET_TRANSPORT_GetHelloHandle 39struct 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 */
87static int
88check_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 */
81static void 114static void
82call_hello_update_cb_async (void *cls) 115handle_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 */
131static void
132schedule_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 */
144static void
145mq_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 */
163static void
164reconnect (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 */
202static void
203schedule_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 */
106struct GNUNET_TRANSPORT_GetHelloHandle * 225struct GNUNET_TRANSPORT_GetHelloHandle *
107GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, 226GNUNET_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,
132void 251void
133GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh) 252GNUNET_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 */