[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