--- stunnel-orig/stunnel-4.20/src/stunnel.c	2006-11-30 15:47:45.000000000 -0500
+++ stunnel-4.20/src/stunnel.c	2006-12-13 04:48:18.000000000 -0500
@@ -53,6 +53,7 @@
 #endif
 
 int volatile num_clients=0; /* Current number of clients */
+int volatile conf_updated=0; /* Conf updated ? */
 
     /* Functions */
 
@@ -78,12 +79,17 @@
 }
 #endif
 
+char *cfg_arg1 = NULL;
+char *cfg_arg2 = NULL;
+
 void main_initialize(char *arg1, char *arg2) {
     ssl_init(); /* initialize SSL library */
     sthreads_init(); /* initialize critical sections & SSL callbacks */
     parse_config(arg1, arg2);
     log_open();
     stunnel_info(0);
+    cfg_arg1 = arg1;
+    cfg_arg2 = arg2;
 }
 
 void main_execute(void) {
@@ -105,10 +111,15 @@
     SOCKADDR_UNION addr;
     s_poll_set fds;
     LOCAL_OPTIONS *opt;
+    int i;
+#if !defined(USE_WIN32) && !defined(USE_OS2)
+    int signal_pipe;
+#endif
     get_limits();
     s_poll_zero(&fds);
 #if !defined(USE_WIN32) && !defined(USE_OS2)
-    s_poll_add(&fds, signal_pipe_init(), 1, 0);
+    signal_pipe = signal_pipe_init();
+    s_poll_add(&fds, signal_pipe, 1, 0);
 #endif
     if(!local_options.next) {
         s_log(LOG_ERR, "No connections defined in config file");
@@ -163,7 +174,7 @@
         create_client(-1, -1, alloc_client_session(opt, -1, -1), client);
     }
     while(1) {
-        if(s_poll_wait(&fds, -1, -1)<0) { /* non-critical error */
+        if(s_poll_wait(&fds, 1, -1)<0) { /* non-critical error */
             log_error(LOG_INFO, get_last_socket_error(),
                 "daemon_loop: s_poll_wait");
             sleep(1); /* to avoid log trashing */
@@ -173,6 +184,46 @@
                     accept_connection(opt);
 
         }
+        if(conf_updated) {
+            for(i=0; i<fds.nfds; i++)
+                close(fds.ufds[i].fd);
+    
+            s_poll_zero(&fds);
+#if !defined(USE_WIN32) && !defined(USE_OS2)
+            s_poll_add(&fds, signal_pipe, 1, 0);
+#endif
+            /* re-bind local ports */
+            for(opt=local_options.next; opt; opt=opt->next) {
+                if(!opt->option.accept) /* no need to bind this service */
+                    continue;
+            memcpy(&addr, &opt->local_addr.addr[0], sizeof(SOCKADDR_UNION));
+            if((opt->fd=socket(addr.sa.sa_family, SOCK_STREAM, 0))<0) {
+                sockerror("local socket");
+                exit(1);
+            }
+            if(alloc_fd(opt->fd))
+               exit(1);
+            if(set_socket_options(opt->fd, 0)<0)
+               exit(1);
+            s_ntop(opt->local_address, &addr);
+            if(bind(opt->fd, &addr.sa, addr_len(addr))) {
+               s_log(LOG_ERR, "Error binding %s to %s",
+                     opt->servname, opt->local_address);
+               sockerror("bind");
+               exit(1);
+            }
+               s_log(LOG_DEBUG, "%s bound to %s", opt->servname, opt->local_address);
+            if(listen(opt->fd, 5)) {
+               sockerror("listen");
+               exit(1);
+            }
+#ifdef FD_CLOEXEC
+            fcntl(opt->fd, F_SETFD, FD_CLOEXEC); /* close socket in child execvp */
+#endif
+            s_poll_add(&fds, opt->fd, 1, 0);
+            }
+	    conf_updated = 0;
+        }
     }
     s_log(LOG_ERR, "INTERNAL ERROR: End of infinite loop 8-)");
 }
@@ -413,9 +464,16 @@
 }
 
 static void signal_handler(int sig) { /* signal handler */
+    if((sig==SIGHUP) && local_options.next) { /* only in service mode */
+	s_log(LOG_NOTICE, "Re-reading configuration");
+	parse_config(cfg_arg1, cfg_arg2);
+	conf_updated = 1;
+    }
+    else {
     s_log(sig==SIGTERM ? LOG_NOTICE : LOG_ERR,
         "Received signal %d; terminating", sig);
     exit(3);
+    }
 }
 #endif /* !defined USE_WIN32 */
 
