mirror of
https://github.com/masterking32/MasterHttpRelayVPN.git
synced 2026-05-19 08:04:38 +03:00
149 lines
3.7 KiB
Go
149 lines
3.7 KiB
Go
// ==============================================================================
|
|
// MasterHttpRelayVPN
|
|
// Author: MasterkinG32
|
|
// Github: https://github.com/masterking32
|
|
// Year: 2026
|
|
// ==============================================================================
|
|
package client
|
|
|
|
import (
|
|
"time"
|
|
|
|
"masterhttprelayvpn/internal/protocol"
|
|
)
|
|
|
|
func (s *SOCKSConnection) queueInboundPacket(packet protocol.Packet, maxBuffered int) ([]protocol.Packet, bool, bool) {
|
|
s.reorderMu.Lock()
|
|
defer s.reorderMu.Unlock()
|
|
|
|
expected := s.expectedInboundSequenceLocked()
|
|
if packet.Sequence < expected {
|
|
return nil, true, false
|
|
}
|
|
pendingForSequence := s.PendingInbound[packet.Sequence]
|
|
if containsPendingInboundPacket(pendingForSequence, packet) {
|
|
return nil, true, false
|
|
}
|
|
if bufferedInboundPacketCount(s.PendingInbound) >= maxBuffered {
|
|
return nil, false, true
|
|
}
|
|
|
|
s.PendingInbound[packet.Sequence] = append(s.PendingInbound[packet.Sequence], PendingInboundPacket{
|
|
Packet: packet,
|
|
QueuedAt: time.Now(),
|
|
})
|
|
|
|
if !s.ConnectAccepted {
|
|
return nil, false, false
|
|
}
|
|
return s.drainReadyInboundLocked(), false, false
|
|
}
|
|
|
|
func (s *SOCKSConnection) activateInboundDrain() []protocol.Packet {
|
|
s.reorderMu.Lock()
|
|
defer s.reorderMu.Unlock()
|
|
return s.drainReadyInboundLocked()
|
|
}
|
|
|
|
func (s *SOCKSConnection) expectedInboundSequenceLocked() uint64 {
|
|
if s.NextInboundSequence == 0 {
|
|
return 1
|
|
}
|
|
return s.NextInboundSequence
|
|
}
|
|
|
|
func (s *SOCKSConnection) drainReadyInboundLocked() []protocol.Packet {
|
|
expected := s.expectedInboundSequenceLocked()
|
|
ready := make([]protocol.Packet, 0)
|
|
for {
|
|
pendingPackets, ok := s.PendingInbound[expected]
|
|
if !ok || len(pendingPackets) == 0 {
|
|
break
|
|
}
|
|
sortPendingInboundPackets(pendingPackets)
|
|
for _, pending := range pendingPackets {
|
|
ready = append(ready, pending.Packet)
|
|
}
|
|
delete(s.PendingInbound, expected)
|
|
expected++
|
|
}
|
|
s.NextInboundSequence = expected
|
|
return ready
|
|
}
|
|
|
|
func (s *SOCKSConnection) hasExpiredInboundGap(timeout time.Duration) bool {
|
|
if timeout <= 0 {
|
|
return false
|
|
}
|
|
|
|
s.reorderMu.Lock()
|
|
defer s.reorderMu.Unlock()
|
|
now := time.Now()
|
|
for _, pendingPackets := range s.PendingInbound {
|
|
for _, pending := range pendingPackets {
|
|
if now.Sub(pending.QueuedAt) >= timeout {
|
|
clear(s.PendingInbound)
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func containsPendingInboundPacket(pendingPackets []PendingInboundPacket, packet protocol.Packet) bool {
|
|
for _, pending := range pendingPackets {
|
|
if pending.Packet.Type == packet.Type &&
|
|
pending.Packet.FragmentID == packet.FragmentID &&
|
|
pending.Packet.TotalFragments == packet.TotalFragments {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func bufferedInboundPacketCount(pending map[uint64][]PendingInboundPacket) int {
|
|
total := 0
|
|
for _, pendingPackets := range pending {
|
|
total += len(pendingPackets)
|
|
}
|
|
return total
|
|
}
|
|
|
|
func sortPendingInboundPackets(pendingPackets []PendingInboundPacket) {
|
|
for i := 1; i < len(pendingPackets); i++ {
|
|
current := pendingPackets[i]
|
|
j := i - 1
|
|
for ; j >= 0 && inboundPacketSortOrder(current.Packet.Type) < inboundPacketSortOrder(pendingPackets[j].Packet.Type); j-- {
|
|
pendingPackets[j+1] = pendingPackets[j]
|
|
}
|
|
pendingPackets[j+1] = current
|
|
}
|
|
}
|
|
|
|
func inboundPacketSortOrder(packetType protocol.PacketType) int {
|
|
switch packetType {
|
|
case protocol.PacketTypeSOCKSData:
|
|
return 0
|
|
case protocol.PacketTypeSOCKSCloseRead:
|
|
return 1
|
|
case protocol.PacketTypeSOCKSCloseWrite:
|
|
return 2
|
|
case protocol.PacketTypeSOCKSRST:
|
|
return 3
|
|
default:
|
|
return 4
|
|
}
|
|
}
|
|
|
|
func isReorderSequencedPacket(packetType protocol.PacketType) bool {
|
|
switch packetType {
|
|
case protocol.PacketTypeSOCKSData,
|
|
protocol.PacketTypeSOCKSCloseRead,
|
|
protocol.PacketTypeSOCKSCloseWrite,
|
|
protocol.PacketTypeSOCKSRST:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|