mirror of
https://github.com/yarrick/iodine.git
synced 2025-02-22 12:58:26 +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;
|
int code, id;
|
||||||
static int datacmc = 0;
|
static int datacmc = 0;
|
||||||
static char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
static char *datacmcchars = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
fragment *f;
|
struct fragment *f;
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
|
|
||||||
/* Get next fragment to send */
|
/* Get next fragment to send */
|
||||||
@ -1080,11 +1080,11 @@ handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
size_t headerlen = DOWNSTREAM_HDR;
|
||||||
int ping;
|
int ping;
|
||||||
memset(f, 0, sizeof(fragment));
|
memset(f, 0, sizeof(struct fragment));
|
||||||
|
|
||||||
f->seqID = data[0];
|
f->seqID = data[0];
|
||||||
|
|
||||||
@ -1164,7 +1164,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
|||||||
struct query q;
|
struct query q;
|
||||||
size_t datalen, buflen;
|
size_t datalen, buflen;
|
||||||
uint8_t buf[64*1024], cbuf[64*1024], *data;
|
uint8_t buf[64*1024], cbuf[64*1024], *data;
|
||||||
fragment f;
|
struct fragment f;
|
||||||
int read, compressed, res, immediate;
|
int read, compressed, res, immediate;
|
||||||
|
|
||||||
memset(&q, 0, sizeof(q));
|
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_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize);
|
||||||
int client_tunnel(int tun_fd, int dns_fd);
|
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);
|
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);
|
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);
|
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;
|
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 *
|
struct frag_buffer *
|
||||||
window_buffer_init(size_t length, unsigned windowsize, unsigned fragsize, int dir)
|
window_buffer_init(size_t length, unsigned windowsize, unsigned fragsize, int dir)
|
||||||
{
|
{
|
||||||
struct frag_buffer *buf;
|
struct frag_buffer *buf;
|
||||||
buf = calloc(sizeof(struct frag_buffer), 1);
|
buf = calloc(1, sizeof(struct frag_buffer));
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
errx(1, "Failed to allocate window buffer memory!");
|
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!");
|
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) {
|
if (!buf->frags) {
|
||||||
errx(1, "Failed to allocate fragment buffer!");
|
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!");
|
WDEBUG("Resizing window buffer with things still in it! This will cause problems!");
|
||||||
}
|
}
|
||||||
if (w->frags) free(w->frags);
|
if (w->frags) free(w->frags);
|
||||||
w->frags = calloc(length, sizeof(fragment));
|
w->frags = calloc(length, sizeof(struct fragment));
|
||||||
if (!w->frags) {
|
if (!w->frags) {
|
||||||
errx(1, "Failed to resize window buffer!");
|
errx(1, "Failed to resize window buffer!");
|
||||||
}
|
}
|
||||||
@ -104,7 +130,7 @@ window_buffer_clear(struct frag_buffer *w)
|
|||||||
{
|
{
|
||||||
if (!w) return;
|
if (!w) return;
|
||||||
|
|
||||||
memset(w->frags, 0, w->length * sizeof(fragment));
|
memset(w->frags, 0, w->length * sizeof(struct fragment));
|
||||||
window_buffer_reset(w);
|
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 */
|
/* Places a fragment in the window after the last one */
|
||||||
int
|
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;
|
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->last_write = WRAP(w->last_write + 1);
|
||||||
w->numitems ++;
|
w->numitems ++;
|
||||||
return 1;
|
return 1;
|
||||||
@ -128,14 +154,14 @@ window_append_fragment(struct frag_buffer *w, fragment *src)
|
|||||||
|
|
||||||
|
|
||||||
ssize_t
|
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)
|
/* Handles fragment received from the sending side (RECV)
|
||||||
* Returns index of fragment in window or <0 if dropped
|
* Returns index of fragment in window or <0 if dropped
|
||||||
* The next ACK MUST be for this fragment */
|
* The next ACK MUST be for this fragment */
|
||||||
{
|
{
|
||||||
/* Check if packet is in window */
|
/* Check if packet is in window */
|
||||||
unsigned startid, endid, offset;
|
unsigned startid, endid, offset;
|
||||||
fragment *fd;
|
struct fragment *fd;
|
||||||
startid = w->start_seq_id;
|
startid = w->start_seq_id;
|
||||||
endid = (w->start_seq_id + w->windowsize) % MAX_SEQ_ID;
|
endid = (w->start_seq_id + w->windowsize) % MAX_SEQ_ID;
|
||||||
offset = SEQ_OFFSET(startid, f->seqID);
|
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 ++;
|
w->numitems ++;
|
||||||
|
|
||||||
fd->retries = 0;
|
fd->retries = 0;
|
||||||
@ -181,6 +207,17 @@ window_process_incoming_fragment(struct frag_buffer *w, fragment *f)
|
|||||||
return dest;
|
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)
|
/* Reassembles first complete sequence of fragments into data. (RECV)
|
||||||
* Returns length of data reassembled, or 0 if no data reassembled */
|
* Returns length of data reassembled, or 0 if no data reassembled */
|
||||||
size_t
|
size_t
|
||||||
@ -198,7 +235,7 @@ window_reassemble_data(struct frag_buffer *w, uint8_t *data, size_t maxlen, int
|
|||||||
}
|
}
|
||||||
if (compression) *compression = 1;
|
if (compression) *compression = 1;
|
||||||
|
|
||||||
fragment *f;
|
struct fragment *f;
|
||||||
size_t i;
|
size_t i;
|
||||||
unsigned curseq;
|
unsigned curseq;
|
||||||
int end = 0;
|
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 */
|
/* Clear all used fragments */
|
||||||
size_t p;
|
size_t p;
|
||||||
ITER_FORWARD(w->chunk_start, WRAP(w->chunk_start + i + 1), w->length, 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->chunk_start = WRAP(woffs + 1);
|
||||||
w->numitems -= i + 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 */
|
*nextresend is time before the next frag will be resent */
|
||||||
{
|
{
|
||||||
struct timeval age, now, oldest;
|
struct timeval age, now, oldest;
|
||||||
fragment *f;
|
struct fragment *f;
|
||||||
size_t tosend = 0;
|
size_t tosend = 0;
|
||||||
|
|
||||||
oldest.tv_sec = 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)
|
/* Returns next fragment to be sent or NULL if nothing (SEND)
|
||||||
* This also handles packet resends, timeouts etc. */
|
* This also handles packet resends, timeouts etc. */
|
||||||
fragment *
|
struct fragment *
|
||||||
window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack)
|
window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack)
|
||||||
{
|
{
|
||||||
struct timeval age, now;
|
struct timeval age, now;
|
||||||
fragment *f = NULL;
|
struct fragment *f = NULL;
|
||||||
|
|
||||||
if (*other_ack >= MAX_SEQ_ID || *other_ack < 0)
|
if (*other_ack >= MAX_SEQ_ID || *other_ack < 0)
|
||||||
*other_ack = -1;
|
*other_ack = -1;
|
||||||
@ -360,7 +397,7 @@ window_get_next_sending_fragment(struct frag_buffer *w, int *other_ack)
|
|||||||
int
|
int
|
||||||
window_get_next_ack(struct frag_buffer *w)
|
window_get_next_ack(struct frag_buffer *w)
|
||||||
{
|
{
|
||||||
fragment *f;
|
struct fragment *f;
|
||||||
for (size_t i = 0; i < w->windowsize; i++) {
|
for (size_t i = 0; i < w->windowsize; i++) {
|
||||||
f = &w->frags[WRAP(w->window_start + i)];
|
f = &w->frags[WRAP(w->window_start + i)];
|
||||||
if (f->len > 0 && f->acks <= 0) {
|
if (f->len > 0 && f->acks <= 0) {
|
||||||
@ -375,7 +412,7 @@ window_get_next_ack(struct frag_buffer *w)
|
|||||||
void
|
void
|
||||||
window_ack(struct frag_buffer *w, int seqid)
|
window_ack(struct frag_buffer *w, int seqid)
|
||||||
{
|
{
|
||||||
fragment *f;
|
struct fragment *f;
|
||||||
if (seqid < 0 || seqid > MAX_SEQ_ID) return;
|
if (seqid < 0 || seqid > MAX_SEQ_ID) return;
|
||||||
for (size_t i = 0; i < w->windowsize; i++) {
|
for (size_t i = 0; i < w->windowsize; i++) {
|
||||||
f = &w->frags[AFTER(w, i)];
|
f = &w->frags[AFTER(w, i)];
|
||||||
@ -406,7 +443,7 @@ window_tick(struct frag_buffer *w)
|
|||||||
if (w->direction == WINDOW_SENDING) {
|
if (w->direction == WINDOW_SENDING) {
|
||||||
WDEBUG("Clearing old fragments in SENDING window.");
|
WDEBUG("Clearing old fragments in SENDING window.");
|
||||||
w->numitems --; /* Clear old fragments */
|
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);
|
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;
|
compressed &= 1;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
static fragment f;
|
struct fragment f;
|
||||||
WDEBUG("add data len %lu, %lu frags, max fragsize %u", len, n, w->maxfraglen);
|
WDEBUG("add data len %lu, %lu frags, max fragsize %u", len, n, w->maxfraglen);
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
memset(&f, 0, sizeof(f));
|
memset(&f, 0, sizeof(f));
|
||||||
|
78
src/window.h
78
src/window.h
@ -22,11 +22,28 @@
|
|||||||
#define MAX_SEQ_ID 256
|
#define MAX_SEQ_ID 256
|
||||||
#define MAX_FRAGSIZE 4096
|
#define MAX_FRAGSIZE 4096
|
||||||
|
|
||||||
/* Window function definitions. */
|
|
||||||
#define WINDOW_SENDING 1
|
#define WINDOW_SENDING 1
|
||||||
#define WINDOW_RECVING 0
|
#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) */
|
size_t len; /* Length of fragment data (0 if fragment unused) */
|
||||||
unsigned seqID; /* fragment sequence ID */
|
unsigned seqID; /* fragment sequence ID */
|
||||||
int ack_other; /* other way ACK seqID (>=0) or unset (<0) */
|
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 */
|
unsigned retries; /* number of times has been sent or dupes recv'd */
|
||||||
struct timeval lastsent; /* timestamp of most recent send attempt */
|
struct timeval lastsent; /* timestamp of most recent send attempt */
|
||||||
int acks; /* number of times packet has been ack'd */
|
int acks; /* number of times packet has been ack'd */
|
||||||
} fragment;
|
};
|
||||||
|
|
||||||
struct frag_buffer {
|
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 windowsize; /* Max number of fragments in flight */
|
||||||
unsigned maxfraglen; /* Max outgoing fragment data size */
|
unsigned maxfraglen; /* Max outgoing fragment data size */
|
||||||
size_t length; /* Length of buffer */
|
size_t length; /* Length of buffer */
|
||||||
@ -59,55 +76,10 @@ struct frag_buffer {
|
|||||||
|
|
||||||
extern int window_debug;
|
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 */
|
/* Window function definitions. */
|
||||||
#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 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 */
|
/* Window buffer creation and housekeeping */
|
||||||
struct frag_buffer *window_buffer_init(size_t length, unsigned windowsize, unsigned fragsize, int dir);
|
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);
|
size_t window_buffer_available(struct frag_buffer *w);
|
||||||
|
|
||||||
/* Places a fragment in the window after the last one */
|
/* 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) */
|
/* 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)
|
/* Reassembles first complete sequence of fragments into data. (RECV)
|
||||||
* Returns length of data reassembled, or 0 if no data reassembled */
|
* 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 *);
|
size_t window_sending(struct frag_buffer *w, struct timeval *);
|
||||||
|
|
||||||
/* Returns next fragment to be sent or NULL if nothing (SEND) */
|
/* 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) */
|
/* Gets the seqid of next fragment to be ACK'd (RECV) */
|
||||||
int window_get_next_ack(struct frag_buffer *w);
|
int window_get_next_ack(struct frag_buffer *w);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user