28
28
* do so, delete this exception statement from your version.
32
#define INCL_DOSPROCESS
31
36
#include "common.h"
32
37
#include "prototypes.h"
34
#define STACK_SIZE 65536
39
#if defined(USE_UCONTEXT) || defined(USE_FORK)
40
/* no need for critical sections */
42
void enter_critical_section(SECTION_CODE i) {
46
void leave_critical_section(SECTION_CODE i) {
50
#endif /* USE_UCONTEXT || USE_FORK */
54
#if defined(CPU_SPARC) && ( \
55
defined(OS_SOLARIS2_0) || \
56
defined(OS_SOLARIS2_1) || \
57
defined(OS_SOLARIS2_2) || \
58
defined(OS_SOLARIS2_3) || \
59
defined(OS_SOLARIS2_4) || \
60
defined(OS_SOLARIS2_5) || \
61
defined(OS_SOLARIS2_6) || \
62
defined(OS_SOLARIS2_7) || \
63
defined(OS_SOLARIS2_8))
69
/* first context on the ready list is the active context */
70
CONTEXT *ready_head=NULL, *ready_tail=NULL; /* ready to execute */
71
CONTEXT *waiting_head=NULL, *waiting_tail=NULL; /* waiting on poll() */
74
unsigned long stunnel_process_id(void) {
75
return (unsigned long)getpid();
78
unsigned long stunnel_thread_id(void) {
79
return ready_head ? ready_head->id : 0;
82
static CONTEXT *new_context(void) {
85
/* allocate and fill the CONTEXT structure */
86
ctx=malloc(sizeof(CONTEXT));
88
s_log(LOG_ERR, "Unable to allocate CONTEXT structure");
94
/* some manuals claim that initialization of ctx structure is required */
95
if(getcontext(&ctx->ctx)<0) {
97
ioerror("getcontext");
100
ctx->ctx.uc_link=NULL; /* it should never happen */
101
#if defined(__sgi) || ARGC==2 /* obsolete ss_sp semantics */
102
ctx->ctx.uc_stack.ss_sp=ctx->stack+STACK_SIZE-8;
104
ctx->ctx.uc_stack.ss_sp=ctx->stack;
106
ctx->ctx.uc_stack.ss_size=STACK_SIZE;
107
ctx->ctx.uc_stack.ss_flags=0;
109
/* attach to the tail of the ready queue */
112
ready_tail->next=ctx;
119
/* s_log is not initialized here, but we can use log_raw */
120
void sthreads_init(void) {
121
/* create the first (listening) context and put it in the running queue */
123
log_raw("Unable create the listening context");
128
int create_client(int ls, int s, void *arg, void *(*cli)(void *)) {
131
s_log(LOG_DEBUG, "Creating a new context");
135
s_log(LOG_DEBUG, "Context %ld created", ctx->id);
136
makecontext(&ctx->ctx, (void(*)(void))cli, ARGC, arg);
140
#endif /* USE_UCONTEXT */
144
void sthreads_init(void) {
148
unsigned long stunnel_process_id(void) {
149
return (unsigned long)getpid();
152
unsigned long stunnel_thread_id(void) {
156
static void null_handler(int sig) {
157
signal(SIGCHLD, null_handler);
160
int create_client(int ls, int s, void *arg, void *(*cli)(void *)) {
171
signal(SIGCHLD, null_handler);
174
default: /* parent */
183
#endif /* USE_FORK */
36
185
#ifdef USE_PTHREAD
40
187
static pthread_mutex_t stunnel_cs[CRIT_SECTIONS];
42
188
static pthread_mutex_t lock_cs[CRYPTO_NUM_LOCKS];
43
189
static pthread_attr_t pth_attr;
130
277
LeaveCriticalSection(stunnel_cs+i);
280
static void locking_callback(int mode, int type,
282
const /* Callback definition has been changed in openssl 0.9.3 */
284
char *file, int line) {
286
EnterCriticalSection(lock_cs+type);
288
LeaveCriticalSection(lock_cs+type);
133
291
void sthreads_init(void) {
136
294
/* Initialize stunnel critical sections */
137
295
for(i=0; i<CRIT_SECTIONS; i++)
138
296
InitializeCriticalSection(stunnel_cs+i);
298
/* Initialize OpenSSL locking callback */
299
for(i=0; i<CRYPTO_NUM_LOCKS; i++)
300
InitializeCriticalSection(lock_cs+i);
301
CRYPTO_set_locking_callback(locking_callback);
141
304
unsigned long stunnel_process_id(void) {
163
326
void enter_critical_section(SECTION_CODE i) {
167
330
void leave_critical_section(SECTION_CODE i) {
171
334
void sthreads_init(void) {
175
337
unsigned long stunnel_process_id(void) {
176
return (unsigned long)getpid();
339
DosGetInfoBlocks(&ptib, NULL);
340
return (unsigned long)ptib->tib_ordinal;
179
343
unsigned long stunnel_thread_id(void) {
183
static void null_handler(int sig) {
184
signal(SIGCHLD, null_handler);
345
DosGetInfoBlocks(NULL, &ppib);
346
return (unsigned long)ppib->pib_ulpid;
187
349
int create_client(int ls, int s, void *arg, void *(*cli)(void *)) {
350
s_log(LOG_DEBUG, "Creating a new thread");
351
if(_beginthread((void(*)(void *))cli, NULL, STACK_SIZE, arg)==-1) {
352
ioerror("_beginthread");
198
signal(SIGCHLD, null_handler);
201
default: /* parent */
355
s_log(LOG_DEBUG, "New thread created");
361
int _beginthread(void (*start_address)(void *),
362
int stack_size, void *arglist) {
366
handle=CreateThread(NULL, stack_size,
367
(LPTHREAD_START_ROUTINE)start_address, arglist, 0, &thread_id);
374
void _endthread(void) {
378
#endif /* !defined(_WIN32_WCE) */
380
#endif /* USE_WIN32 */
212
382
#ifdef DEBUG_STACK_SIZE
214
#define STACK_RESERVE (STACK_SIZE/2)
215
#define TEST_VALUE 44
217
/* Some heuristic to determine the usage of client stack size. It can
218
* fail on some platforms and/or OSes, so it'is not enabled by default. */
384
#define STACK_RESERVE (STACK_SIZE/8)
385
#define VERIFY_AREA ((STACK_SIZE-STACK_RESERVE)/sizeof(u32))
386
#define TEST_VALUE 0xdeadbeef
388
/* some heuristic to determine the usage of client stack size */
220
389
void stack_info(int init) { /* 1-initialize, 0-display */
221
char table[STACK_SIZE-STACK_RESERVE];
390
u32 table[VERIFY_AREA];
392
static int min_num=VERIFY_AREA;
225
memset(table, TEST_VALUE, STACK_SIZE-STACK_RESERVE);
395
for(i=0; i<VERIFY_AREA; i++)
228
while(i<STACK_SIZE-STACK_RESERVE && table[i]==TEST_VALUE)
231
s_log(LOG_ERR, "STACK_RESERVE is to high");
233
s_log(LOG_NOTICE, "stack_info: %d of %d bytes used (%d%%)",
234
STACK_SIZE-STACK_RESERVE-i, STACK_SIZE,
235
(STACK_SIZE-STACK_RESERVE-i)*100/STACK_SIZE);
398
/* the stack is growing down */
399
for(i=0; i<VERIFY_AREA; i++)
400
if(table[i]!=TEST_VALUE)
403
/* the stack is growing up */
404
for(i=0; i<VERIFY_AREA; i++)
405
if(table[VERIFY_AREA-i-1]!=TEST_VALUE)
407
if(i>num) /* use the higher value */
410
s_log(LOG_NOTICE, "STACK_RESERVE is too high");
416
"stack_info: size=%d, current=%d (%d%%), maximum=%d (%d%%)",
418
(int)((VERIFY_AREA-num)*sizeof(u32)),
419
(int)((VERIFY_AREA-num)*sizeof(u32)*100/STACK_SIZE),
420
(int)((VERIFY_AREA-min_num)*sizeof(u32)),
421
(int)((VERIFY_AREA-min_num)*sizeof(u32)*100/STACK_SIZE));