File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / share.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (4 years, 1 month ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    1: /***************************************************************************
    2:  *                                  _   _ ____  _
    3:  *  Project                     ___| | | |  _ \| |
    4:  *                             / __| | | | |_) | |
    5:  *                            | (__| |_| |  _ <| |___
    6:  *                             \___|\___/|_| \_\_____|
    7:  *
    8:  * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
    9:  *
   10:  * This software is licensed as described in the file COPYING, which
   11:  * you should have received as part of this distribution. The terms
   12:  * are also available at https://curl.haxx.se/docs/copyright.html.
   13:  *
   14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
   15:  * copies of the Software, and permit persons to whom the Software is
   16:  * furnished to do so, under the terms of the COPYING file.
   17:  *
   18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
   19:  * KIND, either express or implied.
   20:  *
   21:  ***************************************************************************/
   22: 
   23: #include "curl_setup.h"
   24: 
   25: #include <curl/curl.h>
   26: #include "urldata.h"
   27: #include "share.h"
   28: #include "psl.h"
   29: #include "vtls/vtls.h"
   30: #include "curl_memory.h"
   31: 
   32: /* The last #include file should be: */
   33: #include "memdebug.h"
   34: 
   35: struct Curl_share *
   36: curl_share_init(void)
   37: {
   38:   struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
   39:   if(share) {
   40:     share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
   41: 
   42:     if(Curl_mk_dnscache(&share->hostcache)) {
   43:       free(share);
   44:       return NULL;
   45:     }
   46:   }
   47: 
   48:   return share;
   49: }
   50: 
   51: #undef curl_share_setopt
   52: CURLSHcode
   53: curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
   54: {
   55:   va_list param;
   56:   int type;
   57:   curl_lock_function lockfunc;
   58:   curl_unlock_function unlockfunc;
   59:   void *ptr;
   60:   CURLSHcode res = CURLSHE_OK;
   61: 
   62:   if(share->dirty)
   63:     /* don't allow setting options while one or more handles are already
   64:        using this share */
   65:     return CURLSHE_IN_USE;
   66: 
   67:   va_start(param, option);
   68: 
   69:   switch(option) {
   70:   case CURLSHOPT_SHARE:
   71:     /* this is a type this share will share */
   72:     type = va_arg(param, int);
   73:     share->specifier |= (1<<type);
   74:     switch(type) {
   75:     case CURL_LOCK_DATA_DNS:
   76:       break;
   77: 
   78:     case CURL_LOCK_DATA_COOKIE:
   79: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
   80:       if(!share->cookies) {
   81:         share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE);
   82:         if(!share->cookies)
   83:           res = CURLSHE_NOMEM;
   84:       }
   85: #else   /* CURL_DISABLE_HTTP */
   86:       res = CURLSHE_NOT_BUILT_IN;
   87: #endif
   88:       break;
   89: 
   90:     case CURL_LOCK_DATA_SSL_SESSION:
   91: #ifdef USE_SSL
   92:       if(!share->sslsession) {
   93:         share->max_ssl_sessions = 8;
   94:         share->sslsession = calloc(share->max_ssl_sessions,
   95:                                    sizeof(struct curl_ssl_session));
   96:         share->sessionage = 0;
   97:         if(!share->sslsession)
   98:           res = CURLSHE_NOMEM;
   99:       }
  100: #else
  101:       res = CURLSHE_NOT_BUILT_IN;
  102: #endif
  103:       break;
  104: 
  105:     case CURL_LOCK_DATA_CONNECT:     /* not supported (yet) */
  106:       if(Curl_conncache_init(&share->conn_cache, 103))
  107:         res = CURLSHE_NOMEM;
  108:       break;
  109: 
  110:     case CURL_LOCK_DATA_PSL:
  111: #ifndef USE_LIBPSL
  112:       res = CURLSHE_NOT_BUILT_IN;
  113: #endif
  114:       break;
  115: 
  116:     default:
  117:       res = CURLSHE_BAD_OPTION;
  118:     }
  119:     break;
  120: 
  121:   case CURLSHOPT_UNSHARE:
  122:     /* this is a type this share will no longer share */
  123:     type = va_arg(param, int);
  124:     share->specifier &= ~(1<<type);
  125:     switch(type) {
  126:     case CURL_LOCK_DATA_DNS:
  127:       break;
  128: 
  129:     case CURL_LOCK_DATA_COOKIE:
  130: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
  131:       if(share->cookies) {
  132:         Curl_cookie_cleanup(share->cookies);
  133:         share->cookies = NULL;
  134:       }
  135: #else   /* CURL_DISABLE_HTTP */
  136:       res = CURLSHE_NOT_BUILT_IN;
  137: #endif
  138:       break;
  139: 
  140:     case CURL_LOCK_DATA_SSL_SESSION:
  141: #ifdef USE_SSL
  142:       Curl_safefree(share->sslsession);
  143: #else
  144:       res = CURLSHE_NOT_BUILT_IN;
  145: #endif
  146:       break;
  147: 
  148:     case CURL_LOCK_DATA_CONNECT:
  149:       break;
  150: 
  151:     default:
  152:       res = CURLSHE_BAD_OPTION;
  153:       break;
  154:     }
  155:     break;
  156: 
  157:   case CURLSHOPT_LOCKFUNC:
  158:     lockfunc = va_arg(param, curl_lock_function);
  159:     share->lockfunc = lockfunc;
  160:     break;
  161: 
  162:   case CURLSHOPT_UNLOCKFUNC:
  163:     unlockfunc = va_arg(param, curl_unlock_function);
  164:     share->unlockfunc = unlockfunc;
  165:     break;
  166: 
  167:   case CURLSHOPT_USERDATA:
  168:     ptr = va_arg(param, void *);
  169:     share->clientdata = ptr;
  170:     break;
  171: 
  172:   default:
  173:     res = CURLSHE_BAD_OPTION;
  174:     break;
  175:   }
  176: 
  177:   va_end(param);
  178: 
  179:   return res;
  180: }
  181: 
  182: CURLSHcode
  183: curl_share_cleanup(struct Curl_share *share)
  184: {
  185:   if(share == NULL)
  186:     return CURLSHE_INVALID;
  187: 
  188:   if(share->lockfunc)
  189:     share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
  190:                     share->clientdata);
  191: 
  192:   if(share->dirty) {
  193:     if(share->unlockfunc)
  194:       share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
  195:     return CURLSHE_IN_USE;
  196:   }
  197: 
  198:   Curl_conncache_close_all_connections(&share->conn_cache);
  199:   Curl_conncache_destroy(&share->conn_cache);
  200:   Curl_hash_destroy(&share->hostcache);
  201: 
  202: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
  203:   Curl_cookie_cleanup(share->cookies);
  204: #endif
  205: 
  206: #ifdef USE_SSL
  207:   if(share->sslsession) {
  208:     size_t i;
  209:     for(i = 0; i < share->max_ssl_sessions; i++)
  210:       Curl_ssl_kill_session(&(share->sslsession[i]));
  211:     free(share->sslsession);
  212:   }
  213: #endif
  214: 
  215:   Curl_psl_destroy(&share->psl);
  216: 
  217:   if(share->unlockfunc)
  218:     share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
  219:   free(share);
  220: 
  221:   return CURLSHE_OK;
  222: }
  223: 
  224: 
  225: CURLSHcode
  226: Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
  227:                 curl_lock_access accesstype)
  228: {
  229:   struct Curl_share *share = data->share;
  230: 
  231:   if(share == NULL)
  232:     return CURLSHE_INVALID;
  233: 
  234:   if(share->specifier & (1<<type)) {
  235:     if(share->lockfunc) /* only call this if set! */
  236:       share->lockfunc(data, type, accesstype, share->clientdata);
  237:   }
  238:   /* else if we don't share this, pretend successful lock */
  239: 
  240:   return CURLSHE_OK;
  241: }
  242: 
  243: CURLSHcode
  244: Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
  245: {
  246:   struct Curl_share *share = data->share;
  247: 
  248:   if(share == NULL)
  249:     return CURLSHE_INVALID;
  250: 
  251:   if(share->specifier & (1<<type)) {
  252:     if(share->unlockfunc) /* only call this if set! */
  253:       share->unlockfunc (data, type, share->clientdata);
  254:   }
  255: 
  256:   return CURLSHE_OK;
  257: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>