| 
					
				 | 
			
			
				@@ -7,6 +7,8 @@ package kcp 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"encoding/binary" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/v2ray/v2ray-core/common/alloc" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const ( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -105,7 +107,7 @@ type Segment struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	rto      uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	fastack  uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	xmit     uint32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	data     []byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	data     *alloc.Buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // encode a segment into buffer 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -117,15 +119,15 @@ func (seg *Segment) encode(ptr []byte) []byte { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ptr = ikcp_encode32u(ptr, seg.ts) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ptr = ikcp_encode32u(ptr, seg.sn) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ptr = ikcp_encode32u(ptr, seg.una) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	ptr = ikcp_encode32u(ptr, uint32(len(seg.data))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ptr = ikcp_encode32u(ptr, uint32(seg.data.Len())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return ptr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // NewSegment creates a KCP segment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func NewSegment(size int) *Segment { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	seg := new(Segment) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	seg.data = make([]byte, size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return seg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func NewSegment() *Segment { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return &Segment{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		data: alloc.NewSmallBuffer().Clear(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // KCP defines a single KCP connection 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -190,12 +192,13 @@ func (kcp *KCP) Recv(buffer []byte) (n int) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	count := 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	for k := range kcp.rcv_queue { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		seg := &kcp.rcv_queue[k] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if len(seg.data) > len(buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dataLen := seg.data.Len() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if dataLen > len(buffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		copy(buffer, seg.data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		buffer = buffer[len(seg.data):] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		n += len(seg.data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		copy(buffer, seg.data.Value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		buffer = buffer[dataLen:] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		n += dataLen 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		count++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	kcp.rcv_queue = kcp.rcv_queue[count:] 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -251,8 +254,8 @@ func (kcp *KCP) Send(buffer []byte) int { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			size = len(buffer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		seg := NewSegment(size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		copy(seg.data, buffer[:size]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		seg := NewSegment() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		seg.data.Append(buffer[:size]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		seg.frg = uint32(count - i - 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		kcp.snd_queue = append(kcp.snd_queue, *seg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		buffer = buffer[size:] 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -456,7 +459,7 @@ func (kcp *KCP) Input(data []byte) int { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if _itimediff(sn, kcp.rcv_nxt+kcp.rcv_wnd) < 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				kcp.ack_push(sn, ts) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if _itimediff(sn, kcp.rcv_nxt) >= 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					seg := NewSegment(int(length)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					seg := NewSegment() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					seg.conv = conv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					seg.cmd = uint32(cmd) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					seg.frg = uint32(frg) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -464,7 +467,7 @@ func (kcp *KCP) Input(data []byte) int { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					seg.ts = ts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					seg.sn = sn 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					seg.una = una 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					copy(seg.data, data[:length]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					seg.data.Append(data[:length]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					kcp.parse_data(seg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -666,7 +669,7 @@ func (kcp *KCP) flush() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			segment.una = kcp.rcv_nxt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			size := len(buffer) - len(ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			need := IKCP_OVERHEAD + len(segment.data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			need := IKCP_OVERHEAD + segment.data.Len() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if size+need >= int(kcp.mtu) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				kcp.output(buffer[:size]) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -674,8 +677,10 @@ func (kcp *KCP) flush() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			ptr = segment.encode(ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			copy(ptr, segment.data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			ptr = ptr[len(segment.data):] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			copy(ptr, segment.data.Value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ptr = ptr[segment.data.Len():] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			segment.data.Release() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if segment.xmit >= kcp.dead_link { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				kcp.state = 0xFFFFFFFF 
			 |