]> git.lizzy.rs Git - rudp.git/blob - rudp_imp.h
Switch to CMake
[rudp.git] / rudp_imp.h
1 #ifndef __rudp_imp_h__
2 #define __rudp_imp_h__
3
4 #include "basetype.h"
5 #include "linux_list.h"
6 #include "platform_adpt.h"
7
8
9 #ifndef BYTE_ORDER
10 #define BYTE_ORDER LITTLE_ENDIAN
11 #endif
12
13 #define RUDP_HEADER_TAG         3
14 #define MAX_LOSS_REPORT         63      //6 bits
15 #define MAX_WINDOW              4095    //12 bits
16
17 //rudp packet header: 16 bytes
18 struct rudp_hdr {
19         union {
20                 uint32_t u32_flags;
21                 /*
22                 struct {
23                         uint8_t tag;
24                         uint8_t flags;
25                         uint8_t window;
26                         uint8_t chno;
27                 } u8_flags;
28                 */
29                 struct {
30                         //little endian
31 #if BYTE_ORDER == LITTLE_ENDIAN
32                         uint32_t        chno:8;
33                         uint32_t        window:12;
34                         uint32_t        n_loss:6;       //number of lost packets from "ackno". all packets before ackno are confirmed
35                         uint32_t        ack:1;          //0: no ack; 1: accumulated ack
36                         uint32_t        rst:1;
37                         uint32_t        fin:1;
38                         uint32_t        syn:1;
39                         uint32_t        rudp:2;         //RUDP_HEADER_TAG
40 #else
41                         uint32_t        rudp:2;
42                         uint32_t        syn:1;
43                         uint32_t        fin:1;
44                         uint32_t        rst:1;
45                         uint32_t        ack:1;
46                         uint32_t        n_loss:6;
47                         uint32_t        window:12;      //counted by packages
48                         uint32_t        chno:8;
49 #endif
50
51                 } flags;
52         };
53
54         uint32_t        seqno;          //
55         uint32_t        ackno;          //Ackknowlage all packets BEFORE "ackno". !!!
56
57         uint32_t        crc32;  //crc32 for header
58 };
59 #define PHY_HDR_CHN(hdr) (hdr.flags.chno&1)
60 #define PHY_CHN(chno) ((chno)&1)
61
62 //for 8bits window value
63 #define WINDOW_NTOH(window)     window
64 #define WINDOW_HTON(window)     window
65 //for 16bits window value
66 //#define WINDOW_NTOH(window)   ntohs(window)
67 //#define WINDOW_HTON(window)   htons(window)
68
69
70 //1456 = 1492(IEEE802.2) - 20(Ethernet) - 8(UDP) - 8(PPPoE) - ?
71 #define MAX_PACKET_SIZE 1448
72 #define MAX_DATA_SIZE   (MAX_PACKET_SIZE-sizeof(struct rudp_hdr))
73 struct rudp_pkt {
74         struct rudp_pkt *next;
75
76         //data for sending
77         uint32_t  seqno;                //=ntohl(hdr.seqno), for quick reference
78         unsigned int ts;        //timestamp when sending
79
80         int     trans;          //transmission count
81         int priority;
82
83         int     len;            //length of data, exclude hdr
84         unsigned char *pdata;   //=data by default, move ahead when RUDPRecv is called and partial data in this packet are read out
85         //-----------------
86         struct rudp_hdr hdr;
87         unsigned char data[MAX_DATA_SIZE];
88 };
89
90
91 typedef enum {
92         RS_DEAD = -1,   //all resources except the pointer to rudp_socket itself are freed, only RUDPClose() is allowed
93         RS_CLOSED = 0,  //initally created or accepted
94         RS_LISTEN,
95         RS_SYN_SENT,
96         RS_SYN_RCVD,
97         RS_ESTABLISHED,
98         RS_CLOSE_WAIT,
99         RS_FIN_QUEUED,
100         RS_FIN_WAIT_1,
101         RS_FIN_WAIT_2,
102         RS_CLOSING,
103         RS_TIME_WAIT
104 } RUDPSTATE;
105
106 //----------------------------------------------
107 //
108 // 500ms TIMERs Used in RUDP PCB
109 //  
110 // RT_xxx are for socket, RCT_xxx are for channel
111 //
112 #define RT_KEEP         0
113 #define RT_2MSL         1
114 #define RT_CNT  2
115
116 #define RCT_PERSIST     0
117 #define RCT_REXMT       1
118 #define RCT_CNT 2
119
120 #define RUDPT_RANGESET(tv, value, tvmin, tvmax) { \
121         (tv) = (value); \
122         if ((tv) < (tvmin)) \
123                 (tv) = (tvmin); \
124         else if ((tv) > (tvmax)) \
125                 (tv) = (tvmax); \
126 }
127
128 #define RTV_KEEP_INIT   15
129 #define RTV_REXMTMIN    2
130 #define RTV_REXMTMAX    128
131 #define RTV_PERSMIN     10
132 #define RTV_PERSMAX     120
133 #define RTV_KEEP_CLOSE  5
134 //----------------------------------------------
135
136
137 #define SEQ_LT(a,b) ((int)((a) - (b)) < 0)
138 #define SEQ_LE(a,b) ((int)((a) - (b)) <= 0)
139 #define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
140 #define SEQ_GE(a,b) ((int)((a) - (b)) >= 0)
141
142
143 /*  Buffer size of RUDP.
144  *
145  *  One have to respect to the UDP buffer 
146  *  size (SO_SNDBUF, SO_RCVBUF)
147  */
148 #define DEFAULT_SNDBUF_SIZE     128
149 #define DEFAULT_RCVBUF_SIZE     128     
150 struct sndbuf {
151         uint32_t        seqno;
152         int     max_pkts;       //OPT_RCVBUF
153         int     n_pkt;          /*packets in queue*/
154         int     n_unacked;
155         struct rudp_pkt *first, *last;
156         struct rudp_pkt *not_sent;      //first unsent packet
157         struct rudp_pkt *rexmt; //fast retransmit
158
159
160         int     rawnd;          //receiver's advertised window in ack
161         int     rwnd;           //keeping counted receiver's window, updated as packet is sent or ack is received
162
163         int     rlost;          //receiver reports how many packets are expected to be re-transmitted
164
165
166         /* counter for continuously duplicated acks, 
167          * fast-retransmission starts when reach 3
168          */
169         int     dup_ack;
170         uint32_t        fastretr_end_seq;       //fast re-transmission stop untill this seqno
171
172         // RTT measurement
173         int             stop_rttm;              //stop rtt measurement
174         struct rudp_pkt *pkt_rttm_start;        //rtt measurement resumes from pkt_rttm_start after any re-transmissions
175 };
176
177 struct rcvbuf {
178         uint32_t        first_seq;      //first seq in queue. this seq is pointed by "head"
179         uint32_t        expected_seqno; //expected seqno
180         uint32_t        acked_seqno;    //ACK is sent when delay-time(DELAYED_MS) passed, or at most N(=3?) packets(or N*MSS bytes) received.
181         int     should_ack;     //new packet arrived, should send ack
182         int     n_lost;         //size of first gap(probably lost)
183
184         int     q_size; //OPT_SNBUF
185         struct rudp_pkt **pkt_q;        //size = q_size. A cycle buffer traced by head/tail
186         int     head;   //first packet or first lost packet in buffer
187         int     loss;   //first lost packet, or "tail"
188         int     tail;   //one after the packet with max seqno
189         int     win;    //receiver's window (q_size + head - tail - 1) % q_size, send in every output packet and ACK
190
191         /* queue for channels */
192 };
193
194 struct rudp_channel {
195         int     timer[RCT_CNT]; 
196         int     congested;
197         struct sndbuf   sbuf;
198         struct rcvbuf   rbuf;
199 };
200
201
202 #define MAX_PHY_CHANNELS        2
203 #define MAX_LOG_CHANNELS        128
204 struct rudp_pcb {
205         struct sockaddr_in      local;
206         struct sockaddr_in      peer;
207
208         /* Congestion Control */
209         /*  ca_cnt: congestion avoidance counter. 
210          *         In the progress of congestion avoidance, plus 1 
211          *         when each ACK arrives, when "ca_cnt" reach "cwnd", 
212          *         reset "ca_cnt" and increase "cwnd" by one. 
213          */
214         int     ca_cnt;
215         int     cwnd;           //congestion window
216         int     ssthresh;       //slow start threshold
217
218
219         /* RTO */
220         int     srtt;           //smoothed RTT
221         int     sdev;           //smoothed deviation, or "rttvar"
222         int     rto;            //retransmission timeout
223
224
225         int     rwin_size;      //receiver's win size. keep unchanged after connection is established
226         int     rtw_size;       //receiver's realtime win size
227         struct rudp_channel     channel[MAX_PHY_CHANNELS];
228
229
230         int     retr_cnt;       // Count of SYN or SYN&ACK sent when connection establishment
231 };
232
233 struct rudp_socket;
234 typedef void (*_NONRUDPPACKETCB)(const uint8_t *buff, int len, void *p_user);
235
236 #define RUDP_SOCKET_TAG         0x50445552      //'RUDP'
237 #define RF_ADHOC        0x00000001
238 #define RF_NBLK         0x00000002
239 struct rudp_socket {
240         unsigned int tag;       //'RUDP'
241
242         /* rudp_socket created by RUDPSocket/RUDPBindUdpSocket are
243          * linked with the inst_list chain(pointed by a global list header)
244          */
245         struct list_head inst_list;
246
247         /* rudp_socket return by RUDPAccept are linked to the listening socket's accepted_list. 
248          *
249          * If the listening socket is closed, the first accepted socket take place of 
250          * the listening socket(move into the inst_list chain). 
251          *
252          * "udp_sock" is shared by the sockets in the accepted_list chain, it is closed 
253          * only when accepted_list is empty.
254          */
255         struct list_head accepted_list; 
256
257         /* sockets not accepted by RUDPAccept(...) are placed in a seperated chain,
258          * it's easy to be found when accepted and when the listening socket is closing
259          */
260         struct list_head listen_queue; 
261
262
263         int     udp_sock;
264         BOOL    connected;      //called connect() on udp socket(client socket only)
265
266         int     state;  //RUDPSTATE, refer to TCP's FSM
267         int     timer[RT_CNT];
268
269         struct rudp_pcb *pcb;           //for
270
271         PA_MUTEX        mutex_r, mutex_w;
272 #ifdef _WIN32
273         HANDLE  event_r, event_w;
274 #else
275         pthread_cond_t event_r, event_w;
276 #endif
277         int     flags;
278
279         int     rcvbuf_sz; //size of recv buffer, change before connection. OPT_RUDP_RCVBUF
280
281
282         int err;
283
284         //------------
285         _NONRUDPPACKETCB non_rudp_pkt_cb;
286         void            *p_user;
287 };
288
289 #endif
290