-
Notifications
You must be signed in to change notification settings - Fork 10
/
katz.h
184 lines (153 loc) · 5.29 KB
/
katz.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* Copyright (C) 2012 Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*
* This file is part of katz.
*
* katz is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* katz is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with katz. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <sys/time.h>
#include <time.h>
// TODO:
// - BUF_SIZE:
// 548 is the minimum UDP payload that will always come through
// according to stevens, this is nonsense of course.
// 1) the IP header is variably long,
// 2) hardware that shitty is pretty rare.
// -> use sensible default (1500 - pppoe - max avg ip - udp - katz)
//
// - TIMEOUT should be derived from RTT
// - MIN_SLEEP probably also needs some tuning
#define BUF_SIZE 1000 // XXX: make sure net code can deal with larger packets
#define DEFAULT_BW -1 // bw throttle in bytes/sec, -1 to disable
#define MIN_SLEEP 25 // to prevent wasting CPU for overly exact bw throttling
#define TIMEOUT 200 // when expecting data
#define KEEPALIVE 5000 // when not expecting data
#define MAXQLEN 200 // default window size
/**********************************************************************
**********************************************************************
DATASTRUCTURES
**********************************************************************
**********************************************************************/
#define KNIL 0
#define KSYN 1
#define KACK 2
#define KFIN 3
#define KSI 0
#define KSO 1
#define KFI 2
#define KFO 3
struct katzpack {
uint32_t seq;
uint32_t ack;
uint8_t flag;
char* data;
};
#define KPHSIZE 9
struct katzq {
char *data;
int len;
int seq;
struct timespec sent;
struct katzq *next;
};
struct katzconn {
int sock;
// protocol state
uint32_t seq;
uint32_t lar_count; /* last ack received count */
uint32_t ack;
uint8_t flag;
int keepalive; // how often to send packets in light of no traffic at all
int timeout; // time after which a packet is deemed lost
struct timespec
last_event; // time of last recv/send for use with keepalive
uint32_t dups; // duplicate counter
uint32_t ooo; // counts >1 completing deliveries
// bandwidth state
int bwlim;
int bwrate;
time_t last_check;
// used to enable/disable based on protocoll state
struct pollfd *ipfd;
struct pollfd *opfd;
// data buffers
struct katzq *oq;
struct katzq *oq_last;
/* always set to first unsent packet in oq: */
struct katzq *oq_unsent;
/* always set to next packet in oq to timeout: */
struct katzq *oq_timeout;
uint32_t n_oq;
uint32_t oq_maxlen; // aka winsize
struct katzq *iq;
uint32_t n_iq;
uint32_t iq_seq_ready;
int outstanding_ack;
uint32_t iq_size;
// TODO: implement recv win?
};
struct katzparm {
//char *srchost;
char *srcport;
char *dsthost;
char *dstport;
int ai_family;
int keepalive;
int timeout;
int oq_maxlen;
int bw;
};
/**
* Return difference between (struct timespec*) t2 and t1.
* (The result is positive if t1 is older than t2)
*/
#define m_tsm(t1, t2) \
( \
((t2)->tv_sec - (t1)->tv_sec)*1000 \
+ ((t2)->tv_nsec - (t1)->tv_nsec)/1000000 \
)
const char* event_name(int event);
void print_katzq(struct katzq *q);
void print_katzpack(struct katzpack *p);
void print_katzconn(struct katzconn *conn);
inline struct katzq *free_katzq(struct katzq *q);
inline void katzconn_process_ack(struct katzconn *conn, int ack);
inline void katzconn_insert_oq(struct katzconn *conn, char *data, int len);
inline struct katzq *katzconn_getq(struct katzconn *conn);
inline int katzconn_currate (struct katzconn *conn);
inline int katzconn_allow (struct katzconn *conn);
inline int katzconn_sleep (struct katzconn *conn, int len);
inline int katzconn_keepalive(struct katzconn *conn);
int katzpack_recvmsg(int sock, struct katzpack *p);
int katzpack_sendmsg(struct katzconn *conn, struct katzpack *p, int len);
int katz_process_out(struct katzconn *conn);
int katz_process_in(struct katzconn *conn);
int bind_socket(
int sock, struct addrinfo *remotehints,
char *localport);
int connected_udp_socket(struct katzparm *kp);
int katz_read(struct katzconn *conn, char *buf, int len);
int katz_write(struct katzconn *conn, char *buf, int len);
int katz_connect(struct katzconn *conn);
void katz_disconnect(struct katzconn *conn);
void katz_init_connection(
struct katzconn *conn, struct katzparm *kp,
struct pollfd *ipfd, struct pollfd *opfd);
void katz_peer(struct katzparm *kp);
#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...) ((void) 0)
#endif