Author: renodr
Date: Fri Jun 28 12:46:38 2019
New Revision: 3944

Log:
Add curl DNS resolution patch with header and minor improvements

Added:
   trunk/curl/curl-7.65.1-fix_dns_segfaults-2.patch

Added: trunk/curl/curl-7.65.1-fix_dns_segfaults-2.patch
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ trunk/curl/curl-7.65.1-fix_dns_segfaults-2.patch    Fri Jun 28 12:46:38 
2019        (r3944)
@@ -0,0 +1,319 @@
+Submitted By:            Douglas R. Reno (renodr at linuxfromscratch dot org)
+Original patch by:       Tim Tassonis (stuff at decentral dot ch)
+Initial Package Version: 7.65.1
+Origin:                  Upstream + self (improvements)
+Upstream Status:         Applied
+Description:             Fixes the sockhash function and DNS resolution
+                         segmentation faults.
+
+diff -Naurp curl-7.65.1.orig/lib/hash.h curl-7.65.1/lib/hash.h
+--- curl-7.65.1.orig/lib/hash.h        2019-03-25 03:42:46.000000000 -0500
++++ curl-7.65.1/lib/hash.h     2019-06-28 13:29:56.103933198 -0500
+@@ -7,7 +7,7 @@
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2017, Daniel Stenberg, <dan...@haxx.se>, et al.
++ * Copyright (C) 1998 - 2019, Daniel Stenberg, <dan...@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
+@@ -80,7 +80,7 @@ int Curl_hash_delete(struct curl_hash *h
+ void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
+ void Curl_hash_apply(struct curl_hash *h, void *user,
+                      void (*cb)(void *user, void *ptr));
+-int Curl_hash_count(struct curl_hash *h);
++#define Curl_hash_count(h) ((h)->size)
+ void Curl_hash_destroy(struct curl_hash *h);
+ void Curl_hash_clean(struct curl_hash *h);
+ void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+diff -Naurp curl-7.65.1.orig/lib/multi.c curl-7.65.1/lib/multi.c
+--- curl-7.65.1.orig/lib/multi.c       2019-06-02 16:06:16.000000000 -0500
++++ curl-7.65.1/lib/multi.c    2019-06-28 13:39:28.624208848 -0500
+@@ -189,13 +189,14 @@ static void mstate(struct Curl_easy *dat
+  */
+ 
+ struct Curl_sh_entry {
+-  struct curl_llist list; /* list of easy handles using this socket */
++  struct curl_hash transfers; /* hash of transfers using this socket */
+   unsigned int action;  /* what combined action READ/WRITE this socket waits
+                            for */
+   void *socketp; /* settable by users with curl_multi_assign() */
+   unsigned int users; /* number of transfers using this */
+   unsigned int readers; /* this many transfers want to read */
+   unsigned int writers; /* this many transfers want to write */
++  
+ };
+ /* bits for 'action' having no bits means this socket is not expecting any
+    action */
+@@ -206,12 +207,35 @@ struct Curl_sh_entry {
+ static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
+                                          curl_socket_t s)
+ {
+-  if(s != CURL_SOCKET_BAD)
++  if(s != CURL_SOCKET_BAD) {
+     /* only look for proper sockets */
+-    return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
++   return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
++  }
+   return NULL;
+ }
+ 
++#define THRASH_SIZE 13
++static size_t thrash(void *key, size_t key_length, size_t slots_num)
++{
++   size_t keyval = (size_t)*(struct Curl_easy **)key;
++   (void) key_length;
++
++   return (keyval % slots_num);
++}
++
++static size_t thrash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
++{
++   (void)k1_len;
++   (void)k2_len;
++
++   return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2;
++}
++
++static void thrash_dtor(void *nada)
++{
++   (void)nada;
++}
++
+ /* make sure this socket is present in the hash for this handle */
+ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+                                          curl_socket_t s)
+@@ -219,16 +243,21 @@ static struct Curl_sh_entry *sh_addentry
+   struct Curl_sh_entry *there = sh_getentry(sh, s);
+   struct Curl_sh_entry *check;
+ 
+-  if(there)
++  if(there) {
+     /* it is present, return fine */
+     return there;
++  }
+ 
+   /* not present, add it */
+   check = calloc(1, sizeof(struct Curl_sh_entry));
+   if(!check)
+     return NULL; /* major failure */
+ 
+-  Curl_llist_init(&check->list, NULL);
++  if(Curl_hash_init(&check->transfers, THRASH_SIZE, thrash,
++                    thrash_compare, thrash_dtor)) {
++     free(check);
++     return NULL;
++  }
+ 
+   /* make/add new hash entry */
+   if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+@@ -244,14 +273,8 @@ static struct Curl_sh_entry *sh_addentry
+ static void sh_delentry(struct Curl_sh_entry *entry,
+                         struct curl_hash *sh, curl_socket_t s)
+ {
+-  struct curl_llist *list = &entry->list;
+-  struct curl_llist_element *e;
+-  /* clear the list of transfers first */
+-  for(e = list->head; e; e = list->head) {
+-    struct Curl_easy *dta = e->ptr;
+-    Curl_llist_remove(&entry->list, e, NULL);
+-    dta->sh_entry = NULL;
+-  }
++  Curl_hash_destroy(&entry->transfers);
++
+   /* We remove the hash entry. This will end up in a call to
+      sh_freeentry(). */
+   Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
+@@ -320,17 +343,6 @@ static CURLMcode multi_addmsg(struct Cur
+   return CURLM_OK;
+ }
+ 
+-/*
+- * multi_freeamsg()
+- *
+- * Callback used by the llist system when a single list entry is destroyed.
+- */
+-static void multi_freeamsg(void *a, void *b)
+-{
+-  (void)a;
+-  (void)b;
+-}
+-
+ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
+                                      int chashsize) /* connection hash */
+ {
+@@ -350,8 +362,8 @@ struct Curl_multi *Curl_multi_handle(int
+   if(Curl_conncache_init(&multi->conn_cache, chashsize))
+     goto error;
+ 
+-  Curl_llist_init(&multi->msglist, multi_freeamsg);
+-  Curl_llist_init(&multi->pending, multi_freeamsg);
++  Curl_llist_init(&multi->msglist, NULL);
++  Curl_llist_init(&multi->pending, NULL);
+ 
+   /* -1 means it not set by user, use the default value */
+   multi->maxconnects = -1;
+@@ -789,11 +801,6 @@ bool Curl_multiplex_wanted(const struct
+ static void detach_connnection(struct Curl_easy *data)
+ {
+   struct connectdata *conn = data->conn;
+-  if(data->sh_entry) {
+-    /* still listed as a user of a socket hash entry, remove it */
+-    Curl_llist_remove(&data->sh_entry->list, &data->sh_queue, NULL);
+-    data->sh_entry = NULL;
+-  }
+   if(conn)
+     Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
+   data->conn = NULL;
+@@ -1266,6 +1273,10 @@ static CURLMcode multi_runsingle(struct
+     bool stream_error = FALSE;
+     rc = CURLM_OK;
+ 
++    DEBUGASSERT((data->mstate <= CURLM_STATE_CONNECT) ||
++                (data->mstate >= CURLM_STATE_DONE) ||
++                data->conn);
++
+     if(!data->conn &&
+        data->mstate > CURLM_STATE_CONNECT &&
+        data->mstate < CURLM_STATE_DONE) {
+@@ -2287,30 +2298,22 @@ static CURLMcode singlesocket(struct Cur
+       if(action & CURL_POLL_OUT)
+         entry->writers++;
+ 
+-      /* add 'data' to the list of handles using this socket! */
+-      Curl_llist_insert_next(&entry->list, entry->list.tail,
+-                             data, &data->sh_queue);
+-      data->sh_entry = entry;
++      /* add 'data' to the transfer hash on this socket! */
++      if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key*/
++                        sizeof(struct Curl_easy *), data))
++         return CURLM_OUT_OF_MEMORY;
+     }
+ 
+     comboaction = (entry->writers? CURL_POLL_OUT : 0) |
+       (entry->readers ? CURL_POLL_IN : 0);
+ 
+-#if 0
+-    infof(data, "--- Comboaction: %u readers %u writers\n",
+-          entry->readers, entry->writers);
+-#endif
+-    /* check if it has the same action set */
+-    if(entry->action == comboaction)
++    /* socket existed before and has the same action set as before */
++    if(sincebefore && (entry->action == comboaction))
+       /* same, continue */
+       continue;
+ 
+-    /* we know (entry != NULL) at this point, see the logic above */
+     if(multi->socket_cb)
+-      multi->socket_cb(data,
+-                       s,
+-                       comboaction,
+-                       multi->socket_userp,
++      multi->socket_cb(data, s, comboaction, multi->socket_userp,
+                        entry->socketp);
+ 
+     entry->action = comboaction; /* store the current action state */
+@@ -2352,6 +2355,13 @@ static CURLMcode singlesocket(struct Cur
+                            entry->socketp);
+         sh_delentry(entry, &multi->sockhash, s);
+       }
++      else {
++         /* still users, but remove this handle as a user of this socket */
++         if(Curl_hash_delete(&entry->transfers, (char *)&data,
++                             sizeof(struct Curl_easy *))) {
++            DEBUGASSERT(NULL);
++         }
++      }
+     }
+   } /* for loop over numsocks */
+ 
+@@ -2495,19 +2505,14 @@ static CURLMcode multi_socket(struct Cur
+          and just move on. */
+       ;
+     else {
+-      struct curl_llist *list = &entry->list;
+-      struct curl_llist_element *e;
+-      struct curl_llist_element *enext;
+-      SIGPIPE_VARIABLE(pipe_st);
+-
+-      /* the socket can be shared by many transfers, iterate */
+-      for(e = list->head; e; e = enext) {
+-        data = (struct Curl_easy *)e->ptr;
+-
+-        /* assign 'enext' here since the 'e' struct might be cleared
+-           further down in the singlesocket() call */
+-        enext = e->next;
++      struct curl_hash_iterator iter;
++      struct curl_hash_element *he;
+ 
++        /* the socket can be shared by many transfers, iterate */
++        Curl_hash_start_iterate(&entry->transfers, &iter);
++        for(he = Curl_hash_next_element(&iter); he;
++            he = Curl_hash_next_element(&iter)) {
++        data = (struct Curl_easy *)he->ptr;
+         DEBUGASSERT(data);
+         DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
+ 
+@@ -2515,21 +2520,7 @@ static CURLMcode multi_socket(struct Cur
+           /* set socket event bitmask if they're not locked */
+           data->conn->cselect_bits = ev_bitmask;
+ 
+-        sigpipe_ignore(data, &pipe_st);
+-        result = multi_runsingle(multi, now, data);
+-        sigpipe_restore(&pipe_st);
+-
+-        if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
+-          /* clear the bitmask only if not locked */
+-          data->conn->cselect_bits = 0;
+-
+-        if(CURLM_OK >= result) {
+-          /* get the socket(s) and check if the state has been changed since
+-             last */
+-          result = singlesocket(multi, data);
+-          if(result)
+-            return result;
+-        }
++        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+       }
+ 
+       /* Now we fall-through and do the timer-based stuff, since we don't want
+diff -Naurp curl-7.65.1.orig/lib/url.c curl-7.65.1/lib/url.c
+--- curl-7.65.1.orig/lib/url.c 2019-06-02 09:55:05.000000000 -0500
++++ curl-7.65.1/lib/url.c      2019-06-28 12:09:12.266986168 -0500
+@@ -1673,13 +1673,6 @@ static void free_idnconverted_hostname(s
+ #endif
+ }
+ 
+-static void llist_dtor(void *user, void *element)
+-{
+-  (void)user;
+-  (void)element;
+-  /* Do nothing */
+-}
+-
+ /*
+  * Allocate and initialize a new connectdata object.
+  */
+@@ -1791,7 +1784,7 @@ static struct connectdata *allocate_conn
+ #endif
+ 
+   /* Initialize the easy handle list */
+-  Curl_llist_init(&conn->easyq, (curl_llist_dtor) llist_dtor);
++  Curl_llist_init(&conn->easyq, NULL);
+ 
+ #ifdef HAVE_GSSAPI
+   conn->data_prot = PROT_CLEAR;
+diff -Naurp curl-7.65.1.orig/lib/urldata.h curl-7.65.1/lib/urldata.h
+--- curl-7.65.1.orig/lib/urldata.h     2019-06-04 15:28:08.000000000 -0500
++++ curl-7.65.1/lib/urldata.h  2019-06-28 12:09:33.052737077 -0500
+@@ -1778,8 +1778,6 @@ struct Curl_easy {
+ 
+   struct connectdata *conn;
+   struct curl_llist_element connect_queue;
+-  struct curl_llist_element sh_queue; /* list per Curl_sh_entry */
+-  struct Curl_sh_entry *sh_entry; /* the socket hash this was added to */
+   struct curl_llist_element conn_queue; /* list per connectdata */
+ 
+   CURLMstate mstate;  /* the handle's state */
-- 
http://lists.linuxfromscratch.org/listinfo/patches
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Reply via email to