mirror of
https://github.com/yarrick/iodine.git
synced 2025-02-22 04:48:27 +00:00
Refactored 'fragment' to 'struct fragment' and moved window macros
This commit is contained in:
parent
fa4bc66d44
commit
25a6457e12
@ -688,7 +688,7 @@ send_next_frag(int fd)
|
||||
int code, id;
|
||||
static int datacmc = 0;
|
||||
static char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
fragment *f;
|
||||
struct fragment *f;
|
||||
size_t buflen;
|
||||
|
||||
/* Get next fragment to send */
|
||||
@ -1080,11 +1080,11 @@ handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout)
|
||||
}
|
||||
|
||||
int
|
||||
parse_data(uint8_t *data, size_t len, fragment *f, int *immediate)
|
||||
parse_data(uint8_t *data, size_t len, struct fragment *f, int *immediate)
|
||||
{
|
||||
size_t headerlen = DOWNSTREAM_HDR;
|
||||
int ping;
|
||||
memset(f, 0, sizeof(fragment));
|
||||
memset(f, 0, sizeof(struct fragment));
|
||||
|
||||
f->seqID = data[0];
|
||||
|
||||
@ -1164,7 +1164,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
||||
struct query q;
|
||||
size_t datalen, buflen;
|
||||
uint8_t buf[64*1024], cbuf[64*1024], *data;
|
||||
fragment f;
|
||||
struct fragment f;
|
||||
int read, compressed, res, immediate;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
@ -53,7 +53,7 @@ void client_set_interval(int, int);
|
||||
int client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize);
|
||||
int client_tunnel(int tun_fd, int dns_fd);
|
||||
|
||||
int parse_data(uint8_t *data, size_t len, fragment *f, int *immediate);
|
||||
int parse_data(uint8_t *data, size_t len, struct fragment *f, int *immediate);
|
||||
int handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout);
|
||||
void handshake_switch_options(int dns_fd, int lazy, int compression, char denc);
|
||||
int send_ping(int fd, int ping_response, int ack, int timeout);
|
||||
|
73
src/window.c
73
src/window.c
@ -31,11 +31,37 @@
|
||||
|
||||
int window_debug = 0;
|
||||
|
||||
|
||||
/* Window debugging macro */
|
||||
#ifdef DEBUG_BUILD
|
||||
#define WDEBUG(...) if (window_debug) {\
|
||||
TIMEPRINT("[WINDOW-DEBUG] (%s:%d) ", __FILE__, __LINE__);\
|
||||
fprintf(stderr, __VA_ARGS__);\
|
||||
fprintf(stderr, "\n");\
|
||||
}
|
||||
#else
|
||||
#define WDEBUG(...)
|
||||
#endif
|
||||
|
||||
/* Window-specific macros */
|
||||
/* Gets index of fragment o fragments after window start */
|
||||
#define AFTER(w, o) ((w->window_start + o) % w->length)
|
||||
|
||||
/* Check if fragment index a is within window_buffer *w */
|
||||
#define INWINDOW_INDEX(w, a) ((w->window_start < w->window_end) ? \
|
||||
(a >= w->window_start && a <= w->window_end) : \
|
||||
((a >= w->window_start && a <= w->length - 1) || \
|
||||
(a >= 0 && a <= w->window_end)))
|
||||
|
||||
/* Wrap index x to a value within the window buffer length */
|
||||
#define WRAP(x) ((x) % w->length)
|
||||
|
||||
|
||||
struct frag_buffer *
|
||||
window_buffer_init(size_t length, unsigned windowsize, unsigned fragsize, int dir)
|
||||
{
|
||||
struct frag_buffer *buf;
|
||||
buf = calloc(sizeof(struct frag_buffer), 1);
|
||||
buf = calloc(1, sizeof(struct frag_buffer));
|
||||
if (!buf) {
|
||||
errx(1, "Failed to allocate window buffer memory!");
|
||||
}
|
||||
@ -46,7 +72,7 @@ window_buffer_init(size_t length, unsigned windowsize, unsigned fragsize, int di
|
||||
errx(fragsize, "Fragsize too large! Please recompile with larger MAX_FRAGSIZE!");
|
||||
}
|
||||
|
||||
buf->frags = calloc(length, sizeof(fragment));
|
||||
buf->frags = calloc(length, sizeof(struct fragment));
|
||||
if (!buf->frags) {
|
||||
errx(1, "Failed to allocate fragment buffer!");
|
||||
}
|
||||
@ -83,7 +109,7 @@ window_buffer_resize(struct frag_buffer *w, size_t length)
|
||||
WDEBUG("Resizing window buffer with things still in it! This will cause problems!");
|
||||
}
|
||||
if (w->frags) free(w->frags);
|
||||
w->frags = calloc(length, sizeof(fragment));
|
||||
w->frags = calloc(length, sizeof(struct fragment));
|
||||
if (!w->frags) {
|
||||
errx(1, "Failed to resize window buffer!");
|
||||
}
|
||||
@ -104,7 +130,7 @@ window_buffer_clear(struct frag_buffer *w)
|
||||
{
|
||||
if (!w) return;
|
||||
|
||||
memset(w->frags, 0, w->length * sizeof(fragment));
|
||||
memset(w->frags, 0, w->length * sizeof(struct fragment));
|
||||
window_buffer_reset(w);
|
||||
}
|
||||
|
||||
@ -117,10 +143,10 @@ window_buffer_available(struct frag_buffer *w)
|
||||
|
||||
/* Places a fragment in the window after the last one */
|
||||
int
|
||||
window_append_fragment(struct frag_buffer *w, fragment *src)
|
||||
window_append_fragment(struct frag_buffer *w, struct fragment *src)
|
||||
{
|
||||
if (window_buffer_available(w) < 1) return 0;
|
||||
memcpy(&w->frags[w->last_write], src, sizeof(fragment));
|
||||
memcpy(&w->frags[w->last_write], src, sizeof(struct fragment));
|
||||
w->last_write = WRAP(w->last_write + 1);
|
||||
w->numitems ++;
|
||||
return 1;
|
||||
@ -128,14 +154,14 @@ window_append_fragment(struct frag_buffer *w, fragment *src)
|
||||
|
||||
|
||||
ssize_t
|
||||
window_process_incoming_fragment(struct frag_buffer *w, fragment *f)
|
||||
window_process_incoming_fragment(struct frag_buffer *w, struct fragment *f)
|
||||
/* Handles fragment received from the sending side (RECV)
|
||||
* Returns index of fragment in window or <0 if dropped
|
||||
* The next ACK MUST be for this fragment */
|
||||
{
|
||||
/* Check if packet is in window */
|
||||
unsigned startid, endid, offset;
|
||||
fragment *fd;
|
||||
struct fragment *fd;
|
||||
startid = w->start_seq_id;
|
||||
endid = (w->start_seq_id + w->windowsize) % MAX_SEQ_ID;
|
||||
offset = SEQ_OFFSET(startid, f->seqID);
|
||||
@ -169,7 +195,7 @@ window_process_incoming_fragment(struct frag_buffer *w, fragment *f)
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(fd, f, sizeof(fragment));
|
||||
memcpy(fd, f, sizeof(struct fragment));
|
||||
w->numitems ++;
|
||||
|
||||
fd->retries = 0;
|
||||
@ -181,6 +207,17 @@ window_process_incoming_fragment(struct frag_buffer *w, fragment *f)
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* Perform wrapped iteration of statement with pos = (begin to end) wrapped at
|
||||
* max, executing statement f for every value of pos. */
|
||||
#define ITER_FORWARD(begin, end, max, pos, f) { \
|
||||
if (end >= begin) \
|
||||
for (pos = begin; pos < end && pos < max; pos++) {f}\
|
||||
else {\
|
||||
for (pos = begin; pos < max; pos++) {f}\
|
||||
for (pos = 0; pos < end && pos < max; pos++) {f}\
|
||||
}\
|
||||
}
|
||||
|
||||
/* Reassembles first complete sequence of fragments into data. (RECV)
|
||||
* Returns length of data reassembled, or 0 if no data reassembled */
|
||||
size_t
|
||||
@ -198,7 +235,7 @@ window_reassemble_data(struct frag_buffer *w, uint8_t *data, size_t maxlen, int
|
||||
}
|
||||
if (compression) *compression = 1;
|
||||
|
||||
fragment *f;
|
||||
struct fragment *f;
|
||||
size_t i;
|
||||
unsigned curseq;
|
||||
int end = 0;
|
||||
@ -253,7 +290,7 @@ window_reassemble_data(struct frag_buffer *w, uint8_t *data, size_t maxlen, int
|
||||
/* Clear all used fragments */
|
||||
size_t p;
|
||||
ITER_FORWARD(w->chunk_start, WRAP(w->chunk_start + i + 1), w->length, p,
|
||||
memset(&w->frags[p], 0, sizeof(fragment));
|
||||
memset(&w->frags[p], 0, sizeof(struct fragment));
|
||||
);
|
||||
w->chunk_start = WRAP(woffs + 1);
|
||||
w->numitems -= i + 1;
|
||||
@ -267,7 +304,7 @@ window_sending(struct frag_buffer *w, struct timeval *nextresend)
|
||||
*nextresend is time before the next frag will be resent */
|
||||
{
|
||||
struct timeval age, now, oldest;
|
||||
fragment *f;
|
||||
struct fragment *f;
|
||||
size_t tosend = 0;
|
||||
|
||||
oldest.tv_sec = 0;
|
||||
@ -311,11 +348,11 @@ window_sending(struct frag_buffer *w, struct timeval *nextresend)
|
||||
|
||||
/* Returns next fragment to be sent or NULL if nothing (SEND)
|
||||
* This also handles packet resends, timeouts etc. */
|
||||
fragment *
|
||||
struct fragment *
|
||||
window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack)
|
||||
{
|
||||
struct timeval age, now;
|
||||
fragment *f = NULL;
|
||||
struct fragment *f = NULL;
|
||||
|
||||
if (*other_ack >= MAX_SEQ_ID || *other_ack < 0)
|
||||
*other_ack = -1;
|
||||
@ -360,7 +397,7 @@ window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack)
|
||||
int
|
||||
window_get_next_ack(struct frag_buffer *w)
|
||||
{
|
||||
fragment *f;
|
||||
struct fragment *f;
|
||||
for (size_t i = 0; i < w->windowsize; i++) {
|
||||
f = &w->frags[WRAP(w->window_start + i)];
|
||||
if (f->len > 0 && f->acks <= 0) {
|
||||
@ -375,7 +412,7 @@ window_get_next_ack(struct frag_buffer *w)
|
||||
void
|
||||
window_ack(struct frag_buffer *w, int seqid)
|
||||
{
|
||||
fragment *f;
|
||||
struct fragment *f;
|
||||
if (seqid < 0 || seqid > MAX_SEQ_ID) return;
|
||||
for (size_t i = 0; i < w->windowsize; i++) {
|
||||
f = &w->frags[AFTER(w, i)];
|
||||
@ -406,7 +443,7 @@ window_tick(struct frag_buffer *w)
|
||||
if (w->direction == WINDOW_SENDING) {
|
||||
WDEBUG("Clearing old fragments in SENDING window.");
|
||||
w->numitems --; /* Clear old fragments */
|
||||
memset(&w->frags[w->window_start], 0, sizeof(fragment));
|
||||
memset(&w->frags[w->window_start], 0, sizeof(struct fragment));
|
||||
}
|
||||
w->window_start = AFTER(w, 1);
|
||||
|
||||
@ -428,7 +465,7 @@ window_add_outgoing_data(struct frag_buffer *w, uint8_t *data, size_t len, int c
|
||||
}
|
||||
compressed &= 1;
|
||||
size_t offset = 0;
|
||||
static fragment f;
|
||||
struct fragment f;
|
||||
WDEBUG("add data len %lu, %lu frags, max fragsize %u", len, n, w->maxfraglen);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
memset(&f, 0, sizeof(f));
|
||||
|
78
src/window.h
78
src/window.h
@ -22,11 +22,28 @@
|
||||
#define MAX_SEQ_ID 256
|
||||
#define MAX_FRAGSIZE 4096
|
||||
|
||||
/* Window function definitions. */
|
||||
#define WINDOW_SENDING 1
|
||||
#define WINDOW_RECVING 0
|
||||
|
||||
typedef struct fragment {
|
||||
/* Generic ring-buffer macros */
|
||||
|
||||
/* Distance (going forwards) between a and b in window of length l */
|
||||
#define DISTF(l, a, b) (((a > b) ? a-b : l-a+b-1) % l)
|
||||
|
||||
/* Distance backwards between a and b in window of length l */
|
||||
#define DISTB(l, a, b) (((a < b) ? l-b+a-1 : a-b) % l)
|
||||
|
||||
/* Check if sequence ID a is within sequence range start to end */
|
||||
#define INWINDOW_SEQ(start, end, a) ((start < end) ? \
|
||||
(a >= start && a <= end) : \
|
||||
((a >= start && a <= MAX_SEQ_ID - 1) || \
|
||||
(a <= end)))
|
||||
|
||||
/* Find the wrapped offset between sequence IDs start and a
|
||||
* Note: the maximum possible offset is MAX_SEQ_ID - 1 */
|
||||
#define SEQ_OFFSET(start, a) ((a >= start) ? a - start : MAX_SEQ_ID - start + a)
|
||||
|
||||
struct fragment {
|
||||
size_t len; /* Length of fragment data (0 if fragment unused) */
|
||||
unsigned seqID; /* fragment sequence ID */
|
||||
int ack_other; /* other way ACK seqID (>=0) or unset (<0) */
|
||||
@ -37,10 +54,10 @@ typedef struct fragment {
|
||||
unsigned retries; /* number of times has been sent or dupes recv'd */
|
||||
struct timeval lastsent; /* timestamp of most recent send attempt */
|
||||
int acks; /* number of times packet has been ack'd */
|
||||
} fragment;
|
||||
};
|
||||
|
||||
struct frag_buffer {
|
||||
fragment *frags; /* pointer to array of data fragments */
|
||||
struct fragment *frags; /* pointer to array of data fragments */
|
||||
unsigned windowsize; /* Max number of fragments in flight */
|
||||
unsigned maxfraglen; /* Max outgoing fragment data size */
|
||||
size_t length; /* Length of buffer */
|
||||
@ -59,55 +76,10 @@ struct frag_buffer {
|
||||
|
||||
extern int window_debug;
|
||||
|
||||
/* Window debugging macro */
|
||||
#ifdef DEBUG_BUILD
|
||||
#define WDEBUG(...) if (window_debug) {\
|
||||
TIMEPRINT("[WINDOW-DEBUG] (%s:%d) ", __FILE__, __LINE__);\
|
||||
fprintf(stderr, __VA_ARGS__);\
|
||||
fprintf(stderr, "\n");\
|
||||
}
|
||||
#else
|
||||
#define WDEBUG(...)
|
||||
#endif
|
||||
|
||||
/* Gets index of fragment o fragments after window start */
|
||||
#define AFTER(w, o) ((w->window_start + o) % w->length)
|
||||
|
||||
/* Distance (going forwards) between a and b in window of length l */
|
||||
#define DISTF(l, a, b) (((a > b) ? a-b : l-a+b-1) % l)
|
||||
/* Window function definitions. */
|
||||
|
||||
/* Distance backwards between a and b in window of length l */
|
||||
#define DISTB(l, a, b) (((a < b) ? l-b+a-1 : a-b) % l)
|
||||
|
||||
/* Check if fragment index a is within window_buffer *w */
|
||||
#define INWINDOW_INDEX(w, a) ((w->window_start < w->window_end) ? \
|
||||
(a >= w->window_start && a <= w->window_end) : \
|
||||
((a >= w->window_start && a <= w->length - 1) || \
|
||||
(a >= 0 && a <= w->window_end)))
|
||||
|
||||
/* Check if sequence ID a is within sequence range start to end */
|
||||
#define INWINDOW_SEQ(start, end, a) ((start < end) ? \
|
||||
(a >= start && a <= end) : \
|
||||
((a >= start && a <= MAX_SEQ_ID - 1) || \
|
||||
(a <= end)))
|
||||
|
||||
/* Find the wrapped offset between sequence IDs start and a
|
||||
* Note: the maximum possible offset is MAX_SEQ_ID - 1 */
|
||||
#define SEQ_OFFSET(start, a) ((a >= start) ? a - start : MAX_SEQ_ID - start + a)
|
||||
|
||||
/* Wrap index x to a value within the window buffer length */
|
||||
#define WRAP(x) ((x) % w->length)
|
||||
|
||||
/* Perform wrapped iteration of statement with pos = (begin to end) wrapped at
|
||||
* max, executing statement f for every value of pos. */
|
||||
#define ITER_FORWARD(begin, end, max, pos, f) { \
|
||||
if (end >= begin) \
|
||||
for (pos = begin; pos < end && pos < max; pos++) {f}\
|
||||
else {\
|
||||
for (pos = begin; pos < max; pos++) {f}\
|
||||
for (pos = 0; pos < end && pos < max; pos++) {f}\
|
||||
}\
|
||||
}
|
||||
|
||||
/* Window buffer creation and housekeeping */
|
||||
struct frag_buffer *window_buffer_init(size_t length, unsigned windowsize, unsigned fragsize, int dir);
|
||||
@ -124,10 +96,10 @@ void window_buffer_reset(struct frag_buffer *w);
|
||||
size_t window_buffer_available(struct frag_buffer *w);
|
||||
|
||||
/* Places a fragment in the window after the last one */
|
||||
int window_append_fragment(struct frag_buffer *w, fragment *src);
|
||||
int window_append_fragment(struct frag_buffer *w, struct fragment *src);
|
||||
|
||||
/* Handles fragment received from the sending side (RECV) */
|
||||
ssize_t window_process_incoming_fragment(struct frag_buffer *w, fragment *f);
|
||||
ssize_t window_process_incoming_fragment(struct frag_buffer *w, struct fragment *f);
|
||||
|
||||
/* Reassembles first complete sequence of fragments into data. (RECV)
|
||||
* Returns length of data reassembled, or 0 if no data reassembled */
|
||||
@ -137,7 +109,7 @@ size_t window_reassemble_data(struct frag_buffer *w, uint8_t *data, size_t maxle
|
||||
size_t window_sending(struct frag_buffer *w, struct timeval *);
|
||||
|
||||
/* Returns next fragment to be sent or NULL if nothing (SEND) */
|
||||
fragment *window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack);
|
||||
struct fragment *window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack);
|
||||
|
||||
/* Gets the seqid of next fragment to be ACK'd (RECV) */
|
||||
int window_get_next_ack(struct frag_buffer *w);
|
||||
|
Loading…
x
Reference in New Issue
Block a user