kcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/kcp/ikcp.c ADDED
@@ -0,0 +1,1423 @@
1
+ //=====================================================================
2
+ //
3
+ // KCP - A Better ARQ Protocol Implementation
4
+ // skywind3000 (at) gmail.com, 2010-2011
5
+ //
6
+ // Features:
7
+ // + Average RTT reduce 30% - 40% vs traditional ARQ like tcp.
8
+ // + Maximum RTT reduce three times vs tcp.
9
+ // + Lightweight, distributed as a single source file.
10
+ //
11
+ //=====================================================================
12
+ #include "ikcp.h"
13
+
14
+ #include <stddef.h>
15
+ #include <stdlib.h>
16
+ #include <string.h>
17
+ #include <stdarg.h>
18
+ #include <stdio.h>
19
+
20
+ #define IKCP_FASTACK_CONSERVE
21
+
22
+ //=====================================================================
23
+ // KCP BASIC
24
+ //=====================================================================
25
+ const IUINT32 IKCP_RTO_NDL = 30; // no delay min rto
26
+ const IUINT32 IKCP_RTO_MIN = 100; // normal min rto
27
+ const IUINT32 IKCP_RTO_DEF = 200;
28
+ const IUINT32 IKCP_RTO_MAX = 60000;
29
+ const IUINT32 IKCP_CMD_PUSH = 81; // cmd: push data
30
+ const IUINT32 IKCP_CMD_ACK = 82; // cmd: ack
31
+ const IUINT32 IKCP_CMD_WASK = 83; // cmd: window probe (ask)
32
+ const IUINT32 IKCP_CMD_WINS = 84; // cmd: window size (tell)
33
+ const IUINT32 IKCP_ASK_SEND = 1; // need to send IKCP_CMD_WASK
34
+ const IUINT32 IKCP_ASK_TELL = 2; // need to send IKCP_CMD_WINS
35
+ const IUINT32 IKCP_WND_SND = 32;
36
+ const IUINT32 IKCP_WND_RCV = 128; // must >= max fragment size
37
+ const IUINT32 IKCP_MTU_DEF = 1400;
38
+ const IUINT32 IKCP_ACK_FAST = 3;
39
+ const IUINT32 IKCP_INTERVAL = 100;
40
+ const IUINT32 IKCP_OVERHEAD = 24;
41
+ const IUINT32 IKCP_DEADLINK = 20;
42
+ const IUINT32 IKCP_THRESH_INIT = 2;
43
+ const IUINT32 IKCP_THRESH_MIN = 2;
44
+ const IUINT32 IKCP_PROBE_INIT = 5000; // 7 secs to probe window size
45
+ const IUINT32 IKCP_PROBE_LIMIT = 120000; // up to 120 secs to probe window
46
+ const IUINT32 IKCP_FASTACK_LIMIT = 5; // max times to trigger fastack
47
+
48
+
49
+ //---------------------------------------------------------------------
50
+ // encode / decode
51
+ //---------------------------------------------------------------------
52
+
53
+ /* encode 8 bits unsigned int */
54
+ static inline char *ikcp_encode8u(char *p, unsigned char c)
55
+ {
56
+ *(unsigned char*)p++ = c;
57
+ return p;
58
+ }
59
+
60
+ /* decode 8 bits unsigned int */
61
+ static inline const char *ikcp_decode8u(const char *p, unsigned char *c)
62
+ {
63
+ *c = *(unsigned char*)p++;
64
+ return p;
65
+ }
66
+
67
+ /* encode 16 bits unsigned int (lsb) */
68
+ static inline char *ikcp_encode16u(char *p, unsigned short w)
69
+ {
70
+ #if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN
71
+ *(unsigned char*)(p + 0) = (w & 255);
72
+ *(unsigned char*)(p + 1) = (w >> 8);
73
+ #else
74
+ memcpy(p, &w, 2);
75
+ #endif
76
+ p += 2;
77
+ return p;
78
+ }
79
+
80
+ /* decode 16 bits unsigned int (lsb) */
81
+ static inline const char *ikcp_decode16u(const char *p, unsigned short *w)
82
+ {
83
+ #if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN
84
+ *w = *(const unsigned char*)(p + 1);
85
+ *w = *(const unsigned char*)(p + 0) + (*w << 8);
86
+ #else
87
+ memcpy(w, p, 2);
88
+ #endif
89
+ p += 2;
90
+ return p;
91
+ }
92
+
93
+ /* encode 32 bits unsigned int (lsb) */
94
+ static inline char *ikcp_encode32u(char *p, IUINT32 l)
95
+ {
96
+ #if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN
97
+ *(unsigned char*)(p + 0) = (unsigned char)((l >> 0) & 0xff);
98
+ *(unsigned char*)(p + 1) = (unsigned char)((l >> 8) & 0xff);
99
+ *(unsigned char*)(p + 2) = (unsigned char)((l >> 16) & 0xff);
100
+ *(unsigned char*)(p + 3) = (unsigned char)((l >> 24) & 0xff);
101
+ #else
102
+ memcpy(p, &l, 4);
103
+ #endif
104
+ p += 4;
105
+ return p;
106
+ }
107
+
108
+ /* decode 32 bits unsigned int (lsb) */
109
+ static inline const char *ikcp_decode32u(const char *p, IUINT32 *l)
110
+ {
111
+ #if IWORDS_BIG_ENDIAN || IWORDS_MUST_ALIGN
112
+ *l = *(const unsigned char*)(p + 3);
113
+ *l = *(const unsigned char*)(p + 2) + (*l << 8);
114
+ *l = *(const unsigned char*)(p + 1) + (*l << 8);
115
+ *l = *(const unsigned char*)(p + 0) + (*l << 8);
116
+ #else
117
+ memcpy(l, p, 4);
118
+ #endif
119
+ p += 4;
120
+ return p;
121
+ }
122
+
123
+ static inline IUINT32 _imin_(IUINT32 a, IUINT32 b) {
124
+ return a <= b ? a : b;
125
+ }
126
+
127
+ static inline IUINT32 _imax_(IUINT32 a, IUINT32 b) {
128
+ return a >= b ? a : b;
129
+ }
130
+
131
+ static inline IUINT32 _ibound_(IUINT32 lower, IUINT32 middle, IUINT32 upper)
132
+ {
133
+ return _imin_(_imax_(lower, middle), upper);
134
+ }
135
+
136
+ static inline long _itimediff(IUINT32 later, IUINT32 earlier)
137
+ {
138
+ return ((IINT32)(later - earlier));
139
+ }
140
+
141
+ //---------------------------------------------------------------------
142
+ // manage segment
143
+ //---------------------------------------------------------------------
144
+ typedef struct IKCPSEG IKCPSEG;
145
+
146
+ static void* (*ikcp_malloc_hook)(size_t) = NULL;
147
+ static void (*ikcp_free_hook)(void *) = NULL;
148
+
149
+ // internal malloc
150
+ static void* ikcp_malloc(size_t size) {
151
+ if (ikcp_malloc_hook)
152
+ return ikcp_malloc_hook(size);
153
+ return malloc(size);
154
+ }
155
+
156
+ // internal free
157
+ static void ikcp_free(void *ptr) {
158
+ if (ikcp_free_hook) {
159
+ ikcp_free_hook(ptr);
160
+ } else {
161
+ free(ptr);
162
+ }
163
+ }
164
+
165
+ // redefine allocator
166
+ void ikcp_allocator(void* (*new_malloc)(size_t), void (*new_free)(void*))
167
+ {
168
+ ikcp_malloc_hook = new_malloc;
169
+ ikcp_free_hook = new_free;
170
+ }
171
+
172
+ // allocate a new kcp segment
173
+ static IKCPSEG* ikcp_segment_new(ikcpcb *kcp, int size)
174
+ {
175
+ return (IKCPSEG*)ikcp_malloc(sizeof(IKCPSEG) + size);
176
+ }
177
+
178
+ // delete a segment
179
+ static void ikcp_segment_delete(ikcpcb *kcp, IKCPSEG *seg)
180
+ {
181
+ ikcp_free(seg);
182
+ }
183
+
184
+ // write log
185
+ void ikcp_log(ikcpcb *kcp, int mask, const char *fmt, ...)
186
+ {
187
+ char buffer[1024];
188
+ va_list argptr;
189
+ if ((mask & kcp->logmask) == 0 || kcp->writelog == 0) return;
190
+ va_start(argptr, fmt);
191
+ vsprintf(buffer, fmt, argptr);
192
+ va_end(argptr);
193
+ kcp->writelog(buffer, kcp, kcp->user);
194
+ }
195
+
196
+ // check log mask
197
+ static int ikcp_canlog(const ikcpcb *kcp, int mask)
198
+ {
199
+ if ((mask & kcp->logmask) == 0 || kcp->writelog == NULL) return 0;
200
+ return 1;
201
+ }
202
+
203
+ // output segment
204
+ static int ikcp_output(ikcpcb *kcp, const void *data, int size)
205
+ {
206
+ assert(kcp);
207
+ assert(kcp->output);
208
+ if (ikcp_canlog(kcp, IKCP_LOG_OUTPUT)) {
209
+ ikcp_log(kcp, IKCP_LOG_OUTPUT, "[RO] %ld bytes", (long)size);
210
+ }
211
+ if (size == 0) return 0;
212
+ return kcp->output((const char*)data, size, kcp, kcp->user);
213
+ }
214
+
215
+ // output queue
216
+ void ikcp_qprint(const char *name, const struct IQUEUEHEAD *head)
217
+ {
218
+ #if 0
219
+ const struct IQUEUEHEAD *p;
220
+ printf("<%s>: [", name);
221
+ for (p = head->next; p != head; p = p->next) {
222
+ const IKCPSEG *seg = iqueue_entry(p, const IKCPSEG, node);
223
+ printf("(%lu %d)", (unsigned long)seg->sn, (int)(seg->ts % 10000));
224
+ if (p->next != head) printf(",");
225
+ }
226
+ printf("]\n");
227
+ #endif
228
+ }
229
+
230
+
231
+ //---------------------------------------------------------------------
232
+ // create a new kcpcb
233
+ //---------------------------------------------------------------------
234
+ ikcpcb* ikcp_create(IUINT32 conv, void *user)
235
+ {
236
+ ikcpcb *kcp = (ikcpcb*)ikcp_malloc(sizeof(struct IKCPCB));
237
+ if (kcp == NULL) return NULL;
238
+ kcp->conv = conv;
239
+ kcp->user = user;
240
+ kcp->snd_una = 0;
241
+ kcp->snd_nxt = 0;
242
+ kcp->rcv_nxt = 0;
243
+ kcp->ts_recent = 0;
244
+ kcp->ts_lastack = 0;
245
+ kcp->ts_probe = 0;
246
+ kcp->probe_wait = 0;
247
+ kcp->snd_wnd = IKCP_WND_SND;
248
+ kcp->rcv_wnd = IKCP_WND_RCV;
249
+ kcp->rmt_wnd = IKCP_WND_RCV;
250
+ kcp->cwnd = 0;
251
+ kcp->incr = 0;
252
+ kcp->probe = 0;
253
+ kcp->mtu = IKCP_MTU_DEF;
254
+ kcp->mss = kcp->mtu - IKCP_OVERHEAD;
255
+ kcp->stream = 0;
256
+
257
+ kcp->buffer = (char*)ikcp_malloc((kcp->mtu + IKCP_OVERHEAD) * 3);
258
+ if (kcp->buffer == NULL) {
259
+ ikcp_free(kcp);
260
+ return NULL;
261
+ }
262
+
263
+ iqueue_init(&kcp->snd_queue);
264
+ iqueue_init(&kcp->rcv_queue);
265
+ iqueue_init(&kcp->snd_buf);
266
+ iqueue_init(&kcp->rcv_buf);
267
+ kcp->nrcv_buf = 0;
268
+ kcp->nsnd_buf = 0;
269
+ kcp->nrcv_que = 0;
270
+ kcp->nsnd_que = 0;
271
+ kcp->state = 0;
272
+ kcp->acklist = NULL;
273
+ kcp->ackblock = 0;
274
+ kcp->ackcount = 0;
275
+ kcp->ackedlen = 0;
276
+ kcp->rx_srtt = 0;
277
+ kcp->rx_rttval = 0;
278
+ kcp->rx_rto = IKCP_RTO_DEF;
279
+ kcp->rx_minrto = IKCP_RTO_MIN;
280
+ kcp->current = 0;
281
+ kcp->interval = IKCP_INTERVAL;
282
+ kcp->ts_flush = IKCP_INTERVAL;
283
+ kcp->nodelay = 0;
284
+ kcp->updated = 0;
285
+ kcp->logmask = 0;
286
+ kcp->ssthresh = IKCP_THRESH_INIT;
287
+ kcp->fastresend = 0;
288
+ kcp->fastlimit = IKCP_FASTACK_LIMIT;
289
+ kcp->nocwnd = 0;
290
+ kcp->xmit = 0;
291
+ kcp->dead_link = IKCP_DEADLINK;
292
+ kcp->output = NULL;
293
+ kcp->ccops = NULL;
294
+ kcp->congest = NULL;
295
+ kcp->writelog = NULL;
296
+
297
+ return kcp;
298
+ }
299
+
300
+
301
+ //---------------------------------------------------------------------
302
+ // release a kcpcb
303
+ //---------------------------------------------------------------------
304
+ void ikcp_release(ikcpcb *kcp)
305
+ {
306
+ IKCPSEG *seg;
307
+ assert(kcp);
308
+ if (kcp) {
309
+ if (kcp->ccops && kcp->ccops->release) {
310
+ kcp->ccops->release(kcp);
311
+ }
312
+ while (!iqueue_is_empty(&kcp->snd_buf)) {
313
+ seg = iqueue_entry(kcp->snd_buf.next, IKCPSEG, node);
314
+ iqueue_del(&seg->node);
315
+ ikcp_segment_delete(kcp, seg);
316
+ }
317
+ while (!iqueue_is_empty(&kcp->rcv_buf)) {
318
+ seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
319
+ iqueue_del(&seg->node);
320
+ ikcp_segment_delete(kcp, seg);
321
+ }
322
+ while (!iqueue_is_empty(&kcp->snd_queue)) {
323
+ seg = iqueue_entry(kcp->snd_queue.next, IKCPSEG, node);
324
+ iqueue_del(&seg->node);
325
+ ikcp_segment_delete(kcp, seg);
326
+ }
327
+ while (!iqueue_is_empty(&kcp->rcv_queue)) {
328
+ seg = iqueue_entry(kcp->rcv_queue.next, IKCPSEG, node);
329
+ iqueue_del(&seg->node);
330
+ ikcp_segment_delete(kcp, seg);
331
+ }
332
+ if (kcp->buffer) {
333
+ ikcp_free(kcp->buffer);
334
+ }
335
+ if (kcp->acklist) {
336
+ ikcp_free(kcp->acklist);
337
+ }
338
+
339
+ kcp->nrcv_buf = 0;
340
+ kcp->nsnd_buf = 0;
341
+ kcp->nrcv_que = 0;
342
+ kcp->nsnd_que = 0;
343
+ kcp->ackcount = 0;
344
+ kcp->buffer = NULL;
345
+ kcp->acklist = NULL;
346
+ ikcp_free(kcp);
347
+ }
348
+ }
349
+
350
+
351
+ //---------------------------------------------------------------------
352
+ // set output callback, which will be invoked by kcp
353
+ //---------------------------------------------------------------------
354
+ void ikcp_setoutput(ikcpcb *kcp, int (*output)(const char *buf, int len,
355
+ ikcpcb *kcp, void *user))
356
+ {
357
+ kcp->output = output;
358
+ }
359
+
360
+
361
+ //---------------------------------------------------------------------
362
+ // upper-level recv: returns size, or a negative value for EAGAIN
363
+ //---------------------------------------------------------------------
364
+ int ikcp_recv(ikcpcb *kcp, char *buffer, int len)
365
+ {
366
+ struct IQUEUEHEAD *p;
367
+ int ispeek = (len < 0)? 1 : 0;
368
+ int peeksize;
369
+ int recover = 0;
370
+ IKCPSEG *seg;
371
+ assert(kcp);
372
+
373
+ if (iqueue_is_empty(&kcp->rcv_queue))
374
+ return -1;
375
+
376
+ if (len < 0) len = -len;
377
+
378
+ peeksize = ikcp_peeksize(kcp);
379
+
380
+ if (peeksize < 0)
381
+ return -2;
382
+
383
+ if (peeksize > len)
384
+ return -3;
385
+
386
+ if (kcp->nrcv_que >= kcp->rcv_wnd)
387
+ recover = 1;
388
+
389
+ // merge fragment
390
+ for (len = 0, p = kcp->rcv_queue.next; p != &kcp->rcv_queue; ) {
391
+ int fragment;
392
+ seg = iqueue_entry(p, IKCPSEG, node);
393
+ p = p->next;
394
+
395
+ if (buffer) {
396
+ memcpy(buffer, seg->data, seg->len);
397
+ buffer += seg->len;
398
+ }
399
+
400
+ len += seg->len;
401
+ fragment = seg->frg;
402
+
403
+ if (ikcp_canlog(kcp, IKCP_LOG_RECV)) {
404
+ ikcp_log(kcp, IKCP_LOG_RECV, "recv sn=%lu", (unsigned long)seg->sn);
405
+ }
406
+
407
+ if (ispeek == 0) {
408
+ iqueue_del(&seg->node);
409
+ ikcp_segment_delete(kcp, seg);
410
+ kcp->nrcv_que--;
411
+ }
412
+
413
+ if (fragment == 0)
414
+ break;
415
+ }
416
+
417
+ assert(len == peeksize);
418
+
419
+ // move available data from rcv_buf -> rcv_queue
420
+ while (! iqueue_is_empty(&kcp->rcv_buf)) {
421
+ seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
422
+ if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) {
423
+ iqueue_del(&seg->node);
424
+ kcp->nrcv_buf--;
425
+ iqueue_add_tail(&seg->node, &kcp->rcv_queue);
426
+ kcp->nrcv_que++;
427
+ kcp->rcv_nxt++;
428
+ } else {
429
+ break;
430
+ }
431
+ }
432
+
433
+ // fast recover
434
+ if (kcp->nrcv_que < kcp->rcv_wnd && recover) {
435
+ // ready to send back IKCP_CMD_WINS in ikcp_flush
436
+ // tell remote my window size
437
+ kcp->probe |= IKCP_ASK_TELL;
438
+ }
439
+
440
+ return len;
441
+ }
442
+
443
+
444
+ //---------------------------------------------------------------------
445
+ // peek data size
446
+ //---------------------------------------------------------------------
447
+ int ikcp_peeksize(const ikcpcb *kcp)
448
+ {
449
+ struct IQUEUEHEAD *p;
450
+ IKCPSEG *seg;
451
+ int length = 0;
452
+
453
+ assert(kcp);
454
+
455
+ if (iqueue_is_empty(&kcp->rcv_queue)) return -1;
456
+
457
+ seg = iqueue_entry(kcp->rcv_queue.next, IKCPSEG, node);
458
+ if (seg->frg == 0) return seg->len;
459
+
460
+ if (kcp->nrcv_que < seg->frg + 1) return -1;
461
+
462
+ for (p = kcp->rcv_queue.next; p != &kcp->rcv_queue; p = p->next) {
463
+ seg = iqueue_entry(p, IKCPSEG, node);
464
+ length += seg->len;
465
+ if (seg->frg == 0) break;
466
+ }
467
+
468
+ return length;
469
+ }
470
+
471
+
472
+ //---------------------------------------------------------------------
473
+ // upper-level send: returns size, or a negative value on error
474
+ //---------------------------------------------------------------------
475
+ int ikcp_send(ikcpcb *kcp, const char *buffer, int len)
476
+ {
477
+ IKCPSEG *seg;
478
+ int count, i;
479
+ int sent = 0;
480
+
481
+ assert(kcp->mss > 0);
482
+ if (len < 0) return -1;
483
+
484
+ // append to previous segment in streaming mode (if possible)
485
+ if (kcp->stream != 0) {
486
+ if (!iqueue_is_empty(&kcp->snd_queue)) {
487
+ IKCPSEG *old = iqueue_entry(kcp->snd_queue.prev, IKCPSEG, node);
488
+ if (old->len < kcp->mss) {
489
+ int capacity = kcp->mss - old->len;
490
+ int extend = (len < capacity)? len : capacity;
491
+ seg = ikcp_segment_new(kcp, old->len + extend);
492
+ assert(seg);
493
+ if (seg == NULL) {
494
+ return -2;
495
+ }
496
+ iqueue_add_tail(&seg->node, &kcp->snd_queue);
497
+ memcpy(seg->data, old->data, old->len);
498
+ if (buffer) {
499
+ memcpy(seg->data + old->len, buffer, extend);
500
+ buffer += extend;
501
+ }
502
+ seg->len = old->len + extend;
503
+ seg->frg = 0;
504
+ len -= extend;
505
+ iqueue_del_init(&old->node);
506
+ ikcp_segment_delete(kcp, old);
507
+ sent = extend;
508
+ }
509
+ }
510
+ if (len <= 0) {
511
+ return sent;
512
+ }
513
+ }
514
+
515
+ if (len <= (int)kcp->mss) count = 1;
516
+ else count = (len + kcp->mss - 1) / kcp->mss;
517
+
518
+ if (count >= (int)IKCP_WND_RCV) {
519
+ if (kcp->stream != 0 && sent > 0)
520
+ return sent;
521
+ return -2;
522
+ }
523
+
524
+ if (count == 0) count = 1;
525
+
526
+ // fragment
527
+ for (i = 0; i < count; i++) {
528
+ int size = len > (int)kcp->mss ? (int)kcp->mss : len;
529
+ seg = ikcp_segment_new(kcp, size);
530
+ assert(seg);
531
+ if (seg == NULL) {
532
+ return -2;
533
+ }
534
+ if (buffer && len > 0) {
535
+ memcpy(seg->data, buffer, size);
536
+ }
537
+ seg->len = size;
538
+ seg->frg = (kcp->stream == 0)? (count - i - 1) : 0;
539
+ iqueue_init(&seg->node);
540
+ iqueue_add_tail(&seg->node, &kcp->snd_queue);
541
+ kcp->nsnd_que++;
542
+ if (buffer) {
543
+ buffer += size;
544
+ }
545
+ len -= size;
546
+ sent += size;
547
+ }
548
+
549
+ return sent;
550
+ }
551
+
552
+
553
+ //---------------------------------------------------------------------
554
+ // parse ack
555
+ //---------------------------------------------------------------------
556
+ static void ikcp_update_ack(ikcpcb *kcp, IINT32 rtt)
557
+ {
558
+ IINT32 rto = 0;
559
+ if (kcp->rx_srtt == 0) {
560
+ kcp->rx_srtt = rtt;
561
+ kcp->rx_rttval = rtt / 2;
562
+ } else {
563
+ long delta = rtt - kcp->rx_srtt;
564
+ if (delta < 0) delta = -delta;
565
+ kcp->rx_rttval = (3 * kcp->rx_rttval + delta) / 4;
566
+ kcp->rx_srtt = (7 * kcp->rx_srtt + rtt) / 8;
567
+ if (kcp->rx_srtt < 1) kcp->rx_srtt = 1;
568
+ }
569
+ rto = kcp->rx_srtt + _imax_(kcp->interval, 4 * kcp->rx_rttval);
570
+ kcp->rx_rto = _ibound_(kcp->rx_minrto, rto, IKCP_RTO_MAX);
571
+ if (kcp->ccops && kcp->ccops->on_rtt) {
572
+ kcp->ccops->on_rtt(kcp, rtt);
573
+ }
574
+ }
575
+
576
+ static void ikcp_shrink_buf(ikcpcb *kcp)
577
+ {
578
+ struct IQUEUEHEAD *p = kcp->snd_buf.next;
579
+ if (p != &kcp->snd_buf) {
580
+ IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
581
+ kcp->snd_una = seg->sn;
582
+ } else {
583
+ kcp->snd_una = kcp->snd_nxt;
584
+ }
585
+ }
586
+
587
+ static void ikcp_parse_ack(ikcpcb *kcp, IUINT32 sn)
588
+ {
589
+ struct IQUEUEHEAD *p, *next;
590
+ IINT32 pkt_rtt;
591
+
592
+ if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0)
593
+ return;
594
+
595
+ for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
596
+ IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
597
+ next = p->next;
598
+ if (sn == seg->sn) {
599
+ kcp->ackedlen += seg->len;
600
+ if (kcp->ccops && kcp->ccops->on_pkt_acked) {
601
+ pkt_rtt = -1;
602
+ if (_itimediff(kcp->current, seg->ts) >= 0) {
603
+ pkt_rtt = _itimediff(kcp->current, seg->ts);
604
+ }
605
+ kcp->ccops->on_pkt_acked(kcp, seg->sn, seg->ts,
606
+ seg->len, pkt_rtt, seg->xmit);
607
+ }
608
+ iqueue_del(p);
609
+ ikcp_segment_delete(kcp, seg);
610
+ kcp->nsnd_buf--;
611
+ break;
612
+ }
613
+ if (_itimediff(sn, seg->sn) < 0) {
614
+ break;
615
+ }
616
+ }
617
+ }
618
+
619
+ static void ikcp_parse_una(ikcpcb *kcp, IUINT32 una)
620
+ {
621
+ struct IQUEUEHEAD *p, *next;
622
+ for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
623
+ IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
624
+ next = p->next;
625
+ if (_itimediff(una, seg->sn) > 0) {
626
+ kcp->ackedlen += seg->len;
627
+ if (kcp->ccops && kcp->ccops->on_pkt_acked) {
628
+ kcp->ccops->on_pkt_acked(kcp, seg->sn, seg->ts,
629
+ seg->len, -1, seg->xmit);
630
+ }
631
+ iqueue_del(p);
632
+ ikcp_segment_delete(kcp, seg);
633
+ kcp->nsnd_buf--;
634
+ } else {
635
+ break;
636
+ }
637
+ }
638
+ }
639
+
640
+ static void ikcp_parse_fastack(ikcpcb *kcp, IUINT32 sn, IUINT32 ts)
641
+ {
642
+ struct IQUEUEHEAD *p, *next;
643
+
644
+ if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0)
645
+ return;
646
+
647
+ for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
648
+ IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
649
+ next = p->next;
650
+ if (_itimediff(sn, seg->sn) < 0) {
651
+ break;
652
+ }
653
+ else if (sn != seg->sn) {
654
+ #ifndef IKCP_FASTACK_CONSERVE
655
+ seg->fastack++;
656
+ #else
657
+ if (_itimediff(ts, seg->ts) >= 0)
658
+ seg->fastack++;
659
+ #endif
660
+ }
661
+ }
662
+ }
663
+
664
+
665
+ //---------------------------------------------------------------------
666
+ // ack append
667
+ //---------------------------------------------------------------------
668
+ static void ikcp_ack_push(ikcpcb *kcp, IUINT32 sn, IUINT32 ts)
669
+ {
670
+ IUINT32 newsize = kcp->ackcount + 1;
671
+ IUINT32 *ptr;
672
+
673
+ if (newsize > kcp->ackblock) {
674
+ IUINT32 *acklist;
675
+ IUINT32 newblock;
676
+
677
+ for (newblock = 8; newblock < newsize; newblock <<= 1);
678
+ acklist = (IUINT32*)ikcp_malloc(newblock * sizeof(IUINT32) * 2);
679
+
680
+ if (acklist == NULL) {
681
+ assert(acklist != NULL);
682
+ abort();
683
+ }
684
+
685
+ if (kcp->acklist != NULL) {
686
+ IUINT32 x;
687
+ for (x = 0; x < kcp->ackcount; x++) {
688
+ acklist[x * 2 + 0] = kcp->acklist[x * 2 + 0];
689
+ acklist[x * 2 + 1] = kcp->acklist[x * 2 + 1];
690
+ }
691
+ ikcp_free(kcp->acklist);
692
+ }
693
+
694
+ kcp->acklist = acklist;
695
+ kcp->ackblock = newblock;
696
+ }
697
+
698
+ ptr = &kcp->acklist[kcp->ackcount * 2];
699
+ ptr[0] = sn;
700
+ ptr[1] = ts;
701
+ kcp->ackcount++;
702
+ }
703
+
704
+ static void ikcp_ack_get(const ikcpcb *kcp, int p, IUINT32 *sn, IUINT32 *ts)
705
+ {
706
+ if (sn) sn[0] = kcp->acklist[p * 2 + 0];
707
+ if (ts) ts[0] = kcp->acklist[p * 2 + 1];
708
+ }
709
+
710
+
711
+ //---------------------------------------------------------------------
712
+ // parse data
713
+ //---------------------------------------------------------------------
714
+ void ikcp_parse_data(ikcpcb *kcp, IKCPSEG *newseg)
715
+ {
716
+ struct IQUEUEHEAD *p, *prev;
717
+ IUINT32 sn = newseg->sn;
718
+ int repeat = 0;
719
+
720
+ if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) >= 0 ||
721
+ _itimediff(sn, kcp->rcv_nxt) < 0) {
722
+ ikcp_segment_delete(kcp, newseg);
723
+ return;
724
+ }
725
+
726
+ for (p = kcp->rcv_buf.prev; p != &kcp->rcv_buf; p = prev) {
727
+ IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
728
+ prev = p->prev;
729
+ if (seg->sn == sn) {
730
+ repeat = 1;
731
+ break;
732
+ }
733
+ if (_itimediff(sn, seg->sn) > 0) {
734
+ break;
735
+ }
736
+ }
737
+
738
+ if (repeat == 0) {
739
+ iqueue_init(&newseg->node);
740
+ iqueue_add(&newseg->node, p);
741
+ kcp->nrcv_buf++;
742
+ } else {
743
+ ikcp_segment_delete(kcp, newseg);
744
+ }
745
+
746
+ #if 0
747
+ ikcp_qprint("rcvbuf", &kcp->rcv_buf);
748
+ printf("rcv_nxt=%lu\n", kcp->rcv_nxt);
749
+ #endif
750
+
751
+ // move available data from rcv_buf -> rcv_queue
752
+ while (! iqueue_is_empty(&kcp->rcv_buf)) {
753
+ IKCPSEG *seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
754
+ if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) {
755
+ iqueue_del(&seg->node);
756
+ kcp->nrcv_buf--;
757
+ iqueue_add_tail(&seg->node, &kcp->rcv_queue);
758
+ kcp->nrcv_que++;
759
+ kcp->rcv_nxt++;
760
+ } else {
761
+ break;
762
+ }
763
+ }
764
+
765
+ #if 0
766
+ ikcp_qprint("queue", &kcp->rcv_queue);
767
+ printf("rcv_nxt=%lu\n", kcp->rcv_nxt);
768
+ #endif
769
+
770
+ #if 1
771
+ // printf("snd(buf=%d, queue=%d)\n", kcp->nsnd_buf, kcp->nsnd_que);
772
+ // printf("rcv(buf=%d, queue=%d)\n", kcp->nrcv_buf, kcp->nrcv_que);
773
+ #endif
774
+ }
775
+
776
+
777
+ //---------------------------------------------------------------------
778
+ // input data
779
+ //---------------------------------------------------------------------
780
+ int ikcp_input(ikcpcb *kcp, const char *data, long size)
781
+ {
782
+ IUINT32 prev_una = kcp->snd_una;
783
+ IUINT32 prev_nsnd_buf = kcp->nsnd_buf;
784
+ IUINT32 acked_segs, prior_in_flight;
785
+ IUINT32 maxack = 0, latest_ts = 0;
786
+ int flag = 0;
787
+
788
+ kcp->ackedlen = 0;
789
+
790
+ if (ikcp_canlog(kcp, IKCP_LOG_INPUT)) {
791
+ ikcp_log(kcp, IKCP_LOG_INPUT, "[RI] %d bytes", (int)size);
792
+ }
793
+
794
+ if (data == NULL || (int)size < (int)IKCP_OVERHEAD) return -1;
795
+
796
+ while (1) {
797
+ IUINT32 ts, sn, len, una, conv;
798
+ IUINT16 wnd;
799
+ IUINT8 cmd, frg;
800
+ IKCPSEG *seg;
801
+
802
+ if (size < (int)IKCP_OVERHEAD) break;
803
+
804
+ data = ikcp_decode32u(data, &conv);
805
+ if (conv != kcp->conv) return -1;
806
+
807
+ data = ikcp_decode8u(data, &cmd);
808
+ data = ikcp_decode8u(data, &frg);
809
+ data = ikcp_decode16u(data, &wnd);
810
+ data = ikcp_decode32u(data, &ts);
811
+ data = ikcp_decode32u(data, &sn);
812
+ data = ikcp_decode32u(data, &una);
813
+ data = ikcp_decode32u(data, &len);
814
+
815
+ size -= IKCP_OVERHEAD;
816
+
817
+ if ((long)size < (long)len || (int)len < 0) return -2;
818
+
819
+ if (cmd != IKCP_CMD_PUSH && cmd != IKCP_CMD_ACK &&
820
+ cmd != IKCP_CMD_WASK && cmd != IKCP_CMD_WINS)
821
+ return -3;
822
+
823
+ kcp->rmt_wnd = wnd;
824
+ ikcp_parse_una(kcp, una);
825
+ ikcp_shrink_buf(kcp);
826
+
827
+ if (cmd == IKCP_CMD_ACK) {
828
+ if (_itimediff(kcp->current, ts) >= 0) {
829
+ ikcp_update_ack(kcp, _itimediff(kcp->current, ts));
830
+ }
831
+ ikcp_parse_ack(kcp, sn);
832
+ ikcp_shrink_buf(kcp);
833
+ if (flag == 0) {
834
+ flag = 1;
835
+ maxack = sn;
836
+ latest_ts = ts;
837
+ } else {
838
+ if (_itimediff(sn, maxack) > 0) {
839
+ #ifndef IKCP_FASTACK_CONSERVE
840
+ maxack = sn;
841
+ latest_ts = ts;
842
+ #else
843
+ if (_itimediff(ts, latest_ts) > 0) {
844
+ maxack = sn;
845
+ latest_ts = ts;
846
+ }
847
+ #endif
848
+ }
849
+ }
850
+ if (ikcp_canlog(kcp, IKCP_LOG_IN_ACK)) {
851
+ ikcp_log(kcp, IKCP_LOG_IN_ACK,
852
+ "input ack: sn=%lu rtt=%ld rto=%ld", (unsigned long)sn,
853
+ (long)_itimediff(kcp->current, ts),
854
+ (long)kcp->rx_rto);
855
+ }
856
+ }
857
+ else if (cmd == IKCP_CMD_PUSH) {
858
+ if (ikcp_canlog(kcp, IKCP_LOG_IN_DATA)) {
859
+ ikcp_log(kcp, IKCP_LOG_IN_DATA,
860
+ "input psh: sn=%lu ts=%lu", (unsigned long)sn, (unsigned long)ts);
861
+ }
862
+ if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) < 0) {
863
+ ikcp_ack_push(kcp, sn, ts);
864
+ if (_itimediff(sn, kcp->rcv_nxt) >= 0) {
865
+ seg = ikcp_segment_new(kcp, len);
866
+ seg->conv = conv;
867
+ seg->cmd = cmd;
868
+ seg->frg = frg;
869
+ seg->wnd = wnd;
870
+ seg->ts = ts;
871
+ seg->sn = sn;
872
+ seg->una = una;
873
+ seg->len = len;
874
+
875
+ if (len > 0) {
876
+ memcpy(seg->data, data, len);
877
+ }
878
+
879
+ ikcp_parse_data(kcp, seg);
880
+ }
881
+ }
882
+ }
883
+ else if (cmd == IKCP_CMD_WASK) {
884
+ // ready to send back IKCP_CMD_WINS in ikcp_flush
885
+ // tell remote my window size
886
+ kcp->probe |= IKCP_ASK_TELL;
887
+ if (ikcp_canlog(kcp, IKCP_LOG_IN_PROBE)) {
888
+ ikcp_log(kcp, IKCP_LOG_IN_PROBE, "input probe");
889
+ }
890
+ }
891
+ else if (cmd == IKCP_CMD_WINS) {
892
+ // do nothing
893
+ if (ikcp_canlog(kcp, IKCP_LOG_IN_WINS)) {
894
+ ikcp_log(kcp, IKCP_LOG_IN_WINS,
895
+ "input wins: %lu", (unsigned long)(wnd));
896
+ }
897
+ }
898
+ else {
899
+ return -3;
900
+ }
901
+
902
+ data += len;
903
+ size -= len;
904
+ }
905
+
906
+ if (flag != 0) {
907
+ ikcp_parse_fastack(kcp, maxack, latest_ts);
908
+ }
909
+
910
+ if (_itimediff(kcp->snd_una, prev_una) > 0) {
911
+ acked_segs = kcp->snd_una - prev_una;
912
+ prior_in_flight = prev_nsnd_buf;
913
+ if (kcp->ccops && kcp->ccops->on_ack) {
914
+ kcp->ccops->on_ack(kcp, acked_segs, kcp->ackedlen,
915
+ prior_in_flight);
916
+ }
917
+ else {
918
+ if (kcp->cwnd < kcp->rmt_wnd) {
919
+ IUINT32 mss = kcp->mss;
920
+ if (kcp->cwnd < kcp->ssthresh) {
921
+ kcp->cwnd++;
922
+ kcp->incr += mss;
923
+ } else {
924
+ if (kcp->incr < mss) kcp->incr = mss;
925
+ kcp->incr += (mss * mss) / kcp->incr + (mss / 16);
926
+ if ((kcp->cwnd + 1) * mss <= kcp->incr) {
927
+ #if 1
928
+ kcp->cwnd = (kcp->incr + mss - 1) / ((mss > 0)? mss : 1);
929
+ #else
930
+ kcp->cwnd++;
931
+ #endif
932
+ }
933
+ }
934
+ if (kcp->cwnd > kcp->rmt_wnd) {
935
+ kcp->cwnd = kcp->rmt_wnd;
936
+ kcp->incr = kcp->rmt_wnd * mss;
937
+ }
938
+ }
939
+ }
940
+ }
941
+
942
+ return 0;
943
+ }
944
+
945
+
946
+ //---------------------------------------------------------------------
947
+ // ikcp_encode_seg
948
+ //---------------------------------------------------------------------
949
+ static char *ikcp_encode_seg(char *ptr, const IKCPSEG *seg)
950
+ {
951
+ ptr = ikcp_encode32u(ptr, seg->conv);
952
+ ptr = ikcp_encode8u(ptr, (IUINT8)seg->cmd);
953
+ ptr = ikcp_encode8u(ptr, (IUINT8)seg->frg);
954
+ ptr = ikcp_encode16u(ptr, (IUINT16)seg->wnd);
955
+ ptr = ikcp_encode32u(ptr, seg->ts);
956
+ ptr = ikcp_encode32u(ptr, seg->sn);
957
+ ptr = ikcp_encode32u(ptr, seg->una);
958
+ ptr = ikcp_encode32u(ptr, seg->len);
959
+ return ptr;
960
+ }
961
+
962
+ static int ikcp_wnd_unused(const ikcpcb *kcp)
963
+ {
964
+ if (kcp->nrcv_que < kcp->rcv_wnd) {
965
+ return kcp->rcv_wnd - kcp->nrcv_que;
966
+ }
967
+ return 0;
968
+ }
969
+
970
+
971
+ //---------------------------------------------------------------------
972
+ // ikcp_flush
973
+ //---------------------------------------------------------------------
974
+ void ikcp_flush(ikcpcb *kcp)
975
+ {
976
+ IUINT32 current = kcp->current;
977
+ char *buffer = kcp->buffer;
978
+ char *ptr = buffer;
979
+ int count, size, i;
980
+ IUINT32 resent, cwnd;
981
+ IUINT32 rtomin;
982
+ IUINT32 prior_cwnd;
983
+ IUINT32 eff_cwnd, cur_inflight;
984
+ IINT32 pacing_budget = -1;
985
+ struct IQUEUEHEAD *p;
986
+ int change = 0;
987
+ int lost = 0;
988
+ IKCPSEG seg;
989
+
990
+ // 'ikcp_update' hasn't been called yet.
991
+ if (kcp->updated == 0) return;
992
+
993
+ if (kcp->ccops && kcp->ccops->on_tick) {
994
+ kcp->ccops->on_tick(kcp);
995
+ }
996
+
997
+ if (kcp->ccops && kcp->ccops->pacing_rate) {
998
+ pacing_budget = (IINT32)kcp->ccops->pacing_rate(kcp);
999
+ }
1000
+
1001
+ prior_cwnd = kcp->cwnd;
1002
+
1003
+ seg.conv = kcp->conv;
1004
+ seg.cmd = IKCP_CMD_ACK;
1005
+ seg.frg = 0;
1006
+ seg.wnd = ikcp_wnd_unused(kcp);
1007
+ seg.una = kcp->rcv_nxt;
1008
+ seg.len = 0;
1009
+ seg.sn = 0;
1010
+ seg.ts = 0;
1011
+
1012
+ // flush acknowledges
1013
+ count = kcp->ackcount;
1014
+ for (i = 0; i < count; i++) {
1015
+ size = (int)(ptr - buffer);
1016
+ if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) {
1017
+ ikcp_output(kcp, buffer, size);
1018
+ ptr = buffer;
1019
+ }
1020
+ ikcp_ack_get(kcp, i, &seg.sn, &seg.ts);
1021
+ ptr = ikcp_encode_seg(ptr, &seg);
1022
+ }
1023
+
1024
+ kcp->ackcount = 0;
1025
+
1026
+ // probe window size (if remote window size equals zero)
1027
+ if (kcp->rmt_wnd == 0) {
1028
+ if (kcp->probe_wait == 0) {
1029
+ kcp->probe_wait = IKCP_PROBE_INIT;
1030
+ kcp->ts_probe = kcp->current + kcp->probe_wait;
1031
+ }
1032
+ else {
1033
+ if (_itimediff(kcp->current, kcp->ts_probe) >= 0) {
1034
+ if (kcp->probe_wait < IKCP_PROBE_INIT)
1035
+ kcp->probe_wait = IKCP_PROBE_INIT;
1036
+ kcp->probe_wait += kcp->probe_wait / 2;
1037
+ if (kcp->probe_wait > IKCP_PROBE_LIMIT)
1038
+ kcp->probe_wait = IKCP_PROBE_LIMIT;
1039
+ kcp->ts_probe = kcp->current + kcp->probe_wait;
1040
+ kcp->probe |= IKCP_ASK_SEND;
1041
+ }
1042
+ }
1043
+ } else {
1044
+ kcp->ts_probe = 0;
1045
+ kcp->probe_wait = 0;
1046
+ }
1047
+
1048
+ // flush window probing commands
1049
+ if (kcp->probe & IKCP_ASK_SEND) {
1050
+ seg.cmd = IKCP_CMD_WASK;
1051
+ size = (int)(ptr - buffer);
1052
+ if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) {
1053
+ ikcp_output(kcp, buffer, size);
1054
+ ptr = buffer;
1055
+ }
1056
+ ptr = ikcp_encode_seg(ptr, &seg);
1057
+ }
1058
+
1059
+ // flush window probing commands
1060
+ if (kcp->probe & IKCP_ASK_TELL) {
1061
+ seg.cmd = IKCP_CMD_WINS;
1062
+ size = (int)(ptr - buffer);
1063
+ if (size + (int)IKCP_OVERHEAD > (int)kcp->mtu) {
1064
+ ikcp_output(kcp, buffer, size);
1065
+ ptr = buffer;
1066
+ }
1067
+ ptr = ikcp_encode_seg(ptr, &seg);
1068
+ }
1069
+
1070
+ kcp->probe = 0;
1071
+
1072
+ // calculate window size
1073
+ cwnd = _imin_(kcp->snd_wnd, kcp->rmt_wnd);
1074
+ if (kcp->ccops != NULL || kcp->nocwnd == 0) cwnd = _imin_(kcp->cwnd, cwnd);
1075
+
1076
+ // move data from snd_queue to snd_buf
1077
+ while (_itimediff(kcp->snd_nxt, kcp->snd_una + cwnd) < 0) {
1078
+ IKCPSEG *newseg;
1079
+ if (iqueue_is_empty(&kcp->snd_queue)) break;
1080
+
1081
+ newseg = iqueue_entry(kcp->snd_queue.next, IKCPSEG, node);
1082
+
1083
+ iqueue_del(&newseg->node);
1084
+ iqueue_add_tail(&newseg->node, &kcp->snd_buf);
1085
+ kcp->nsnd_que--;
1086
+ kcp->nsnd_buf++;
1087
+
1088
+ newseg->conv = kcp->conv;
1089
+ newseg->cmd = IKCP_CMD_PUSH;
1090
+ newseg->wnd = seg.wnd;
1091
+ newseg->ts = current;
1092
+ newseg->sn = kcp->snd_nxt++;
1093
+ newseg->una = kcp->rcv_nxt;
1094
+ newseg->resendts = current;
1095
+ newseg->rto = kcp->rx_rto;
1096
+ newseg->fastack = 0;
1097
+ newseg->xmit = 0;
1098
+ }
1099
+
1100
+ // check on_app_limited
1101
+ if (kcp->ccops && kcp->ccops->on_app_limited) {
1102
+ if (iqueue_is_empty(&kcp->snd_queue)) {
1103
+ eff_cwnd = _imin_(kcp->snd_wnd, kcp->rmt_wnd);
1104
+ eff_cwnd = _imin_(kcp->cwnd, eff_cwnd);
1105
+ cur_inflight = kcp->nsnd_buf;
1106
+ if (cur_inflight < eff_cwnd) {
1107
+ kcp->ccops->on_app_limited(kcp, cur_inflight);
1108
+ }
1109
+ }
1110
+ }
1111
+
1112
+ // calculate resent
1113
+ resent = (kcp->fastresend > 0)? (IUINT32)kcp->fastresend : 0xffffffff;
1114
+ rtomin = (kcp->nodelay == 0)? (kcp->rx_rto >> 3) : 0;
1115
+
1116
+ // flush data segments
1117
+ for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) {
1118
+ IKCPSEG *segment = iqueue_entry(p, IKCPSEG, node);
1119
+ int needsend = 0;
1120
+ if (segment->xmit == 0) {
1121
+ needsend = 1;
1122
+ segment->xmit++;
1123
+ segment->rto = kcp->rx_rto;
1124
+ segment->resendts = current + segment->rto + rtomin;
1125
+ }
1126
+ else if (_itimediff(current, segment->resendts) >= 0) {
1127
+ needsend = 1;
1128
+ segment->xmit++;
1129
+ kcp->xmit++;
1130
+ if (kcp->nodelay == 0) {
1131
+ segment->rto += _imax_(segment->rto, (IUINT32)kcp->rx_rto);
1132
+ } else {
1133
+ IINT32 step = (kcp->nodelay < 2)?
1134
+ ((IINT32)(segment->rto)) : kcp->rx_rto;
1135
+ segment->rto += step / 2;
1136
+ }
1137
+ segment->resendts = current + segment->rto;
1138
+ lost = 1;
1139
+ }
1140
+ else if (segment->fastack >= resent) {
1141
+ if ((int)segment->xmit <= kcp->fastlimit ||
1142
+ kcp->fastlimit <= 0) {
1143
+ needsend = 1;
1144
+ segment->xmit++;
1145
+ segment->fastack = 0;
1146
+ segment->resendts = current + segment->rto;
1147
+ change++;
1148
+ }
1149
+ }
1150
+
1151
+ if (needsend) {
1152
+ int need;
1153
+ segment->ts = current;
1154
+ segment->wnd = seg.wnd;
1155
+ segment->una = kcp->rcv_nxt;
1156
+
1157
+ if (pacing_budget >= 0 && pacing_budget < (IINT32)segment->len) {
1158
+ break;
1159
+ }
1160
+
1161
+ if (kcp->ccops && kcp->ccops->on_pkt_sent) {
1162
+ kcp->ccops->on_pkt_sent(kcp, segment->sn, current,
1163
+ segment->len, kcp->nsnd_buf, segment->xmit);
1164
+ }
1165
+
1166
+ size = (int)(ptr - buffer);
1167
+ need = IKCP_OVERHEAD + segment->len;
1168
+
1169
+ if (size + need > (int)kcp->mtu) {
1170
+ ikcp_output(kcp, buffer, size);
1171
+ ptr = buffer;
1172
+ }
1173
+
1174
+ ptr = ikcp_encode_seg(ptr, segment);
1175
+
1176
+ if (segment->len > 0) {
1177
+ memcpy(ptr, segment->data, segment->len);
1178
+ ptr += segment->len;
1179
+ }
1180
+
1181
+ if (pacing_budget >= 0) {
1182
+ pacing_budget -= (IINT32)segment->len;
1183
+ }
1184
+
1185
+ if (segment->xmit >= kcp->dead_link) {
1186
+ kcp->state = (IUINT32)-1;
1187
+ }
1188
+ }
1189
+ }
1190
+
1191
+ // flash remaining segments
1192
+ size = (int)(ptr - buffer);
1193
+ if (size > 0) {
1194
+ ikcp_output(kcp, buffer, size);
1195
+ }
1196
+
1197
+ // update ssthresh
1198
+ if (change) {
1199
+ if (kcp->ccops && kcp->ccops->on_fast_retransmit) {
1200
+ kcp->ccops->on_fast_retransmit(kcp, (IUINT32)change,
1201
+ kcp->nsnd_buf, prior_cwnd);
1202
+ }
1203
+ else {
1204
+ IUINT32 inflight = kcp->snd_nxt - kcp->snd_una;
1205
+ kcp->ssthresh = inflight / 2;
1206
+ if (kcp->ssthresh < IKCP_THRESH_MIN)
1207
+ kcp->ssthresh = IKCP_THRESH_MIN;
1208
+ kcp->cwnd = kcp->ssthresh + resent;
1209
+ kcp->incr = kcp->cwnd * kcp->mss;
1210
+ }
1211
+ }
1212
+
1213
+ if (lost) {
1214
+ if (kcp->ccops && kcp->ccops->on_timeout) {
1215
+ kcp->ccops->on_timeout(kcp, prior_cwnd);
1216
+ }
1217
+ else {
1218
+ kcp->ssthresh = prior_cwnd / 2;
1219
+ if (kcp->ssthresh < IKCP_THRESH_MIN)
1220
+ kcp->ssthresh = IKCP_THRESH_MIN;
1221
+ kcp->cwnd = 1;
1222
+ kcp->incr = kcp->mss;
1223
+ }
1224
+ }
1225
+
1226
+ if (kcp->cwnd < 1) {
1227
+ kcp->cwnd = 1;
1228
+ kcp->incr = kcp->mss;
1229
+ }
1230
+ }
1231
+
1232
+
1233
+ //---------------------------------------------------------------------
1234
+ // update state (call it repeatedly, every 10ms-100ms), or you can ask
1235
+ // ikcp_check when to call it again (if no ikcp_input/_send calls occur).
1236
+ // 'current' - current timestamp in milliseconds.
1237
+ //---------------------------------------------------------------------
1238
+ void ikcp_update(ikcpcb *kcp, IUINT32 current)
1239
+ {
1240
+ IINT32 slap;
1241
+
1242
+ kcp->current = current;
1243
+
1244
+ if (kcp->updated == 0) {
1245
+ kcp->updated = 1;
1246
+ kcp->ts_flush = kcp->current;
1247
+ }
1248
+
1249
+ slap = _itimediff(kcp->current, kcp->ts_flush);
1250
+
1251
+ if (slap >= 10000 || slap < -10000) {
1252
+ kcp->ts_flush = kcp->current;
1253
+ slap = 0;
1254
+ }
1255
+
1256
+ if (slap >= 0) {
1257
+ kcp->ts_flush += kcp->interval;
1258
+ if (_itimediff(kcp->current, kcp->ts_flush) >= 0) {
1259
+ kcp->ts_flush = kcp->current + kcp->interval;
1260
+ }
1261
+ ikcp_flush(kcp);
1262
+ }
1263
+ }
1264
+
1265
+
1266
+ //---------------------------------------------------------------------
1267
+ // Determines when you should invoke ikcp_update next:
1268
+ // returns the timestamp (in milliseconds) at which you should call
1269
+ // ikcp_update, assuming no ikcp_input/_send calls occur in between.
1270
+ // You can call ikcp_update at that time instead of calling it repeatedly.
1271
+ // Important for reducing unnecessary ikcp_update invocations. Use it to
1272
+ // schedule ikcp_update (e.g., implementing an epoll-like mechanism,
1273
+ // or optimizing ikcp_update when handling massive kcp connections).
1274
+ //---------------------------------------------------------------------
1275
+ IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current)
1276
+ {
1277
+ IUINT32 ts_flush = kcp->ts_flush;
1278
+ IINT32 tm_flush = 0x7fffffff;
1279
+ IINT32 tm_packet = 0x7fffffff;
1280
+ IUINT32 minimal = 0;
1281
+ struct IQUEUEHEAD *p;
1282
+
1283
+ if (kcp->updated == 0) {
1284
+ return current;
1285
+ }
1286
+
1287
+ if (_itimediff(current, ts_flush) >= 10000 ||
1288
+ _itimediff(current, ts_flush) < -10000) {
1289
+ ts_flush = current;
1290
+ }
1291
+
1292
+ if (_itimediff(current, ts_flush) >= 0) {
1293
+ return current;
1294
+ }
1295
+
1296
+ tm_flush = _itimediff(ts_flush, current);
1297
+
1298
+ for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) {
1299
+ const IKCPSEG *seg = iqueue_entry(p, const IKCPSEG, node);
1300
+ IINT32 diff = _itimediff(seg->resendts, current);
1301
+ if (diff <= 0) {
1302
+ return current;
1303
+ }
1304
+ if (diff < tm_packet) tm_packet = diff;
1305
+ }
1306
+
1307
+ minimal = (IUINT32)(tm_packet < tm_flush ? tm_packet : tm_flush);
1308
+ if (minimal >= kcp->interval) minimal = kcp->interval;
1309
+
1310
+ return current + minimal;
1311
+ }
1312
+
1313
+
1314
+
1315
+ int ikcp_setmtu(ikcpcb *kcp, int mtu)
1316
+ {
1317
+ char *buffer;
1318
+ if (mtu < 50 || mtu < (int)IKCP_OVERHEAD)
1319
+ return -1;
1320
+ buffer = (char*)ikcp_malloc((mtu + IKCP_OVERHEAD) * 3);
1321
+ if (buffer == NULL)
1322
+ return -2;
1323
+ kcp->mtu = mtu;
1324
+ kcp->mss = kcp->mtu - IKCP_OVERHEAD;
1325
+ ikcp_free(kcp->buffer);
1326
+ kcp->buffer = buffer;
1327
+ return 0;
1328
+ }
1329
+
1330
+ int ikcp_interval(ikcpcb *kcp, int interval)
1331
+ {
1332
+ if (interval > 5000) interval = 5000;
1333
+ else if (interval < 10) interval = 10;
1334
+ kcp->interval = interval;
1335
+ return 0;
1336
+ }
1337
+
1338
+ int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
1339
+ {
1340
+ if (nodelay >= 0) {
1341
+ kcp->nodelay = nodelay;
1342
+ if (nodelay) {
1343
+ kcp->rx_minrto = IKCP_RTO_NDL;
1344
+ }
1345
+ else {
1346
+ kcp->rx_minrto = IKCP_RTO_MIN;
1347
+ }
1348
+ }
1349
+ if (interval >= 0) {
1350
+ if (interval > 5000) interval = 5000;
1351
+ else if (interval < 10) interval = 10;
1352
+ kcp->interval = interval;
1353
+ }
1354
+ if (resend >= 0) {
1355
+ kcp->fastresend = resend;
1356
+ }
1357
+ if (nc >= 0) {
1358
+ kcp->nocwnd = nc;
1359
+ }
1360
+ return 0;
1361
+ }
1362
+
1363
+
1364
+ int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd)
1365
+ {
1366
+ if (kcp) {
1367
+ if (sndwnd > 0) {
1368
+ kcp->snd_wnd = sndwnd;
1369
+ }
1370
+ if (rcvwnd > 0) { // must >= max fragment size
1371
+ kcp->rcv_wnd = _imax_(rcvwnd, IKCP_WND_RCV);
1372
+ }
1373
+ }
1374
+ return 0;
1375
+ }
1376
+
1377
+ int ikcp_waitsnd(const ikcpcb *kcp)
1378
+ {
1379
+ return kcp->nsnd_buf + kcp->nsnd_que;
1380
+ }
1381
+
1382
+
1383
+ // read conv
1384
+ IUINT32 ikcp_getconv(const void *ptr)
1385
+ {
1386
+ IUINT32 conv;
1387
+ ikcp_decode32u((const char*)ptr, &conv);
1388
+ return conv;
1389
+ }
1390
+
1391
+
1392
+ //---------------------------------------------------------------------
1393
+ // install congestion control
1394
+ //---------------------------------------------------------------------
1395
+ int ikcp_setcc(ikcpcb *kcp, const struct IKCPOPS *ops)
1396
+ {
1397
+ assert(kcp);
1398
+ if (kcp->ccops && kcp->ccops->release) {
1399
+ kcp->ccops->release(kcp);
1400
+ }
1401
+ kcp->congest = NULL;
1402
+ kcp->ccops = ops;
1403
+ if (ops) {
1404
+ if (ops->init) {
1405
+ if (ops->init(kcp) < 0) {
1406
+ kcp->ccops = NULL;
1407
+ kcp->congest = NULL;
1408
+ if (kcp->cwnd < 1) kcp->cwnd = 1;
1409
+ kcp->incr = kcp->cwnd * kcp->mss;
1410
+ return -1;
1411
+ }
1412
+ }
1413
+ }
1414
+ else {
1415
+ if (kcp->cwnd < 1) kcp->cwnd = 1;
1416
+ kcp->incr = kcp->cwnd * kcp->mss;
1417
+ if (kcp->incr < kcp->mss) kcp->incr = kcp->mss;
1418
+ }
1419
+ return 0;
1420
+ }
1421
+
1422
+
1423
+