summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2014-06-30 02:20:43 +0000
committerChristian Pointner <equinox@anytun.org>2014-06-30 02:20:43 +0000
commitce0ba1127385a10ad4ef1c51763550245f608778 (patch)
tree9c4f15148d38d689d99edbbff57f5d7689f5f8f1
parentdisable kx-control for now (diff)
also use select for writes to unix socket
-rw-r--r--src/keyexchange.c93
-rw-r--r--src/keyexchange.h2
-rw-r--r--src/uanytun.c20
3 files changed, 74 insertions, 41 deletions
diff --git a/src/keyexchange.c b/src/keyexchange.c
index 14396fe..0806ad6 100644
--- a/src/keyexchange.c
+++ b/src/keyexchange.c
@@ -50,14 +50,18 @@
#include "datatypes.h"
#include "keyexchange.h"
-
#include "log.h"
+#include <errno.h>
+#include <string.h>
+
int keyexchange_init(keyexchange_t* kx, const char* path_control, const char* path_data)
{
if(!kx)
return -1;
+ memset(kx->data_buf_, 0, sizeof(kx->data_buf_));
+ kx->data_buf_len_ = 0;
// int ret = unixdomain_init(&(kx->control_interface_), path_control);
int ret = unixdomain_init(&(kx->control_interface_), NULL); // ignore control interface for now
if(ret) return ret;
@@ -71,8 +75,14 @@ int keyexchange_init(keyexchange_t* kx, const char* path_control, const char* pa
int keyexchange_fill_fd_set(keyexchange_t* kx, fd_set* read, fd_set* write)
{
- return unixdomain_fill_fd_set(&(kx->data_interface_), read);
- // ignoreing writes and control interface for now
+ int maxfd = unixdomain_fill_fd_set(&(kx->data_interface_), read);
+ if(kx->data_buf_len_) {
+ FD_SET(kx->data_interface_.client_fd_, write);
+ maxfd = (kx->data_interface_.client_fd_ > maxfd) ? kx->data_interface_.client_fd_ : maxfd;
+ }
+
+ // ignoring control interface for now
+ return maxfd;
}
void keyexchange_close(keyexchange_t* kx)
@@ -81,43 +91,62 @@ void keyexchange_close(keyexchange_t* kx)
unixdomain_close(&(kx->data_interface_));
}
-static int keyexchange_handle_read(keyexchange_t* kx, fd_set* readyfds)
+static int keyexchange_handle_accept(keyexchange_t* kx, unixdomain_t* sock)
{
- if(FD_ISSET(kx->data_interface_.server_fd_, readyfds)) {
- int old_fd = kx->data_interface_.client_fd_;
- if(unixdomain_accept(&(kx->data_interface_))) {
- return -1;
- }
- if(old_fd != kx->data_interface_.client_fd_) {
- log_printf(INFO, "key exchange: new client");
- }
+ int old_fd = sock->client_fd_;
+ if(unixdomain_accept(sock)) {
+ return -1;
}
- if(FD_ISSET(kx->data_interface_.client_fd_, readyfds)) {
- u_int8_t buf[100];
- int len = unixdomain_read(&(kx->data_interface_), buf, sizeof(buf));
- if(len < 0) {
- log_printf(ERROR, "key exchange: client error!!!!!");
- } if(!len) {
- log_printf(INFO, "key exchange: client disconnected");
- kx->data_interface_.client_fd_ = -1;
- } else {
- buf[len] = 0;
- log_printf(DEBUG, "key exchange: received string '%s'", buf);
- unixdomain_write(&(kx->data_interface_), buf, len);
- }
+ if(old_fd != sock->client_fd_) {
+ log_printf(INFO, "key exchange: new client");
+ }
+ return 0;
+}
+
+static int keyexchange_handle_read_data(keyexchange_t* kx)
+{
+ // TODO: don't overwrite existing data
+ // fix sizeof
+ int len = unixdomain_read(&(kx->data_interface_), kx->data_buf_, sizeof(kx->data_buf_) - 1);
+ if(len <= 0) {
+ if(!len)
+ log_printf(INFO, "key exchange: data interface disconnected");
+ else
+ log_printf(ERROR, "key exchange: data interface error: %s", strerror(errno));
+ kx->data_interface_.client_fd_ = -1;
+ } else {
+ // TODO: this is a temporary fix for strings ending with linefeed
+ if(kx->data_buf_[len-1] == '\n')
+ kx->data_buf_len_ = len - 1;
+ else
+ kx->data_buf_len_ = len;
+
+ kx->data_buf_[kx->data_buf_len_] = 0;
+ log_printf(DEBUG, "key exchange: data interface received string '%s'", kx->data_buf_);
}
return 0;
}
-/* static int keyexchange_handle_write(keyexchange_t* kx, fd_set* readyfds) */
-/* { */
-/* // TODO: implement this */
-/* return 0; */
-/* } */
+static int keyexchange_handle_write_data(keyexchange_t* kx)
+{
+ int ret = unixdomain_write(&(kx->data_interface_), kx->data_buf_, kx->data_buf_len_);
+ // TODO: handle partial writes
+ kx->data_buf_len_ = 0;
+ return ret;
+}
int keyexchange_handle(keyexchange_t* kx, fd_set* rreadyfds, fd_set* wreadyfds)
{
- return keyexchange_handle_read(kx, rreadyfds);
- // ignoreing writes for now
+ if(FD_ISSET(kx->data_interface_.server_fd_, rreadyfds))
+ return keyexchange_handle_accept(kx, &(kx->data_interface_));
+
+ if(FD_ISSET(kx->data_interface_.client_fd_, rreadyfds))
+ return keyexchange_handle_read_data(kx);
+
+ if(FD_ISSET(kx->data_interface_.client_fd_, wreadyfds))
+ return keyexchange_handle_write_data(kx);
+
+ // control interface for now
+ return 0;
}
diff --git a/src/keyexchange.h b/src/keyexchange.h
index f1d686f..615eb6d 100644
--- a/src/keyexchange.h
+++ b/src/keyexchange.h
@@ -52,6 +52,8 @@
#include "unixdomain.h"
struct keyexchange_struct {
+ u_int8_t data_buf_[2048]; // TODO: constant...
+ u_int32_t data_buf_len_;
unixdomain_t data_interface_;
unixdomain_t control_interface_;
};
diff --git a/src/uanytun.c b/src/uanytun.c
index da7dc3d..e7d7de7 100644
--- a/src/uanytun.c
+++ b/src/uanytun.c
@@ -232,7 +232,7 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
encrypted_packet_t encrypted_packet;
encrypted_packet_init(&encrypted_packet, opt->auth_tag_length_);
seq_nr_t seq_nr = 0;
- fd_set readfds, readyfds;
+ fd_set readfds, rreadyfds, wreadyfds;
keyexchange_t kx;
cipher_t c;
@@ -258,10 +258,12 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
nfds = (nfds < sig_fd) ? sig_fd : nfds;
while(!return_value) {
- memcpy(&readyfds, &readfds, sizeof(readyfds));
- int kx_max_fd = keyexchange_fill_fd_set(&kx, &readyfds, NULL);
- int tmp = (nfds < kx_max_fd) ? kx_max_fd : nfds;
- int ret = select(tmp + 1, &readyfds, NULL, NULL, NULL);
+ FD_ZERO(&wreadyfds);
+ memcpy(&rreadyfds, &readfds, sizeof(rreadyfds));
+ int kx_max_fd = keyexchange_fill_fd_set(&kx, &rreadyfds, &wreadyfds);
+ int maxfd = (nfds < kx_max_fd) ? kx_max_fd : nfds;
+
+ int ret = select(maxfd + 1, &rreadyfds, &wreadyfds, NULL, NULL);
if(ret == -1 && errno != EINTR) {
log_printf(ERROR, "select returned with error: %s", strerror(errno));
return_value = -1;
@@ -270,7 +272,7 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
if(!ret || ret == -1)
continue;
- if(FD_ISSET(sig_fd, &readyfds)) {
+ if(FD_ISSET(sig_fd, &rreadyfds)) {
return_value = signal_handle();
if(return_value == 1)
break;
@@ -284,17 +286,17 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
return_value = 0;
}
- if(FD_ISSET(dev->fd_, &readyfds)) {
+ if(FD_ISSET(dev->fd_, &rreadyfds)) {
return_value = process_tun_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_nr);
if(return_value)
break;
}
- keyexchange_handle(&kx, &readyfds, NULL);
+ keyexchange_handle(&kx, &rreadyfds, &wreadyfds);
udp_socket_t* s = sock->socks_;
while(s) {
- if(FD_ISSET(s->fd_, &readyfds)) {
+ if(FD_ISSET(s->fd_, &rreadyfds)) {
return_value = process_sock_data(dev, s->fd_, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_win);
if(return_value)
break;