mirror of
				https://github.com/bolucat/Archive.git
				synced 2025-10-31 11:57:05 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package nat
 | |
| 
 | |
| import (
 | |
| 	"net"
 | |
| 	"sync"
 | |
| 
 | |
| 	C "github.com/MerlinKodo/clash-rev/constant"
 | |
| 
 | |
| 	"github.com/puzpuzpuz/xsync/v2"
 | |
| )
 | |
| 
 | |
| type Table struct {
 | |
| 	mapping *xsync.MapOf[string, *Entry]
 | |
| 	lockMap *xsync.MapOf[string, *sync.Cond]
 | |
| }
 | |
| 
 | |
| type Entry struct {
 | |
| 	PacketConn      C.PacketConn
 | |
| 	WriteBackProxy  C.WriteBackProxy
 | |
| 	LocalUDPConnMap *xsync.MapOf[string, *net.UDPConn]
 | |
| 	LocalLockMap    *xsync.MapOf[string, *sync.Cond]
 | |
| }
 | |
| 
 | |
| func (t *Table) Set(key string, e C.PacketConn, w C.WriteBackProxy) {
 | |
| 	t.mapping.Store(key, &Entry{
 | |
| 		PacketConn:      e,
 | |
| 		WriteBackProxy:  w,
 | |
| 		LocalUDPConnMap: xsync.NewMapOf[*net.UDPConn](),
 | |
| 		LocalLockMap:    xsync.NewMapOf[*sync.Cond](),
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func (t *Table) Get(key string) (C.PacketConn, C.WriteBackProxy) {
 | |
| 	entry, exist := t.getEntry(key)
 | |
| 	if !exist {
 | |
| 		return nil, nil
 | |
| 	}
 | |
| 	return entry.PacketConn, entry.WriteBackProxy
 | |
| }
 | |
| 
 | |
| func (t *Table) GetOrCreateLock(key string) (*sync.Cond, bool) {
 | |
| 	item, loaded := t.lockMap.LoadOrCompute(key, makeLock)
 | |
| 	return item, loaded
 | |
| }
 | |
| 
 | |
| func (t *Table) Delete(key string) {
 | |
| 	t.mapping.Delete(key)
 | |
| }
 | |
| 
 | |
| func (t *Table) DeleteLock(lockKey string) {
 | |
| 	t.lockMap.Delete(lockKey)
 | |
| }
 | |
| 
 | |
| func (t *Table) GetForLocalConn(lAddr, rAddr string) *net.UDPConn {
 | |
| 	entry, exist := t.getEntry(lAddr)
 | |
| 	if !exist {
 | |
| 		return nil
 | |
| 	}
 | |
| 	item, exist := entry.LocalUDPConnMap.Load(rAddr)
 | |
| 	if !exist {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return item
 | |
| }
 | |
| 
 | |
| func (t *Table) AddForLocalConn(lAddr, rAddr string, conn *net.UDPConn) bool {
 | |
| 	entry, exist := t.getEntry(lAddr)
 | |
| 	if !exist {
 | |
| 		return false
 | |
| 	}
 | |
| 	entry.LocalUDPConnMap.Store(rAddr, conn)
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func (t *Table) RangeForLocalConn(lAddr string, f func(key string, value *net.UDPConn) bool) {
 | |
| 	entry, exist := t.getEntry(lAddr)
 | |
| 	if !exist {
 | |
| 		return
 | |
| 	}
 | |
| 	entry.LocalUDPConnMap.Range(f)
 | |
| }
 | |
| 
 | |
| func (t *Table) GetOrCreateLockForLocalConn(lAddr, key string) (*sync.Cond, bool) {
 | |
| 	entry, loaded := t.getEntry(lAddr)
 | |
| 	if !loaded {
 | |
| 		return nil, false
 | |
| 	}
 | |
| 	item, loaded := entry.LocalLockMap.LoadOrCompute(key, makeLock)
 | |
| 	return item, loaded
 | |
| }
 | |
| 
 | |
| func (t *Table) DeleteForLocalConn(lAddr, key string) {
 | |
| 	entry, loaded := t.getEntry(lAddr)
 | |
| 	if !loaded {
 | |
| 		return
 | |
| 	}
 | |
| 	entry.LocalUDPConnMap.Delete(key)
 | |
| }
 | |
| 
 | |
| func (t *Table) DeleteLockForLocalConn(lAddr, key string) {
 | |
| 	entry, loaded := t.getEntry(lAddr)
 | |
| 	if !loaded {
 | |
| 		return
 | |
| 	}
 | |
| 	entry.LocalLockMap.Delete(key)
 | |
| }
 | |
| 
 | |
| func (t *Table) getEntry(key string) (*Entry, bool) {
 | |
| 	return t.mapping.Load(key)
 | |
| }
 | |
| 
 | |
| func makeLock() *sync.Cond {
 | |
| 	return sync.NewCond(&sync.Mutex{})
 | |
| }
 | |
| 
 | |
| // New return *Cache
 | |
| func New() *Table {
 | |
| 	return &Table{
 | |
| 		mapping: xsync.NewMapOf[*Entry](),
 | |
| 		lockMap: xsync.NewMapOf[*sync.Cond](),
 | |
| 	}
 | |
| }
 | 
