[Pkg-privacy-commits] [onioncat] 121/340: - fixed erroneous sockaddr size in socks connect (leaded to failure on OpenBSD) - improved tunnel name determination - fixed ifconfig for OpenBSD - fixed mem leak in thread creation process - replaced static local_listeners by configurable ones (for OC listen and controller listen) - graceful shutdown (CTRL-C or SIGINT)

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 13:04:31 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch debian
in repository onioncat.

commit 200648acf7e2aa9b679eb681ea4cb05763d3a991
Author: eagle <eagle at 58e1ccc2-750e-0410-8d0d-f93ca75ab447>
Date:   Tue Feb 3 11:26:39 2009 +0000

    - fixed erroneous sockaddr size in socks connect (leaded to failure on
      OpenBSD)
    - improved tunnel name determination
    - fixed ifconfig for OpenBSD
    - fixed mem leak in thread creation process
    - replaced static local_listeners by configurable ones (for OC listen and
      controller listen)
    - graceful shutdown (CTRL-C or SIGINT)
    
    
    git-svn-id: http://www.cypherpunk.at/svn/onioncat/trunk@433 58e1ccc2-750e-0410-8d0d-f93ca75ab447
---
 ChangeLog        |   8 ++++
 TODO             |   8 ++--
 configure        |  22 ++++-----
 src/ocat.c       |  68 +++++++++++++++++++++++++-
 src/ocat.h       |  22 +++++++--
 src/ocatctrl.c   |  22 ++-------
 src/ocatlibe.c   |   5 ++
 src/ocatlog.c    |   9 ++++
 src/ocatroute.c  | 144 +++++++++++++++++--------------------------------------
 src/ocatsetup.c  |  47 ++++++++++++++++--
 src/ocatsocks.c  |  10 ++--
 src/ocatthread.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++------
 src/ocattun.c    |  37 +++++++++++++-
 13 files changed, 381 insertions(+), 162 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 418bda6..4141f87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
 * version 0.1.10
+ - fixed erroneous sockaddr size in socks connect (leaded to failure on
+ OpenBSD)
+ - improved tunnel name determination
+ - fixed ifconfig for OpenBSD
+ - fixed mem leak in thread creation process
+ - replaced static local_listeners by configurable ones (for OC listen and
+ controller listen)
+ - graceful shutdown (CTRL-C or SIGINT)
  - thread stack size configurable (necessary because OpenBSD stacksize seems
  to be to small)
 
diff --git a/TODO b/TODO
index f7c2c15..bf657df 100644
--- a/TODO
+++ b/TODO
@@ -1,12 +1,12 @@
+* OpenBSD TAP device might not work (see OpenBSD man page tun(4))
+* add Windows tunnel code
+* finish SOCKS5 code for I2P
 * work on header compression (start at RFC2507 or 3095)
-* disconnected permanent peers are not reconnected sometimes
 * peer reconnections timeout should be implemented (to not reconnect to fast)
 * log connect log to OC console
-* sometimes a peer is connected a second time for an unknown reason
 * forward multicasting packets (ff00::/8)
 * frame checking may be improved
 * generally improve tun opening routine
-* header compression
 * log levels and log output are currently somehow random
 * interaction with OS routing table to be able to forward packets to "foreign" networks beside the TOR prefix
 * peer list should be improved
@@ -27,3 +27,5 @@
 //* IPv4 forwarding + routing
 //* fragment handler
 //* improve getopt() -- currently many things are hardcoded
+//* disconnected permanent peers are not reconnected sometimes
+//* sometimes a peer is connected a second time for an unknown reason
diff --git a/configure b/configure
index b9db20b..ab34e49 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for onioncat 0.1.10-430M.
+# Generated by GNU Autoconf 2.61 for onioncat 0.1.10-432M.
 #
 # Report bugs to <rahra at cypherpunk.at>.
 #
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='onioncat'
 PACKAGE_TARNAME='onioncat'
-PACKAGE_VERSION='0.1.10-430M'
-PACKAGE_STRING='onioncat 0.1.10-430M'
+PACKAGE_VERSION='0.1.10-432M'
+PACKAGE_STRING='onioncat 0.1.10-432M'
 PACKAGE_BUGREPORT='rahra at cypherpunk.at'
 
 # Factoring default headers for most tests.
@@ -1206,7 +1206,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures onioncat 0.1.10-430M to adapt to many kinds of systems.
+\`configure' configures onioncat 0.1.10-432M to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1272,7 +1272,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of onioncat 0.1.10-430M:";;
+     short | recursive ) echo "Configuration of onioncat 0.1.10-432M:";;
    esac
   cat <<\_ACEOF
 
@@ -1362,7 +1362,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-onioncat configure 0.1.10-430M
+onioncat configure 0.1.10-432M
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1376,7 +1376,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by onioncat $as_me 0.1.10-430M, which was
+It was created by onioncat $as_me 0.1.10-432M, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2066,7 +2066,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='onioncat'
- VERSION='0.1.10-430M'
+ VERSION='0.1.10-432M'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2217,7 +2217,7 @@ ac_config_headers="$ac_config_headers config.h"
 
 
 cat >>confdefs.h <<\_ACEOF
-#define SVN_REVISION "430M"
+#define SVN_REVISION "432M"
 _ACEOF
 
 
@@ -5300,7 +5300,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by onioncat $as_me 0.1.10-430M, which was
+This file was extended by onioncat $as_me 0.1.10-432M, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -5353,7 +5353,7 @@ Report bugs to <bug-autoconf at gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-onioncat config.status 0.1.10-430M
+onioncat config.status 0.1.10-432M
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/src/ocat.c b/src/ocat.c
index ccb38e4..f5c6adb 100644
--- a/src/ocat.c
+++ b/src/ocat.c
@@ -19,6 +19,10 @@
 #include "ocat.h"
 
 
+//! set to one if SIGINT is catched
+static int sig_term_ = 0;
+
+
 void usage(const char *s)
 {
    fprintf(stderr, 
@@ -119,9 +123,57 @@ void background(void)
 }
 
 
+/*! Signal handler for SIGINT. */
+void sig_handler(int sig)
+{
+   sig_term_ = 1;
+}
+
+
+void install_sig(void)
+{
+   struct sigaction sa;
+
+   memset(&sa, 0, sizeof(sa));
+   sa.sa_handler = sig_handler;
+   log_debug("installing signal handler");
+   if (sigaction(SIGINT, &sa, NULL) == -1)
+      log_msg(LOG_ERR, "could not install signal handler: \"%s\"", strerror(errno)), exit(1);
+}
+
+
+void cleanup_system(void)
+{
+   OcatPeer_t *peer;
+
+   log_msg(LOG_NOTICE, "waiting for system cleanup...");
+   // close tunnel interface
+   log_debug("closing tunfd %d (and %d)", CNF(tunfd[0]), CNF(tunfd[1]));
+   oe_close(CNF(tunfd[0]));
+   if (CNF(tunfd[0]) != CNF(tunfd[1]))
+      oe_close(CNF(tunfd[1]));
+
+   // close and delete all peers
+   log_debug("deleting peers");
+   lock_peers();
+   for (peer = get_first_peer(); peer; peer = peer->next)
+   {
+      lock_peer(peer);
+      log_debug("closing tcpfd %d", peer->tcpfd);
+      oe_close(peer->tcpfd);
+      unlock_peer(peer);
+      log_debug("deleting peer at %p", peer);
+      delete_peer(peer);
+   }
+   unlock_peers();
+
+   // join threads
+   join_threads();
+}
+
+
 int main(int argc, char *argv[])
 {
-   //char tunname[IFNAMSIZ] = {0}, 
    char *s, ip6addr[INET6_ADDRSTRLEN], hw[20], def[100];
    int c, runasroot = 0;
    struct passwd *pwd;
@@ -225,6 +277,7 @@ int main(int argc, char *argv[])
 
    // init main thread
    (void) init_ocat_thread("main");
+   detach_thread();
 
    if (urlconv == 2)
    {
@@ -366,10 +419,21 @@ int main(int argc, char *argv[])
       ctrl_handler((void*) c);
    }
 
+   // install signal handler
+   install_sig();
+
    // start forwarding packets from tunnel
    log_msg(LOG_INFO, "starting packet forwarder");
-   packet_forwarder();
+   while (!sig_term_)
+      packet_forwarder();
+
+   log_msg(LOG_NOTICE, "caught termination request");
+   // set global termination flag
+   set_term_req();
+   // initiate termination
+   cleanup_system();
 
+   log_msg(LOG_INFO, "Thanks for using OnionCat. Good Bye!");
    return 0;
 }
 
diff --git a/src/ocat.h b/src/ocat.h
index 2b8d403..eece06f 100644
--- a/src/ocat.h
+++ b/src/ocat.h
@@ -151,6 +151,8 @@
 #define STAT_WAKEUP 600
 //! keepalive time
 #define KEEPALIVE_TIME (MAX_IDLE_TIME/2)
+//! select timeout (to avoid endless blocking)
+#define SELECT_TIMEOUT 10
 
 #define LOG_FCONN 0x80
 
@@ -170,7 +172,7 @@
 
 #define THREAD_NAME_LEN 11
 //! thread stack size (default stack size on OpenBSD is too small)
-#define THREAD_STACK_SIZE 1048576
+#define THREAD_STACK_SIZE 262144
 
 #define SOCKS_CONNECTING 1
 #define SOCKS_MAX_RETRY 3
@@ -209,7 +211,7 @@
 #define IPV4_KEY 0
 #define IPV6_KEY 1
 
-#define SOCKADDR_SIZE(x) (x->sa_family == AF_INET ? sizeof(struct sockaddr_in) : x->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0)
+#define SOCKADDR_SIZE(x) (((struct sockaddr*) x)->sa_family == AF_INET ? sizeof(struct sockaddr_in) : ((struct sockaddr*) x)->sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0)
 
 #define VERSION_STRING_LEN 256
 
@@ -276,6 +278,12 @@ struct OcatSetup
    int rand_addr;
    char version[VERSION_STRING_LEN];
    int sizeof_setup;
+   int term_req;
+   pthread_mutex_t mutex;
+   //! listening sockets for controller interface
+   struct sockaddr **ctrl_listen;
+   int *ctrl_listen_fd;
+   int ctrl_listen_cnt;
 };
 
 #ifdef PACKET_QUEUE
@@ -335,6 +343,7 @@ typedef struct OcatThread
    struct OcatThread *next;
    pthread_t handle;
    pthread_attr_t attr;
+   int detached;
    int id;
    char name[THREAD_NAME_LEN];
    void *(*entry)(void*);
@@ -511,7 +520,7 @@ void *socket_cleaner(void *);
 void *ocat_controller(void *);
 void *ctrl_handler(void *);
 int insert_peer(int, const SocksQueue_t *, time_t);
-int run_local_listeners(short, int *, int (action_accept)(int));
+int run_listeners(struct sockaddr **, int *, int, int (*)(int));
 int send_keepalive(OcatPeer_t *);
 
 /* ocatthread.c */
@@ -519,6 +528,11 @@ const OcatThread_t *init_ocat_thread(const char *);
 int run_ocat_thread(const char *, void *(*)(void*), void*);
 const OcatThread_t *get_thread(void);
 int set_thread_name(const char *);
+void join_threads(void);
+void detach_thread(void);
+void print_threads(FILE *);
+int term_req(void);
+void set_term_req(void);
 
 /* ocatcompat.c */
 #ifndef HAVE_STRLCAT
@@ -544,6 +558,8 @@ void delete_peer(OcatPeer_t *);
 extern struct OcatSetup setup_;
 void print_setup_struct(FILE *);
 void init_setup(void);
+void lock_setup(void);
+void unlock_setup(void);
 
 /* ocatipv4route.c */
 struct in6_addr *ipv4_lookup_route(uint32_t);
diff --git a/src/ocatctrl.c b/src/ocatctrl.c
index 0f4d95e..737d7ea 100644
--- a/src/ocatctrl.c
+++ b/src/ocatctrl.c
@@ -25,9 +25,6 @@
 
 #include "ocat.h"
 
-//! file descriptors of control port
-static int ctrlfd_[2];
-
 
 /*! ctrl_handler handles connections to local control port.
  *  @param p void* typcasted to int contains fd of connected socket.
@@ -42,12 +39,10 @@ void *ctrl_handler(void *p)
    char buf[FRAME_SIZE], addrstr[INET6_ADDRSTRLEN], onionstr[ONION_NAME_SIZE], timestr[32], *s, *tokbuf;
    int rlen, cfd;
    struct tm *tm;
-   OcatThread_t *th;
    OcatPeer_t *peer;
    struct in6_addr in6;
 
-   if ((rlen = pthread_detach(pthread_self())))
-      log_msg(LOG_ERR, "thread couldn't self-detach: \"%s\"", strerror(rlen));
+   detach_thread();
 
    fd = (int) p;
    if (CNF(config_read))
@@ -175,20 +170,12 @@ void *ctrl_handler(void *p)
       }
       else if (!strcmp(buf, "threads"))
       {
-         pthread_mutex_lock(&thread_mutex_);
-         for (th = octh_; th; th = th->next)
-            fprintf(ff, "%2d: %s\n", th->id, th->name);
-         pthread_mutex_unlock(&thread_mutex_);
+         print_threads(ff);
       }
       else if (!strcmp(buf, "terminate"))
       {
          log_msg(LOG_INFO, "terminate request from control port");
-         //FIXME: fds should be closed properly
-         exit(0);
-      }
-      else if (!strcmp(buf, "fds"))
-      {
-         fprintf(fo, "conntroller sockets: %d/%d\n", ctrlfd_[0], ctrlfd_[1]);
+         kill(getpid(), SIGINT);
       }
       else if (!strcmp(buf, "route"))
       {
@@ -271,7 +258,6 @@ void *ctrl_handler(void *p)
                "close <n> ...... close file descriptor <n> of a peer\n"
                "status ......... list peer status\n"
                "threads ........ show active threads\n"
-               "fds ............ show open file descriptors (w/o peers)\n"
                "route .......... show routing table\n"
                "route <dst IP> <netmask> <IPv6 gw>\n"
                "   ............. add route to routing table\n"
@@ -312,7 +298,7 @@ int run_ctrl_handler(int fd)
 
 void *ocat_controller(void *p)
 {
-   run_local_listeners(CNF(ocat_ctrl_port), ctrlfd_, run_ctrl_handler);
+   run_listeners(CNF(ctrl_listen), CNF(ctrl_listen_fd), CNF(ctrl_listen_cnt), run_ctrl_handler);
    return NULL;
 }
 
diff --git a/src/ocatlibe.c b/src/ocatlibe.c
index 3077445..1863050 100644
--- a/src/ocatlibe.c
+++ b/src/ocatlibe.c
@@ -158,3 +158,8 @@ void add_listener(const char *buf, const char *def)
       log_msg(LOG_EMERG, "could not convert address string '%s'", buf), exit(1);
 }
 
+
+void delete_listeners(struct sockaddr **adr, int *fd, int cnt)
+{
+}
+
diff --git a/src/ocatlog.c b/src/ocatlog.c
index bf350f3..a5edb24 100644
--- a/src/ocatlog.c
+++ b/src/ocatlog.c
@@ -83,6 +83,7 @@ void vlog_msgf(FILE *out, int lf, const char *fmt, va_list ap)
    time_t t;
    char timestr[TIMESTRLEN] = "", timez[TIMESTRLEN] = "";
    const OcatThread_t *th = get_thread();
+   OcatThread_t ths;
    int level = LOG_PRI(lf);
 
    if (CNF(debug_level) < level)
@@ -98,6 +99,14 @@ void vlog_msgf(FILE *out, int lf, const char *fmt, va_list ap)
       (void) strftime(timez, TIMESTRLEN, "%z", tm);
    }
 
+   // if thread struct not in list
+   if (!th)
+   {
+      strlcpy(ths.name, "<NEW>", THREAD_NAME_LEN);
+      ths.id = -1;
+      th = &ths;
+   }
+
    (void) pthread_mutex_lock(&log_mutex_);
    fprintf(out, "%s.%03d %s [%d:%-*s:%6s] ", timestr, (int) (tv.tv_usec / 1000), timez, th->id, THREAD_NAME_LEN - 1, th->name, flty_[level]);
    vfprintf(out, fmt, ap);
diff --git a/src/ocatroute.c b/src/ocatroute.c
index 658455a..6ce0daa 100644
--- a/src/ocatroute.c
+++ b/src/ocatroute.c
@@ -34,8 +34,6 @@
 #define IPHDLEN sizeof(struct ip)
 #endif
 
-// file descriptor of tcp listener
-//int sockfd_[2];
 // file descriptors of socket_receiver pipe
 // used for internal communication
 static int lpfd_[2];
@@ -267,12 +265,17 @@ void *socket_receiver(void *p)
    struct in6_addr *in6;
    int drop = 0;
    struct ether_header *eh = (struct ether_header*) (buf + 4);
+   struct timeval tv;
 
    if (pipe(lpfd_) < 0)
       log_msg(LOG_EMERG, "could not create pipe for socket_receiver: \"%s\"", strerror(errno)), exit(1);
 
    for (;;)
    {
+      // check for termination request
+      if (term_req())
+         break;
+
       FD_ZERO(&rset);
       FD_SET(lpfd_[0], &rset);
       maxfd = lpfd_[0];
@@ -299,8 +302,10 @@ void *socket_receiver(void *p)
       }
       unlock_peers();
 
+      tv.tv_sec = SELECT_TIMEOUT;
+      tv.tv_usec = 0;
       log_debug("selecting...");
-      if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, NULL)) == -1)
+      if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, &tv)) == -1)
       {
          log_msg(LOG_EMERG, "select encountered error: \"%s\", restarting", strerror(errno));
          continue;
@@ -531,6 +536,12 @@ void *socket_receiver(void *p)
         unlock_peer(peer);
       } // while (maxfd)
    } // for (;;)
+
+   // closing pipe
+   oe_close(lpfd_[0]);
+   oe_close(lpfd_[1]);
+
+   return NULL;
 }
 
 
@@ -641,27 +652,27 @@ int create_listener(struct sockaddr *addr, int sock_len)
 }
 
 
-/** run_listeners(...) is a generic socket acceptor for
- *  local TCP ports (IPv4+IPv6).
- *  It listens on a given list of sockets.
- *  Every time a connection comes in the function action_accept is
- *  called with the incoming file descriptor as parameter.
- *  @param addr Double pointer to sockaddr structs. It MUST be terminated by a null pointer.
- *  @param sockfd Points to an int array. The array must contain at least 
- *         as much entries as the sockaddr pointer has entries.
- *  @param action_accept Function pointer to function that should be called if a
- *         connection arrives.
- *  @return File descriptor or -1 on error.
+/*! run_listeners(...) is a generic socket acceptor for TCP ports.  It listens
+ * on a given list of sockets.  Every time a connection comes in the function
+ * action_accept is called with the incoming file descriptor as parameter.
+ *
+ * @param addr Double pointer to sockaddr structs. It MUST be terminated by a
+ * null pointer.  
+ * @param sockfd Points to an int array. The array must contain at least as
+ * much entries as the sockaddr pointer has entries.  
+ * @param action_accept Function pointer to function that should be called if a
+ * connection arrives.  
+ * @return Always 0.
  */
 int run_listeners(struct sockaddr **addr, int *sockfd, int cnt, int (action_accept)(int))
 {
    int fd;
-   //struct sockaddr *saddr;
    struct sockaddr_in6 in6;
    fd_set rset;
    int maxfd, i;
    socklen_t alen;
    char iabuf[INET6_ADDRSTRLEN];
+   struct timeval tv;
 
    for (i = 0; i < cnt; i++)
    {
@@ -672,6 +683,10 @@ int run_listeners(struct sockaddr **addr, int *sockfd, int cnt, int (action_acce
 
    for (;;)
    {
+      // check for termination request
+      if (term_req())
+         break;
+
       log_debug("setting up fd_set");
       FD_ZERO(&rset);
       maxfd = -1;
@@ -691,8 +706,10 @@ int run_listeners(struct sockaddr **addr, int *sockfd, int cnt, int (action_acce
          break;
       }
 
+      tv.tv_sec = SELECT_TIMEOUT;
+      tv.tv_usec = 0;
       log_debug("selecting locally (maxfd = %d)", maxfd);
-      if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, NULL)) == -1)
+      if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, &tv)) == -1)
       {
          log_debug("select returned: \"%s\"", strerror(errno));
          continue;
@@ -720,98 +737,20 @@ int run_listeners(struct sockaddr **addr, int *sockfd, int cnt, int (action_acce
                iabuf, INET6_ADDRSTRLEN);
          log_msg(LOG_INFO | LOG_FCONN, "connection %d [%d] accepted on listener %d from %s port %d", fd, i, sockfd[i], iabuf, ntohs(in6.sin6_port));
          (void) action_accept(fd);
-      }
+      } // for
    }
-   log_debug("run_listeners returns");
-   return 0;
-}
-
-
-/** run_local_listeners(...) is a generic socket acceptor for
- *  local TCP ports (IPv4+IPv6).
- *  Every time a connection comes in the function action_accept is
- *  called with the incoming file descriptor as parameter.
- */
-int run_local_listeners(short port, int *sockfd, int (action_accept)(int))
-{
-   int fd;
-   struct sockaddr_in in;
-   struct sockaddr_in6 in6;
-   fd_set rset;
-   int maxfd, i;
-   socklen_t alen;
-   char iabuf[INET6_ADDRSTRLEN];
-
-   memset(&in, 0, sizeof(in));
-   memset(&in6, 0, sizeof(in6));
-
-   in.sin_family = AF_INET;
-   in.sin_port = htons(port);
-   in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-   in6.sin6_family = AF_INET6;
-   in6.sin6_port = htons(port);
-   memcpy(&in6.sin6_addr.s6_addr, &in6addr_loopback, sizeof(in6addr_loopback));
-
-#ifdef HAVE_SIN_LEN
-   in.sin_len = sizeof(in);
-   in6.sin6_len = sizeof(in6);
-#endif
-
-   log_debug("creating IPv4 listener");
-   if ((sockfd[0] = create_listener((struct sockaddr*) &in, sizeof(in))) == -1)
-      log_msg(LOG_EMERG, "exiting"), exit(1);
-
-   log_debug("creating IPv6 listener");
-   if ((sockfd[1] = create_listener((struct sockaddr*) &in6, sizeof(in6))) == -1)
-      log_msg(LOG_EMERG, "exiting"), exit(1);
-
-   for (;;)
-   {
-      log_debug("setting up fd_set");
-      FD_ZERO(&rset);
-      FD_SET(sockfd[0], &rset);
-      FD_SET(sockfd[1], &rset);
-
-      maxfd = sockfd[0] > sockfd[1] ? sockfd[0] : sockfd[1];
-      log_debug("selecting locally (maxfd = %d)", maxfd);
-      if ((maxfd = select(maxfd + 1, &rset, NULL, NULL, NULL)) == -1)
-      {
-         log_debug("select returned: \"%s\"", strerror(errno));
-         continue;
-      }
-      log_debug("select returned %d fds ready", maxfd);
 
-      for (i = 0; maxfd && (i < 2); i++)
-      {
-         log_debug("checking fd %d (maxfd = %d, i = %d)", sockfd[i], maxfd, i);
-         if (!FD_ISSET(sockfd[i], &rset))
-            continue;
-         maxfd--;
-         alen = sizeof(in6);
-         log_debug("accepting connection on %d", sockfd[i]);
-         if ((fd = accept(sockfd[i], (struct sockaddr*) &in6, &alen)) < 0)
-         {
-            log_msg(LOG_ERR, "error accepting connection on %d: \"%s\"", sockfd[i], strerror(errno));
-            // FIXME: there should be additional error handling!
-            continue;
-         }
+   // closing listeners
+   for (i = 0; i < cnt; i++)
+      oe_close(sockfd[i]);
 
-         inet_ntop(in6.sin6_family,
-               in6.sin6_family == AF_INET6 ? &in6.sin6_addr :
-               (void*) &((struct sockaddr_in*) &in6)->sin_addr,
-               iabuf, INET6_ADDRSTRLEN);
-         log_msg(LOG_INFO | LOG_FCONN, "connection %d accepted on listener %d from %s port %d", fd, sockfd[i], iabuf, ntohs(in6.sin6_port));
-         (void) action_accept(fd);
-      }
-   }
+   log_debug("run_listeners returns");
    return 0;
 }
 
 
 void *socket_acceptor(void *p)
 {
-   //run_local_listeners(CNF(ocat_listen_port), sockfd_, insert_anon_peer);
    run_listeners(CNF(oc_listen), CNF(oc_listen_fd), CNF(oc_listen_cnt), insert_anon_peer);
    return NULL;
 }
@@ -840,7 +779,7 @@ void packet_forwarder(void)
          log_debug("read from tun %d returned on error: \"%s\"", CNF(tunfd[0]), strerror(rlen));
          if (rlen == EINTR)
          {
-            log_debug("signal caught, exiting");
+            log_debug("signal caught, exiting from packet_forwarder");
             return;
          }
          log_debug("restart reading");
@@ -970,6 +909,10 @@ void *socket_cleaner(void *ptr)
 
    for (;;)
    {
+      // check for termination request
+      if (term_req())
+         break;
+
       sleep(CLEANER_WAKEUP);
       log_debug("wakeup");
 
@@ -1022,5 +965,6 @@ void *socket_cleaner(void *ptr)
       }
       unlock_peers();
    }
+   return NULL;
 }
 
diff --git a/src/ocatsetup.c b/src/ocatsetup.c
index 445e260..9fd4571 100644
--- a/src/ocatsetup.c
+++ b/src/ocatsetup.c
@@ -27,6 +27,11 @@
 
 
 static struct sockaddr_in6 socks_dst6_;
+static struct sockaddr_in ctrl_listen_;
+static struct sockaddr_in6 ctrl_listen6_;
+static struct sockaddr *ctrl_listen_ptr_[] = 
+   {(struct sockaddr*) &ctrl_listen_, (struct sockaddr*) &ctrl_listen6_, NULL};
+static int ctrl_fd_[2] = {-1, -1};
 
 struct OcatSetup setup_ =
 {
@@ -70,7 +75,15 @@ struct OcatSetup setup_ =
    //! rand_addr
    0,
    {0},
-   sizeof(struct OcatSetup)
+   sizeof(struct OcatSetup),
+   0,
+   PTHREAD_MUTEX_INITIALIZER,
+   // ctrl_listen
+   ctrl_listen_ptr_,
+   // oc_listen_fd
+   ctrl_fd_,
+   // oc_listen_cnt
+   2
 };
 
 
@@ -93,11 +106,25 @@ void init_setup(void)
    setup_.socks_dst->sin_port = htons(TOR_SOCKS_PORT);
    setup_.socks_dst->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 #ifdef HAVE_SIN_LEN
-   setup_.socks_dst->sin_len = sizeof(socks_dst6_);
+   setup_.socks_dst->sin_len = SOCKADDR_SIZE(setup_.socks_dst);
 #endif
 
    snprintf(setup_.version, VERSION_STRING_LEN, "%s (c) %s -- compiled %s %s", PACKAGE_STRING, OCAT_AUTHOR, __DATE__, __TIME__);
 
+   ctrl_listen_.sin_family = AF_INET;
+   ctrl_listen_.sin_port = htons(setup_.ocat_ctrl_port);
+   ctrl_listen_.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+#ifdef HAVE_SIN_LEN
+   ctrl_listen_.sin_len = sizeof(ctrl_listen_);
+#endif
+
+   ctrl_listen6_.sin6_family = AF_INET6;
+   ctrl_listen6_.sin6_port = htons(setup_.ocat_ctrl_port);
+   ctrl_listen6_.sin6_addr = in6addr_loopback; //IN6ADDR_LOOPBACK_INIT;
+#ifdef HAVE_SIN_LEN
+   ctrl_listen6_.sin6_len = sizeof(ctrl_listen6_);
+#endif
+
 }
 
 
@@ -157,6 +184,7 @@ void print_setup_struct(FILE *f)
          "uptime                 = %d days, %d:%02d\n"
          "version[%3d+1/%3d]     = \"%s\"\n"
          "sizeof_setup           = %d\n"
+         "term_req               = %d\n"
          ,
          IPV4_KEY, ntohl(setup_.fhd_key[IPV4_KEY]), IPV6_KEY, ntohl(setup_.fhd_key[IPV6_KEY]),
          setup_.fhd_key_len,
@@ -188,7 +216,8 @@ void print_setup_struct(FILE *f)
          setup_.daemon,
          t / (3600 * 24), t / 3600 % 24, t / 60 % 60,
          strlen(setup_.version), VERSION_STRING_LEN, setup_.version,
-         setup_.sizeof_setup
+         setup_.sizeof_setup,
+         setup_.term_req
          );
 
    for (i = 0; i < ROOT_PEERS; i++)
@@ -219,3 +248,15 @@ void print_setup_struct(FILE *f)
    }
 }
 
+
+void lock_setup(void)
+{
+   pthread_mutex_lock(&setup_.mutex);
+}
+
+
+void unlock_setup(void)
+{
+   pthread_mutex_unlock(&setup_.mutex);
+}
+
diff --git a/src/ocatsocks.c b/src/ocatsocks.c
index 407263a..01ab278 100644
--- a/src/ocatsocks.c
+++ b/src/ocatsocks.c
@@ -44,7 +44,7 @@ int socks_srv_con(void)
       return E_SOCKS_SOCK;
 
    t = time(NULL);
-   if (connect(fd, (struct sockaddr*) CNF(socks_dst), sizeof(struct sockaddr_in6)) == -1)
+   if (connect(fd, (struct sockaddr*) CNF(socks_dst), SOCKADDR_SIZE(CNF(socks_dst))) == -1)
    {
       log_msg(LOG_ERR, "connect() to SOCKS port %s:%d failed: \"%s\". Sleeping for %d seconds.", inet_ntop(CNF(socks_dst)->sin_family, CNF(socks_dst)->sin_family == AF_INET ? (char*) &CNF(socks_dst)->sin_addr : (char*) &CNF(socks_dst6)->sin6_addr, addr, sizeof(addr)), ntohs(CNF(socks_dst)->sin_port), strerror(errno), TOR_SOCKS_CONN_TIMEOUT);
       oe_close(fd);
@@ -60,7 +60,8 @@ int socks_connect(const SocksQueue_t *sq)
 {
 //   struct sockaddr_in in;
    int fd, t, len;
-   char buf[FRAME_SIZE], onion[ONION_NAME_SIZE], addr[INET6_ADDRSTRLEN];
+   char buf[FRAME_SIZE], onion[ONION_NAME_SIZE];
+   //char addr[INET6_ADDRSTRLEN];
    SocksHdr_t *shdr = (SocksHdr_t*) buf;
    OcatPeer_t *peer;
 
@@ -197,11 +198,10 @@ void *socks_connector(void *p)
 {
    OcatPeer_t *peer;
    SocksQueue_t *squeue;
-   int i, rc, ps, run = 1, t_abs, t_diff;
+   int i, ps, run = 1, t_abs, t_diff;
    char thn[THREAD_NAME_LEN] = "cn:", on[ONION_NAME_LEN];
 
-   if ((rc = pthread_detach(pthread_self())))
-      log_msg(LOG_ERR, "couldn't detach: \"%s\"", strerror(rc));
+   detach_thread();
 
    pthread_mutex_lock(&socks_queue_mutex_);
    socks_thread_cnt_++;
diff --git a/src/ocatthread.c b/src/ocatthread.c
index fcef448..06ddbde 100644
--- a/src/ocatthread.c
+++ b/src/ocatthread.c
@@ -33,23 +33,31 @@ pthread_mutex_t thread_mutex_ = PTHREAD_MUTEX_INITIALIZER;
 OcatThread_t *octh_ = NULL;
 
 
-const OcatThread_t *init_ocat_thread(const char *name)
+void init_ocat_thread_struct(OcatThread_t *th)
 {
-   OcatThread_t *th;
-
-   // get memory for the ocat internal thread structure
-   if (!(th = malloc(sizeof(OcatThread_t))))
-      return NULL;
-
    // init ocat thread structure
+   th->handle = pthread_self();
    pthread_mutex_lock(&thread_mutex_);
    th->id = thread_id_++;
-   strncpy(th->name, name, THREAD_NAME_LEN);
-   th->name[THREAD_NAME_LEN - 1] = '\0';
-   th->handle = pthread_self();
    th->next = octh_;
    octh_ = th;
    pthread_mutex_unlock(&thread_mutex_);
+}
+
+
+const OcatThread_t *init_ocat_thread(const char *name)
+{
+   OcatThread_t *th;
+
+   // get memory for the ocat internal thread structure
+   if (!(th = calloc(1, sizeof(OcatThread_t))))
+   {
+      log_msg(LOG_ERR, "could not get memory for thread struct: \"%s\"", strerror(errno));
+      return NULL;
+   }
+
+   strlcpy(th->name, name, THREAD_NAME_LEN);
+   init_ocat_thread_struct(th);
 
    return th;
 }
@@ -66,18 +74,19 @@ void *thread_run(void *p)
    pthread_sigmask(SIG_BLOCK, &ss, NULL);
 
    // init internal ocat thread structure
-   (void) init_ocat_thread(((OcatThread_t *)p)->name);
+   init_ocat_thread_struct((OcatThread_t *) p);
 
    // call thread entry function
    log_debug("starting thread");
    r = ((OcatThread_t*)p)->entry(((OcatThread_t*)p)->parm);
    log_debug("terminating thread");
 
+   // delete thread struct from list and free memory
    pthread_mutex_lock(&thread_mutex_);
    for (tl = &octh_; *tl; tl = &(*tl)->next)
       if ((*tl)->handle == ((OcatThread_t*)p)->handle)
          break;
-   free(p);
+   //free(p);
    if ((p = *tl))
    {
       *tl = (*tl)->next;
@@ -98,15 +107,14 @@ int run_ocat_thread(const char *name, void *(*thfunc)(void*), void *parm)
    // this is because pthread_create pushes only one arg.
    // the helper struct is freed again from the thread
    // (within thread_run()).
-   if (!(th = malloc(sizeof(OcatThread_t))))
+   if (!(th = calloc(1, sizeof(OcatThread_t))))
    {
       rc = errno;
       log_msg(LOG_EMERG, "could not create thread %s: \"%s\"", name, strerror(errno));
       return rc;
    }
 
-   strncpy(th->name, name, THREAD_NAME_LEN);
-   th->name[THREAD_NAME_LEN - 1] = '\0';
+   strlcpy(th->name, name, THREAD_NAME_LEN);
    th->entry = thfunc;
    th->parm = parm;
 
@@ -115,6 +123,15 @@ int run_ocat_thread(const char *name, void *(*thfunc)(void*), void *parm)
       log_msg(LOG_ERR, "could not init pthread attr: \"%s\"", strerror(rc));
       return rc;
    }
+
+#ifdef DEBUG
+   size_t ss;
+   if ((rc - pthread_attr_getstacksize(&th->attr, &ss)))
+      log_debug("could not get thread stack size attr: \"%s\"", strerror(rc));
+   else
+      log_debug("default thread stack size %dk, setting to %dk", ss / 1024, THREAD_STACK_SIZE / 1024);
+#endif
+
    if ((rc - pthread_attr_setstacksize(&th->attr, THREAD_STACK_SIZE)))
    {
       log_msg(LOG_EMERG, "could not init thread stack size attr - system may be unstable: \"%s\"", strerror(rc));
@@ -166,3 +183,97 @@ int set_thread_name(const char *n)
    return e;
 }
 
+
+void print_threads(FILE *f)
+{
+   OcatThread_t *th;
+
+   pthread_mutex_lock(&thread_mutex_);
+   for (th = octh_; th; th = th->next)
+   {
+      fprintf(f, "[%s] "
+            "handle = 0x%08lx, "
+            "id = %d, "
+            "entry = %p, "
+            "parm = %p, "
+            "detached = %d\n",
+            th->name, (long) th->handle, th->id, th->entry, th->parm, th->detached);
+   }
+   pthread_mutex_unlock(&thread_mutex_);
+}
+
+
+void join_threads(void)
+{
+   OcatThread_t *th, thb;
+   void *ret;
+   int rc;
+
+   for (;;)
+   {
+      pthread_mutex_lock(&thread_mutex_);
+      for (th = octh_; th && th->detached; th = th->next);
+      if (!th)
+      {
+         pthread_mutex_unlock(&thread_mutex_);
+         break;
+      }
+      memcpy(&thb, th, sizeof(OcatThread_t));
+      pthread_mutex_unlock(&thread_mutex_);
+
+      log_debug("joing thread \"%s\" (%d)", thb.name, thb.id);
+      if ((rc = pthread_join(thb.handle, &ret)))
+         log_msg(LOG_ERR, "error joining thread: \"%s\"", strerror(rc));
+      log_debug("thread successful joined and return %p", ret);
+      sleep(10);
+   }
+   log_debug("no more joinable threads available");
+}
+
+
+void detach_thread(void)
+{
+   OcatThread_t *th;
+   pthread_t thread = pthread_self();
+   int rc;
+
+   pthread_mutex_lock(&thread_mutex_);
+   for (th = octh_; th; th = th->next)
+      if (th->handle == thread)
+         break;
+   if (th && !(rc = pthread_detach(thread)))
+      th->detached = 1;
+   pthread_mutex_unlock(&thread_mutex_);
+
+   if (!th)
+      log_msg(LOG_EMERG, "thread tries to detach but is not in list");
+   else if (rc)
+      log_msg(LOG_ERR, "could not detach thread: \"%s\"", strerror(rc));
+   else
+      log_debug("thread detached");
+}
+
+
+/*! Check for termination request.
+ *  @return 1 if termination requested, otherwise 0.
+ */
+int term_req(void)
+{
+   int trq;
+
+   lock_setup();
+   trq = CNF(term_req);
+   unlock_setup();
+
+   return trq;
+}
+
+
+/*! Set termination request. */
+void set_term_req(void)
+{
+   lock_setup();
+   CNF(term_req) = 1;
+   unlock_setup();
+}
+
diff --git a/src/ocattun.c b/src/ocattun.c
index 2ac9bac..3b1dab7 100644
--- a/src/ocattun.c
+++ b/src/ocattun.c
@@ -30,6 +30,7 @@
 
 char *tun_dev_ = TUN_DEV;
 
+#define IFCBUF 1024
 
 int tun_alloc(char *dev, struct in6_addr addr)
 {
@@ -37,7 +38,7 @@ int tun_alloc(char *dev, struct in6_addr addr)
    int fd;
    char astr[INET6_ADDRSTRLEN];
    char astr4[INET_ADDRSTRLEN];
-   char buf[FRAME_SIZE];
+   char buf[IFCBUF];
    struct in_addr netmask = {CNF(ocat_addr4_mask)};
 
 	log_debug("opening tun \"%s\"", tun_dev_);
@@ -84,6 +85,33 @@ int tun_alloc(char *dev, struct in6_addr addr)
    CNF(fhd_key[IPV6_KEY]) = htonl(AF_INET6);
    CNF(fhd_key[IPV4_KEY]) = htonl(AF_INET);
 
+   // get interface name
+   if (!CNF(use_tap))
+   {
+      if (strstr(tun_dev_, "tun"))
+         strlcpy(dev, strstr(tun_dev_, "tun"), IFNAMSIZ);
+      else
+         strlcpy(dev, "tun0", IFNAMSIZ);
+   }
+   else
+   {
+       if (strstr(tun_dev_, "tap"))
+         strlcpy(dev, strstr(tun_dev_, "tap"), IFNAMSIZ);
+      else
+         strlcpy(dev, "tap0", IFNAMSIZ);
+   }
+   /*
+   if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
+   {
+      log_msg(LOG_ERR, "could not SIOCGIFADDR to get interface name: \"%s\"", strerror(errno));
+      strlcpy(dev, "tun0", IFNAMSIZ);
+   }
+   else
+   {
+      strlcpy(dev, ifr.ifr_name, IFNAMSIZ);
+   }
+   */
+
 #ifdef __FreeBSD__
 
    int prm = 1;
@@ -108,9 +136,14 @@ int tun_alloc(char *dev, struct in6_addr addr)
 
 #endif
 
+
    if (!CNF(use_tap))
    {
-      snprintf(buf, sizeof(buf), "ifconfig tun0 inet6 %s/%d up", astr, TOR_PREFIX_LEN);
+#ifdef __OpenBSD__
+      snprintf(buf, sizeof(buf), "ifconfig %s inet6 %s prefixlen %d up", dev, astr, TOR_PREFIX_LEN);
+#else
+      snprintf(buf, sizeof(buf), "ifconfig %s inet6 %s/%d up", dev, astr, TOR_PREFIX_LEN);
+#endif
       log_debug("setting IP on tun: \"%s\"", buf);
       if (system(buf) == -1)
          log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onioncat.git



More information about the Pkg-privacy-commits mailing list