A little bit of refactoring - separated iodined.c into separate files

Fixed up client side compile issues
Removed old packet handling code - TODO: use sliding window buffer
instead
This commit is contained in:
frekky 2015-08-21 16:57:54 +08:00
parent 83f70608fc
commit 844abefcf8
13 changed files with 2178 additions and 2299 deletions

View File

@ -1,7 +1,7 @@
COMMONOBJS = tun.o dns.o read.o encoding.o login.o base32.o base64.o base64u.o base128.o md5.o window.o common.o COMMONOBJS = tun.o dns.o read.o encoding.o login.o base32.o base64.o base64u.o base128.o md5.o window.o common.o
CLIENTOBJS = iodine.o client.o util.o CLIENTOBJS = iodine.o client.o util.o
CLIENT = ../bin/iodine CLIENT = ../bin/iodine
SERVEROBJS = iodined.o user.o fw_query.o SERVEROBJS = iodined.o user.o fw_query.o server.o
SERVER = ../bin/iodined SERVER = ../bin/iodined
OS = `echo $(TARGETOS) | tr "a-z" "A-Z"` OS = `echo $(TARGETOS) | tr "a-z" "A-Z"`

View File

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>, * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se> * 2006-2009 Bjorn Andersson <flex@kryo.se>,
* 2015 Frekk van Blagh <frekk@frekkworks.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -132,7 +133,7 @@ client_init()
// TODO: user-set window size (command line option) // TODO: user-set window size (command line option)
outbuf = window_buffer_init(100, 10, hostname_maxlen, WINDOW_SENDING); outbuf = window_buffer_init(100, 10, hostname_maxlen, WINDOW_SENDING);
/* Incoming buffer max fragsize doesn't matter */ /* Incoming buffer max fragsize doesn't matter */
inbuf = window_buffer_init(100, 10, 1200, WINDOW_RECVING); inbuf = window_buffer_init(128, 10, MAX_FRAGSIZE, WINDOW_RECVING);
next_downstream_ack = -1; next_downstream_ack = -1;
current_nameserver = 0; current_nameserver = 0;
@ -362,13 +363,33 @@ is_sending()
return (outbuf->numitems > 0); return (outbuf->numitems > 0);
} }
static void
send_ping(int fd, int ping_response) // TODO: setup window sync stuff in ping
{
if (conn == CONN_DNS_NULL) {
char data[4];
data[0] = userid;
data[1] = inbuf->start_seq_id & 0xff;
data[2] = outbuf->start_seq_id & 0xff;
data[3] = outbuf->windowsize & 0xff;
data[4] = inbuf->windowsize & 0xff;
data[5] = ping_response & 1;
data[6] = (rand_seed >> 8) & 0xff;
data[7] = (rand_seed >> 0) & 0xff;
rand_seed++;
send_packet(fd, 'p', data, sizeof(data));
} else {
send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING);
}
}
static void static void
send_next_frag(int fd) send_next_frag(int fd)
/* Sends next available fragment of data from the outgoing window buffer */ /* Sends next available fragment of data from the outgoing window buffer */
{ {
static uint8_t buf[MAX_FRAGSIZE]; static uint8_t buf[MAX_FRAGSIZE];
size_t len;
int code; int code;
static int datacmc = 0; static int datacmc = 0;
static char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789"; static char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789";
@ -381,13 +402,13 @@ send_next_frag(int fd)
if (is_sending()) { if (is_sending()) {
/* There is stuff to send but we're out of sync, so send a ping /* There is stuff to send but we're out of sync, so send a ping
* to get things back in order and keep the packets flowing */ * to get things back in order and keep the packets flowing */
send_ping(fd); send_ping(fd, 1);
} }
return; /* nothing to send - why was this called? */ return; /* nothing to send - why was this called? */
} }
/* Note: must be same, or smaller than send_fragsize_probe() */ /* Note: must be same, or smaller than send_fragsize_probe() */
len = build_hostname(buf, sizeof(buf), f->data, f->len, topdomain, dataenc, hostname_maxlen); build_hostname((char *)buf, sizeof(buf), (char *)f->data, f->len, topdomain, dataenc, hostname_maxlen);
/* Build upstream data header (see doc/proto_xxxxxxxx.txt) */ /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */
@ -411,29 +432,7 @@ send_next_frag(int fd)
if (datacmc >= 36) if (datacmc >= 36)
datacmc = 0; datacmc = 0;
send_query(fd, buf); send_query(fd, (char *)buf);
}
static void
send_ping(int fd, int ping_response) // TODO: setup window sync stuff in ping
{
if (conn == CONN_DNS_NULL) {
char data[4];
data[0] = userid;
data[1] = inbuf->start_seq_id & 0xff;
data[2] = outbuf->start_seq_id & 0xff;
data[3] = outbuf->windowsize & 0xff;
data[4] = inbuf->windowsize & 0xff;
data[5] = ping_response & 1;
data[6] = (rand_seed >> 8) & 0xff;
data[7] = (rand_seed >> 0) & 0xff;
rand_seed++;
send_packet(fd, 'p', data, sizeof(data));
} else {
send_raw(fd, NULL, 0, userid, RAW_HDR_CMD_PING);
}
} }
static void static void
@ -574,7 +573,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
} }
static int static int
read_dns_withq(int dns_fd, int tun_fd, uint8_t *buf, int buflen, struct query *q) read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q)
/* Returns -1 on receive error or decode error, including DNS error replies. /* Returns -1 on receive error or decode error, including DNS error replies.
Returns 0 on replies that could be correct but are useless, and are not Returns 0 on replies that could be correct but are useless, and are not
DNS error replies. DNS error replies.
@ -671,7 +670,7 @@ read_dns_withq(int dns_fd, int tun_fd, uint8_t *buf, int buflen, struct query *q
r -= RAW_HDR_LEN; r -= RAW_HDR_LEN;
datalen = sizeof(buf); datalen = sizeof(buf);
if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) &data[RAW_HDR_LEN], r) == Z_OK) { if (uncompress((uint8_t*)buf, &datalen, (uint8_t*) &data[RAW_HDR_LEN], r) == Z_OK) {
write_tun(tun_fd, buf, datalen); write_tun(tun_fd, (uint8_t*)buf, datalen);
} }
/* don't process any further */ /* don't process any further */
@ -766,15 +765,27 @@ static int
parse_data(uint8_t *data, size_t len, fragment *f) parse_data(uint8_t *data, size_t len, fragment *f)
{ {
memset(f, 0, sizeof(fragment)); memset(f, 0, sizeof(fragment));
f->seqID = data[0]; int ping = (data[3] >> 5) & 1;
f->start = data[3] & 1; if (!ping) {
f->end = (data[3] >> 1) & 1; f->seqID = data[0];
f->is_nack = (data[3] >> 2) & 1; f->start = data[3] & 1;
f->ack_other = (data[3] >> 3) & 1 ? data[1] : -1; f->end = (data[3] >> 1) & 1;
f->compressed = (data[3] >> 4) & 1; f->is_nack = (data[3] >> 2) & 1;
f->len = len - 3; f->ack_other = (data[3] >> 3) & 1 ? data[1] : -1;
memcpy(f->data, data + 3, MIN(f->len, sizeof(f->data))); f->compressed = (data[3] >> 4) & 1;
return (data[3] >> 5) & 1; /* return ping flag (if corresponding query was a ping) */ f->len = len - 3;
memcpy(f->data, data + 3, MIN(f->len, sizeof(f->data)));
} else { /* Handle ping stuff */
if (len != 5) return 1; /* invalid packet - continue */
static unsigned in_start_seq, out_start_seq, in_wsize, out_wsize;
out_start_seq = data[0];
in_start_seq = data[1];
in_wsize = data[3];
out_wsize = data[4];
warnx("Pingy thingy received.");
// TODO: handle pings
}
return ping; /* return ping flag (if corresponding query was a ping) */
} }
static int static int
@ -825,7 +836,7 @@ tunnel_dns(int tun_fd, int dns_fd)
memset(&q, 0, sizeof(q)); memset(&q, 0, sizeof(q));
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
memset(cbuf, 0, sizeof(cbuf)); memset(cbuf, 0, sizeof(cbuf));
read = read_dns_withq(dns_fd, tun_fd, cbuf, sizeof(cbuf), &q); read = read_dns_withq(dns_fd, tun_fd, (char *)cbuf, sizeof(cbuf), &q);
if (conn != CONN_DNS_NULL) if (conn != CONN_DNS_NULL)
return 1; /* everything already done */ return 1; /* everything already done */
@ -895,9 +906,9 @@ tunnel_dns(int tun_fd, int dns_fd)
/* Decode the downstream data header and fragment-ify ready for processing */ /* Decode the downstream data header and fragment-ify ready for processing */
res = parse_data(cbuf, read, &f); res = parse_data(cbuf, read, &f);
/* if this response was a reverse ping/response to a ping: do something different? */ /* if this response was a reverse ping/response to a ping, we need to do something */
if (res) { if (res) {
// TODO: handle pings to resync window goto skip_recv;
} }
window_ack(outbuf, f.ack_other); window_ack(outbuf, f.ack_other);
@ -954,6 +965,7 @@ tunnel_dns(int tun_fd, int dns_fd)
send_something_now = 1; send_something_now = 1;
} }
skip_recv:
/* Move window along after doing all data processing */ /* Move window along after doing all data processing */
window_tick(inbuf); window_tick(inbuf);
@ -968,7 +980,7 @@ tunnel_dns(int tun_fd, int dns_fd)
/* Send ping if we didn't send anything yet */ /* Send ping if we didn't send anything yet */
if (send_something_now) { if (send_something_now) {
send_ping(dns_fd); send_ping(dns_fd, 0);
send_ping_soon = 0; send_ping_soon = 0;
} }
@ -1031,10 +1043,10 @@ client_tunnel(int tun_fd, int dns_fd)
send_next_frag(dns_fd); send_next_frag(dns_fd);
} else { } else {
outbuf->resends = 0; outbuf->resends = 0;
send_ping(dns_fd); send_ping(dns_fd, 1);
} }
} else { } else {
send_ping(dns_fd); send_ping(dns_fd, 0);
} }
send_ping_soon = 0; send_ping_soon = 0;
@ -2324,7 +2336,7 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
fragsize = handshake_autoprobe_fragsize(dns_fd); fragsize = handshake_autoprobe_fragsize(dns_fd);
if (fragsize > MAX_FRAGSIZE) { if (fragsize > MAX_FRAGSIZE) {
/* This is very unlikely except perhaps over LAN */ /* This is very unlikely except perhaps over LAN */
fprintf(stderr, "Can transfer fragsize of %d, however iodine has been compiled with MAX_FRAGSIZE = %d. To fully utilize this connection, please recompile iodine/iodined."); fprintf(stderr, "Can transfer fragsize of %d, however iodine has been compiled with MAX_FRAGSIZE = %d. To fully utilize this connection, please recompile iodine/iodined.", fragsize, MAX_FRAGSIZE);
fragsize = MAX_FRAGSIZE; fragsize = MAX_FRAGSIZE;
} }
if (!fragsize) { if (!fragsize) {

View File

@ -22,13 +22,13 @@
int int
build_hostname(char *buf, size_t buflen, build_hostname(char *buf, size_t buflen,
const char *data, const size_t datalen, const char *data, const size_t datalen,
const char *topdomain, struct encoder *encoder, int maxlen) const char *topdomain, struct encoder *encoder, size_t maxlen)
{ {
size_t space; size_t space;
char *b; char *b;
space = MIN((size_t)maxlen, buflen) - strlen(topdomain) - 8; space = MIN(maxlen, buflen) - strlen(topdomain) - DOWNSTREAM_HDR + 3;
/* 8 = 5 max header length + 1 dot before topdomain + 2 safety */ /* max header length + 1 dot before topdomain + 2 safety */
if (!encoder->places_dots()) if (!encoder->places_dots())
space -= (space / 57); /* space for dots */ space -= (space / 57); /* space for dots */

View File

@ -35,7 +35,7 @@ struct encoder {
int (*blocksize_encoded)(void); int (*blocksize_encoded)(void);
}; };
int build_hostname(char *, size_t, const char *, const size_t, const char *, struct encoder *, int); int build_hostname(char *, size_t, const char *, const size_t, const char *, struct encoder *, size_t);
int unpack_data(char *, size_t, char *, size_t, struct encoder *); int unpack_data(char *, size_t, char *, size_t, struct encoder *);
int inline_dotify(char *, size_t); int inline_dotify(char *, size_t);
int inline_undotify(char *, size_t); int inline_undotify(char *, size_t);

File diff suppressed because it is too large Load Diff

1877
src/server.c Normal file

File diff suppressed because it is too large Load Diff

111
src/server.h Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2006-2015 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>,
* 2015 Frekk van Blagh <frekk@frekkworks.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __SERVER_H__
#define __SERVER_H__
#ifdef WINDOWS32
#include "windows.h"
#include <winsock2.h>
#else
#include <arpa/nameser.h>
#ifdef DARWIN
#define BIND_8_COMPAT
#include <arpa/nameser_compat.h>
#endif
#define _XPG4_2
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <grp.h>
#include <sys/uio.h>
#include <pwd.h>
#include <netdb.h>
#include <syslog.h>
#endif
#define DNSCACHE_LEN 10
/* Undefine to disable. Should be less than 18; also see comments in iodined.c */
#define QMEMPING_LEN 30
/* Max advisable: 64k/2 = 32000. Total mem usage: QMEMPING_LEN * USERS * 6 bytes */
#define QMEMDATA_LEN 15
/* Max advisable: 36/2 = 18. Total mem usage: QMEMDATA_LEN * USERS * 6 bytes */
#define PASSWORD_ENV_VAR "IODINED_PASS"
#if defined IP_RECVDSTADDR
# define DSTADDR_SOCKOPT IP_RECVDSTADDR
# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x))
#elif defined IP_PKTINFO
# define DSTADDR_SOCKOPT IP_PKTINFO
# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))
#endif
#ifndef IPV6_RECVPKTINFO
#define IPV6_RECVPKTINFO IPV6_PKTINFO
#endif
#if !defined(BSD) && !defined(__GLIBC__)
static char *__progname;
#endif
/* Struct with IPv4 and IPv6 file descriptors.
* Need to be passed on down to tunneling code since we can get a
* packet on one fd meant for a user on the other.
*/
struct dnsfd {
int v4fd;
int v6fd;
};
typedef enum {
VERSION_ACK,
VERSION_NACK,
VERSION_FULL
} version_ack_t;
extern char *topdomain;
extern char password[33];
extern struct encoder *b32;
extern struct encoder *b64;
extern struct encoder *b64u;
extern struct encoder *b128;
extern int check_ip;
extern int my_mtu;
extern in_addr_t my_ip;
extern int netmask;
extern in_addr_t ns_ip;
extern int bind_port;
extern int debug;
void server_init();
void server_stop();
int server_tunnel(int tun_fd, struct dnsfd *dns_fds, int bind_fd, int max_idle_time);
int read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q);
void write_dns(int fd, struct query *q, char *data, int datalen, char downenc);
void handle_full_packet(int tun_fd, struct dnsfd *dns_fds, int userid, uint8_t *data, size_t len);
void handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query *q, int domain_len);
void handle_ns_request(int dns_fd, struct query *q);
void handle_a_request(int dns_fd, struct query *q, int fakeip);
#endif /* __SERVER_H__ */

View File

@ -504,7 +504,7 @@ read_tun(int tun_fd, char *buf, size_t len)
} }
#else #else
int int
write_tun(int tun_fd, char *data, size_t len) write_tun(int tun_fd, uint8_t *data, size_t len)
{ {
#if defined (FREEBSD) || defined (NETBSD) #if defined (FREEBSD) || defined (NETBSD)
/* FreeBSD/NetBSD has no header */ /* FreeBSD/NetBSD has no header */
@ -545,7 +545,7 @@ write_tun(int tun_fd, char *data, size_t len)
} }
ssize_t ssize_t
read_tun(int tun_fd, char *buf, size_t len) read_tun(int tun_fd, uint8_t *buf, size_t len)
{ {
#if defined (FREEBSD) || defined (NETBSD) #if defined (FREEBSD) || defined (NETBSD)
/* FreeBSD/NetBSD has no header */ /* FreeBSD/NetBSD has no header */

View File

@ -20,8 +20,8 @@
int open_tun(const char *); int open_tun(const char *);
void close_tun(int); void close_tun(int);
int write_tun(int, char *, size_t); int write_tun(int, uint8_t *, size_t);
ssize_t read_tun(int, char *, size_t); ssize_t read_tun(int, uint8_t *, size_t);
int tun_setip(const char *, const char *, int); int tun_setip(const char *, const char *, int);
int tun_setmtu(const unsigned); int tun_setmtu(const unsigned);

View File

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>, * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se> * 2006-2009 Bjorn Andersson <flex@kryo.se>,
* 2015 Frekk van Blagh <frekk@frekkworks.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -33,9 +34,12 @@
#include "common.h" #include "common.h"
#include "encoding.h" #include "encoding.h"
#include "user.h" #include "user.h"
#include "window.h"
struct tun_user *users; struct tun_user *users;
unsigned usercount; unsigned usercount;
int created_users;
int int
init_users(in_addr_t my_ip, int netbits) init_users(in_addr_t my_ip, int netbits)
@ -60,6 +64,7 @@ init_users(in_addr_t my_ip, int netbits)
maxusers = (1 << (32-netbits)) - 3; /* 3: Net addr, broadcast addr, iodined addr */ maxusers = (1 << (32-netbits)) - 3; /* 3: Net addr, broadcast addr, iodined addr */
usercount = MIN(maxusers, USERS); usercount = MIN(maxusers, USERS);
if (users) free(users);
users = calloc(usercount, sizeof(struct tun_user)); users = calloc(usercount, sizeof(struct tun_user));
for (i = 0; i < usercount; i++) { for (i = 0; i < usercount; i++) {
in_addr_t ip; in_addr_t ip;
@ -74,11 +79,7 @@ init_users(in_addr_t my_ip, int netbits)
} }
users[i].tun_ip = ip; users[i].tun_ip = ip;
net.s_addr = ip; net.s_addr = ip;
users[i].disabled = 0; /* Rest is reset on login ('V' packet) or already 0 */
users[i].authenticated = 0;
users[i].authenticated_raw = 0;
users[i].active = 0;
/* Rest is reset on login ('V' packet) */
} }
return usercount; return usercount;
@ -95,75 +96,55 @@ users_get_first_ip()
int int
find_user_by_ip(uint32_t ip) find_user_by_ip(uint32_t ip)
{ {
int ret; for (int i = 0; i < usercount; i++) {
int i; if (user_active(i) && users[i].authenticated && ip == users[i].tun_ip) {
return i;
ret = -1;
for (i = 0; i < usercount; i++) {
if (users[i].active &&
users[i].authenticated &&
!users[i].disabled &&
users[i].last_pkt + 60 > time(NULL) &&
ip == users[i].tun_ip) {
ret = i;
break;
} }
} }
return ret; return -1;
}
int
user_sending(int user)
{
return users[user].outgoing->numitems > 0;
}
int
user_active(int i)
{
return users[i].active && !users[i].disabled && users[i].last_pkt + 60 > time(NULL);
} }
int int
all_users_waiting_to_send() all_users_waiting_to_send()
/* If this returns true, then reading from tun device is blocked. /* If this returns true, then reading from tun device is blocked.
So only return true when all clients have at least one packet in So only return true when all clients have at least one fragment in
the outpacket-queue, so that sending back-to-back is possible the outgoing buffer, so that sending back-to-back is possible
without going through another select loop. without going through another select loop.
*/ */
{ {
time_t now; for (int i = 0; i < usercount; i++)
int ret; if (!(user_active(i) && user_sending(i))) return 0;
int i; return 1;
ret = 1;
now = time(NULL);
for (i = 0; i < usercount; i++) {
if (users[i].active && !users[i].disabled &&
users[i].last_pkt + 60 > now &&
((users[i].conn == CONN_RAW_UDP) ||
((users[i].conn == CONN_DNS_NULL)
#ifdef OUTPACKETQ_LEN
&& users[i].outpacketq_filled < 1
#else
&& users[i].outpacket.len == 0
#endif
))) {
ret = 0;
break;
}
}
return ret;
} }
int int
find_available_user() find_available_user()
{ {
int ret = -1; for (int u = 0; u < usercount; u++) {
int i;
for (i = 0; i < usercount; i++) {
/* Not used at all or not used in one minute */ /* Not used at all or not used in one minute */
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) { if (!user_active(u)) {
users[i].active = 1; /* reset all stats */
users[i].authenticated = 0; memset(&users[u], 0, sizeof(users[u]));
users[i].authenticated_raw = 0; users[u].active = 1;
users[i].last_pkt = time(NULL); users[u].last_pkt = time(NULL);
users[i].fragsize = 4096; users[u].fragsize = MAX_FRAGSIZE;
users[i].conn = CONN_DNS_NULL; users[u].conn = CONN_DNS_NULL;
ret = i; return u;
break;
} }
} }
return ret; return -1;
} }
void void
@ -187,3 +168,60 @@ user_set_conn_type(int userid, enum connection c)
users[userid].conn = c; users[userid].conn = c;
} }
/* This will not check that user has passed login challenge */
int
check_user_and_ip(int userid, struct query *q)
{
/* Note: duplicate in handle_raw_login() except IP-address check */
if (userid < 0 || userid >= created_users ) {
return 1;
}
if (!users[userid].active || users[userid].disabled) {
return 1;
}
if (users[userid].last_pkt + 60 < time(NULL)) {
return 1;
}
/* return early if IP checking is disabled */
if (!check_ip) {
return 0;
}
if (q->from.ss_family != users[userid].host.ss_family) {
return 1;
}
/* Check IPv4 */
if (q->from.ss_family == AF_INET) {
struct sockaddr_in *expected, *received;
expected = (struct sockaddr_in *) &(users[userid].host);
received = (struct sockaddr_in *) &(q->from);
return memcmp(&(expected->sin_addr), &(received->sin_addr), sizeof(struct in_addr));
}
/* Check IPv6 */
if (q->from.ss_family == AF_INET6) {
struct sockaddr_in6 *expected, *received;
expected = (struct sockaddr_in6 *) &(users[userid].host);
received = (struct sockaddr_in6 *) &(q->from);
return memcmp(&(expected->sin6_addr), &(received->sin6_addr), sizeof(struct in6_addr));
}
/* Unknown address family */
return 1;
}
/* This checks that user has passed normal (non-raw) login challenge */
int
check_authenticated_user_and_ip(int userid, struct query *q)
{
int res = check_user_and_ip(userid, q);
if (res)
return res;
if (!users[userid].authenticated)
return 1;
return 0;
}

View File

@ -1,6 +1,7 @@
/* /*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>, * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se> * 2006-2009 Bjorn Andersson <flex@kryo.se>,
* 2015 Frekk van Blagh <frekk@frekkworks.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -18,22 +19,11 @@
#ifndef __USER_H__ #ifndef __USER_H__
#define __USER_H__ #define __USER_H__
#include "window.h"
#include "server.h"
#define USERS 16 #define USERS 16
#define OUTPACKETQ_LEN 4 /* Note: 16 users * 1 packet = 1MB */
/* Undefine to have no queue for packets coming in from tun device, which may
lead to massive dropping in multi-user situations with high traffic. */
#define DNSCACHE_LEN 4
/* Undefine to disable. Should be less than 18; also see comments in iodined.c */
#define QMEMPING_LEN 30
/* Max advisable: 64k/2 = 32000. Total mem usage: QMEMPING_LEN * USERS * 6 bytes */
#define QMEMDATA_LEN 15
/* Max advisable: 36/2 = 18. Total mem usage: QMEMDATA_LEN * USERS * 6 bytes */
struct tun_user { struct tun_user {
char id; char id;
int active; int active;
@ -48,13 +38,11 @@ struct tun_user {
struct query q; struct query q;
struct query q_sendrealsoon; struct query q_sendrealsoon;
int q_sendrealsoon_new; int q_sendrealsoon_new;
struct packet inpacket; struct frag_buffer *incoming;
struct packet outpacket; struct frag_buffer *outgoing;
int outfragresent; int next_upstream_ack;
struct encoder *encoder; struct encoder *encoder;
char downenc; char downenc;
int out_acked_seqno;
int out_acked_fragment;
int fragsize; int fragsize;
enum connection conn; enum connection conn;
int lazy; int lazy;
@ -64,11 +52,6 @@ struct tun_user {
unsigned char qmemdata_cmc[QMEMDATA_LEN * 4]; unsigned char qmemdata_cmc[QMEMDATA_LEN * 4];
unsigned short qmemdata_type[QMEMDATA_LEN]; unsigned short qmemdata_type[QMEMDATA_LEN];
int qmemdata_lastfilled; int qmemdata_lastfilled;
#ifdef OUTPACKETQ_LEN
struct packet outpacketq[OUTPACKETQ_LEN];
int outpacketq_nexttouse;
int outpacketq_filled;
#endif
#ifdef DNSCACHE_LEN #ifdef DNSCACHE_LEN
struct query dnscache_q[DNSCACHE_LEN]; struct query dnscache_q[DNSCACHE_LEN];
char dnscache_answer[DNSCACHE_LEN][4096]; char dnscache_answer[DNSCACHE_LEN][4096];
@ -78,11 +61,17 @@ struct tun_user {
}; };
extern struct tun_user *users; extern struct tun_user *users;
extern int created_users;
int user_sending(int user);
int all_users_waiting_to_send();
int user_active(int i);
int check_authenticated_user_and_ip(int userid, struct query *q);
int check_user_and_ip(int userid, struct query *q);
int init_users(in_addr_t, int); int init_users(in_addr_t, int);
const char* users_get_first_ip(); const char* users_get_first_ip();
int find_user_by_ip(uint32_t); int find_user_by_ip(uint32_t);
int all_users_waiting_to_send();
int find_available_user(); int find_available_user();
void user_switch_codec(int userid, struct encoder *enc); void user_switch_codec(int userid, struct encoder *enc);
void user_set_conn_type(int userid, enum connection c); void user_set_conn_type(int userid, enum connection c);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015 Frekk van Blagh * Copyright (c) 2015 Frekk van Blagh <frekk@frekkworks.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015 Frekk van Blagh * Copyright (c) 2015 Frekk van Blagh <frekk@frekkworks.com>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -18,7 +18,7 @@
#define __WINDOW_H__ #define __WINDOW_H__
#define MAX_SEQ_ID 256 #define MAX_SEQ_ID 256
#define MAX_FRAGSIZE 2048 #define MAX_FRAGSIZE 4096
#define ACK_TIMEOUT 5 #define ACK_TIMEOUT 5
#define WINDOW_SENDING 1 #define WINDOW_SENDING 1
@ -95,7 +95,7 @@ fragment *window_get_next_sending_fragment(struct frag_buffer *w, int other_ack)
int window_get_next_ack(struct frag_buffer *w); int window_get_next_ack(struct frag_buffer *w);
/* Sets the fragment with seqid to be ACK'd (SEND) */ /* Sets the fragment with seqid to be ACK'd (SEND) */
void window_ack(struct frag_buffer *w, unsigned seqid); void window_ack(struct frag_buffer *w, int seqid);
/* To be called after all other processing has been done /* To be called after all other processing has been done
* when anything happens (moves window etc) (SEND/RECV) */ * when anything happens (moves window etc) (SEND/RECV) */