diff options
author | Christian Pointner <equinox@anytun.org> | 2014-06-30 02:20:43 +0000 |
---|---|---|
committer | Christian Pointner <equinox@anytun.org> | 2014-06-30 02:20:43 +0000 |
commit | ce0ba1127385a10ad4ef1c51763550245f608778 (patch) | |
tree | 9c4f15148d38d689d99edbbff57f5d7689f5f8f1 | |
parent | disable kx-control for now (diff) |
also use select for writes to unix socket
-rw-r--r-- | src/keyexchange.c | 93 | ||||
-rw-r--r-- | src/keyexchange.h | 2 | ||||
-rw-r--r-- | src/uanytun.c | 20 |
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; |