- fix ucontext handling (backport from v4.37)

- fix non-blocking socket handling (backport from v4.37)

OBS-URL: https://build.opensuse.org/package/show/security:Stunnel/stunnel?expand=0&rev=42
This commit is contained in:
Daniel Rahn 2011-06-18 10:18:17 +00:00 committed by Git OBS Bridge
parent 7464662073
commit dc83cf7bf4
4 changed files with 506 additions and 166 deletions

441
fix-ucontext-handling.patch Normal file
View File

@ -0,0 +1,441 @@
--- src/network.c 2011-05-01 23:28:59.000000000 +0200
+++ src/network.c 2011-05-08 09:45:04.000000000 +0200
@@ -119,10 +119,10 @@
int retval, retry;
CONTEXT *context, *prev;
int min_timeout;
- int nfds, i;
+ unsigned int nfds, i;
time_t now;
short *signal_revents;
- static int max_nfds=0;
+ static unsigned int max_nfds=0;
static struct pollfd *ufds=NULL;
time(&now);
@@ -216,51 +216,56 @@
}
int s_poll_wait(s_poll_set *fds, int sec, int msec) {
- /* FIXME: msec parameter is currently ignored with UCONTEXT threads */
CONTEXT *context; /* current context */
static CONTEXT *to_free=NULL; /* delayed memory deallocation */
+ /* FIXME: msec parameter is currently ignored with UCONTEXT threads */
+ (void)msec; /* skip warning about unused parameter */
+
/* remove the current context from ready queue */
context=ready_head;
ready_head=ready_head->next;
if(!ready_head) /* the queue is empty */
ready_tail=NULL;
+ /* it it safe to s_log() after new ready_head is set */
+
+ /* it's illegal to deallocate the stack of the current context */
+ if(to_free) { /* a delayed deallocation is scheduled */
+ s_log(LOG_DEBUG, "Releasing context %ld", to_free->id);
+ free(to_free->stack);
+ free(to_free);
+ to_free=NULL;
+ }
+ /* manage the current thread */
if(fds) { /* something to wait for -> swap the context */
context->fds=fds; /* set file descriptors to wait for */
context->finish=sec<0 ? -1 : time(NULL)+sec;
- /* move (append) the current context to the waiting queue */
+
+ /* append the current context to the waiting queue */
context->next=NULL;
if(waiting_tail)
waiting_tail->next=context;
waiting_tail=context;
if(!waiting_head)
waiting_head=context;
- while(!ready_head) /* no context ready */
- scan_waiting_queue();
+ } else { /* nothing to wait for -> drop the context */
+ to_free=context; /* schedule for delayed deallocation */
+ }
+
+ while(!ready_head) /* wait until there is a thread to switch to */
+ scan_waiting_queue();
+
+ /* switch threads */
+ if(fds) { /* swap the current context */
if(context->id!=ready_head->id) {
s_log(LOG_DEBUG, "Context swap: %ld -> %ld",
context->id, ready_head->id);
swapcontext(&context->context, &ready_head->context);
s_log(LOG_DEBUG, "Current context: %ld", ready_head->id);
- if(to_free) {
- s_log(LOG_DEBUG, "Releasing context %ld", to_free->id);
- free(to_free->stack);
- free(to_free);
- to_free=NULL;
- }
}
return ready_head->ready;
- } else { /* nothing to wait for -> drop the context */
- /* it's illegal to deallocate the stack of the current context */
- if(to_free) {
- s_log(LOG_DEBUG, "Releasing context %ld", to_free->id);
- free(to_free->stack);
- free(to_free);
- }
- to_free=context;
- while(!ready_head) /* no context ready */
- scan_waiting_queue();
+ } else { /* drop the current context */
s_log(LOG_DEBUG, "Context set: %ld (dropped) -> %ld",
context->id, ready_head->id);
setcontext(&ready_head->context);
@@ -701,6 +706,10 @@
longjmp(c->err, 1); /* error */
}
line=str_realloc(line, ptr+1);
+ if(!line) {
+ s_log(LOG_CRIT, "Memory allocation failed");
+ longjmp(c->err, 1); /* error */
+ }
switch(readsocket(fd, line+ptr, 1)) {
case -1: /* error */
sockerror("readsocket (fdgetline)");
--- src/sthreads.c 2011-05-02 23:58:45.000000000 +0200
+++ src/sthreads.c 2011-05-10 11:45:18.000000000 +0200
@@ -47,10 +47,12 @@
/* no need for critical sections */
void enter_critical_section(SECTION_CODE i) {
+ (void)i; /* skip warning about unused parameter */
/* empty */
}
void leave_critical_section(SECTION_CODE i) {
+ (void)i; /* skip warning about unused parameter */
/* empty */
}
@@ -76,7 +78,6 @@
/* first context on the ready list is the active context */
CONTEXT *ready_head=NULL, *ready_tail=NULL; /* ready to execute */
CONTEXT *waiting_head=NULL, *waiting_tail=NULL; /* waiting on poll() */
-int next_id=1;
unsigned long stunnel_process_id(void) {
return (unsigned long)getpid();
@@ -86,63 +87,48 @@
return ready_head ? ready_head->id : 0;
}
-static CONTEXT *new_context(int stack_size) {
+static CONTEXT *new_context(void) {
+ static int next_id=1;
CONTEXT *context;
/* allocate and fill the CONTEXT structure */
- context=str_alloc(sizeof(CONTEXT));
+ context=calloc(1, sizeof(CONTEXT));
if(!context) {
s_log(LOG_ERR, "Unable to allocate CONTEXT structure");
return NULL;
}
- context->stack=str_alloc(stack_size);
- if(!context->stack) {
- s_log(LOG_ERR, "Unable to allocate CONTEXT stack");
- return NULL;
- }
context->id=next_id++;
context->fds=NULL;
context->ready=0;
- /* some manuals claim that initialization of context structure is required */
- if(getcontext(&context->context)<0) {
- str_free(context->stack);
- str_free(context);
- ioerror("getcontext");
- return NULL;
- }
- context->context.uc_link=NULL; /* it should never happen */
-#if defined(__sgi) || ARGC==2 /* obsolete ss_sp semantics */
- context->context.uc_stack.ss_sp=context->stack+stack_size-8;
-#else
- context->context.uc_stack.ss_sp=context->stack;
-#endif
- context->context.uc_stack.ss_size=stack_size;
- context->context.uc_stack.ss_flags=0;
- /* attach to the tail of the ready queue */
+ /* append to the tail of the ready queue */
context->next=NULL;
if(ready_tail)
ready_tail->next=context;
ready_tail=context;
if(!ready_head)
ready_head=context;
+
return context;
}
void sthreads_init(void) {
/* create the first (listening) context and put it in the running queue */
- if(!new_context(DEFAULT_STACK_SIZE)) {
+ if(!new_context()) {
s_log(LOG_ERR, "Unable create the listening context");
die(1);
}
+ /* no need to initialize ucontext_t structure here
+ it will be initialied with swapcontext() call */
}
int create_client(int ls, int s, CLI *arg, void *(*cli)(void *)) {
CONTEXT *context;
(void)ls; /* this parameter is only used with USE_FORK */
+
s_log(LOG_DEBUG, "Creating a new context");
- context=new_context(arg->opt->stack_size);
+ context=new_context();
if(!context) {
if(arg)
free(arg);
@@ -150,6 +136,38 @@
closesocket(s);
return -1;
}
+
+ /* initialize context_t structure */
+ if(getcontext(&context->context)<0) {
+ free(context);
+ if(arg)
+ free(arg);
+ if(s>=0)
+ closesocket(s);
+ ioerror("getcontext");
+ return -1;
+ }
+ context->context.uc_link=NULL; /* stunnel does not use uc_link */
+
+ /* create stack */
+ context->stack=calloc(1, arg->opt->stack_size);
+ if(!context->stack) {
+ free(context);
+ if(arg)
+ free(arg);
+ if(s>=0)
+ closesocket(s);
+ s_log(LOG_ERR, "Unable to allocate stack");
+ return -1;
+ }
+#if defined(__sgi) || ARGC==2 /* obsolete ss_sp semantics */
+ context->context.uc_stack.ss_sp=context->stack+arg->opt->stack_size-8;
+#else
+ context->context.uc_stack.ss_sp=context->stack;
+#endif
+ context->context.uc_stack.ss_size=arg->opt->stack_size;
+ context->context.uc_stack.ss_flags=0;
+
s_log(LOG_DEBUG, "Context %ld created", context->id);
makecontext(&context->context, (void(*)(void))cli, ARGC, arg);
return 0;
@@ -298,7 +316,7 @@
/* Disabled on OS X due to strange problems on Mac OS X 10.5
it seems to restore signal mask somewhere (I couldn't find where)
effectively blocking signals after first accepted connection */
- sigset_t sigset;
+ sigset_t new_set, old_set;
#endif /* HAVE_PTHREAD_SIGMASK && !__APPLE__*/
(void)ls; /* this parameter is only used with USE_FORK */
@@ -306,9 +324,8 @@
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(__APPLE__)
/* the idea is that only the main thread handles all the signals with
* posix threads; signals are blocked for any other thread */
- sigfillset(&sigset);
- pthread_sigmask(SIG_SETMASK, &sigset, NULL); /* block signals */
- sigemptyset(&sigset); /* prepare for unblocking */
+ sigfillset(&new_set);
+ pthread_sigmask(SIG_SETMASK, &new_set, &old_set); /* block signals */
#endif /* HAVE_PTHREAD_SIGMASK && !__APPLE__*/
pthread_attr_init(&pth_attr);
pthread_attr_setdetachstate(&pth_attr, PTHREAD_CREATE_DETACHED);
@@ -316,7 +333,7 @@
error=pthread_create(&thread, &pth_attr, cli, arg);
pthread_attr_destroy(&pth_attr);
#if defined(HAVE_PTHREAD_SIGMASK) && !defined(__APPLE__)
- pthread_sigmask(SIG_SETMASK, &sigset, NULL); /* unblock signals */
+ pthread_sigmask(SIG_SETMASK, &old_set, NULL); /* unblock signals */
#endif /* HAVE_PTHREAD_SIGMASK && !__APPLE__*/
if(error) {
--- src/client.c 2011-05-02 18:12:53.000000000 +0200
+++ src/client.c 2011-06-17 15:19:44.000000000 +0200
@@ -106,10 +106,8 @@
if(!c->opt->option.retry)
break;
sleep(1); /* FIXME: not a good idea in ucontext threading */
-#ifndef USE_UCONTEXT
str_stats();
str_cleanup();
-#endif
}
} else
run_client(c);
@@ -119,18 +117,17 @@
#ifdef DEBUG_STACK_SIZE
stack_info(0); /* display computed value */
#endif
+#ifdef USE_UCONTEXT
+ s_log(LOG_DEBUG, "Context %ld closed", ready_head->id);
+#endif
str_stats();
-#if defined(USE_WIN32) && !defined(_WIN32_WCE)
str_cleanup();
+ /* s_log() is not allowed after str_cleanup() */
+#if defined(USE_WIN32) && !defined(_WIN32_WCE)
_endthread();
#endif
#ifdef USE_UCONTEXT
- s_log(LOG_DEBUG, "Context %ld closed", ready_head->id);
- /* no str_cleanup() here, as all contexts share the same CPU thread */
s_poll_wait(NULL, 0, 0); /* wait on poll() */
- s_log(LOG_ERR, "INTERNAL ERROR: failed to drop context");
-#else
- str_cleanup();
#endif
return NULL;
}
@@ -283,6 +280,15 @@
SSL_set_session_id_context(c->ssl, (unsigned char *)sid_ctx,
strlen(sid_ctx));
if(c->opt->option.client) {
+#ifndef OPENSSL_NO_TLSEXT
+ if(c->opt->host_name) {
+ s_log(LOG_DEBUG, "SNI host name: %s", c->opt->host_name);
+ if(!SSL_set_tlsext_host_name(c->ssl, c->opt->host_name)) {
+ sslerror("SSL_set_tlsext_host_name");
+ longjmp(c->err, 1);
+ }
+ }
+#endif
if(c->opt->session) {
enter_critical_section(CRIT_SESSION);
SSL_set_session(c->ssl, c->opt->session);
@@ -314,9 +320,9 @@
while(1) {
#if OPENSSL_VERSION_NUMBER<0x1000002f
- /* this critical section is a crude workaround for CVE-2010-3864 */
- /* see http://www.securityfocus.com/bid/44884 for details */
- /* NOTE: this critical section also covers callbacks (e.g. OCSP) */
+ /* this critical section is a crude workaround for CVE-2010-3864 *
+ * see http://www.securityfocus.com/bid/44884 for details *
+ * NOTE: this critical section also covers callbacks (e.g. OCSP) */
enter_critical_section(CRIT_SSL);
#endif /* OpenSSL version < 1.0.0b */
if(c->opt->option.client)
@@ -821,22 +827,26 @@
type=strchr(line, ':');
if(!type) {
s_log(LOG_ERR, "Malformed IDENT response");
+ str_free(line);
longjmp(c->err, 1);
}
*type++='\0';
system=strchr(type, ':');
if(!system) {
s_log(LOG_ERR, "Malformed IDENT response");
+ str_free(line);
longjmp(c->err, 1);
}
*system++='\0';
if(strcmp(type, " USERID ")) {
s_log(LOG_ERR, "Incorrect INETD response type");
+ str_free(line);
longjmp(c->err, 1);
}
user=strchr(system, ':');
if(!user) {
s_log(LOG_ERR, "Malformed IDENT response");
+ str_free(line);
longjmp(c->err, 1);
}
*user++='\0';
@@ -846,9 +856,11 @@
safestring(user);
s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user %s)",
c->accepted_address, user);
+ str_free(line);
longjmp(c->err, 1);
}
s_log(LOG_INFO, "IDENT authentication passed");
+ str_free(line);
}
#if defined(_WIN32_WCE) || defined(__vms)
@@ -878,8 +890,8 @@
execname_l=str2tstr(c->opt->execname);
execargs_l=str2tstr(c->opt->execargs);
CreateProcess(execname_l, execargs_l, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
- free(execname_l);
- free(execargs_l);
+ str_free(execname_l);
+ str_free(execargs_l);
closesocket(fd[1]);
CloseHandle(pi.hProcess);
@@ -916,6 +928,7 @@
longjmp(c->err, 1);
case 0: /* child */
closesocket(fd[0]);
+ set_nonblock(fd[1], 0); /* switch back to blocking mode */
/* dup2() does not copy FD_CLOEXEC flag */
dup2(fd[1], 0);
dup2(fd[1], 1);
@@ -969,9 +982,10 @@
s=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#1");
if(s<0)
longjmp(c->err, 1);
- fd[1]=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2");
- if(fd[1]<0)
+ c->fd=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2");
+ if(c->fd<0)
longjmp(c->err, 1);
+
addrlen=sizeof addr;
memset(&addr, 0, addrlen);
addr.in.sin_family=AF_INET;
@@ -979,22 +993,30 @@
addr.in.sin_port=htons(0); /* dynamic port allocation */
if(bind(s, &addr.sa, addrlen))
log_error(LOG_DEBUG, get_last_socket_error(), "bind#1");
- if(bind(fd[1], &addr.sa, addrlen))
+ if(bind(c->fd, &addr.sa, addrlen))
log_error(LOG_DEBUG, get_last_socket_error(), "bind#2");
+
if(listen(s, 1)) {
+ closesocket(s);
sockerror("listen");
longjmp(c->err, 1);
}
if(getsockname(s, &addr.sa, &addrlen)) {
+ closesocket(s);
sockerror("getsockname");
longjmp(c->err, 1);
}
- if(connect(fd[1], &addr.sa, addrlen)) {
- sockerror("connect");
+ if(connect_blocking(c, &addr, addr_len(addr))) {
+ closesocket(s);
longjmp(c->err, 1);
}
- if((fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept"))<0)
+ fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept");
+ if(fd[0]<0) {
+ closesocket(s);
longjmp(c->err, 1);
+ }
+ fd[1]=c->fd;
+ c->fd=-1;
closesocket(s); /* don't care about the result */
#else
if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "socketpair"))

View File

@ -1,159 +1,3 @@
--- src/client.c 2011-05-02 18:12:53.000000000 +0200
+++ src/client.c 2011-06-17 15:19:44.000000000 +0200
@@ -106,10 +106,8 @@
if(!c->opt->option.retry)
break;
sleep(1); /* FIXME: not a good idea in ucontext threading */
-#ifndef USE_UCONTEXT
str_stats();
str_cleanup();
-#endif
}
} else
run_client(c);
@@ -119,18 +117,17 @@
#ifdef DEBUG_STACK_SIZE
stack_info(0); /* display computed value */
#endif
+#ifdef USE_UCONTEXT
+ s_log(LOG_DEBUG, "Context %ld closed", ready_head->id);
+#endif
str_stats();
-#if defined(USE_WIN32) && !defined(_WIN32_WCE)
str_cleanup();
+ /* s_log() is not allowed after str_cleanup() */
+#if defined(USE_WIN32) && !defined(_WIN32_WCE)
_endthread();
#endif
#ifdef USE_UCONTEXT
- s_log(LOG_DEBUG, "Context %ld closed", ready_head->id);
- /* no str_cleanup() here, as all contexts share the same CPU thread */
s_poll_wait(NULL, 0, 0); /* wait on poll() */
- s_log(LOG_ERR, "INTERNAL ERROR: failed to drop context");
-#else
- str_cleanup();
#endif
return NULL;
}
@@ -314,9 +320,9 @@
while(1) {
#if OPENSSL_VERSION_NUMBER<0x1000002f
- /* this critical section is a crude workaround for CVE-2010-3864 */
- /* see http://www.securityfocus.com/bid/44884 for details */
- /* NOTE: this critical section also covers callbacks (e.g. OCSP) */
+ /* this critical section is a crude workaround for CVE-2010-3864 *
+ * see http://www.securityfocus.com/bid/44884 for details *
+ * NOTE: this critical section also covers callbacks (e.g. OCSP) */
enter_critical_section(CRIT_SSL);
#endif /* OpenSSL version < 1.0.0b */
if(c->opt->option.client)
@@ -821,22 +827,26 @@
type=strchr(line, ':');
if(!type) {
s_log(LOG_ERR, "Malformed IDENT response");
+ str_free(line);
longjmp(c->err, 1);
}
*type++='\0';
system=strchr(type, ':');
if(!system) {
s_log(LOG_ERR, "Malformed IDENT response");
+ str_free(line);
longjmp(c->err, 1);
}
*system++='\0';
if(strcmp(type, " USERID ")) {
s_log(LOG_ERR, "Incorrect INETD response type");
+ str_free(line);
longjmp(c->err, 1);
}
user=strchr(system, ':');
if(!user) {
s_log(LOG_ERR, "Malformed IDENT response");
+ str_free(line);
longjmp(c->err, 1);
}
*user++='\0';
@@ -846,9 +856,11 @@
safestring(user);
s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user %s)",
c->accepted_address, user);
+ str_free(line);
longjmp(c->err, 1);
}
s_log(LOG_INFO, "IDENT authentication passed");
+ str_free(line);
}
#if defined(_WIN32_WCE) || defined(__vms)
@@ -878,8 +890,8 @@
execname_l=str2tstr(c->opt->execname);
execargs_l=str2tstr(c->opt->execargs);
CreateProcess(execname_l, execargs_l, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
- free(execname_l);
- free(execargs_l);
+ str_free(execname_l);
+ str_free(execargs_l);
closesocket(fd[1]);
CloseHandle(pi.hProcess);
@@ -916,6 +928,7 @@
longjmp(c->err, 1);
case 0: /* child */
closesocket(fd[0]);
+ set_nonblock(fd[1], 0); /* switch back to blocking mode */
/* dup2() does not copy FD_CLOEXEC flag */
dup2(fd[1], 0);
dup2(fd[1], 1);
@@ -969,9 +982,10 @@
s=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#1");
if(s<0)
longjmp(c->err, 1);
- fd[1]=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2");
- if(fd[1]<0)
+ c->fd=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2");
+ if(c->fd<0)
longjmp(c->err, 1);
+
addrlen=sizeof addr;
memset(&addr, 0, addrlen);
addr.in.sin_family=AF_INET;
@@ -979,22 +993,30 @@
addr.in.sin_port=htons(0); /* dynamic port allocation */
if(bind(s, &addr.sa, addrlen))
log_error(LOG_DEBUG, get_last_socket_error(), "bind#1");
- if(bind(fd[1], &addr.sa, addrlen))
+ if(bind(c->fd, &addr.sa, addrlen))
log_error(LOG_DEBUG, get_last_socket_error(), "bind#2");
+
if(listen(s, 1)) {
+ closesocket(s);
sockerror("listen");
longjmp(c->err, 1);
}
if(getsockname(s, &addr.sa, &addrlen)) {
+ closesocket(s);
sockerror("getsockname");
longjmp(c->err, 1);
}
- if(connect(fd[1], &addr.sa, addrlen)) {
- sockerror("connect");
+ if(connect_blocking(c, &addr, addr_len(addr))) {
+ closesocket(s);
longjmp(c->err, 1);
}
- if((fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept"))<0)
+ fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept");
+ if(fd[0]<0) {
+ closesocket(s);
longjmp(c->err, 1);
+ }
+ fd[1]=c->fd;
+ c->fd=-1;
closesocket(s); /* don't care about the result */
#else
if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "socketpair"))
--- src/stunnel.c 2011/06/18 04:05:08 1.1
+++ src/stunnel.c 2011/06/18 04:09:42
@@ -496,11 +496,9 @@
@ -229,13 +73,61 @@
}
/**************************************** log messages to identify build */
--- src/prototypes.h 2011/06/18 04:05:02 1.1
+++ src/prototypes.h 2011/06/18 04:06:08
@@ -256,6 +256,7 @@
int s_accept(int, struct sockaddr *, socklen_t *, int, char *);
void stunnel_info(int);
void die(int);
+void set_nonblock(int, unsigned long);
--- src/prototypes.h 2011-06-18 12:14:22.883741503 +0200
+++ src/prototypes.h 2011-06-17 15:14:24.000000000 +0200
@@ -154,6 +154,7 @@
SOCKADDR_LIST local_addr, remote_addr, source_addr;
char *username;
char *remote_address;
+ char *host_name;
int timeout_busy; /* maximum waiting for data time */
int timeout_close; /* maximum close_notify time */
int timeout_connect; /* maximum connect() time */
@@ -322,7 +323,6 @@
void child_status(void); /* dead libwrap or 'exec' process detected */
#endif
int set_socket_options(int, int);
-void set_nonblock(int, unsigned long);
int get_socket_error(const int);
/**************************************** prototypes for log.c */
/**************************************** prototypes for client.c */
@@ -333,24 +333,26 @@
} FD;
typedef struct {
+ SSL *ssl; /* SSL connnection */
SERVICE_OPTIONS *opt;
- char accepted_address[IPLEN]; /* text */
+ jmp_buf err; /* exception handler */
+
+ char accepted_address[IPLEN]; /* IP address as text for logging */
SOCKADDR_LIST peer_addr; /* peer address */
FD local_rfd, local_wfd; /* read and write local descriptors */
FD remote_fd; /* remote file descriptor */
- SSL *ssl; /* SSL Connection */
SOCKADDR_LIST bind_addr;
/* IP for explicit local bind or transparent proxy */
- unsigned long pid; /* PID of local process */
+ unsigned long pid; /* PID of the local process */
int fd; /* temporary file descriptor */
- jmp_buf err;
+ /* data for transfer() function */
char sock_buff[BUFFSIZE]; /* socket read buffer */
char ssl_buff[BUFFSIZE]; /* SSL read buffer */
int sock_ptr, ssl_ptr; /* index of first unused byte in buffer */
FD *sock_rfd, *sock_wfd; /* read and write socket descriptors */
FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */
- int sock_bytes, ssl_bytes; /* bytes written to socket and ssl */
+ int sock_bytes, ssl_bytes; /* bytes written to socket and SSL */
s_poll_set fds; /* file descriptors */
} CLI;
@@ -408,6 +410,7 @@
int ready; /* number of ready file descriptors */
time_t finish; /* when to finish poll() for this context */
struct CONTEXT_STRUCTURE *next; /* next context on a list */
+ void *tls; /* thread local storage for str.c */
} CONTEXT;
extern CONTEXT *ready_head, *ready_tail;
extern CONTEXT *waiting_head, *waiting_tail;

View File

@ -1,7 +1,12 @@
-------------------------------------------------------------------
Sat Jun 18 10:04:29 UTC 2011 - daniel.rahn@novell.com
- fix ucontext handling (backport from v4.37)
-------------------------------------------------------------------
Sat Jun 18 03:59:20 UTC 2011 - daniel.rahn@novell.com
- fix non-blocking socket handling (backport from 4.37)
- fix non-blocking socket handling (backport from v4.37)
-------------------------------------------------------------------
Thu Jun 16 11:44:32 UTC 2011 - daniel.rahn@novell.com

View File

@ -34,6 +34,7 @@ Source3: sysconfig.syslog-stunnel
Source4: stunnel.rc
Patch0: stunnel-listenqueue-option.patch
Patch1: non-blocking-socket-handling.patch
Patch2: fix-ucontext-handling.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define VENDOR SUSE
@ -50,8 +51,9 @@ without any changes to the program code.
%prep
%setup -q
%patch0 -p0
%patch1 -p0
%patch0 -p0
%patch2 -p0
%build
#autoreconf -fi