58
58
59
59
// forward error correction
60
60
fec * FEC
61
- fecGroup [][]byte
61
+ fecDataShards [][]byte
62
62
fecHeaderOffset int
63
63
fecPayloadOffset int
64
64
@@ -119,10 +119,10 @@ func newUDPSession(conv uint32, dataShards, parityShards int, l *Listener, conn
119
119
}
120
120
sess .fecPayloadOffset = sess .fecHeaderOffset + fecHeaderSize
121
121
122
- // fec data group
123
- sess .fecGroup = make ([][]byte , sess .fec .shardSize )
124
- for k := range sess .fecGroup {
125
- sess .fecGroup [k ] = make ([]byte , mtuLimit )
122
+ // fec data shards
123
+ sess .fecDataShards = make ([][]byte , sess .fec .shardSize )
124
+ for k := range sess .fecDataShards {
125
+ sess .fecDataShards [k ] = make ([]byte , mtuLimit )
126
126
}
127
127
}
128
128
@@ -136,9 +136,7 @@ func newUDPSession(conv uint32, dataShards, parityShards int, l *Listener, conn
136
136
137
137
sess .kcp = NewKCP (conv , func (buf []byte , size int ) {
138
138
if size >= IKCP_OVERHEAD {
139
- ext := xmitBuf .Get ().([]byte )[:sess .headerSize + size ]
140
- copy (ext [sess .headerSize :], buf )
141
- sess .output (ext )
139
+ sess .output (buf [:size ])
142
140
}
143
141
})
144
142
sess .kcp .WndSize (defaultWndSize , defaultWndSize )
@@ -416,38 +414,52 @@ func (s *UDPSession) SetKeepAlive(interval int) {
416
414
// 3. Encryption
417
415
// 4. emit to emitTask
418
416
// 5. emitTask WriteTo kernel
419
- func (s * UDPSession ) output (ext []byte ) {
417
+ func (s * UDPSession ) output (buf []byte ) {
420
418
var ecc [][]byte
419
+
420
+ // extend buf's header space
421
+ ext := xmitBuf .Get ().([]byte )[:s .headerSize + len (buf )]
422
+ copy (ext [s .headerSize :], buf )
423
+
424
+ // FEC stage
421
425
if s .fec != nil {
422
426
s .fec .markData (ext [s .fecHeaderOffset :])
423
427
binary .LittleEndian .PutUint16 (ext [s .fecPayloadOffset :], uint16 (len (ext [s .fecPayloadOffset :])))
424
428
425
- // copy data to fec group
429
+ // copy data to fec datashards
426
430
sz := len (ext )
427
- s .fecGroup [s .fecCnt ] = s .fecGroup [s .fecCnt ][:sz ]
428
- copy (s .fecGroup [s .fecCnt ], ext )
431
+ s .fecDataShards [s .fecCnt ] = s .fecDataShards [s .fecCnt ][:sz ]
432
+ copy (s .fecDataShards [s .fecCnt ], ext )
429
433
s .fecCnt ++
434
+
435
+ // record max datashard length
430
436
if sz > s .fecMaxSize {
431
437
s .fecMaxSize = sz
432
438
}
433
439
434
440
// calculate Reed-Solomon Erasure Code
435
441
if s .fecCnt == s .fec .dataShards {
442
+ // bzero each datashard's tail
436
443
for i := 0 ; i < s .fec .dataShards ; i ++ {
437
- shard := s .fecGroup [i ]
444
+ shard := s .fecDataShards [i ]
438
445
slen := len (shard )
439
446
xorBytes (shard [slen :s .fecMaxSize ], shard [slen :s .fecMaxSize ], shard [slen :s .fecMaxSize ])
440
447
}
441
- ecc = s .fec .calcECC (s .fecGroup , s .fecPayloadOffset , s .fecMaxSize )
448
+
449
+ // calculation of RS
450
+ ecc = s .fec .calcECC (s .fecDataShards , s .fecPayloadOffset , s .fecMaxSize )
442
451
for k := range ecc {
443
452
s .fec .markFEC (ecc [k ][s .fecHeaderOffset :])
444
453
ecc [k ] = ecc [k ][:s .fecMaxSize ]
445
454
}
455
+
456
+ // reset counters to zero
446
457
s .fecCnt = 0
447
458
s .fecMaxSize = 0
448
459
}
449
460
}
450
461
462
+ // encryption stage
451
463
if s .block != nil {
452
464
io .ReadFull (rand .Reader , ext [:nonceSize ])
453
465
checksum := crc32 .ChecksumIEEE (ext [cryptHeaderSize :])
@@ -464,6 +476,7 @@ func (s *UDPSession) output(ext []byte) {
464
476
}
465
477
}
466
478
479
+ // emit stage
467
480
defaultEmitter .emit (emitPacket {s .conn , s .remote , ext , true })
468
481
if ecc != nil {
469
482
for k := range ecc {
0 commit comments