[Pkg-privacy-commits] [onioncat] 13/340: thread startup improved local control socket implemented with some commands

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 13:04:20 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 77908b5b46b618f603d8bf132a309910e70f9dfb
Author: eagle <eagle at 58e1ccc2-750e-0410-8d0d-f93ca75ab447>
Date:   Fri Feb 8 23:31:47 2008 +0000

    thread startup improved
    local control socket implemented with some commands
    
    
    git-svn-id: http://www.cypherpunk.at/svn/onioncat/trunk@128 58e1ccc2-750e-0410-8d0d-f93ca75ab447
---
 Makefile     |   2 +-
 RELEASE      |   6 +++
 TODO         |   5 ++
 ocat.c       |  27 ++++++----
 ocat.h       |  50 +++++++++++++-----
 ocatlog.c    |   6 +--
 ocatroute.c  | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 ocatthread.c |  77 ++++++++++++++++++++++++++++
 ocatv6conv.c |   5 +-
 9 files changed, 302 insertions(+), 39 deletions(-)

diff --git a/Makefile b/Makefile
index cd7486e..54a1e00 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ TARGET = ocat
 
 all: $(TARGET)
 
-ocat: ocatroute.o ocattun.o ocatv6conv.o ocatlog.o
+ocat: ocatroute.o ocattun.o ocatv6conv.o ocatlog.o ocatthread.o
 
 clean:
 	rm -f *.o $(TARGET)
diff --git a/RELEASE b/RELEASE
index 69e2bcd..1e8c69c 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1,3 +1,8 @@
+* 
+ - local controller socket available: commands: status, close, exit, quit
+ - thread start routine modularized
+ - logging improved
+
 * verion 0.1.1
  - improved interoperability
  - compiles also und FreeBSD 6.1
@@ -6,3 +11,4 @@
 
 * version 0.1
  - works good under linux, gcc-4.2, linux-2.6.22
+
diff --git a/TODO b/TODO
index 29a6064..f078907 100644
--- a/TODO
+++ b/TODO
@@ -5,5 +5,10 @@
 * improve getopt() -- currently many things are hardcoded
 //* packets received on sockets should be validated (Ethertype, ip)
 * improve tun header test (check for src and dst ip)
+* generally improve tun opening routine
 * licence
+* socks_connector queue
+* header compression
+* fragment handler
+* packet_forwarder depends on socks_connector, currently possible unclean startup (not dangerous)
 
diff --git a/ocat.c b/ocat.c
index 4881500..88ce9a8 100644
--- a/ocat.c
+++ b/ocat.c
@@ -122,6 +122,8 @@ int main(int argc, char *argv[])
    if (!argv[optind])
       usage(argv[0]), exit(1);
 
+   (void) init_ocat_thread("main");
+
    if (urlconv == 2)
    {
       if (inet_pton(AF_INET6, argv[optind], &addr) <= 0)
@@ -160,19 +162,18 @@ int main(int argc, char *argv[])
       exit(0);
 #endif
    log_msg(L_NOTICE, "[main] local IP is %s on %s", ip6addr, tunname);
+
+
    // start socket receiver thread
-   init_socket_receiver();
+   //init_socket_receiver();
+   run_ocat_thread("receiver", socket_receiver);
    // create listening socket and start socket acceptor
-   init_socket_acceptor();
+   //init_socket_acceptor();
+   run_ocat_thread("acceptor", socket_acceptor);
    // starting socket cleaner
-   init_socket_cleaner();
+   //init_socket_cleaner();
+   run_ocat_thread("cleaner", socket_cleaner);
 
-/*   // create socks connector thread
-   init_socks_connector();
-   // start packet dequeuer
-   init_packet_dequeuer();
-*/
-   
    if (!runasroot && !getuid())
    {
       log_msg(L_NOTICE, "[main] running as root, changing uid/gid to %d/%d", uid, gid);
@@ -184,9 +185,13 @@ int main(int argc, char *argv[])
    log_msg(L_NOTICE, "[main] uid/gid = %d/%d", getuid(), getgid());
 
    // create socks connector thread
-   init_socks_connector();
+   //init_socks_connector();
+   run_ocat_thread("connector", socks_connector);
    // start packet dequeuer
-   init_packet_dequeuer();
+   //init_packet_dequeuer();
+   run_ocat_thread("dequeuer", packet_dequeuer);
+
+   run_ocat_thread("controller", ocat_controller);
 
    // start forwarding packets from tunnel
    log_msg(L_NOTICE, "[main] starting packet forwarder");
diff --git a/ocat.h b/ocat.h
index 7e69968..79c3c87 100644
--- a/ocat.h
+++ b/ocat.h
@@ -1,21 +1,20 @@
 #ifndef OCAT_H
 #define OCAT_H
 
-//#define _POSIX_C_SOURCE 199309L
 
 #include <time.h>
 #include <netinet/in.h>
 #include <netinet/ip6.h>
+#include <pthread.h>
 
 
-//#define BUFLEN 64*1024
-
 #define IP6HLEN sizeof(struct ip6_hdr)
 // TOR prefix : FD87:D87E:EB43::/40
 #define TOR_PREFIX {0xfd,0x87,0xd8,0x7e,0xeb,0x43}
 #define TOR_PREFIX_LEN 48
 #define MAXPEERS 1024
 #define OCAT_LISTEN_PORT 8000
+#define OCAT_CTRL_PORT 8001
 #define OCAT_DEST_PORT 80
 #define TOR_SOCKS_PORT 9050
 
@@ -43,9 +42,14 @@
 
 //#define PEER_CONNECT 0
 #define PEER_ACTIVE 1
+
 #define PEER_INCOMING 0
 #define PEER_OUTGOING 1
 
+#define THREAD_NAME_LEN 11
+//#define MAX_THREADS 8
+
+
 typedef struct PacketQueue
 {
    struct PacketQueue *next;
@@ -70,8 +74,18 @@ typedef struct OnionPeer
    time_t time;            //<! timestamp of latest packet
    int state;              //<! status of peer
    int dir;
+   unsigned long out;
+   unsigned long in;
 } OnionPeer_t;
 
+typedef struct OcatThread
+{
+   struct OcatThread *next;
+   pthread_t handle;
+   int id;
+   char name[THREAD_NAME_LEN];
+} OcatThread_t;
+
 typedef struct OcatHdr
 {
    struct ip6_hdrctl oh_ip6hdrctl;
@@ -98,7 +112,7 @@ void log_msg(int, const char *, ...);
 void set_ipv6_addr(int, struct in6_addr, int);
 
 /* ocatv6conv.c */
-void ipv6tonion(const struct in6_addr *, char *);
+char *ipv6tonion(const struct in6_addr *, char *);
 int oniontipv6(const char *, struct in6_addr *);
 int has_tor_prefix(const struct in6_addr *);
 
@@ -109,21 +123,33 @@ void test_tun_hdr(void);
 #endif
 
 /* ocatroute.c */
-OnionPeer_t *search_peer(const struct in6_addr *);
-OnionPeer_t *establish_peer(int fd, const struct in6_addr *);
+//OnionPeer_t *search_peer(const struct in6_addr *);
+//OnionPeer_t *establish_peer(int fd, const struct in6_addr *);
 void init_peers(void);
-void init_socket_acceptor(void);
-void init_socket_receiver(void);
-void init_socks_connector(void);
+//void init_socket_acceptor(void);
+//void init_socket_receiver(void);
+//void init_socks_connector(void);
 //void push_socks_connector(const struct in6_addr *);
 //int socks_connect(const char *);
-//void *socket_receiver(void *p);
+void *socket_receiver(void *);
 //void update_peer_time(const OnionPeer_t *);
 //const OnionPeer_t *forward_packet(const struct in6_addr *, const char *, int);
 //void queue_packet(const struct in6_addr *, const char *, int);
-void init_packet_dequeuer(void);
+//void init_packet_dequeuer(void);
 void packet_forwarder(void);
-void init_socket_cleaner(void);
+//void init_socket_cleaner(void);
+void *packet_dequeuer(void *);
+void *socket_acceptor(void *);
+void *socks_connector(void *);
+void *socket_cleaner(void *);
+void *ocat_controller(void *);
+
+
+/* ocatthread.c */
+//void init_threads(void);
+const OcatThread_t *init_ocat_thread(const char *);
+int run_ocat_thread(const char *, void *(*)(void*));
+const OcatThread_t *get_thread(void);
 
 
 #endif
diff --git a/ocatlog.c b/ocatlog.c
index 263bb5d..c5e533c 100644
--- a/ocatlog.c
+++ b/ocatlog.c
@@ -17,24 +17,24 @@ static const char *flty_[] = {"info", "notice", "error", "fatal", "debug"};
 
 void log_msg(int lf, const char *fmt, ...)
 {
-   unsigned tid;
    struct tm *tm;
    time_t t;
    FILE *out = stderr;
    char timestr[32] = "";
    va_list ap;
+   const OcatThread_t *th = get_thread();
 
    if (debug_level_ < lf || lf < 0)
       return;
 
+   //th = get_thread();
    t = time(NULL);
    tm = localtime(&t);
    if (tm)
       strftime(timestr, 32, "%c", tm);
-   tid = (unsigned) pthread_self();
 
    pthread_mutex_lock(&log_mutex_);
-   fprintf(out, "%s [%08x] %6s ", timestr, tid, flty_[lf]);
+   fprintf(out, "%s [%d:%-*s] %6s ", timestr, th->id, THREAD_NAME_LEN - 1, th->name, flty_[lf]);
 
    va_start(ap, fmt);
    vfprintf(out, fmt, ap);
diff --git a/ocatroute.c b/ocatroute.c
index e2ad771..2423620 100644
--- a/ocatroute.c
+++ b/ocatroute.c
@@ -144,6 +144,7 @@ void rewrite_framehdr(char *buf, int len)
       log_msg(L_DEBUG, "[forwarding_packet]");
       write(peer->tcpfd, buf, buflen);
       peer->time = time(NULL);
+      peer->out += buflen;
    }
    pthread_mutex_unlock(&peer_mutex_);
 
@@ -186,7 +187,8 @@ void *packet_dequeuer(void *p)
    int rc, timed = 0;
    time_t delay;
 
-   log_msg(L_NOTICE, "[packet_dequeuer] running");
+   (void) init_ocat_thread(p);
+
    for (;;)
    {
       pthread_mutex_lock(&queue_mutex_);
@@ -240,6 +242,7 @@ void *packet_dequeuer(void *p)
 }
 
 
+/*
 void init_packet_dequeuer(void)
 {
    pthread_t thread;
@@ -248,6 +251,7 @@ void init_packet_dequeuer(void)
    if ((rc = pthread_create(&thread, NULL, packet_dequeuer, NULL)))
       log_msg(L_FATAL, "[init_packet_dequeuer] could not start socket_receiver thread: \"%s\"", strerror(rc));
 }
+*/
 
 
 const static char hdigit_[] = "0123456789abcdef";
@@ -326,7 +330,11 @@ void *socket_receiver(void *p)
    struct ip6_hdr *ihd;
    ihd = (struct ip6_hdr*) &buf[4];
 
-   log_msg(L_DEBUG, "[socket_receiver] running");
+   (void) init_ocat_thread(p);
+
+   if (pipe(lpfd_) < 0)
+      log_msg(L_FATAL, "[init_socket_receiver] could not create pipe for socket_receiver: \"%s\"", strerror(errno)), exit(1);
+
    for (;;)
    {
       FD_ZERO(&rset);
@@ -406,6 +414,7 @@ void *socket_receiver(void *p)
             pthread_mutex_lock(&peer_mutex_);
             // update timestamp
             peer_[i].time = time(NULL);
+            peer_[i].in += len;
             // set IP address if it is not set yet and frame is valid
             if (plen && !memcmp(&peer_[i].addr, &in6addr_any, sizeof(struct in6_addr)))
             {
@@ -425,6 +434,7 @@ void *socket_receiver(void *p)
 }
 
 
+/*
 void init_socket_receiver(void)
 {
    pthread_t thread;
@@ -436,6 +446,7 @@ void init_socket_receiver(void)
    if ((rc = pthread_create(&thread, NULL, socket_receiver, NULL)))
       log_msg(L_FATAL, "[init_socket_receiver] could not start socket_receiver thread: \"%s\"", strerror(rc));
 }
+*/
 
 
 void set_nonblock(int fd)
@@ -485,11 +496,32 @@ void insert_peer(int fd, const struct in6_addr *addr)
 
 void *socket_acceptor(void *p)
 {
-//   struct ReceiverInfo *fwinfo;
-//   OnionPeer_t *peer;
    int fd;
+   struct sockaddr_in in;
+
+   (void) init_ocat_thread(p);
 
    log_msg(L_NOTICE, "[socket_acceptor] running");
+
+   memset(&in, 0, sizeof(in));
+   in.sin_family = AF_INET;
+   in.sin_port = htons(ocat_listen_port_);
+   in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+#ifndef linux
+   in.sin_len = sizeof(in);
+#endif
+
+   if ((sockfd_ = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+      log_msg(L_FATAL, "[init_socket_acceptor] could not create listener socker: \"%s\"", strerror(errno)), exit(1);
+
+   if (bind(sockfd_, (struct sockaddr*) &in, sizeof(struct sockaddr_in)) < 0)
+      log_msg(L_FATAL, "[init_socket_acceptor] could not bind listener: \"%s\"", strerror(errno)), exit(1);
+
+   if (listen(sockfd_, 32) < 0)
+      log_msg(L_FATAL, "[init_socket_acceptor] could not bring listener to listening state: \"%s\"", strerror(errno)), exit(1);
+   
+   log_msg(L_NOTICE, "[init_socket_acceptor] created local listener on port %d", ocat_listen_port_);
+
    for (;;)
    {
       log_msg(L_DEBUG, "[socket acceptor] is accepting further connections");
@@ -504,9 +536,10 @@ void *socket_acceptor(void *p)
 }
 
 
+/*
 void init_socket_acceptor(void)
 {
-   struct sockaddr_in in /*= {AF_INET, htons(ocat_listen_port_), {htonl(INADDR_LOOPBACK)}}*/ ;
+   struct sockaddr_in in;
    pthread_t thread;
    int rc;
 
@@ -532,6 +565,7 @@ void init_socket_acceptor(void)
    if ((rc = pthread_create(&thread, NULL, socket_acceptor, NULL)))
       log_msg(L_FATAL, "[init_socket_acceptor] could not create socket_acceptor: \"%s\"", strerror(rc)), exit(1);
 }
+*/
 
 
 //int socks_connect(const char *onion)
@@ -607,6 +641,11 @@ void *socks_connector(void *p)
    struct in6_addr addr;
    int len;
 
+   (void) init_ocat_thread(p);
+
+   if (pipe(cpfd_) < 0)
+      log_msg(L_FATAL, "[init_socks_connector] could not create pipe for socks_connector: \"%s\"", strerror(errno)), exit(1);
+
    log_msg(L_NOTICE, "[socks_connector] running");
 
    for (;;)
@@ -634,7 +673,7 @@ void *socks_connector(void *p)
    }
 }
 
-
+/*
 void init_socks_connector(void)
 {
    pthread_t thread;
@@ -646,6 +685,7 @@ void init_socks_connector(void)
    if ((rc = pthread_create(&thread, NULL, socks_connector, NULL)))
       log_msg(L_FATAL, "[init_socks_connector] could not start socks_connector thread: \"%s\"", strerror(rc));
 }
+*/
 
 
 void packet_forwarder(void)
@@ -686,17 +726,20 @@ void packet_forwarder(void)
 void *socket_cleaner(void *p)
 {
    int i;
-   log_msg(L_NOTICE, "[socket_cleaner] running");
+
+   (void) init_ocat_thread(p);
+
+   log_msg(L_NOTICE, "running");
    for (;;)
    {
       sleep(CLEANER_WAKEUP);
-      log_msg(L_DEBUG, "[socket_cleaner] wakeup");
+      log_msg(L_DEBUG, "wakeup");
       pthread_mutex_lock(&peer_mutex_);
       for (i = 0; i < MAXPEERS; i++)
       {
          if (peer_[i].state && peer_[i].time + MAX_IDLE_TIME < time(NULL))
          {
-            log_msg(L_NOTICE, "[socket_cleaner] peer %d timed out, closing.", peer_[i].tcpfd);
+            log_msg(L_NOTICE, "peer %d timed out, closing.", peer_[i].tcpfd);
             close(peer_[i].tcpfd);
             delete_peer(&peer_[i]);
          }
@@ -705,7 +748,7 @@ void *socket_cleaner(void *p)
    }
 }
 
-
+/*
 void init_socket_cleaner(void)
 {
    pthread_t thread;
@@ -714,4 +757,104 @@ void init_socket_cleaner(void)
    if ((rc = pthread_create(&thread, NULL, socket_cleaner, NULL)))
       log_msg(L_FATAL, "[init_socket_cleaner] could not start thread: \"%s\"", strerror(rc));
 }
+*/
+
+
+void *ocat_controller(void *p)
+{
+   int fd;
+   struct sockaddr_in in;
+   char buf[FRAME_SIZE], addrstr[INET6_ADDRSTRLEN], onionstr[ONION_NAME_SIZE];
+   int rlen, i, cfd;
+
+   (void) init_ocat_thread(p);
+
+   memset(&in, 0, sizeof(in));
+   in.sin_family = AF_INET;
+   in.sin_port = htons(OCAT_CTRL_PORT);
+   in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+#ifndef linux
+   in.sin_len = sizeof(in);
+#endif
+
+   if ((sockfd_ = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+      log_msg(L_FATAL, "could not create listener socker: \"%s\"", strerror(errno)), exit(1);
+
+   if (bind(sockfd_, (struct sockaddr*) &in, sizeof(struct sockaddr_in)) < 0)
+      log_msg(L_FATAL, "could not bind listener: \"%s\"", strerror(errno)), exit(1);
+
+   if (listen(sockfd_, 5) < 0)
+      log_msg(L_FATAL, "could not bring listener to listening state: \"%s\"", strerror(errno)), exit(1);
+   
+   log_msg(L_NOTICE, "created local listener on port %d", ocat_listen_port_);
+
+   for (;;)
+   {
+      log_msg(L_DEBUG, "accepting connections");
+      if ((fd = accept(sockfd_, NULL, NULL)) < 0)
+         log_msg(L_FATAL, "error in acception: \"%s\"", strerror(errno)), exit(1);
+      log_msg(L_NOTICE, "connection accepted");
+
+      for (;;)
+      {
+         /*
+         for (i = 0; (rlen = read(fd, &buf[i], 1)) > 0; i++)
+            if (buf[i] == '\n')
+            {
+               buf[i] = '\0';
+               break;
+            }
+            */
+
+         write(fd, "> ", 2);
+
+         if ((rlen = read(fd, buf, FRAME_SIZE)) == -1)
+         {
+            log_msg(L_FATAL, "read error on %d: \"%s\", closing", fd, strerror(errno));
+            break;
+         }
+
+         if (!rlen || buf[0] == 4 || !strncmp(buf, "exit", 4) || !strncmp(buf, "quit", 4))
+            break;
+         else if (!strncmp(buf, "status", 6))
+         {
+            pthread_mutex_lock(&peer_mutex_);
+            for (i = 0; i < MAXPEERS; i++)
+               if (peer_[i].state == PEER_ACTIVE)
+               {
+                  sprintf(buf, "[%s]\n fd = %d\n addr = %s\n dir = \"%s\"\n idle = %ld\n bytes_in = %ld\n bytes_out = %ld\n\n",
+                        ipv6tonion(&peer_[i].addr, onionstr), peer_[i].tcpfd,
+                        inet_ntop(AF_INET6, &peer_[i].addr, addrstr, INET6_ADDRSTRLEN),
+                        peer_[i].dir == PEER_INCOMING ? "in" : "out",
+                        time(NULL) - peer_[i].time, peer_[i].in, peer_[i].out);
+                  write(fd, buf, strlen(buf));
+               }
+            pthread_mutex_unlock(&peer_mutex_);
+         }
+         else if (!strncmp(buf, "close ", 6))
+         {
+            cfd = atoi(&buf[6]);
+            pthread_mutex_lock(&peer_mutex_);
+            for (i = 0; i < MAXPEERS; i++)
+               if (peer_[i].tcpfd == cfd)
+               {
+                  log_msg(L_NOTICE, "close request for %d", cfd);
+                  close(cfd);
+                  delete_peer(&peer_[i]);
+                  break;
+               }
+            pthread_mutex_unlock(&peer_mutex_);
+         }
+         else
+         {
+            strcpy(buf, "unknown command\n");
+            write(fd, buf, strlen(buf));
+         }
+      }
+      log_msg(L_NOTICE, "closing session %d", fd);
+      close(fd);
+   }
+
+   return NULL;
+}
 
diff --git a/ocatthread.c b/ocatthread.c
new file mode 100644
index 0000000..54a5432
--- /dev/null
+++ b/ocatthread.c
@@ -0,0 +1,77 @@
+/*! ocatroute.c
+ *  Contains functions for managing both kind of TCP peers.
+ *  Those are active SOCKS4A and passive TCP-LISTEN.
+ *
+ *  @author Bernhard Fischer <rahra _at_ cypherpunk at>
+ *  @version 2008/02/03-01
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "ocat.h"
+
+
+// global thread id var and mutex for thread initializiation
+static int thread_id_ = 0;
+static pthread_mutex_t thread_mutex_ = PTHREAD_MUTEX_INITIALIZER;
+static OcatThread_t *octh_ = NULL;
+
+/*
+void init_threads(void)
+{
+   memset(octh_, 0, sizeof(OcatThread_t) * MAX_THREADS);
+}
+*/
+
+
+const OcatThread_t *init_ocat_thread(const char *name)
+{
+   OcatThread_t *th;
+
+   if (!(th = malloc(sizeof(OcatThread_t))))
+      return NULL;
+
+   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_);
+
+   log_msg(L_NOTICE, "running");
+   return th;
+}
+
+
+int run_ocat_thread(const char *name, void *(*thfunc)(void*))
+{
+   int rc;
+   pthread_t th;
+
+   log_msg(L_DEBUG, "starting [%s]", name);
+   if ((rc = pthread_create(&th, NULL, thfunc, (void*) name)))
+      log_msg(L_FATAL, "could not start thread %s: \"%s\"", name, strerror(rc));
+
+   return rc;
+}
+
+
+const OcatThread_t *get_thread(void)
+{
+   OcatThread_t *th;
+   pthread_t thread = pthread_self();
+
+   pthread_mutex_lock(&thread_mutex_);
+   for (th = octh_; th; th = th->next)
+      if (th->handle == thread)
+         break;
+   pthread_mutex_unlock(&thread_mutex_);
+
+   return th;
+}
+
diff --git a/ocatv6conv.c b/ocatv6conv.c
index 06bb571..ebd6c78 100644
--- a/ocatv6conv.c
+++ b/ocatv6conv.c
@@ -85,10 +85,10 @@ int oniontipv6(const char *onion, struct in6_addr *ip6)
 }
 
 
-void ipv6tonion(const struct in6_addr *ip6, char *onion)
+char *ipv6tonion(const struct in6_addr *ip6, char *onion)
 {
    int i;
-   char bin[16];
+   char bin[16], *r = onion;
 
    memcpy(bin, (char*) ip6 + 6, 16);
 
@@ -105,5 +105,6 @@ void ipv6tonion(const struct in6_addr *ip6, char *onion)
       */
    }
    *onion = '\0';
+   return r;
 }
 

-- 
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