github.com/shaoyuan1943/gokcp@v0.0.0-20201026071748-5b36d4c87f61/kcp.go (about)

     1  package gokcp
     2  
     3  import (
     4  	_ "unsafe"
     5  )
     6  
     7  type segment struct {
     8  	convID     uint32
     9  	cmd        uint32 // package type
    10  	frg        uint32 // user data slice number, 0 is last
    11  	wnd        uint32 // recv window size
    12  	ts         uint32 // send message timestamp
    13  	sn         uint32 // sequence number
    14  	una        uint32 // next message sequence number(recv)
    15  	resendTs   uint32 // send time stamp
    16  	rto        uint32
    17  	fastACK    uint32 // skip ACK times
    18  	xmit       uint32
    19  	dataBuffer []byte
    20  	acked      bool // flag this segment ack incept
    21  }
    22  
    23  func (seg *segment) reset() {
    24  	seg.convID = 0
    25  	seg.cmd = 0
    26  	seg.frg = 0
    27  	seg.wnd = 0
    28  	seg.ts = 0
    29  	seg.sn = 0
    30  	seg.una = 0
    31  	seg.resendTs = 0
    32  	seg.rto = 0
    33  	seg.fastACK = 0
    34  	seg.xmit = 0
    35  	seg.dataBuffer = seg.dataBuffer[:0]
    36  	seg.acked = false
    37  }
    38  
    39  type KCP struct {
    40  	convID, mtu, mss, state             uint32
    41  	lastACK                             uint32
    42  	sendUNA, sendNext, recvNext         uint32
    43  	ssthresh                            uint32
    44  	rxRTTValue, rxSRTT, rxRTO, rxMinRTO int32
    45  	sendWnd, recvWnd, remoteWnd, cwnd   uint32
    46  	interval, tsFlush, xmit             uint32
    47  	noDelay                             bool
    48  	updated                             uint32
    49  	probe, tsProbe, probeWait           uint32
    50  	deadLink, incr                      uint32
    51  	sendQueue, recvQueue                []*segment
    52  	sendBuffer, recvBuffer              []*segment
    53  	ackList                             []uint64
    54  	buffer                              *Buffer
    55  	fastResendACK, fastACKLimit         uint32
    56  	nocwnd, streamMode                  bool
    57  	outputCallback                      OutputCallback
    58  	mdev, mdevMax, rttSN                int32
    59  	stableNetwork                       bool
    60  }
    61  
    62  func NewKCP(convID uint32, outputCallbakc OutputCallback) *KCP {
    63  	kcp := &KCP{convID: convID, outputCallback: outputCallbakc}
    64  	kcp.sendWnd = KCP_WND_SND
    65  	kcp.recvWnd = KCP_WND_RCV
    66  	kcp.remoteWnd = KCP_WND_RCV
    67  	kcp.mtu = KCP_MTU_DEF
    68  	kcp.mss = kcp.mtu - KCP_OVERHEAD
    69  	kcp.rxRTO = int32(KCP_RTO_DEF)
    70  	kcp.rxMinRTO = int32(KCP_RTO_MIN)
    71  	kcp.interval = KCP_INTERVAL
    72  	kcp.tsFlush = KCP_INTERVAL
    73  	kcp.ssthresh = KCP_THRESH_INIT
    74  	kcp.fastACKLimit = KCP_FASTACK_LIMIT
    75  	kcp.deadLink = KCP_DEADLINK
    76  
    77  	return kcp
    78  }
    79  
    80  func (kcp *KCP) SetOutput(outputCallback OutputCallback) {
    81  	if outputCallback != nil {
    82  		kcp.outputCallback = outputCallback
    83  	}
    84  }
    85  
    86  // calculate a message data size
    87  func (kcp *KCP) PeekSize() (size int) {
    88  	if len(kcp.recvQueue) <= 0 {
    89  		return 0
    90  	}
    91  
    92  	seg := kcp.recvQueue[0]
    93  	if seg.frg == 0 {
    94  		return len(seg.dataBuffer)
    95  	}
    96  
    97  	if len(kcp.recvQueue) < int(seg.frg+1) {
    98  		return 0
    99  	}
   100  
   101  	for idx := range kcp.recvQueue {
   102  		seg := kcp.recvQueue[idx]
   103  		size += len(seg.dataBuffer)
   104  		if seg.frg == 0 {
   105  			break
   106  		}
   107  	}
   108  
   109  	return
   110  }
   111  
   112  // read a whole message packet
   113  // User or upper level recv: returns size, returns below zero for EAGAIN
   114  func (kcp *KCP) Recv(buffer []byte) (int, error) {
   115  	if len(kcp.recvQueue) == 0 {
   116  		return 0, ErrNoReadableData
   117  	}
   118  
   119  	peekSize := kcp.PeekSize()
   120  	if peekSize <= 0 {
   121  		return 0, ErrNoReadableData
   122  	}
   123  
   124  	if peekSize > len(buffer) {
   125  		return 0, ErrNoEnoughSpace
   126  	}
   127  
   128  	isFastRecover := false
   129  	if len(kcp.recvQueue) >= int(kcp.recvWnd) {
   130  		isFastRecover = true
   131  	}
   132  
   133  	// merge fragment
   134  	n := 0
   135  	count := 0
   136  	for idx := range kcp.recvQueue {
   137  		seg := kcp.recvQueue[idx]
   138  		frg := seg.frg
   139  		copy(buffer[n:], seg.dataBuffer)
   140  		n += len(seg.dataBuffer)
   141  		count++
   142  
   143  		putSegment(seg)
   144  		if frg == 0 {
   145  			break
   146  		}
   147  	}
   148  
   149  	if count > 0 {
   150  		kcp.recvQueue = removeFront(kcp.recvQueue, count)
   151  	}
   152  
   153  	// move seg from recvBuffer to recvQueue
   154  	count = 0
   155  	for idx := range kcp.recvBuffer {
   156  		seg := kcp.recvBuffer[idx]
   157  		if seg.sn == kcp.recvNext && len(kcp.recvQueue)+count < int(kcp.recvWnd) {
   158  			kcp.recvQueue = append(kcp.recvQueue, seg)
   159  			kcp.recvNext++
   160  			count++
   161  		} else {
   162  			break
   163  		}
   164  	}
   165  
   166  	if count > 0 {
   167  		kcp.recvBuffer = removeFront(kcp.recvBuffer, count)
   168  	}
   169  
   170  	// tell remote my recv window size, need to send KCP_CMD_WINS
   171  	if (len(kcp.recvQueue) < int(kcp.recvWnd)) && isFastRecover {
   172  		// ready to send back IKCP_CMD_WINS in ikcp_flush
   173  		// tell remote my window size in next 'flush'
   174  		kcp.probe |= KCP_ASK_TELL
   175  	}
   176  
   177  	return n, nil
   178  }
   179  
   180  func (kcp *KCP) Send(buffer []byte) error {
   181  	// append to previous segment in streaming mode (if possible)
   182  	if kcp.streamMode {
   183  		if len(kcp.sendQueue) > 0 {
   184  			seg := kcp.sendQueue[len(kcp.sendQueue)-1]
   185  			if len(seg.dataBuffer) < int(kcp.mss) {
   186  				capacity := int(kcp.mss) - len(seg.dataBuffer)
   187  				extend := 0
   188  				if len(buffer) < capacity {
   189  					extend = len(buffer)
   190  				} else {
   191  					extend = capacity
   192  				}
   193  
   194  				// copy data to old segment
   195  				orgLen := len(seg.dataBuffer)
   196  				seg.dataBuffer = seg.dataBuffer[:orgLen+extend]
   197  				copy(seg.dataBuffer[orgLen:], buffer)
   198  				buffer = buffer[extend:]
   199  			}
   200  		}
   201  
   202  		if len(buffer) == 0 {
   203  			return nil
   204  		}
   205  	}
   206  
   207  	count := 0
   208  	if len(buffer) <= (int)(kcp.mss) {
   209  		count = 1
   210  	} else {
   211  		count = (len(buffer) + int(kcp.mss) - 1) / int(kcp.mss)
   212  	}
   213  
   214  	if count >= int(KCP_WND_RCV) {
   215  		return ErrDataTooLong
   216  	}
   217  
   218  	if count == 0 {
   219  		count = 1
   220  	}
   221  
   222  	// slice data to fregment
   223  	for i := 0; i < count; i++ {
   224  		size := len(buffer)
   225  		if size > int(kcp.mss) {
   226  			size = int(kcp.mss)
   227  		}
   228  
   229  		seg := getSegment(kcp.mss)
   230  		seg.dataBuffer = seg.dataBuffer[:size]
   231  		copy(seg.dataBuffer, buffer[:size])
   232  		if kcp.streamMode {
   233  			seg.frg = 0
   234  		} else {
   235  			seg.frg = uint32(count - i - 1)
   236  		}
   237  
   238  		kcp.sendQueue = append(kcp.sendQueue, seg)
   239  		buffer = buffer[size:]
   240  	}
   241  
   242  	return nil
   243  }
   244  
   245  func (kcp *KCP) updateACK(rtt int32) int32 {
   246  	if kcp.stableNetwork {
   247  		return kcp.updateACK2(rtt)
   248  	}
   249  
   250  	return kcp.updateACK1(rtt)
   251  }
   252  
   253  // calculate RTO
   254  // RFC6298:http://tools.ietf.org/html/rfc6298
   255  func (kcp *KCP) updateACK1(rtt int32) int32 {
   256  	if kcp.rxSRTT == 0 {
   257  		kcp.rxSRTT = rtt
   258  		kcp.rxRTTValue = rtt >> 1 // 1/2
   259  	} else {
   260  		delta := rtt - kcp.rxSRTT
   261  		if delta < 0 {
   262  			delta = -delta
   263  		}
   264  
   265  		kcp.rxRTTValue = (3*kcp.rxRTTValue + delta) / 4 // 1/4
   266  		kcp.rxSRTT = (7*kcp.rxSRTT + rtt) / 8           // 1/8
   267  		if kcp.rxSRTT < 1 {
   268  			kcp.rxSRTT = 1
   269  		}
   270  	}
   271  
   272  	rto := kcp.rxSRTT + int32(max(kcp.interval, uint32(4*kcp.rxRTTValue)))
   273  	kcp.rxRTO = int32(bound(uint32(kcp.rxMinRTO), uint32(rto), KCP_RTO_MAX))
   274  	return kcp.rxRTO
   275  }
   276  
   277  // calculate RTO
   278  // updateACK2 port from tcp_input.c 'tcp_rtt_estimator' function
   279  // https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_input.c
   280  func (kcp *KCP) updateACK2(rtt int32) int32 {
   281  	srtt := kcp.rxSRTT
   282  	m := rtt
   283  	if kcp.rxSRTT == 0 {
   284  		srtt = m << 3
   285  		kcp.mdev = m << 1 // make sure rto = 3*rtt
   286  		kcp.rxRTTValue = int32(max(uint32(kcp.mdev), KCP_RTO_MIN))
   287  		kcp.mdevMax = kcp.rxRTTValue
   288  		kcp.rttSN = int32(kcp.sendNext)
   289  	} else {
   290  		m -= srtt >> 3
   291  		srtt += m // rtt = 7/8 rtt + 1/8 new
   292  		if m < 0 {
   293  			m = -m // abs
   294  			m -= (kcp.mdev >> 2)
   295  			if m > 0 {
   296  				m >>= 3
   297  			}
   298  		} else {
   299  			m -= (kcp.mdev >> 2)
   300  		}
   301  
   302  		kcp.mdev += m // mdev = 3/4 mdev + 1/4 new
   303  		if kcp.mdev > kcp.mdevMax {
   304  			kcp.mdevMax = kcp.mdev
   305  			if kcp.mdevMax > kcp.rxRTTValue {
   306  				kcp.rxRTTValue = kcp.mdevMax
   307  			}
   308  
   309  			if int32(kcp.sendUNA) > kcp.rttSN {
   310  				if kcp.mdevMax < kcp.rxRTTValue {
   311  					kcp.rxRTTValue -= (kcp.rxRTTValue - kcp.mdevMax) >> 2
   312  				}
   313  
   314  				kcp.rttSN = int32(kcp.sendNext)
   315  				kcp.mdevMax = int32(KCP_RTO_MIN)
   316  			}
   317  		}
   318  	}
   319  
   320  	kcp.rxSRTT = int32(max(1, uint32(srtt)))
   321  	//rto := kcp.rxSRTT*1 + 4*kcp.mdev
   322  	rto := rtt + 4*kcp.mdev
   323  	kcp.rxRTO = int32(bound(uint32(kcp.rxMinRTO), uint32(rto), KCP_RTO_MAX))
   324  	return kcp.rxRTO
   325  }
   326  
   327  func (kcp *KCP) setSendUNA() {
   328  	if len(kcp.sendBuffer) > 0 {
   329  		seg := kcp.sendBuffer[0]
   330  		kcp.sendUNA = seg.sn
   331  	} else {
   332  		kcp.sendUNA = kcp.sendNext
   333  	}
   334  }
   335  
   336  func (kcp *KCP) parseACK(sn uint32) {
   337  	if timediff(sn, kcp.sendUNA) < 0 || timediff(sn, kcp.sendNext) >= 0 {
   338  		return
   339  	}
   340  
   341  	for idx := range kcp.sendBuffer {
   342  		seg := kcp.sendBuffer[idx]
   343  		if sn == seg.sn {
   344  			seg.acked = true
   345  			break
   346  		}
   347  
   348  		if timediff(sn, seg.sn) < 0 {
   349  			break
   350  		}
   351  	}
   352  }
   353  
   354  func (kcp *KCP) parseUNA(una uint32) {
   355  	count := 0
   356  	for idx := range kcp.sendBuffer {
   357  		seg := kcp.sendBuffer[idx]
   358  		if timediff(una, seg.sn) > 0 {
   359  			putSegment(seg)
   360  			count++
   361  		} else {
   362  			break
   363  		}
   364  	}
   365  
   366  	if count > 0 {
   367  		kcp.sendBuffer = removeFront(kcp.sendBuffer, count)
   368  	}
   369  }
   370  
   371  func (kcp *KCP) parseFastACK(sn uint32, ts uint32) {
   372  	if timediff(sn, kcp.sendUNA) < 0 || timediff(sn, kcp.sendNext) >= 0 {
   373  		return
   374  	}
   375  
   376  	for idx := range kcp.sendBuffer {
   377  		seg := kcp.sendBuffer[idx]
   378  		if timediff(sn, seg.sn) < 0 {
   379  			break
   380  		} else if sn != seg.sn {
   381  			if timediff(ts, seg.ts) >= 0 {
   382  				seg.fastACK++
   383  			}
   384  		}
   385  	}
   386  }
   387  
   388  func (kcp *KCP) pushACK(sn, ts uint32) {
   389  	kcp.ackList = append(kcp.ackList, packACK(sn, ts))
   390  }
   391  
   392  // Return true if this message has been received
   393  func (kcp *KCP) parseData(newseg *segment) bool {
   394  	repeat := false
   395  	sn := newseg.sn
   396  	if timediff(sn, kcp.recvNext+kcp.recvWnd) >= 0 || timediff(sn, kcp.recvNext) < 0 {
   397  		return true
   398  	}
   399  
   400  	istIdx := 0
   401  	for idx := len(kcp.recvBuffer) - 1; idx >= 0; idx-- {
   402  		seg := kcp.recvBuffer[idx]
   403  		if seg.sn == sn {
   404  			// repeat message package
   405  			repeat = true
   406  			break
   407  		}
   408  
   409  		if timediff(sn, seg.sn) > 0 {
   410  			istIdx = idx + 1
   411  			break
   412  		}
   413  	}
   414  
   415  	if !repeat {
   416  		if istIdx == len(kcp.recvBuffer) {
   417  			kcp.recvBuffer = append(kcp.recvBuffer, newseg)
   418  		} else {
   419  			kcp.recvBuffer = append(kcp.recvBuffer, &segment{})
   420  			copy(kcp.recvBuffer[istIdx+1:], kcp.recvBuffer[istIdx:])
   421  			kcp.recvBuffer[istIdx] = newseg
   422  		}
   423  	}
   424  
   425  	// move available data from recvBuffer -> recvQueue
   426  	count := 0
   427  	for idx := range kcp.recvBuffer {
   428  		seg := kcp.recvBuffer[idx]
   429  		if seg.sn == kcp.recvNext && len(kcp.recvQueue) < int(kcp.recvWnd) {
   430  			count++
   431  			kcp.recvNext++
   432  		} else {
   433  			break
   434  		}
   435  	}
   436  
   437  	if count > 0 {
   438  		kcp.recvQueue = append(kcp.recvQueue, kcp.recvBuffer[:count]...)
   439  		kcp.recvBuffer = removeFront(kcp.recvBuffer, count)
   440  	}
   441  	return repeat
   442  }
   443  
   444  func (kcp *KCP) Input(data []byte) error {
   445  	prevUNA := kcp.sendUNA
   446  	var maxACK, latestACKTime uint32 = 0, 0
   447  	flag := 0
   448  
   449  	if len(data) < int(KCP_OVERHEAD) {
   450  		return ErrDataInvalid
   451  	}
   452  
   453  	currentTime := SetupFromNowMS()
   454  	for {
   455  		var ts, sn, length, una, convID uint32
   456  		var wnd uint16
   457  		var cmd, frg uint8
   458  		if len(data) < int(KCP_OVERHEAD) {
   459  			break
   460  		}
   461  
   462  		data = decode32u(data, &convID)
   463  		if convID != kcp.convID {
   464  			return ErrDifferenceConvID
   465  		}
   466  
   467  		data = decode8u(data, &cmd)
   468  		data = decode8u(data, &frg)
   469  		data = decode16u(data, &wnd)
   470  		data = decode32u(data, &ts)
   471  		data = decode32u(data, &sn)
   472  		data = decode32u(data, &una)
   473  		data = decode32u(data, &length)
   474  
   475  		if len(data) < int(length) || length < 0 {
   476  			return ErrDataInvalid
   477  		}
   478  
   479  		if uint32(cmd) != KCP_CMD_PUSH && uint32(cmd) != KCP_CMD_ACK &&
   480  			uint32(cmd) != KCP_CMD_WASK && uint32(cmd) != KCP_CMD_WINS {
   481  			return ErrDataInvalid
   482  		}
   483  
   484  		kcp.remoteWnd = uint32(wnd)
   485  		kcp.parseUNA(una)
   486  		kcp.setSendUNA()
   487  		switch uint32(cmd) {
   488  		case KCP_CMD_ACK:
   489  			if timediff(currentTime, ts) >= 0 {
   490  				_ = kcp.updateACK(timediff(currentTime, ts))
   491  			}
   492  			kcp.parseACK(sn)
   493  			kcp.setSendUNA()
   494  
   495  			if flag == 0 {
   496  				flag = 1
   497  				maxACK = sn
   498  				latestACKTime = ts
   499  			} else {
   500  				if timediff(sn, maxACK) > 0 {
   501  					maxACK = sn
   502  					latestACKTime = ts
   503  				}
   504  			}
   505  		case KCP_CMD_PUSH:
   506  			if timediff(sn, kcp.recvNext+kcp.recvWnd) < 0 {
   507  				kcp.pushACK(sn, ts)
   508  				if timediff(sn, kcp.recvNext) >= 0 {
   509  					seg := getSegment(kcp.mss)
   510  					seg.dataBuffer = seg.dataBuffer[:length]
   511  					seg.convID = convID
   512  					seg.cmd = uint32(cmd)
   513  					seg.frg = uint32(frg)
   514  					seg.wnd = uint32(wnd)
   515  					seg.ts = ts
   516  					seg.sn = sn
   517  					seg.una = una
   518  					repeat := kcp.parseData(seg)
   519  					if !repeat {
   520  						// delay copy
   521  						if length > 0 {
   522  							copy(seg.dataBuffer, data[:length])
   523  						}
   524  					} else {
   525  						// repeat packet, throw it away
   526  						putSegment(seg)
   527  					}
   528  				}
   529  			}
   530  		case KCP_CMD_WASK:
   531  			// ready to send back IKCP_CMD_WINS in ikcp_flush
   532  			// tell remote my window size
   533  			kcp.probe |= KCP_ASK_TELL
   534  		case KCP_CMD_WINS:
   535  			// do nothing
   536  		default:
   537  			return ErrDataInvalid
   538  		}
   539  
   540  		data = data[length:]
   541  	}
   542  
   543  	if flag != 0 {
   544  		kcp.parseFastACK(maxACK, latestACKTime)
   545  	}
   546  
   547  	// update local cwnd
   548  	if timediff(kcp.sendUNA, prevUNA) > 0 {
   549  		if kcp.cwnd < kcp.remoteWnd {
   550  			mss := kcp.mss
   551  			if kcp.cwnd < kcp.ssthresh {
   552  				kcp.cwnd++
   553  				kcp.incr += mss
   554  			} else {
   555  				if kcp.incr < mss {
   556  					kcp.incr = mss
   557  				}
   558  
   559  				// like tcp
   560  				kcp.incr += (mss*mss)/kcp.incr + (mss / 16)
   561  				if (kcp.cwnd+1)*mss <= kcp.incr {
   562  					var tmpVar uint32 = 1
   563  					if mss > 0 {
   564  						tmpVar = mss
   565  					}
   566  					kcp.cwnd = (kcp.incr + mss - 1) / tmpVar
   567  				}
   568  			}
   569  
   570  			if kcp.cwnd > kcp.remoteWnd {
   571  				kcp.cwnd = kcp.remoteWnd
   572  				kcp.incr = kcp.remoteWnd * mss
   573  			}
   574  		}
   575  	}
   576  
   577  	return nil
   578  }
   579  
   580  func (kcp *KCP) flush(isClose bool) error {
   581  	if kcp.updated == 0 {
   582  		return nil
   583  	}
   584  
   585  	currentTime := SetupFromNowMS()
   586  	seg := &segment{}
   587  	seg.convID = kcp.convID
   588  	seg.cmd = KCP_CMD_ACK
   589  	seg.frg = 0
   590  	// wnd unused
   591  	if uint32(len(kcp.recvQueue)) < kcp.recvWnd {
   592  		seg.wnd = kcp.recvWnd - uint32(len(kcp.recvQueue))
   593  	}
   594  	seg.una = kcp.recvNext
   595  	seg.sn = 0
   596  	seg.ts = 0
   597  
   598  	if !isClose {
   599  		// flush acknowledges
   600  		for idx := range kcp.ackList {
   601  			if kcp.buffer.RawLen()+int(KCP_OVERHEAD) > int(kcp.mtu) {
   602  				err := kcp.outputCallback(kcp.buffer.RawData())
   603  				if err != nil {
   604  					return err
   605  				}
   606  
   607  				kcp.buffer.Reset()
   608  			}
   609  
   610  			seg.sn, seg.ts = unpackACK(kcp.ackList[idx])
   611  			kcp.buffer.WriteOverHeader(seg)
   612  		}
   613  	}
   614  	kcp.ackList = kcp.ackList[:0]
   615  
   616  	// probe window size (if remote window size equals zero)
   617  	if kcp.remoteWnd == 0 {
   618  		if kcp.probeWait == 0 {
   619  			kcp.probeWait = KCP_PROBE_INIT
   620  			kcp.tsProbe = currentTime + kcp.probeWait
   621  		} else {
   622  			if timediff(currentTime, kcp.probeWait) >= 0 {
   623  				if kcp.probeWait < KCP_PROBE_INIT {
   624  					kcp.probeWait = KCP_PROBE_INIT
   625  				}
   626  				kcp.probeWait += kcp.probeWait / 2
   627  
   628  				if kcp.probeWait > KCP_PROBE_LIMIT {
   629  					kcp.probeWait = KCP_PROBE_LIMIT
   630  				}
   631  				kcp.tsProbe = currentTime + kcp.probeWait
   632  				kcp.probe |= KCP_ASK_SEND
   633  			}
   634  		}
   635  	} else {
   636  		kcp.tsProbe = 0
   637  		kcp.probeWait = 0
   638  	}
   639  
   640  	if !isClose {
   641  		// flush window probing commands
   642  		if (kcp.probe & KCP_ASK_SEND) != 0 {
   643  			seg.cmd = KCP_CMD_WASK
   644  			if kcp.buffer.RawLen()+int(KCP_OVERHEAD) > int(kcp.mtu) {
   645  				err := kcp.outputCallback(kcp.buffer.RawData())
   646  				if err != nil {
   647  					return err
   648  				}
   649  				kcp.buffer.Reset()
   650  			}
   651  
   652  			kcp.buffer.WriteOverHeader(seg)
   653  		}
   654  
   655  		if (kcp.probe & KCP_ASK_TELL) != 0 {
   656  			seg.cmd = KCP_CMD_WINS
   657  			if kcp.buffer.RawLen()+int(KCP_OVERHEAD) > int(kcp.mtu) {
   658  				err := kcp.outputCallback(kcp.buffer.RawData())
   659  				if err != nil {
   660  					return err
   661  				}
   662  				kcp.buffer.Reset()
   663  			}
   664  
   665  			kcp.buffer.WriteOverHeader(seg)
   666  		}
   667  		kcp.probe = 0
   668  	}
   669  
   670  	// calculate window size
   671  	cwnd := min(kcp.sendWnd, kcp.remoteWnd)
   672  	if !kcp.nocwnd {
   673  		cwnd = min(kcp.cwnd, cwnd)
   674  	}
   675  
   676  	// move data from sendQueue to sendBuffer
   677  	count := 0
   678  	for idx := 0; idx < len(kcp.sendQueue); idx++ {
   679  		// flow control
   680  		// too many package are not ACKed maybe the net is crowd, so send this message next time
   681  		if timediff(kcp.sendNext, kcp.sendUNA+cwnd) >= 0 {
   682  			break
   683  		}
   684  
   685  		newseg := kcp.sendQueue[idx]
   686  		newseg.convID = kcp.convID
   687  		newseg.cmd = KCP_CMD_PUSH
   688  		newseg.wnd = seg.wnd
   689  		newseg.ts = currentTime
   690  		newseg.sn = kcp.sendNext
   691  		newseg.una = kcp.recvNext
   692  		newseg.resendTs = currentTime
   693  		newseg.rto = uint32(kcp.rxRTO)
   694  		newseg.fastACK = 0
   695  		newseg.xmit = 0
   696  		kcp.sendBuffer = append(kcp.sendBuffer, newseg)
   697  		kcp.sendNext++
   698  		count++
   699  	}
   700  	if count > 0 {
   701  		kcp.sendQueue = removeFront(kcp.sendQueue, count)
   702  	}
   703  
   704  	// calculate resent
   705  	var resent uint32
   706  	if kcp.fastResendACK > 0 {
   707  		resent = kcp.fastResendACK
   708  	} else {
   709  		resent = 0xFFFFFFFF
   710  	}
   711  
   712  	var minRTO uint32
   713  	if !kcp.noDelay {
   714  		minRTO = uint32(kcp.rxRTO >> 3)
   715  	} else {
   716  		minRTO = 0
   717  	}
   718  
   719  	// flush data segments
   720  	lost := false
   721  	change := 0
   722  	for idx := 0; idx < len(kcp.sendBuffer); idx++ {
   723  		sendSegment := kcp.sendBuffer[idx]
   724  		needSend := false
   725  		if sendSegment.acked {
   726  			continue
   727  		}
   728  
   729  		// first send
   730  		if sendSegment.xmit == 0 {
   731  			needSend = true
   732  			sendSegment.xmit++
   733  			sendSegment.rto = uint32(kcp.rxRTO)
   734  			sendSegment.resendTs = currentTime + sendSegment.rto + minRTO
   735  		} else if timediff(currentTime, sendSegment.resendTs) >= 0 {
   736  			needSend = true
   737  			sendSegment.xmit++
   738  			kcp.xmit++
   739  			if !kcp.noDelay {
   740  				sendSegment.rto += uint32(kcp.rxRTO)
   741  			} else {
   742  				sendSegment.rto += uint32(kcp.rxRTO / 2)
   743  			}
   744  			sendSegment.resendTs = currentTime + sendSegment.rto
   745  			lost = true
   746  		} else if sendSegment.fastACK >= resent {
   747  			if sendSegment.xmit <= kcp.fastACKLimit || kcp.fastACKLimit <= 0 {
   748  				needSend = true
   749  				sendSegment.xmit++
   750  				sendSegment.fastACK = 0
   751  				sendSegment.resendTs = currentTime + sendSegment.rto
   752  				change++
   753  			}
   754  		}
   755  
   756  		if needSend {
   757  			sendSegment.ts = currentTime
   758  			sendSegment.wnd = seg.wnd
   759  			sendSegment.una = kcp.recvNext
   760  
   761  			if kcp.buffer.RawLen()+int(KCP_OVERHEAD)+len(sendSegment.dataBuffer) > int(kcp.mtu) {
   762  				err := kcp.outputCallback(kcp.buffer.RawData())
   763  				if err != nil {
   764  					return err
   765  				}
   766  				kcp.buffer.Reset()
   767  			}
   768  
   769  			kcp.buffer.WriteOverHeader(sendSegment)
   770  			if len(sendSegment.dataBuffer) > 0 {
   771  				kcp.buffer.Write(sendSegment.dataBuffer)
   772  			}
   773  
   774  			if sendSegment.xmit >= kcp.deadLink {
   775  				kcp.state = 0xFFFFFFFF
   776  			}
   777  		}
   778  	}
   779  
   780  	// flash remain segments
   781  	if kcp.buffer.Len() > 0 {
   782  		err := kcp.outputCallback(kcp.buffer.RawData())
   783  		if err != nil {
   784  			return err
   785  		}
   786  		kcp.buffer.Reset()
   787  	}
   788  
   789  	// update ssthresh
   790  	// rate halving, https://tools.ietf.org/html/rfc6937
   791  	if change > 0 {
   792  		inflight := kcp.sendNext - kcp.sendUNA
   793  		kcp.ssthresh = inflight / 2
   794  		if kcp.ssthresh < KCP_THRESH_MIN {
   795  			kcp.ssthresh = KCP_THRESH_MIN
   796  		}
   797  		kcp.cwnd = kcp.ssthresh + resent
   798  		kcp.incr = kcp.cwnd * kcp.mss
   799  	}
   800  
   801  	// if some package lost
   802  	if lost {
   803  		kcp.ssthresh = cwnd / 2
   804  		if kcp.ssthresh < KCP_THRESH_MIN {
   805  			kcp.ssthresh = KCP_THRESH_MIN
   806  		}
   807  
   808  		kcp.cwnd = 1
   809  		kcp.incr = kcp.mss
   810  	}
   811  
   812  	if kcp.cwnd < 1 {
   813  		kcp.cwnd = 1
   814  		kcp.incr = kcp.mss
   815  	}
   816  
   817  	return nil
   818  }
   819  
   820  //---------------------------------------------------------------------
   821  // update state (call it repeatedly, every 10ms-100ms), or you can ask
   822  // 'Check' when to call it again (without Input/Send calling).
   823  //---------------------------------------------------------------------
   824  func (kcp *KCP) Update() error {
   825  	currentTime := SetupFromNowMS()
   826  	if kcp.updated == 0 {
   827  		kcp.updated = 1
   828  		kcp.tsFlush = currentTime
   829  	}
   830  
   831  	slap := timediff(currentTime, kcp.tsFlush)
   832  	if slap >= 10000 || slap < -10000 {
   833  		kcp.tsFlush = currentTime
   834  		slap = 0
   835  	}
   836  
   837  	if slap >= 0 {
   838  		kcp.tsFlush += kcp.interval
   839  		if timediff(currentTime, kcp.tsFlush) >= 0 {
   840  			kcp.tsFlush = currentTime + kcp.interval
   841  		}
   842  
   843  		return kcp.flush(false)
   844  	}
   845  
   846  	return nil
   847  }
   848  
   849  func (kcp *KCP) SetBufferReserved(reserved int) bool {
   850  	if reserved < 0 || reserved >= int(kcp.mtu-KCP_OVERHEAD) {
   851  		return false
   852  	}
   853  
   854  	kcp.mss = kcp.mtu - KCP_OVERHEAD - uint32(reserved)
   855  	kcp.buffer = nil
   856  	kcp.buffer = NewBuffer(int(kcp.mtu), reserved)
   857  	return true
   858  }
   859  
   860  func (kcp *KCP) SetMTU(mtu int) bool {
   861  	if mtu < 50 || mtu < int(KCP_OVERHEAD) {
   862  		return false
   863  	}
   864  
   865  	kcp.mtu = uint32(mtu)
   866  	return true
   867  }
   868  
   869  func (kcp *KCP) SetInterval(interval int) {
   870  	if interval > 5000 {
   871  		interval = 5000
   872  	} else if interval < 5 {
   873  		interval = 5
   874  	}
   875  
   876  	kcp.interval = uint32(interval)
   877  }
   878  
   879  //---------------------------------------------------------------------
   880  // Determine when should you invoke Update:
   881  // returns when you should invoke Update in millisec, if there
   882  // is no Input/Send calling. you can call Update in that
   883  // time, instead of call update repeatly.
   884  
   885  // Important to reduce unnacessary Update invoking. use it to
   886  // schedule Update (eg. implementing an epoll-like mechanism,
   887  // or optimize Update when handling massive kcp connections)
   888  // wiki: https://github.com/skywind3000/kcp/wiki/KCP-Best-Practice
   889  //---------------------------------------------------------------------
   890  func (kcp *KCP) Check() uint32 {
   891  	currentTime := SetupFromNowMS()
   892  	if kcp.updated == 0 {
   893  		return currentTime
   894  	}
   895  
   896  	tsFlush := kcp.tsFlush
   897  	if timediff(currentTime, tsFlush) >= 10000 || timediff(currentTime, tsFlush) < -10000 {
   898  		tsFlush = currentTime
   899  	}
   900  
   901  	if timediff(currentTime, tsFlush) >= 0 {
   902  		return currentTime
   903  	}
   904  
   905  	tmPacket := 0x7FFFFFFF
   906  	tmFlush := 0x7FFFFFFF
   907  	minimal := 0
   908  	tsFlush = uint32(timediff(tsFlush, currentTime))
   909  	for idx := range kcp.sendBuffer {
   910  		seg := kcp.sendBuffer[idx]
   911  		diff := timediff(seg.resendTs, currentTime)
   912  		if diff <= 0 {
   913  			return currentTime
   914  		}
   915  		if int(diff) < tmPacket {
   916  			tmPacket = int(diff)
   917  		}
   918  	}
   919  
   920  	if tmPacket < tmFlush {
   921  		minimal = tmPacket
   922  	} else {
   923  		minimal = tmFlush
   924  	}
   925  
   926  	if minimal >= int(kcp.interval) {
   927  		minimal = int(kcp.interval)
   928  	}
   929  
   930  	return currentTime + uint32(minimal)
   931  }
   932  
   933  func (kcp *KCP) SetNoDelay(noDelay bool, interval, resend int, nc bool) {
   934  	kcp.noDelay = noDelay
   935  	if kcp.noDelay {
   936  		kcp.rxMinRTO = int32(KCP_RTO_NDL)
   937  	} else {
   938  		kcp.rxMinRTO = int32(KCP_RTO_MIN)
   939  	}
   940  
   941  	kcp.SetInterval(interval)
   942  	kcp.fastResendACK = uint32(resend)
   943  	kcp.nocwnd = nc
   944  }
   945  
   946  func (kcp *KCP) SetWndSize(sendWnd, recvWnd int) {
   947  	kcp.sendWnd = uint32(sendWnd)
   948  	kcp.recvWnd = max(uint32(recvWnd), KCP_WND_RCV)
   949  }
   950  
   951  func (kcp *KCP) SendWnd() uint32 {
   952  	return kcp.sendWnd
   953  }
   954  
   955  func (kcp *KCP) RemoteWnd() uint32 {
   956  	return kcp.remoteWnd
   957  }
   958  
   959  func (kcp *KCP) WaitSend() int {
   960  	return len(kcp.sendQueue) + len(kcp.sendBuffer)
   961  }
   962  
   963  func (kcp *KCP) MTU() uint32 {
   964  	return kcp.mtu
   965  }
   966  
   967  func (kcp *KCP) MSS() uint32 {
   968  	return kcp.mss
   969  }
   970  
   971  func (kcp *KCP) SetStreamMode(streamMode bool) {
   972  	kcp.streamMode = streamMode
   973  }
   974  
   975  func (kcp *KCP) IsStreamMode() bool {
   976  	return kcp.streamMode
   977  }
   978  
   979  func (kcp *KCP) FlushWhenClosed() {
   980  	kcp.flush(true)
   981  }
   982  
   983  func (kcp *KCP) ConvID() uint32 {
   984  	return kcp.convID
   985  }
   986  
   987  func (kcp *KCP) RTO() int32 {
   988  	return kcp.rxRTO
   989  }
   990  
   991  type KCPStatus struct {
   992  	SendUNA       int
   993  	SendNext      int
   994  	RecvNext      int
   995  	LastACK       int
   996  	Threshold     int
   997  	RTO           int
   998  	FastResendACK int
   999  	FastACKLimit  int
  1000  	SendWnd       int
  1001  	RecvWnd       int
  1002  	RemoteWnd     int
  1003  	Wnd           int
  1004  	SendQueueLen  int
  1005  	SendBufferLen int
  1006  	RecvQueueLen  int
  1007  	RecvBufferLen int
  1008  	ACKListLen    int
  1009  	Incr          int
  1010  }
  1011  
  1012  func (kcp *KCP) Snapshot(status *KCPStatus) {
  1013  	if status == nil {
  1014  		return
  1015  	}
  1016  
  1017  	status.SendUNA = int(kcp.sendUNA)
  1018  	status.SendNext = int(kcp.sendNext)
  1019  	status.RecvNext = int(kcp.recvNext)
  1020  	status.LastACK = int(kcp.lastACK)
  1021  	status.Threshold = int(kcp.ssthresh)
  1022  	status.RTO = int(kcp.rxRTO)
  1023  	status.FastResendACK = int(kcp.fastResendACK)
  1024  	status.FastACKLimit = int(kcp.fastACKLimit)
  1025  	status.SendWnd = int(kcp.sendWnd)
  1026  	status.RecvWnd = int(kcp.recvWnd)
  1027  	status.RemoteWnd = int(kcp.remoteWnd)
  1028  	status.Wnd = int(kcp.cwnd)
  1029  	status.SendQueueLen = len(kcp.sendQueue)
  1030  	status.SendBufferLen = len(kcp.sendBuffer)
  1031  	status.RecvQueueLen = len(kcp.recvQueue)
  1032  	status.RecvBufferLen = len(kcp.recvBuffer)
  1033  	status.ACKListLen = len(kcp.ackList)
  1034  	status.Incr = int(kcp.incr)
  1035  }