* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2013-2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "memdebug.h"
struct site_blacklist_entry {
- char *hostname;
+ struct curl_llist_element list;
unsigned short port;
+ char hostname[1];
};
static void site_blacklist_llist_dtor(void *user, void *element)
{
struct site_blacklist_entry *entry = element;
(void)user;
-
- Curl_safefree(entry->hostname);
free(entry);
}
curl_off_t recv_size = -2; /* Make it easy to spot in the log */
/* Find the head of the recv pipe, if any */
- if(conn->recv_pipe && conn->recv_pipe->head) {
- struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr;
+ if(conn->recv_pipe.head) {
+ struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr;
recv_size = recv_handle->req.size;
static CURLcode addHandleToPipeline(struct Curl_easy *data,
struct curl_llist *pipeline)
{
- if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
- return CURLE_OUT_OF_MEMORY;
+ Curl_llist_insert_next(pipeline, pipeline->tail, data,
+ &data->pipeline_queue);
return CURLE_OK;
}
CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
struct connectdata *conn)
{
- struct curl_llist_element *sendhead = conn->send_pipe->head;
+ struct curl_llist_element *sendhead = conn->send_pipe.head;
struct curl_llist *pipeline;
CURLcode result;
- pipeline = conn->send_pipe;
+ pipeline = &conn->send_pipe;
result = addHandleToPipeline(handle, pipeline);
- if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
+ if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
/* this is a new one as head, expire it */
Curl_pipeline_leave_write(conn); /* not in use yet */
- Curl_expire(conn->send_pipe->head->ptr, 0);
+ Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
}
#if 0 /* enable for pipeline debugging */
{
struct curl_llist_element *curr;
- curr = conn->send_pipe->head;
+ curr = conn->send_pipe.head;
while(curr) {
if(curr->ptr == handle) {
- Curl_llist_move(conn->send_pipe, curr,
- conn->recv_pipe, conn->recv_pipe->tail);
+ Curl_llist_move(&conn->send_pipe, curr,
+ &conn->recv_pipe, conn->recv_pipe.tail);
- if(conn->send_pipe->head) {
+ if(conn->send_pipe.head) {
/* Since there's a new easy handle at the start of the send pipeline,
set its timeout value to 1ms to make it trigger instantly */
Curl_pipeline_leave_write(conn); /* not used now */
#ifdef DEBUGBUILD
infof(conn->data, "%p is at send pipe head B!\n",
- (void *)conn->send_pipe->head->ptr);
+ (void *)conn->send_pipe.head->ptr);
#endif
- Curl_expire(conn->send_pipe->head->ptr, 0);
+ Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
}
/* The receiver's list is not really interesting here since either this
}
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
- struct curl_llist **list_ptr)
+ struct curl_llist *list)
{
- struct curl_llist *old_list = *list_ptr;
- struct curl_llist *new_list = NULL;
+ /* Free the old list */
+ if(list->size)
+ Curl_llist_destroy(list, NULL);
if(sites) {
- new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
- if(!new_list)
- return CURLM_OUT_OF_MEMORY;
+ Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor);
/* Parse the URLs and populate the list */
while(*sites) {
- char *hostname;
char *port;
struct site_blacklist_entry *entry;
- hostname = strdup(*sites);
- if(!hostname) {
- Curl_llist_destroy(new_list, NULL);
- return CURLM_OUT_OF_MEMORY;
- }
-
- entry = malloc(sizeof(struct site_blacklist_entry));
+ entry = malloc(sizeof(struct site_blacklist_entry) + strlen(*sites));
if(!entry) {
- free(hostname);
- Curl_llist_destroy(new_list, NULL);
+ Curl_llist_destroy(list, NULL);
return CURLM_OUT_OF_MEMORY;
}
+ strcpy(entry->hostname, *sites);
- port = strchr(hostname, ':');
+ port = strchr(entry->hostname, ':');
if(port) {
*port = '\0';
port++;
entry->port = 80;
}
- entry->hostname = hostname;
-
- if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
- site_blacklist_llist_dtor(NULL, entry);
- Curl_llist_destroy(new_list, NULL);
- return CURLM_OUT_OF_MEMORY;
- }
-
+ Curl_llist_insert_next(list, list->tail, entry, &entry->list);
sites++;
}
}
- /* Free the old list */
- if(old_list) {
- Curl_llist_destroy(old_list, NULL);
- }
-
- /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
- *list_ptr = new_list;
-
return CURLM_OK;
}
+struct blacklist_node {
+ struct curl_llist_element list;
+ char server_name[1];
+};
+
bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
char *server_name)
{
if(handle->multi && server_name) {
- struct curl_llist *blacklist =
+ struct curl_llist *list =
Curl_multi_pipelining_server_bl(handle->multi);
- if(blacklist) {
- struct curl_llist_element *curr;
-
- curr = blacklist->head;
- while(curr) {
- char *bl_server_name;
-
- bl_server_name = curr->ptr;
- if(strncasecompare(bl_server_name, server_name,
- strlen(bl_server_name))) {
- infof(handle, "Server %s is blacklisted\n", server_name);
- return TRUE;
- }
- curr = curr->next;
+ struct curl_llist_element *e = list->head;
+ while(e) {
+ struct blacklist_node *bl = (struct blacklist_node *)e;
+ if(strncasecompare(bl->server_name, server_name,
+ strlen(bl->server_name))) {
+ infof(handle, "Server %s is blacklisted\n", server_name);
+ return TRUE;
}
+ e = e->next;
}
DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
}
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
- struct curl_llist **list_ptr)
+ struct curl_llist *list)
{
- struct curl_llist *old_list = *list_ptr;
- struct curl_llist *new_list = NULL;
+ /* Free the old list */
+ if(list->size)
+ Curl_llist_destroy(list, NULL);
if(servers) {
- new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
- if(!new_list)
- return CURLM_OUT_OF_MEMORY;
+ Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor);
/* Parse the URLs and populate the list */
while(*servers) {
- char *server_name;
-
- server_name = strdup(*servers);
- if(!server_name) {
- Curl_llist_destroy(new_list, NULL);
- return CURLM_OUT_OF_MEMORY;
- }
+ struct blacklist_node *n;
+ size_t len = strlen(*servers);
- if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) {
- Curl_llist_destroy(new_list, NULL);
- Curl_safefree(server_name);
+ n = malloc(sizeof(struct blacklist_node) + len);
+ if(!n) {
+ Curl_llist_destroy(list, NULL);
return CURLM_OUT_OF_MEMORY;
}
+ strcpy(n->server_name, *servers);
+ Curl_llist_insert_next(list, list->tail, n, &n->list);
servers++;
}
}
- /* Free the old list */
- if(old_list) {
- Curl_llist_destroy(old_list, NULL);
- }
-
- /* This might be NULL if sites == NULL, i.e the blacklist is cleared */
- *list_ptr = new_list;
return CURLM_OK;
}
bool Curl_recvpipe_head(struct Curl_easy *data,
struct connectdata *conn)
{
- return pipe_head(data, conn->recv_pipe);
+ return pipe_head(data, &conn->recv_pipe);
}
/* returns TRUE if the given handle is head of the send pipe */
bool Curl_sendpipe_head(struct Curl_easy *data,
struct connectdata *conn)
{
- return pipe_head(data, conn->send_pipe);
+ return pipe_head(data, &conn->send_pipe);
}