+
+/**
+ * Callback if the STun request have a error
+ *
+ * @param cls the NAT handle
+ * @param result , the status
+ */
+static void
+stun_request_callback(void *cls,
+ enum GNUNET_NAT_StatusCode result)
+{
+
+ struct GNUNET_NAT_Handle *h = cls;
+
+ if(NULL == cls)
+ return;
+
+ h->waiting_stun = GNUNET_NO;
+
+ if(result != GNUNET_OK)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Error processing a STUN request");
+ }
+
+};
+
+/**
+ * CHECK if is a valid STUN packet sending to GNUNET_NAT_stun_handle_packet.
+ * It also check if it can handle the packet based on the NAT handler.
+ * You don't need to call anything else to check if the packet is valid,
+ *
+ * @param cls the NAT handle
+ * @param data, packet
+ * @param len, packet length
+ *
+ * @return #GNUNET_NO if it can't decode, #GNUNET_YES if is a packet
+ */
+int
+GNUNET_NAT_is_valid_stun_packet(void *cls, const void *data, size_t len)
+{
+ struct GNUNET_NAT_Handle *h = cls;
+ struct sockaddr_in answer;
+
+ /* We are not expecting a STUN message*/
+ if(!h->waiting_stun)
+ return GNUNET_NO;
+
+ /*We dont have STUN installed*/
+ if(!h->use_stun)
+ return GNUNET_NO;
+
+ /* Empty the answer structure */
+ memset(&answer, 0, sizeof(struct sockaddr_in));
+
+ /*Lets handle the packet*/
+ int valid = GNUNET_NAT_stun_handle_packet(data,len, &answer);
+ if(valid)
+ {
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Stun server returned IP %s , with port %d \n", inet_ntoa(answer.sin_addr), ntohs(answer.sin_port));
+ /* ADD IP AS VALID*/
+ add_to_address_list (h, LAL_EXTERNAL_IP, (const struct sockaddr *) &answer,
+ sizeof (struct sockaddr_in));
+ h->waiting_stun = GNUNET_NO;
+ return GNUNET_YES;
+ }
+ else
+ {
+ return GNUNET_NO;
+ }
+
+
+
+}
+
+/**
+ * Task to do a STUN request
+ *
+ * @param cls the NAT handle
+ * @param tc scheduler context
+ */
+static void
+process_stun (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_NAT_Handle *h = cls;
+
+ h->stun_task = NULL;
+
+
+
+ struct StunServerList* elem = h->actual_stun_server;
+
+ /* Make the request */
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "I will request the stun server %s:%i !\n", elem->address, elem->port);
+
+ if(GNUNET_OK == GNUNET_NAT_stun_make_request(elem->address, elem->port, h->socket, &stun_request_callback, NULL))
+ {
+ h->waiting_stun = GNUNET_YES;
+ }
+ else
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "STUN request failed %s:%i !\n", elem->address, elem->port);
+ }
+
+ h->stun_task =
+ GNUNET_SCHEDULER_add_delayed (h->stun_frequency,
+ &process_stun, h);
+
+ /* Set actual Server*/
+ if(elem->next)
+ {
+ h->actual_stun_server = elem->next;
+ }
+ else
+ {
+ h->actual_stun_server = h->stun_servers_head;
+ }
+
+}
+
+
+