Imported Upstream version 0.3.3
[debian/uanytun.git] / src / uanytun.c
index 0e36781..53acbaf 100644 (file)
@@ -15,7 +15,7 @@
  *  tunneling and relaying of packets of any protocol.
  *  
  *
- *  Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
+ *  Copyright (C) 2007-2010 Christian Pointner <equinox@anytun.org>
  *
  *  This file is part of uAnytun.
  *
 #ifndef NO_CRYPT
 #include "key_derivation.h"
 #include "auth_algo.h"
-
-#ifndef USE_SSL_CRYPTO
-#include <gcrypt.h>
-#endif
+#else
+typedef u_int8_t auth_algo_t;
 #endif
-
+#include "init_crypt.h"
 
 #include "daemon.h"
 #include "sysexec.h"
 
-#ifndef NO_CRYPT
-#ifndef USE_SSL_CRYPTO
-
-#define MIN_GCRYPT_VERSION "1.2.0"
-
-int init_libgcrypt()
-{
-  if(!gcry_check_version(MIN_GCRYPT_VERSION)) {
-    log_printf(NOTICE, "invalid Version of libgcrypt, should be >= %s", MIN_GCRYPT_VERSION);
-    return -1;
-  }
-
-  gcry_error_t err = gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
-  if(err) {
-    log_printf(ERROR, "failed to disable secure memory: %s", gcry_strerror(err));
-    return -1;
-  }
-
-  err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
-  if(err) {
-    log_printf(ERROR, "failed to finish libgcrypt initialization: %s", gcry_strerror(err));
-    return -1;
-  }
-
-  log_printf(NOTICE, "libgcrypt init finished");
-  return 0;
-}
-#endif
-#endif
-
-#ifdef NO_CRYPT
-typedef u_int8_t auth_algo_t;
-#endif
 
 int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win)
 {
@@ -138,7 +103,7 @@ int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_
   return 0;
 }
 
-int process_tun_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
+int process_tun_data(tun_device_t* dev, udp_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
                      cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_nr_t seq_nr)
 {
   plain_packet_set_payload_length(plain_packet, -1);
@@ -167,7 +132,7 @@ int process_tun_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plai
 #ifndef NO_CRYPT
   auth_algo_generate(aa, kd, kd_outbound, encrypted_packet);
 #endif
-  
   len = udp_write(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet));
   if(len == -1)
     log_printf(ERROR, "error on sending udp packet: %s", strerror(errno));
@@ -175,7 +140,7 @@ int process_tun_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plai
   return 0;
 }
 
-int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
+int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
                       cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win)
 {
   plain_packet_set_payload_length(plain_packet, -1);
@@ -183,13 +148,13 @@ int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, pla
 
   udp_endpoint_t remote;
   memset(&remote, 0, sizeof(udp_endpoint_t));
-  int len = udp_read(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet), &remote);
+  int len = udp_read(sock, fd, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet), &remote);
   if(len == -1) {
     log_printf(ERROR, "error on receiving udp packet: %s", strerror(errno));
     return 0;
   }
   else if(len < encrypted_packet_get_minimum_length(encrypted_packet)) {
-    log_printf(WARNING, "received packet is to short");
+    log_printf(WARNING, "received packet is too short");
     return 0;
   }
   encrypted_packet_set_length(encrypted_packet, len);
@@ -216,6 +181,7 @@ int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, pla
     return -2;
   }
    
+  udp_set_active_sock(sock, fd);
   if(memcmp(&remote, &(sock->remote_end_), sizeof(remote))) {
     memcpy(&(sock->remote_end_), &remote, sizeof(remote));
     sock->remote_end_set_ = 1;
@@ -241,7 +207,7 @@ int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, pla
 }
 
 
-int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
+int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
 {
   log_printf(INFO, "entering main loop");
 
@@ -263,8 +229,8 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
 
   FD_ZERO(&readfds);
   FD_SET(dev->fd_, &readfds);
-  FD_SET(sock->fd_, &readfds);
-  int nfds = dev->fd_ > sock->fd_ ? dev->fd_ : sock->fd_;
+  int nfds = udp_init_fd_set(sock, &readfds);
+  nfds = dev->fd_ > nfds ? dev->fd_ : nfds;
 
   int return_value = 0;
   int sig_fd = signal_init();
@@ -299,10 +265,14 @@ int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
         break;
     }
 
-    if(FD_ISSET(sock->fd_, &readyfds)) {
-      return_value = process_sock_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_win); 
-      if(return_value)
-        break;
+    udp_socket_t* s = sock->socks_;
+    while(s) {
+      if(FD_ISSET(s->fd_, &readyfds)) {
+        return_value = process_sock_data(dev, s->fd_, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_win); 
+        if(return_value)
+          break;
+      }
+      s = s->next_;
     }
   }
 
@@ -336,35 +306,36 @@ int main(int argc, char* argv[])
     if(ret == -4) {
       fprintf(stderr, "syntax error: unknown role name\n\n");
     }
+    if(ret == -5) {
+      options_print_version();
+    }
 
-    if(ret != -2) 
+    if(ret != -2 && ret != -5
       options_print_usage();
 
+    if(ret == -1 || ret == -5)
+      ret = 0;
+
     options_clear(&opt);
     log_close();
     exit(ret);
   }
   string_list_element_t* tmp = opt.log_targets_.first_;
-  if(!tmp) {
-    log_add_target("syslog:3,uanytun,daemon");
-  }
-  else {
-    while(tmp) {
-      ret = log_add_target(tmp->string_);
-      if(ret) {
-        switch(ret) {
-        case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
-        case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
-        case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
-        default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
-        }
-        
-        options_clear(&opt);
-        log_close();
-        exit(ret);
+  while(tmp) {
+    ret = log_add_target(tmp->string_);
+    if(ret) {
+      switch(ret) {
+      case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
+      case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
+      case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
+      default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
       }
-      tmp = tmp->next_;
+        
+      options_clear(&opt);
+      log_close();
+      exit(ret);
     }
+    tmp = tmp->next_;
   }
 
   log_printf(NOTICE, "just started...");
@@ -378,17 +349,13 @@ int main(int argc, char* argv[])
       exit(-1);
     }
 
-#ifndef NO_CRYPT
-#ifndef USE_SSL_CRYPTO
-  ret = init_libgcrypt();
+  ret = init_crypt();
   if(ret) {
-    log_printf(ERROR, "error on libgcrpyt initialization, exitting");
+    log_printf(ERROR, "error on crpyto initialization, exitting");
     options_clear(&opt);
     log_close();
     exit(ret);
   }
-#endif
-#endif
 
   tun_device_t dev;
   ret = tun_init(&dev, opt.dev_name_, opt.dev_type_, opt.ifconfig_param_.net_addr_, opt.ifconfig_param_.prefix_length_);
@@ -408,7 +375,7 @@ int main(int argc, char* argv[])
   }
 
 
-  udp_socket_t sock;
+  udp_t sock;
   ret = udp_init(&sock, opt.local_addr_, opt.local_port_, opt.resolv_addr_type_);
   if(ret) {
     log_printf(ERROR, "error on udp_init, exitting");
@@ -417,12 +384,6 @@ int main(int argc, char* argv[])
     log_close();
     exit(ret);
   }
-  char* local_string = udp_get_local_end_string(&sock);
-  if(local_string) {
-    log_printf(NOTICE, "listening on: %s", local_string);
-    free(local_string);
-  }
-
 
   if(opt.remote_addr_) {
     if(!udp_set_remote(&sock, opt.remote_addr_, opt.remote_port_, opt.resolv_addr_type_)) {