other-licenses/android/res_state.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /*
michael@0 2 * Copyright (C) 2008 The Android Open Source Project
michael@0 3 * All rights reserved.
michael@0 4 *
michael@0 5 * Redistribution and use in source and binary forms, with or without
michael@0 6 * modification, are permitted provided that the following conditions
michael@0 7 * are met:
michael@0 8 * * Redistributions of source code must retain the above copyright
michael@0 9 * notice, this list of conditions and the following disclaimer.
michael@0 10 * * Redistributions in binary form must reproduce the above copyright
michael@0 11 * notice, this list of conditions and the following disclaimer in
michael@0 12 * the documentation and/or other materials provided with the
michael@0 13 * distribution.
michael@0 14 *
michael@0 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
michael@0 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
michael@0 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
michael@0 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
michael@0 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
michael@0 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
michael@0 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@0 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@0 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@0 26 * SUCH DAMAGE.
michael@0 27 */
michael@0 28
michael@0 29 /*
michael@0 30 * This version of this file is derived from Android 2.3 "Gingerbread",
michael@0 31 * which contains uncredited changes by Android/Google developers. It has
michael@0 32 * been modified in 2011 for use in the Android build of Mozilla Firefox by
michael@0 33 * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
michael@0 34 * and Steve Workman <sjhworkman@gmail.com>).
michael@0 35 * These changes are offered under the same license as the original NetBSD
michael@0 36 * file, whose copyright and license are unchanged above.
michael@0 37 */
michael@0 38
michael@0 39 /*
michael@0 40 * This version of this file is derived from Android 2.3 "Gingerbread",
michael@0 41 * which contains uncredited changes by Android/Google developers. It has
michael@0 42 * been modified in 2011 for use in the Android build of Mozilla Firefox by
michael@0 43 * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
michael@0 44 * and Steve Workman <sjhworkman@gmail.com>).
michael@0 45 * These changes are offered under the same license as the original NetBSD
michael@0 46 * file, whose copyright and license are unchanged above.
michael@0 47 */
michael@0 48
michael@0 49 #define ANDROID_CHANGES 1
michael@0 50 #define MOZILLA_NECKO_EXCLUDE_CODE 1
michael@0 51
michael@0 52 #include <sys/cdefs.h>
michael@0 53 #include <sys/types.h>
michael@0 54 #include <arpa/inet.h>
michael@0 55 #include "arpa_nameser.h"
michael@0 56 #include <netdb.h>
michael@0 57 #include "resolv_private.h"
michael@0 58 #include "resolv_cache.h"
michael@0 59 #include <pthread.h>
michael@0 60 #include <stdlib.h>
michael@0 61
michael@0 62 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
michael@0 63 #include <sys/_system_properties.h>
michael@0 64
michael@0 65 static pthread_key_t _res_key;
michael@0 66 static pthread_once_t _res_once;
michael@0 67
michael@0 68 typedef struct {
michael@0 69 int _h_errno;
michael@0 70 struct __res_state _nres[1];
michael@0 71 unsigned _serial;
michael@0 72 struct prop_info* _pi;
michael@0 73 struct res_static _rstatic[1];
michael@0 74 } _res_thread;
michael@0 75
michael@0 76 static _res_thread*
michael@0 77 _res_thread_alloc(void)
michael@0 78 {
michael@0 79 _res_thread* rt = malloc(sizeof(*rt));
michael@0 80
michael@0 81 if (rt) {
michael@0 82 rt->_h_errno = 0;
michael@0 83 /* Special system property which tracks any changes to 'net.*'. */
michael@0 84 rt->_serial = 0;
michael@0 85 rt->_pi = (struct prop_info*) __system_property_find("net.change");
michael@0 86 if (rt->_pi) {
michael@0 87 rt->_serial = rt->_pi->serial;
michael@0 88 }
michael@0 89 if ( res_ninit( rt->_nres ) < 0 ) {
michael@0 90 free(rt);
michael@0 91 rt = NULL;
michael@0 92 } else {
michael@0 93 memset(rt->_rstatic, 0, sizeof rt->_rstatic);
michael@0 94 }
michael@0 95 }
michael@0 96 return rt;
michael@0 97 }
michael@0 98
michael@0 99 static void
michael@0 100 _res_static_done( res_static rs )
michael@0 101 {
michael@0 102 /* fortunately, there is nothing to do here, since the
michael@0 103 * points in h_addr_ptrs and host_aliases should all
michael@0 104 * point to 'hostbuf'
michael@0 105 */
michael@0 106 if (rs->hostf) { /* should not happen in theory, but just be safe */
michael@0 107 fclose(rs->hostf);
michael@0 108 rs->hostf = NULL;
michael@0 109 }
michael@0 110 free(rs->servent.s_aliases);
michael@0 111 }
michael@0 112
michael@0 113 static void
michael@0 114 _res_thread_free( void* _rt )
michael@0 115 {
michael@0 116 _res_thread* rt = _rt;
michael@0 117
michael@0 118 _res_static_done(rt->_rstatic);
michael@0 119 res_ndestroy(rt->_nres);
michael@0 120 free(rt);
michael@0 121 }
michael@0 122
michael@0 123 static void
michael@0 124 _res_init_key( void )
michael@0 125 {
michael@0 126 pthread_key_create( &_res_key, _res_thread_free );
michael@0 127 }
michael@0 128
michael@0 129 static _res_thread*
michael@0 130 _res_thread_get(void)
michael@0 131 {
michael@0 132 _res_thread* rt;
michael@0 133 pthread_once( &_res_once, _res_init_key );
michael@0 134 rt = pthread_getspecific( _res_key );
michael@0 135 if (rt == NULL) {
michael@0 136 if ((rt = _res_thread_alloc()) == NULL) {
michael@0 137 return NULL;
michael@0 138 }
michael@0 139 rt->_h_errno = 0;
michael@0 140 rt->_serial = 0;
michael@0 141 pthread_setspecific( _res_key, rt );
michael@0 142 }
michael@0 143 /* Check the serial value for any chanes to net.* properties. */
michael@0 144 if (rt->_pi == NULL) {
michael@0 145 rt->_pi = (struct prop_info*) __system_property_find("net.change");
michael@0 146 }
michael@0 147 if (rt->_pi == NULL || rt->_serial == rt->_pi->serial) {
michael@0 148 return rt;
michael@0 149 }
michael@0 150 rt->_serial = rt->_pi->serial;
michael@0 151 /* Reload from system properties. */
michael@0 152 if ( res_ninit( rt->_nres ) < 0 ) {
michael@0 153 free(rt);
michael@0 154 rt = NULL;
michael@0 155 pthread_setspecific( _res_key, rt );
michael@0 156 }
michael@0 157 #ifdef USE_RESOLV_CACHE
michael@0 158 _resolv_cache_reset(rt->_serial);
michael@0 159 #endif
michael@0 160 return rt;
michael@0 161 }
michael@0 162
michael@0 163 struct __res_state _nres;
michael@0 164
michael@0 165 #if 0
michael@0 166 struct resolv_cache*
michael@0 167 __get_res_cache(void)
michael@0 168 {
michael@0 169 _res_thread* rt = _res_thread_get();
michael@0 170
michael@0 171 if (!rt)
michael@0 172 return NULL;
michael@0 173
michael@0 174 if (!rt->_cache) {
michael@0 175 rt->_cache = _resolv_cache_create();
michael@0 176 }
michael@0 177 return rt->_cache;
michael@0 178 }
michael@0 179 #endif
michael@0 180
michael@0 181 int*
michael@0 182 __get_h_errno(void)
michael@0 183 {
michael@0 184 _res_thread* rt = _res_thread_get();
michael@0 185 static int panic = NETDB_INTERNAL;
michael@0 186
michael@0 187 return rt ? &rt->_h_errno : &panic;
michael@0 188 }
michael@0 189
michael@0 190 res_state
michael@0 191 __res_get_state(void)
michael@0 192 {
michael@0 193 _res_thread* rt = _res_thread_get();
michael@0 194
michael@0 195 return rt ? rt->_nres : NULL;
michael@0 196 }
michael@0 197
michael@0 198 void
michael@0 199 __res_put_state(res_state res)
michael@0 200 {
michael@0 201 /* nothing to do */
michael@0 202 res=res;
michael@0 203 }
michael@0 204
michael@0 205 res_static
michael@0 206 __res_get_static(void)
michael@0 207 {
michael@0 208 _res_thread* rt = _res_thread_get();
michael@0 209
michael@0 210 return rt ? rt->_rstatic : NULL;
michael@0 211 }

mercurial