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
CLIENTOBJS = iodine.o client.o util.o
CLIENT = ../bin/iodine
SERVEROBJS = iodined.o user.o fw_query.o
SERVEROBJS = iodined.o user.o fw_query.o server.o
SERVER = ../bin/iodined
OS = `echo $(TARGETOS) | tr "a-z" "A-Z"`

View File

@ -1,6 +1,7 @@
/*
* 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
* 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)
outbuf = window_buffer_init(100, 10, hostname_maxlen, WINDOW_SENDING);
/* 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;
current_nameserver = 0;
@ -362,13 +363,33 @@ is_sending()
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
send_next_frag(int fd)
/* Sends next available fragment of data from the outgoing window buffer */
{
static uint8_t buf[MAX_FRAGSIZE];
size_t len;
int code;
static int datacmc = 0;
static char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789";
@ -381,13 +402,13 @@ send_next_frag(int fd)
if (is_sending()) {
/* 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 */
send_ping(fd);
send_ping(fd, 1);
}
return; /* nothing to send - why was this called? */
}
/* 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) */
@ -411,29 +432,7 @@ send_next_frag(int fd)
if (datacmc >= 36)
datacmc = 0;
send_query(fd, 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);
}
send_query(fd, (char *)buf);
}
static void
@ -574,7 +573,7 @@ dns_namedec(char *outdata, int outdatalen, char *buf, int buflen)
}
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 0 on replies that could be correct but are useless, and are not
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;
datalen = sizeof(buf);
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 */
@ -766,6 +765,8 @@ static int
parse_data(uint8_t *data, size_t len, fragment *f)
{
memset(f, 0, sizeof(fragment));
int ping = (data[3] >> 5) & 1;
if (!ping) {
f->seqID = data[0];
f->start = data[3] & 1;
f->end = (data[3] >> 1) & 1;
@ -774,7 +775,17 @@ parse_data(uint8_t *data, size_t len, fragment *f)
f->compressed = (data[3] >> 4) & 1;
f->len = len - 3;
memcpy(f->data, data + 3, MIN(f->len, sizeof(f->data)));
return (data[3] >> 5) & 1; /* return ping flag (if corresponding query was a ping) */
} 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
@ -825,7 +836,7 @@ tunnel_dns(int tun_fd, int dns_fd)
memset(&q, 0, sizeof(q));
memset(buf, 0, sizeof(buf));
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)
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 */
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) {
// TODO: handle pings to resync window
goto skip_recv;
}
window_ack(outbuf, f.ack_other);
@ -954,6 +965,7 @@ tunnel_dns(int tun_fd, int dns_fd)
send_something_now = 1;
}
skip_recv:
/* Move window along after doing all data processing */
window_tick(inbuf);
@ -968,7 +980,7 @@ tunnel_dns(int tun_fd, int dns_fd)
/* Send ping if we didn't send anything yet */
if (send_something_now) {
send_ping(dns_fd);
send_ping(dns_fd, 0);
send_ping_soon = 0;
}
@ -1031,10 +1043,10 @@ client_tunnel(int tun_fd, int dns_fd)
send_next_frag(dns_fd);
} else {
outbuf->resends = 0;
send_ping(dns_fd);
send_ping(dns_fd, 1);
}
} else {
send_ping(dns_fd);
send_ping(dns_fd, 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);
if (fragsize > MAX_FRAGSIZE) {
/* 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;
}
if (!fragsize) {

View File

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

View File

@ -35,7 +35,7 @@ struct encoder {
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 inline_dotify(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
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)
/* FreeBSD/NetBSD has no header */
@ -545,7 +545,7 @@ write_tun(int tun_fd, char *data, size_t len)
}
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)
/* FreeBSD/NetBSD has no header */

View File

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

View File

@ -1,6 +1,7 @@
/*
* 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
* purpose with or without fee is hereby granted, provided that the above
@ -33,9 +34,12 @@
#include "common.h"
#include "encoding.h"
#include "user.h"
#include "window.h"
struct tun_user *users;
unsigned usercount;
int created_users;
int
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 */
usercount = MIN(maxusers, USERS);
if (users) free(users);
users = calloc(usercount, sizeof(struct tun_user));
for (i = 0; i < usercount; i++) {
in_addr_t ip;
@ -74,11 +79,7 @@ init_users(in_addr_t my_ip, int netbits)
}
users[i].tun_ip = ip;
net.s_addr = ip;
users[i].disabled = 0;
users[i].authenticated = 0;
users[i].authenticated_raw = 0;
users[i].active = 0;
/* Rest is reset on login ('V' packet) */
/* Rest is reset on login ('V' packet) or already 0 */
}
return usercount;
@ -95,75 +96,55 @@ users_get_first_ip()
int
find_user_by_ip(uint32_t ip)
{
int ret;
int i;
for (int i = 0; i < usercount; i++) {
if (user_active(i) && users[i].authenticated && ip == users[i].tun_ip) {
return i;
}
}
return -1;
}
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;
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
all_users_waiting_to_send()
/* If this returns true, then reading from tun device is blocked.
So only return true when all clients have at least one packet in
the outpacket-queue, so that sending back-to-back is possible
So only return true when all clients have at least one fragment in
the outgoing buffer, so that sending back-to-back is possible
without going through another select loop.
*/
{
time_t now;
int ret;
int i;
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;
for (int i = 0; i < usercount; i++)
if (!(user_active(i) && user_sending(i))) return 0;
return 1;
}
int
find_available_user()
{
int ret = -1;
int i;
for (i = 0; i < usercount; i++) {
for (int u = 0; u < usercount; u++) {
/* Not used at all or not used in one minute */
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) {
users[i].active = 1;
users[i].authenticated = 0;
users[i].authenticated_raw = 0;
users[i].last_pkt = time(NULL);
users[i].fragsize = 4096;
users[i].conn = CONN_DNS_NULL;
ret = i;
break;
if (!user_active(u)) {
/* reset all stats */
memset(&users[u], 0, sizeof(users[u]));
users[u].active = 1;
users[u].last_pkt = time(NULL);
users[u].fragsize = MAX_FRAGSIZE;
users[u].conn = CONN_DNS_NULL;
return u;
}
}
return ret;
return -1;
}
void
@ -187,3 +168,60 @@ user_set_conn_type(int userid, enum connection 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>,
* 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
* purpose with or without fee is hereby granted, provided that the above
@ -18,22 +19,11 @@
#ifndef __USER_H__
#define __USER_H__
#include "window.h"
#include "server.h"
#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 {
char id;
int active;
@ -48,13 +38,11 @@ struct tun_user {
struct query q;
struct query q_sendrealsoon;
int q_sendrealsoon_new;
struct packet inpacket;
struct packet outpacket;
int outfragresent;
struct frag_buffer *incoming;
struct frag_buffer *outgoing;
int next_upstream_ack;
struct encoder *encoder;
char downenc;
int out_acked_seqno;
int out_acked_fragment;
int fragsize;
enum connection conn;
int lazy;
@ -64,11 +52,6 @@ struct tun_user {
unsigned char qmemdata_cmc[QMEMDATA_LEN * 4];
unsigned short qmemdata_type[QMEMDATA_LEN];
int qmemdata_lastfilled;
#ifdef OUTPACKETQ_LEN
struct packet outpacketq[OUTPACKETQ_LEN];
int outpacketq_nexttouse;
int outpacketq_filled;
#endif
#ifdef DNSCACHE_LEN
struct query dnscache_q[DNSCACHE_LEN];
char dnscache_answer[DNSCACHE_LEN][4096];
@ -78,11 +61,17 @@ struct tun_user {
};
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);
const char* users_get_first_ip();
int find_user_by_ip(uint32_t);
int all_users_waiting_to_send();
int find_available_user();
void user_switch_codec(int userid, struct encoder *enc);
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
* 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
* purpose with or without fee is hereby granted, provided that the above
@ -18,7 +18,7 @@
#define __WINDOW_H__
#define MAX_SEQ_ID 256
#define MAX_FRAGSIZE 2048
#define MAX_FRAGSIZE 4096
#define ACK_TIMEOUT 5
#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);
/* 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
* when anything happens (moves window etc) (SEND/RECV) */