package fasthttp

import (
	
	
)

type perIPConnCounter struct {
	pool sync.Pool
	lock sync.Mutex
	m    map[uint32]int
}

func ( *perIPConnCounter) ( uint32) int {
	.lock.Lock()
	if .m == nil {
		.m = make(map[uint32]int)
	}
	 := .m[] + 1
	.m[] = 
	.lock.Unlock()
	return 
}

func ( *perIPConnCounter) ( uint32) {
	.lock.Lock()
	defer .lock.Unlock()
	if .m == nil {
		// developer safeguard
		panic("BUG: perIPConnCounter.Register() wasn't called")
	}
	 := .m[] - 1
	if  < 0 {
		 = 0
	}
	.m[] = 
}

type perIPConn struct {
	net.Conn

	ip               uint32
	perIPConnCounter *perIPConnCounter
}

func acquirePerIPConn( net.Conn,  uint32,  *perIPConnCounter) *perIPConn {
	 := .pool.Get()
	if  == nil {
		return &perIPConn{
			perIPConnCounter: ,
			Conn:             ,
			ip:               ,
		}
	}
	 := .(*perIPConn)
	.Conn = 
	.ip = 
	return 
}

func releasePerIPConn( *perIPConn) {
	.Conn = nil
	.perIPConnCounter.pool.Put()
}

func ( *perIPConn) () error {
	 := .Conn.Close()
	.perIPConnCounter.Unregister(.ip)
	releasePerIPConn()
	return 
}

func getUint32IP( net.Conn) uint32 {
	return ip2uint32(getConnIP4())
}

func getConnIP4( net.Conn) net.IP {
	 := .RemoteAddr()
	,  := .(*net.TCPAddr)
	if ! {
		return net.IPv4zero
	}
	return .IP.To4()
}

func ip2uint32( net.IP) uint32 {
	if len() != 4 {
		return 0
	}
	return uint32([0])<<24 | uint32([1])<<16 | uint32([2])<<8 | uint32([3])
}

func uint322ip( uint32) net.IP {
	 := make([]byte, 4)
	[0] = byte( >> 24)
	[1] = byte( >> 16)
	[2] = byte( >> 8)
	[3] = byte()
	return 
}