summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2016-02-25 00:34:22 +0100
committerChristian Pointner <equinox@anytun.org>2016-02-25 00:34:22 +0100
commit59106bf1a66a4e210f8cc98bddb760cfa8cff06a (patch)
tree998eda912f48de7523aa22e446531c2129feb429 /src
parentupdated doc and other stuff after moving to GIT (diff)
parentfixed checking (missing OpenssL License File) (diff)
merged rail mode to master
Diffstat (limited to 'src')
-rw-r--r--src/options.c8
-rw-r--r--src/options.h1
-rw-r--r--src/uanytun.c11
-rw-r--r--src/udp.c111
-rw-r--r--src/udp.h3
5 files changed, 117 insertions, 17 deletions
diff --git a/src/options.c b/src/options.c
index c3038bb..015a9a5 100644
--- a/src/options.c
+++ b/src/options.c
@@ -260,6 +260,7 @@ int options_parse(options_t* opt, int argc, char* argv[])
PARSE_INT_PARAM("-s","--sender-id", opt->sender_id_)
PARSE_STRING_LIST("-L","--log", opt->log_targets_)
PARSE_BOOL_PARAM("-U", "--debug", opt->debug_)
+ PARSE_BOOL_PARAM("-Y", "--rail-mode", opt->rail_mode_)
PARSE_STRING_PARAM("-r","--remote-host", opt->remote_addr_)
PARSE_STRING_PARAM("-o","--remote-port", opt->remote_port_)
PARSE_BOOL_PARAM("-4","--ipv4-only", ipv4_only)
@@ -361,6 +362,7 @@ void options_default(options_t* opt)
opt->local_addr_ = NULL;
opt->local_port_ = strdup("4444");
opt->sender_id_ = 0;
+ opt->rail_mode_ = 0;
opt->remote_addr_ = NULL;
opt->remote_port_ = strdup("4444");
opt->resolv_addr_type_ = ANY;
@@ -447,14 +449,15 @@ void options_print_usage()
printf(" [-C|--chroot] <path> chroot to this directory\n");
printf(" [-P|--write-pid] <path> write pid to this file\n");
printf(" [-i|--interface] <ip-address> local ip address to bind to\n");
- printf(" [-p|--port] <port> local port to bind to\n");
+ printf(" [-p|--port] <port>[:<port>] local port to bind to (use port:port for range - RAIL)\n");
printf(" [-s|--sender-id ] <sender id> the sender id to use\n");
printf(" [-L|--log] <target>:<level>[,<param1>[,<param2>..]]\n");
printf(" add a log target, can be invoked several times\n");
printf(" [-U|--debug] don't daemonize and log to stdout with maximum log level\n");
+ printf(" [-Y|--rail-mode] enable RAIL mode\n");
printf(" [-r|--remote-host] <hostname|ip> remote host\n");
- printf(" [-o|--remote-port] <port> remote port\n");
+ printf(" [-o|--remote-port] <port>[:<port>] remote port (use port:port for range - RAIL)\n");
printf(" [-4|--ipv4-only] always resolv IPv4 addresses\n");
printf(" [-6|--ipv6-only] always resolv IPv6 addresses\n");
printf(" [-d|--dev] <name> device name\n");
@@ -507,6 +510,7 @@ void options_print(options_t* opt)
printf("local_addr: '%s'\n", opt->local_addr_);
printf("local_port: '%s'\n", opt->local_port_);
printf("sender_id: %d\n", opt->sender_id_);
+ printf("rail-mode: %s\n", !opt->rail_mode_ ? "false" : "true");
printf("remote_addr: '%s'\n", opt->remote_addr_);
printf("remote_port: '%s'\n", opt->remote_port_);
printf("resolv_addr_type: ");
diff --git a/src/options.h b/src/options.h
index 8f3593f..fa4d554 100644
--- a/src/options.h
+++ b/src/options.h
@@ -75,6 +75,7 @@ struct options_struct {
char* local_addr_;
char* local_port_;
sender_id_t sender_id_;
+ int rail_mode_;
char* remote_addr_;
char* remote_port_;
resolv_addr_type_t resolv_addr_type_;
diff --git a/src/uanytun.c b/src/uanytun.c
index da90eda..c5d6291 100644
--- a/src/uanytun.c
+++ b/src/uanytun.c
@@ -188,16 +188,21 @@ int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, pl
}
#endif
+ if(sock->rail_mode_)
+ udp_update_remote(sock, fd, &remote);
+
int result = seq_win_check_and_add(seq_win, encrypted_packet_get_sender_id(encrypted_packet), encrypted_packet_get_seq_nr(encrypted_packet));
if(result > 0) {
- log_printf(WARNING, "detected replay attack, discarding packet");
+ if(!(sock->rail_mode_))
+ log_printf(WARNING, "detected replay attack, discarding packet");
return 0;
} else if(result < 0) {
log_printf(ERROR, "memory error at sequence window");
return -2;
}
- udp_update_remote(sock, fd, &remote);
+ if(!sock->rail_mode_)
+ udp_update_remote(sock, fd, &remote);
if(encrypted_packet_get_payload_length(encrypted_packet) <= plain_packet_get_header_length()) {
log_printf(WARNING, "ignoring packet with zero length payload");
@@ -390,7 +395,7 @@ int main(int argc, char* argv[])
udp_t sock;
- ret = udp_init(&sock, opt.local_addr_, opt.local_port_, opt.resolv_addr_type_);
+ ret = udp_init(&sock, opt.local_addr_, opt.local_port_, opt.resolv_addr_type_, opt.rail_mode_);
if(ret) {
log_printf(ERROR, "error on udp_init, exitting");
tun_close(&dev);
diff --git a/src/udp.c b/src/udp.c
index 239e074..568f738 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -161,18 +161,53 @@ static int udp_resolv_local(udp_t* sock, const char* local_addr, const char* por
return 0;
}
-int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type)
+static int udp_split_port_range(const char* port, const char* colon, u_int32_t* low, u_int32_t* high)
+{
+ *low = atoi(port);
+ *high = atoi(colon+1);
+ if(*low < 1 || *low > 65535 || *high < 1 || *high > 65535 || *high < *low) {
+ log_printf(ERROR, "illegal port range");
+ return -1;
+ }
+ return 0;
+}
+
+int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type, int rail_mode)
{
if(!sock || !port)
return -1;
sock->socks_ = NULL;
sock->active_sock_ = NULL;
+ sock->rail_mode_ = rail_mode;
unsigned int idx = 0;
- int ret = udp_resolv_local(sock, local_addr, port, resolv_type, &idx);
- if(ret)
- return ret;
+ const char* colon = strchr(port, ':');
+ if(!colon) {
+ int ret = udp_resolv_local(sock, local_addr, port, resolv_type, &idx);
+ if(ret)
+ return ret;
+ } else {
+ if(!rail_mode)
+ log_printf(WARNING, "A port range has been defined - enabling RAIL mode");
+ sock->rail_mode_ = 1;
+
+ u_int32_t port_num, port_end;
+ if(udp_split_port_range(port, colon, &port_num, &port_end))
+ return -1;
+ do {
+ char port_str[10];
+ snprintf(port_str, sizeof(port_str), "%d", port_num);
+ int ret = udp_resolv_local(sock, local_addr, port_str, resolv_type, &idx);
+ if(ret)
+ return ret;
+
+ port_num++;
+ } while(port_num <= port_end);
+ }
+
+ if(sock->rail_mode_)
+ log_printf(NOTICE, "RAIL mode enabled");
return 0;
}
@@ -193,7 +228,7 @@ int udp_fill_fd_set(udp_t* sock, fd_set* set)
int udp_has_remote(udp_t* sock)
{
- if(!sock->active_sock_ || !sock->active_sock_->remote_end_set_)
+ if(!sock->rail_mode_ && (!sock->active_sock_ || !sock->active_sock_->remote_end_set_))
return 0;
udp_socket_t* s = sock->socks_;
@@ -206,13 +241,10 @@ int udp_has_remote(udp_t* sock)
return 0;
}
-int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type)
+static int udp_resolv_remote__(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type)
{
struct addrinfo hints, *res;
- if(!sock || !remote_addr || !port)
- return -1;
-
res = NULL;
memset (&hints, 0, sizeof (hints));
hints.ai_socktype = SOCK_DGRAM;
@@ -268,6 +300,36 @@ int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, re
return 0;
}
+int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type)
+{
+ if(!sock || !remote_addr || !port)
+ return -1;
+
+ const char* colon = strchr(port, ':');
+ if(!colon) {
+ return udp_resolv_remote__(sock, remote_addr, port, resolv_type);
+ } else {
+ if(!sock->rail_mode_)
+ log_printf(WARNING, "A port range has been defined - enabling RAIL mode");
+ sock->rail_mode_ = 1;
+
+ u_int32_t port_num, port_end;
+ if(udp_split_port_range(port, colon, &port_num, &port_end))
+ return -1;
+ do {
+ char port_str[10];
+ snprintf(port_str, sizeof(port_str), "%d", port_num);
+ int ret = udp_resolv_remote__(sock, remote_addr, port_str, resolv_type);
+ if(ret)
+ return ret;
+
+ port_num++;
+ } while(port_num <= port_end);
+ }
+
+ return 0;
+}
+
void udp_update_remote(udp_t* sock, int fd, udp_endpoint_t* remote)
{
if(!sock)
@@ -351,10 +413,37 @@ int udp_read(udp_t* sock, int fd, u_int8_t* buf, u_int32_t len, udp_endpoint_t*
}
-int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len)
+static int udp_write_active_sock(udp_t* sock, u_int8_t* buf, u_int32_t len)
{
- if(!sock || !buf || !sock->active_sock_ || !sock->active_sock_->remote_end_set_)
+ if(!sock->active_sock_ || !sock->active_sock_->remote_end_set_)
return 0;
return sendto(sock->active_sock_->fd_, buf, len, 0, (struct sockaddr *)&(sock->active_sock_->remote_end_.addr_), sock->active_sock_->remote_end_.len_);
}
+
+static int udp_write_rail(udp_t* sock, u_int8_t* buf, u_int32_t len)
+{
+ int i=0;
+
+ udp_socket_t* s = sock->socks_;
+ while(s) {
+ if(s->remote_end_set_) {
+ sendto(s->fd_, buf, len, 0, (struct sockaddr *)&(s->remote_end_.addr_), s->remote_end_.len_);
+ i++;
+ }
+ s = s->next_;
+ }
+
+ return len;
+}
+
+int udp_write(udp_t* sock, u_int8_t* buf, u_int32_t len)
+{
+ if(!sock || !buf)
+ return 0;
+
+ if(sock->rail_mode_)
+ return udp_write_rail(sock, buf, len);
+
+ return udp_write_active_sock(sock, buf, len);
+}
diff --git a/src/udp.h b/src/udp.h
index d0d218d..bb266b0 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -72,10 +72,11 @@ typedef struct udp_socket_struct udp_socket_t;
struct udp_struct {
udp_socket_t* socks_;
udp_socket_t* active_sock_;
+ int rail_mode_;
};
typedef struct udp_struct udp_t;
-int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type);
+int udp_init(udp_t* sock, const char* local_addr, const char* port, resolv_addr_type_t resolv_type, int rail_mode);
int udp_fill_fd_set(udp_t* sock, fd_set* set);
int udp_has_remote(udp_t* sock);
int udp_resolv_remote(udp_t* sock, const char* remote_addr, const char* port, resolv_addr_type_t resolv_type);