Browse code

- added low_mem_threshold1 & low_mem_threshold2 (the ammount of free memory from which tls operations will start to fail preemptively is now configurable; by default the value depends on the number of processes) - doc update

Andrei Pelinescu-Onciul authored on 28/02/2007 01:38:47
Showing 7 changed files
... ...
@@ -78,10 +78,49 @@ Important Notes
78 78
    The tls module includes workarounds for the following known openssl
79 79
    bugs: openssl #1204 (disable SS_OP_TLS_BLOCK_PADDING_BUG if
80 80
    compression is enabled, for versions between 0.9.8 and 0.9.8c),
81
-   openssl #1468 (fix zlib compression memory allocation) and openssl
82
-   #1467 (kerberos support will be disabled if openssl version less than
83
-   0.9.8e-beta1). The bug reports can be viewed at
84
-   http://rt.openssl.org/.
81
+   openssl #1468 (fix zlib compression memory allocation), openssl #1467
82
+   (kerberos support will be disabled if the openssl version is less than
83
+   0.9.8e-beta1) and openssl #1491 (stop using tls in low memory
84
+   situations due to the very high risk of openssl crashing or leaking
85
+   memory). The bug reports can be viewed at http://rt.openssl.org/.
86
+
87
+Compiling the TLS Module
88
+
89
+   In most case compiling the TLS module is as simple as:
90
+make modules modules=modules/tls
91
+
92
+   or
93
+cd modules/tls
94
+make
95
+
96
+   or (compiling whole ser and the tls module)
97
+make all include_modules=tls
98
+
99
+   .
100
+
101
+   However in some cases the openssl library requires linking with other
102
+   libraries. For example compiling the openssl library with kerberos and
103
+   zlib-shared support will require linking the tls module with libkrb5
104
+   and libz. In this case just add TLS_EXTRA_LIBS="library list" to
105
+   make's command line. E.g.:
106
+make TLS_EXTRA_LIBS="-lkrb5 -lz" all include_modules=tls
107
+
108
+   In general, if ser fails to start with a symbol not found error when
109
+   trying to load the tls module (check the log), it means some needed
110
+   library was not linked and it must be added to TLS_EXTRA_LIBS
111
+
112
+TLS and Low Memory
113
+
114
+   The openssl library doesn't handle very well low memory situations. If
115
+   memory allocations start to fail (due to memory shortage), openssl can
116
+   crash or cause memory leaks (making the memory shortage even worse).
117
+   As of this writing all openssl versions were affected (includind
118
+   0.9.8e), see openssl bug #1491. The tls module has some workarounds
119
+   for preventing this problem (see low_mem_treshold1 and
120
+   low_mem_threshold2), however starting ser with enough shared memory is
121
+   higly recommended. When this is not possible a quick way to
122
+   significantly reduce openssl memory usage it to disable compression
123
+   (see tls_disable_compression).
85 124
 
86 125
 Known Limitations
87 126
 
... ...
@@ -383,6 +422,57 @@ tls_log (int)
383 422
 modparam("tls", "tls_log", 10)
384 423
 ...
385 424
 
425
+low_mem_threshold1 (integer)
426
+
427
+   Sets the minimal free memory from which new tls connection will start
428
+   to fail. The value is expressed in KB.
429
+
430
+   The default value depends on whether the openssl library used handles
431
+   well low memory situations (openssl bug #1491). As of this writing
432
+   this is not true for any openssl version (including 0.9.8e).
433
+
434
+   If an ill-behaved openssl version is detected, a very conservative
435
+   value is choosed, which depends on the maximum possible number of
436
+   simultaneously created tls connections (and hence on the process
437
+   number).
438
+
439
+   The following values have a special meaning:
440
+     * -1 - use the default value
441
+     * 0 - disable (tls connections will not fail preemptively)
442
+
443
+   See also low_mem_threshold2.
444
+
445
+   Example 15. Set low_memory_threshold1 parameter
446
+...
447
+modparam("tls", "low_memory_threshold1", -1)
448
+...
449
+
450
+low_mem_threshold2 (integer)
451
+
452
+   Sets the minimal free memory from which tls operations on already
453
+   established tls connections will start to fail preemptively. The value
454
+   is expressed in KB.
455
+
456
+   The default value depends on whether the openssl library used handles
457
+   well low memory situations (openssl bug #1491). As of this writing
458
+   this is not true for any openssl version (including 0.9.8e).
459
+
460
+   If an ill-behaved openssl version is detected, a very conservative
461
+   value is choosed, which depends on the maximum possible number of
462
+   simultaneously created tls connections (and hence on the process
463
+   number).
464
+
465
+   The following values have a special meaning:
466
+     * -1 - use the default value
467
+     * 0 - disable (tls operations will not fail preemptively)
468
+
469
+   See also low_mem_threshold1.
470
+
471
+   Example 16. Set low_memory_threshold2 parameter
472
+...
473
+modparam("tls", "low_memory_threshold2", -1)
474
+...
475
+
386 476
 tls_force_run (boolean)
387 477
 
388 478
    If enabled ser will start even if some of the openssl sanity checks
... ...
@@ -399,7 +489,7 @@ tls_force_run (boolean)
399 489
 
400 490
    By default tls_force_run is disabled.
401 491
 
402
-   Example 15. Set tls_force_run parameter
492
+   Example 17. Set tls_force_run parameter
403 493
 ...
404 494
 modparam("tls", "tls_force_run", 11)
405 495
 ...
... ...
@@ -429,7 +519,7 @@ config (string)
429 519
    ser acts as a server when it accepts a connection and as a client when
430 520
    it initiates a new connection by itself (it connects to something).
431 521
 
432
-   Example 16. Short config file
522
+   Example 18. Short config file
433 523
 [server:default]
434 524
 method = TLSv1
435 525
 verify_certificate = no
... ...
@@ -455,7 +545,7 @@ ca_list = local_ca.pem
455 545
    For a more complete example check the tls.cfg distributed with the ser
456 546
    source (sip_router/modules/tls/tls.cfg).
457 547
 
458
-   Example 17. Set config parameter
548
+   Example 19. Set config parameter
459 549
 ...
460 550
 modparam("tls", "config", "/usr/local/etc/ser/tls.cfg")
461 551
 ...
... ...
@@ -292,6 +292,84 @@ modparam("tls", "tls_log", 10)
292 292
 	</example>
293 293
 	</section>
294 294
 
295
+<section id="low_mem_threshold1">
296
+	<title><varname>low_mem_threshold1</varname> (integer)</title>
297
+	<para>
298
+		Sets the minimal free memory from which new tls connection will start to fail. The value is expressed in KB.
299
+	</para>
300
+	<para>
301
+		The default value depends on whether the openssl library used handles well low memory situations (openssl bug #1491). As of this writing this is not true for any openssl version (including 0.9.8e).
302
+	</para>
303
+	<para>
304
+		If an ill-behaved openssl version is detected, a very conservative value is choosed, which depends on the maximum possible number of simultaneously created tls connections (and hence on the process number).
305
+	</para>
306
+	<para>
307
+		The following values have a special meaning:
308
+	</para>
309
+	<itemizedlist>
310
+			<listitem>
311
+				<para>
312
+					-1 - use the default value
313
+				</para>
314
+			</listitem>
315
+			<listitem>
316
+				<para>
317
+					0 - disable (tls connections will not fail preemptively)
318
+				</para>
319
+			</listitem>
320
+	</itemizedlist>
321
+	<para>
322
+		See also <varname>low_mem_threshold2</varname>.
323
+	</para>
324
+	<example>
325
+		<title>Set <varname>low_memory_threshold1</varname> parameter</title>
326
+		<programlisting>
327
+...
328
+modparam("tls", "low_memory_threshold1", -1)
329
+...
330
+	</programlisting>
331
+	</example>
332
+	</section>
333
+
334
+<section id="low_mem_threshold2">
335
+	<title><varname>low_mem_threshold2</varname> (integer)</title>
336
+	<para>
337
+		Sets the minimal free memory from which tls operations on already established tls connections will start to fail preemptively.  The value is expressed in KB.
338
+	</para>
339
+	<para>
340
+		The default value depends on whether the openssl library used handles well low memory situations (openssl bug #1491). As of this writing this is not true for any openssl version (including 0.9.8e).
341
+	</para>
342
+	<para>
343
+		If an ill-behaved openssl version is detected, a very conservative value is choosed, which depends on the maximum possible number of simultaneously created tls connections (and hence on the process number).
344
+	</para>
345
+	<para>
346
+		The following values have a special meaning:
347
+	</para>
348
+	<itemizedlist>
349
+			<listitem>
350
+				<para>
351
+					-1 - use the default value
352
+				</para>
353
+			</listitem>
354
+			<listitem>
355
+				<para>
356
+					0 - disable (tls operations will not fail preemptively)
357
+				</para>
358
+			</listitem>
359
+	</itemizedlist>
360
+	<para>
361
+		See also <varname>low_mem_threshold1</varname>.
362
+	</para>
363
+	<example>
364
+		<title>Set <varname>low_memory_threshold2</varname> parameter</title>
365
+		<programlisting>
366
+...
367
+modparam("tls", "low_memory_threshold2", -1)
368
+...
369
+	</programlisting>
370
+	</example>
371
+	</section>
372
+
295 373
 	<section id="tls_force_run">
296 374
 	<title><varname>tls_force_run</varname> (boolean)</title>
297 375
 	<para>
... ...
@@ -77,6 +77,44 @@ route{
77 77
   <ulink url="http://rt.openssl.org/">http://rt.openssl.org/</ulink>.
78 78
 		</para>
79 79
 		</section>
80
+
81
+
82
+		<section id="tls.compile">
83
+		<title>Compiling the TLS Module</title>
84
+		<para>
85
+			In most case compiling the TLS module is as simple as:
86
+			<programlisting>
87
+make modules modules=modules/tls
88
+			</programlisting>
89
+			or
90
+			<programlisting>
91
+cd modules/tls
92
+make
93
+			</programlisting>
94
+			or (compiling whole ser and the tls module)
95
+			<programlisting>
96
+make all include_modules=tls
97
+			</programlisting>
98
+			.
99
+		</para>
100
+		<para>
101
+			However in some cases the openssl library requires linking with other libraries. For example compiling the openssl library with kerberos and zlib-shared support will require linking the tls module with libkrb5 and libz. In this case just add  <emphasis>TLS_EXTRA_LIBS</emphasis>="library list" to make's command line. E.g.:
102
+			<programlisting>
103
+make TLS_EXTRA_LIBS="-lkrb5 -lz" all include_modules=tls
104
+			</programlisting>
105
+		</para>
106
+		<para>
107
+			In general, if ser fails to start with a symbol not found error when trying to load the tls module (check the log), it means some needed library was not linked and it must be added to <emphasis>TLS_EXTRA_LIBS</emphasis>
108
+		</para>
109
+		</section>
110
+
111
+		<section id="tls.low_memory">
112
+		<title>TLS and Low Memory</title>
113
+		<para>
114
+			The openssl library doesn't handle very well low memory situations. If memory allocations start to fail (due to memory shortage), openssl can crash or cause memory leaks (making the memory shortage even worse). As of this writing all openssl versions were affected (includind 0.9.8e), see openssl bug #1491. The tls module has some workarounds for preventing this problem (see <varname>low_mem_treshold1</varname> and <varname>low_mem_threshold2</varname>), however starting ser with enough shared memory is higly recommended. When this is not possible a quick way to significantly reduce openssl memory usage it to  disable compression (see <varname>tls_disable_compression</varname>).
115
+		</para>
116
+		</section>
117
+
80 118
 		<section id="tls.known_limitations">
81 119
 		<title>Known Limitations</title>
82 120
 		<para>
... ...
@@ -102,7 +102,8 @@ to compile on the  _target_ system)"
102 102
 #ifdef TLS_KSSL_WORKARROUND
103 103
 int openssl_kssl_malloc_bug=0; /* is openssl bug #1467 present ? */
104 104
 #endif
105
-int openssl_low_mem_bug=0; /* openssl bug #1491 workaround */
105
+int openssl_mem_threshold1=-1; /* low memory threshold for connect/accept */
106
+int openssl_mem_threshold2=-1; /* like above but for other tsl operations */
106 107
 int tls_disable_compression = 0; /* by default enabled */
107 108
 int tls_force_run = 0; /* ignore some start-up sanity checks, use it
108 109
 						  at your own risk */
... ...
@@ -533,15 +534,32 @@ int init_tls_h(void)
533 534
 			" kerberos support will be disabled...\n");
534 535
 	}
535 536
 	#endif
536
-	LOG(L_WARN, "tls: init_tls_h: openssl low memory bugs (#1491) workaround"
537
-				" enabled (on low memory tls operations will fail"
538
-				" preemptively)\n");
539
-	openssl_low_mem_bug=1; /* openssl bug #1491 workaround, for now
540
-								always enabled */
537
+	 /* set free memory threshold for openssl bug #1491 workaround */
538
+	if (openssl_mem_threshold1<0){
539
+		/* default */
540
+		openssl_mem_threshold1=512*1024*get_max_procs();
541
+	}else
542
+		openssl_mem_threshold1*=1024; /* KB */
543
+	if (openssl_mem_threshold2<0){
544
+		/* default */
545
+		openssl_mem_threshold2=256*1024*get_max_procs();
546
+	}else
547
+		openssl_mem_threshold2*=1024; /* KB */
548
+	if ((openssl_mem_threshold1==0) || (openssl_mem_threshold2==0))
549
+		LOG(L_WARN, "tls: openssl bug #1491 (crash/mem leaks on low memory)"
550
+					" workarround disabled\n");
551
+	else
552
+		LOG(L_WARN, "tls: openssl bug #1491 (crash/mem leaks on low memory)"
553
+				" workaround enabled (on low memory tls operations will fail"
554
+				" preemptively) with free memory thresholds %d and %d bytes\n",
555
+				openssl_mem_threshold1, openssl_mem_threshold2);
556
+	
541 557
 	if (shm_available()==(unsigned long)(-1)){
542 558
 		LOG(L_WARN, "tls: ser compiled without MALLOC_STATS support:"
543 559
 				" the workaround for low mem. openssl bugs will _not_ "
544 560
 				"work\n");
561
+		openssl_mem_threshold1=0;
562
+		openssl_mem_threshold2=0;
545 563
 	}
546 564
 	SSL_library_init();
547 565
 	SSL_load_error_strings();
... ...
@@ -43,7 +43,8 @@
43 43
 #define TLS_KSSL_WORKARROUND
44 44
 extern int openssl_kssl_malloc_bug; /* is openssl bug #1467 present ? */
45 45
 #endif
46
-extern int openssl_low_mem_bug; /* openssl bug #1491 workarround */
46
+extern int openssl_mem_threshold1; /* low memory threshold for connect */
47
+extern int openssl_mem_threshold2; /* like above but for other tsl operations */
47 48
 
48 49
 
49 50
 extern int tls_disable_compression; /* by default enabled */
... ...
@@ -208,6 +208,8 @@ static param_export_t params[] = {
208 208
 	{"config",              PARAM_STR,    &tls_cfg_file           },
209 209
 	{"tls_disable_compression", PARAM_INT,&tls_disable_compression},
210 210
 	{"tls_force_run",       PARAM_INT,    &tls_force_run},
211
+	{"low_mem_threshold1",       PARAM_INT,    &openssl_mem_threshold1},
212
+	{"low_mem_threshold2",       PARAM_INT,    &openssl_mem_threshold2},
211 213
 	{0, 0, 0}
212 214
 };
213 215
 
... ...
@@ -53,8 +53,10 @@
53 53
 #include "tls_server.h"
54 54
 
55 55
 /* low memory treshold for openssl bug #1491 workaround */
56
-#define MIN_FREE_MEM_NEW_CONNECTION	(512*1024*get_max_procs()) /* 512k*no*/
57
-#define MIN_FREE_MEM_CONNECTED		(256*1024*get_max_procs()) /* 128k*no*/
56
+#define LOW_MEM_NEW_CONNECTION_TEST() \
57
+	((openssl_mem_threshold1) && (shm_available()<openssl_mem_threshold1))
58
+#define LOW_MEM_CONNECTED_TEST() \
59
+	((openssl_mem_threshold2) && (shm_available()<openssl_mem_threshold2))
58 60
 
59 61
 /* 
60 62
  * finish the ssl init (creates the SSL and set extra_data to it)
... ...
@@ -67,7 +69,7 @@ static int tls_complete_init(struct tcp_connection* c)
67 69
 	struct tls_extra_data* data = 0;
68 70
 	tls_cfg_t* cfg;
69 71
 
70
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_NEW_CONNECTION)){
72
+	if (LOW_MEM_NEW_CONNECTION_TEST()){
71 73
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
72 74
 				" operation: %lu\n", shm_available());
73 75
 		goto error2;
... ...
@@ -142,7 +144,7 @@ static int tls_update_fd(struct tcp_connection *c, int fd)
142 144
 	if (!c->extra_data && tls_complete_init(c) < 0) {
143 145
 		ERR("Delayed init failed\n");
144 146
 		return -1;
145
-	}else if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
147
+	}else if (LOW_MEM_CONNECTED_TEST()){
146 148
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
147 149
 				" operation: %lu\n", shm_available());
148 150
 		return -1;
... ...
@@ -304,7 +306,7 @@ static int tls_accept(struct tcp_connection *c, int* error)
304 306
 		     /* Not critical */
305 307
 		return 0;
306 308
 	}
307
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_NEW_CONNECTION)){
309
+	if (LOW_MEM_NEW_CONNECTION_TEST()){
308 310
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
309 311
 				" operation: %lu\n", shm_available());
310 312
 		goto err;
... ...
@@ -401,7 +403,7 @@ static int tls_connect(struct tcp_connection *c, int* error)
401 403
 		     /* Not critical */
402 404
 		return 0;
403 405
 	}
404
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_NEW_CONNECTION)){
406
+	if (LOW_MEM_NEW_CONNECTION_TEST()){
405 407
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
406 408
 				" operation: %lu\n", shm_available());
407 409
 		goto err;
... ...
@@ -498,7 +500,7 @@ static int tls_shutdown(struct tcp_connection *c)
498 500
 		ERR("No SSL data to perform tls_shutdown\n");
499 501
 		return -1;
500 502
 	}
501
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
503
+	if (LOW_MEM_CONNECTED_TEST()){
502 504
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
503 505
 				" operation: %lu\n", shm_available());
504 506
 		goto err;
... ...
@@ -573,7 +575,7 @@ static int tls_write(struct tcp_connection *c, const void *buf, size_t len, int*
573 575
 	ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
574 576
 
575 577
 	err = 0;
576
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
578
+	if (LOW_MEM_CONNECTED_TEST()){
577 579
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
578 580
 				" operation: %lu\n", shm_available());
579 581
 		ret=-1;
... ...
@@ -818,7 +820,7 @@ int tls_h_read(struct tcp_connection * c)
818 820
 		r->error = TCP_REQ_OVERRUN;
819 821
 		return -1;
820 822
 	}
821
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
823
+	if (LOW_MEM_CONNECTED_TEST()){
822 824
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
823 825
 				" operation: %lu\n", shm_available());
824 826
 		return -1;