int cleanup_sock;
};
+/**
+ * DLL for Network Handles
+ */
+struct NetworkHandleList
+{
+ /*DLL*/
+ struct NetworkHandleList *next;
+
+ /*DLL*/
+ struct NetworkHandleList *prev;
+
+ /* The handle */
+ struct GNUNET_NETWORK_Handle *h;
+};
/**
* A structure for all running Httpds
/* The task ID */
GNUNET_SCHEDULER_TaskIdentifier httpd_task;
+
+ /* Handles associated with this daemon */
+ struct NetworkHandleList *socket_handles_head;
+
+ /* Handles associated with this daemon */
+ struct NetworkHandleList *socket_handles_tail;
};
/**
/* The associated daemon list entry */
struct MhdHttpList *mhd;
+
+ /* The associated response */
+ struct MHD_Response *response;
};
return total;
}
-
+/**
+ * Ask cURL for the select sets and schedule download
+ */
+static void
+curl_download_prepare ();
/**
* Callback to free content
* @param cls content to free
*/
static void
-mhd_content_free (void *cls)
+mhd_content_free (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct ProxyCurlTask *ctask = cls;
if (NULL != ctask->headers)
curl_slist_free_all (ctask->headers);
- if (NULL != ctask->curl)
- curl_easy_cleanup (ctask->curl);
+ if (NULL != ctask->headers)
+ curl_slist_free_all (ctask->resolver);
- ctask->curl = NULL;
+ if (NULL != ctask->response)
+ MHD_destroy_response (ctask->response);
GNUNET_free (ctask);
}
-/**
- * Postprocessing task that uses GNS to shorten names
- *
- * @param cls the proxycurltask
- * @param tc the task context
- *
-static void
-postprocess_name (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct ProxyCurlTask *ctask = cls;
- char tmp[strlen(ctask->pp_buf)];
-
- sprintf ( tmp, "%s%s", ctask->pp_buf, ctask->authority);
-
- GNUNET_GNS_shorten (gns_handle,
- tmp,
- &process_shorten,
- ctask);
-
-}
-*/
-
/**
* Callback for MHD response
*
regmatch_t m[RE_N_MATCHES];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MHD: content cb\n");
+ "MHD: content cb %s\n", ctask->url);
if (ctask->download_successful &&
(ctask->buf_status == BUF_WAIT_FOR_CURL))
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"MHD: sending response for %s\n", ctask->url);
ctask->download_in_progress = GNUNET_NO;
- curl_multi_remove_handle (curl_multi, ctask->curl);
- curl_easy_cleanup (ctask->curl);
+ GNUNET_SCHEDULER_add_now (&mhd_content_free, ctask);
GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
total_mhd_connections--;
return MHD_CONTENT_READER_END_OF_STREAM;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"MHD: sending error response\n");
ctask->download_in_progress = GNUNET_NO;
- curl_multi_remove_handle (curl_multi, ctask->curl);
- curl_easy_cleanup (ctask->curl);
+ GNUNET_SCHEDULER_add_now (&mhd_content_free, ctask);
GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
total_mhd_connections--;
return MHD_CONTENT_READER_END_WITH_ERROR;
&process_shorten,
ctask);
- //postprocess_name(ctask, NULL);
- //ctask->pp_task = GNUNET_SCHEDULER_add_now (&postprocess_name, ctask);
-
return 0;
}
}
ctask->bytes_in_buffer = 0;
ctask->buf_status = BUF_WAIT_FOR_CURL;
ctask->buffer_ptr = ctask->buffer;
- curl_easy_pause (ctask->curl, CURLPAUSE_CONT);
+ if (NULL != ctask->curl)
+ curl_easy_pause (ctask->curl, CURLPAUSE_CONT);
GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
}
}
struct ProxyCurlTask *ctask;
int num_ctasks;
+ struct ProxyCurlTask *clean_head = NULL;
+ struct ProxyCurlTask *clean_tail = NULL;
+
curl_download_task = GNUNET_SCHEDULER_NO_TASK;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
for (; ctask != NULL; ctask = ctask->next)
{
+ if (NULL == ctask->curl)
+ continue;
+
if (memcmp (msg->easy_handle, ctask->curl, sizeof (CURL)) != 0)
continue;
ctask->download_error = GNUNET_YES;
//curl_multi_remove_handle (curl_multi, ctask->curl);
//curl_easy_cleanup (ctask->curl);
+ //ctask->curl = NULL;
GNUNET_CONTAINER_DLL_remove (ctasks_head, ctasks_tail,
ctask);
+ GNUNET_CONTAINER_DLL_insert (clean_head, clean_tail, ctask);
break;
}
GNUNET_assert (ctask != NULL);
for (; ctask != NULL; ctask = ctask->next)
{
+ if (NULL == ctask->curl)
+ continue;
+
if (memcmp (msg->easy_handle, ctask->curl, sizeof (CURL)) != 0)
continue;
ctask->download_successful = GNUNET_YES;
//curl_multi_remove_handle (curl_multi, ctask->curl);
//curl_easy_cleanup (ctask->curl);
+ //ctask->curl = NULL;
GNUNET_CONTAINER_DLL_remove (ctasks_head, ctasks_tail,
ctask);
+ GNUNET_CONTAINER_DLL_insert (clean_head, clean_tail, ctask);
+
break;
}
GNUNET_assert (ctask != NULL);
break;
}
} while (msgnum > 0);
+
+ for (ctask=clean_head; ctask != NULL; ctask = ctask->next)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Removing cURL task %s.\n", ctask->url);
+ curl_multi_remove_handle (curl_multi, ctask->curl);
+ curl_easy_cleanup (ctask->curl);
+ ctask->curl = NULL;
+ }
num_ctasks=0;
for (ctask=ctasks_head; ctask != NULL; ctask = ctask->next)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"SSL target server: %s\n", ssl_ip);
sprintf (resolvename, "%s:%d:%s", ctask->leho, HTTPS_PORT, ssl_ip);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Curl resolve: %s\n", resolvename);
ctask->resolver = curl_slist_append ( ctask->resolver, resolvename);
curl_easy_setopt (ctask->curl, CURLOPT_RESOLVE, ctask->resolver);
struct MhdHttpList* hd = cls;
const char* page = "<html><head><title>gnoxy</title>"\
"</head><body>cURL fail</body></html>";
- struct MHD_Response *response = NULL;
+
char host[265];
char curlurl[512];
int ret = MHD_YES;
if ((ctask->curl == NULL) || (curl_multi == NULL))
{
- response = MHD_create_response_from_buffer (strlen (page),
+ ctask->response = MHD_create_response_from_buffer (strlen (page),
(void*)page,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (con,
MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
+ ctask->response);
+ MHD_destroy_response (ctask->response);
GNUNET_free (ctask);
return ret;
}
//download_prepare (ctask);
//curl_download_prepare ();
- response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
- MHD_SIZE_UNKNOWN,
+ ctask->response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
+ 20,
&mhd_content_cb,
ctask,
- &mhd_content_free);
+ NULL);
- ret = MHD_queue_response (con, MHD_HTTP_OK, response);
+ ret = MHD_queue_response (con, MHD_HTTP_OK, ctask->response);
//MHD_destroy_response (response);
struct sockaddr *addr;
socklen_t len;
- fd = GNUNET_NETWORK_get_fd (h);
+ fd = dup (GNUNET_NETWORK_get_fd (h));
addr = GNUNET_NETWORK_get_addr (h);
len = GNUNET_NETWORK_get_addrlen (h);
{
struct MhdHttpList *hd = NULL;
struct ProxyGNSCertificate *pgc;
+ struct NetworkHandleList *nh;
for (hd = mhd_httpd_head; hd != NULL; hd = hd->next)
{
GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd);
}
+
+ nh = GNUNET_malloc (sizeof (struct NetworkHandleList));
+ nh->h = h;
+
+ GNUNET_CONTAINER_DLL_insert (hd->socket_handles_head,
+ hd->socket_handles_tail,
+ nh);
return add_handle_to_mhd (h, hd->daemon);
}
struct sockaddr_in remote_addr;
struct in_addr *r_sin_addr;
+ struct NetworkHandleList *nh;
+
s5r->rtask = GNUNET_SCHEDULER_NO_TASK;
if ((NULL != tc->write_ready) &&
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Requested connection is HTTP\n");
+ nh = GNUNET_malloc (sizeof (struct NetworkHandleList));
+ nh->h = s5r->sock;
+
+ GNUNET_CONTAINER_DLL_insert (mhd_httpd_head->socket_handles_head,
+ mhd_httpd_head->socket_handles_tail,
+ nh);
+
ret = add_handle_to_mhd ( s5r->sock, httpd );
}
struct MhdHttpList *hd;
struct MhdHttpList *tmp_hd;
+ struct NetworkHandleList *nh;
+ struct NetworkHandleList *tmp_nh;
struct ProxyCurlTask *ctask;
struct ProxyCurlTask *ctask_tmp;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Shutting down...\n");
+ MHD_fini ();
gnutls_global_deinit ();
if (GNUNET_SCHEDULER_NO_TASK != curl_download_task)
hd->daemon = NULL;
}
+ for (nh = hd->socket_handles_head; nh != NULL; nh = tmp_nh)
+ {
+ tmp_nh = nh->next;
+
+ GNUNET_NETWORK_socket_close (nh->h);
+
+ GNUNET_free (nh);
+ }
+
if (NULL != hd->proxy_cert)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
ctask->curl = NULL;
if (NULL != ctask->headers)
curl_slist_free_all (ctask->headers);
+ if (NULL != ctask->resolver)
+ curl_slist_free_all (ctask->resolver);
+
+ if (NULL != ctask->response)
+ MHD_destroy_response (ctask->response);
+
GNUNET_free (ctask);
}
if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
return 2;
+
GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL);
ret =
(GNUNET_OK ==
_("GNUnet GNS proxy"),
options,
&run, NULL)) ? 0 : 1;
+ GNUNET_free_non_null ((char*)argv);
+
return ret;
}