diff --git a/fix-ucontext-handling.patch b/fix-ucontext-handling.patch new file mode 100644 index 0000000..f71024d --- /dev/null +++ b/fix-ucontext-handling.patch @@ -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")) diff --git a/non-blocking-socket-handling.patch b/non-blocking-socket-handling.patch index e30acf8..e6e6632 100644 --- a/non-blocking-socket-handling.patch +++ b/non-blocking-socket-handling.patch @@ -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; diff --git a/stunnel.changes b/stunnel.changes index 7e3beb2..8321b91 100644 --- a/stunnel.changes +++ b/stunnel.changes @@ -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 diff --git a/stunnel.spec b/stunnel.spec index b9dfc19..3846435 100644 --- a/stunnel.spec +++ b/stunnel.spec @@ -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