diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c54f65..9b1d7ca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: cache: true - name: Test - run: go test -v . + run: go test -v ./... - name: Build uses: goreleaser/goreleaser-action@v6 diff --git a/.gitignore b/.gitignore index 53ba03b..17b3186 100644 --- a/.gitignore +++ b/.gitignore @@ -17,12 +17,14 @@ # custom .idea .vscode +.zed .DS_Store # dev test only /dev/ dev*.go +*_test.go dist diff --git a/dns/client.go b/dns/client.go index 9d78dd0..e82f293 100644 --- a/dns/client.go +++ b/dns/client.go @@ -179,7 +179,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) ( ups := c.UpStream(qname) server = ups.Server() - for i := 0; i < ups.Len(); i++ { + for range ups.Len() { var rc net.Conn rc, err = dialer.Dial(network, server) if err != nil { diff --git a/dns/message.go b/dns/message.go index adbbab1..ec53613 100644 --- a/dns/message.go +++ b/dns/message.go @@ -5,7 +5,7 @@ import ( "encoding/binary" "errors" "io" - "math/rand" + "math/rand/v2" "net/netip" "strings" ) @@ -146,7 +146,7 @@ func UnmarshalMessage(b []byte) (*Message, error) { // resp answers rrIdx := HeaderLen + qLen - for i := 0; i < int(m.Header.ANCOUNT); i++ { + for range int(m.Header.ANCOUNT) { rr := &RR{} rrLen, err := m.UnmarshalRR(rrIdx, rr) if err != nil { diff --git a/proxy/obfs/tls.go b/proxy/obfs/tls.go index 42b0da0..9548964 100644 --- a/proxy/obfs/tls.go +++ b/proxy/obfs/tls.go @@ -64,10 +64,7 @@ func (c *TLSObfsConn) Write(b []byte) (int, error) { n := len(b) for i := 0; i < n; i += chunkSize { buf.Reset() - end := i + chunkSize - if end > n { - end = n - } + end := min(i+chunkSize, n) buf.Write([]byte{0x17, 0x03, 0x03}) binary.Write(buf, binary.BigEndian, uint16(len(b[i:end]))) diff --git a/proxy/ssr/internal/cipher/cipher.go b/proxy/ssr/internal/cipher/cipher.go index 0e79f02..7a88aac 100644 --- a/proxy/ssr/internal/cipher/cipher.go +++ b/proxy/ssr/internal/cipher/cipher.go @@ -5,10 +5,10 @@ import ( "crypto/cipher" "crypto/des" "crypto/md5" + "crypto/rand" "crypto/rc4" "encoding/binary" "errors" - "math/rand" "github.com/aead/chacha20" "github.com/dgryski/go-camellia" diff --git a/proxy/ssr/internal/client.go b/proxy/ssr/internal/client.go index 0fd3eab..4109350 100644 --- a/proxy/ssr/internal/client.go +++ b/proxy/ssr/internal/client.go @@ -8,9 +8,7 @@ import ( "bytes" "errors" "fmt" - "math/rand" "net" - "time" "github.com/nadoo/glider/pkg/pool" "github.com/nadoo/glider/proxy" @@ -21,10 +19,6 @@ import ( var bufSize = proxy.TCPBufSize -func init() { - rand.Seed(time.Now().UnixNano()) -} - // SSTCPConn the struct that override the net.Conn methods type SSTCPConn struct { net.Conn diff --git a/proxy/ssr/internal/obfs/http_post.go b/proxy/ssr/internal/obfs/http_post.go index 9a148e5..d1dce8f 100644 --- a/proxy/ssr/internal/obfs/http_post.go +++ b/proxy/ssr/internal/obfs/http_post.go @@ -1,7 +1,7 @@ package obfs import ( - "math/rand" + "math/rand/v2" ) func init() { @@ -13,7 +13,7 @@ func newHttpPost() IObfs { // newHttpSimple create a http_simple object t := &httpSimplePost{ - userAgentIndex: rand.Intn(len(requestUserAgent)), + userAgentIndex: rand.IntN(len(requestUserAgent)), methodGet: false, } return t diff --git a/proxy/ssr/internal/obfs/http_simple.go b/proxy/ssr/internal/obfs/http_simple.go index beda5dc..f438c25 100644 --- a/proxy/ssr/internal/obfs/http_simple.go +++ b/proxy/ssr/internal/obfs/http_simple.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/hex" "fmt" - "math/rand" + "math/rand/v2" "strings" "github.com/nadoo/glider/proxy/ssr/internal/ssr" @@ -55,7 +55,7 @@ func newHttpSimple() IObfs { t := &httpSimplePost{ rawTransSent: false, rawTransReceived: false, - userAgentIndex: rand.Intn(len(requestUserAgent)), + userAgentIndex: rand.IntN(len(requestUserAgent)), methodGet: true, } return t @@ -80,14 +80,14 @@ func (t *httpSimplePost) GetData() any { func (t *httpSimplePost) boundary() (ret string) { set := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - for i := 0; i < 32; i++ { - ret = fmt.Sprintf("%s%c", ret, set[rand.Intn(len(set))]) + for range 32 { + ret = fmt.Sprintf("%s%c", ret, set[rand.IntN(len(set))]) } return } func (t *httpSimplePost) data2URLEncode(data []byte) (ret string) { - for i := 0; i < len(data); i++ { + for i := range data { ret = fmt.Sprintf("%s%%%s", ret, hex.EncodeToString([]byte{data[i]})) } return @@ -101,12 +101,12 @@ func (t *httpSimplePost) Encode(data []byte) (encodedData []byte, err error) { dataLength := len(data) var headData []byte if headSize := t.IVLen + t.HeadLen; dataLength-headSize > 64 { - headData = make([]byte, headSize+rand.Intn(64)) + headData = make([]byte, headSize+rand.IntN(64)) } else { headData = make([]byte, dataLength) } copy(headData, data[0:len(headData)]) - requestPathIndex := rand.Intn(len(requestPath)/2) * 2 + requestPathIndex := rand.IntN(len(requestPath)/2) * 2 host := t.Host var customHead string @@ -122,7 +122,7 @@ func (t *httpSimplePost) Encode(data []byte) (encodedData []byte, err error) { } hosts := strings.Split(param, ",") if len(hosts) > 0 { - host = strings.TrimSpace(hosts[rand.Intn(len(hosts))]) + host = strings.TrimSpace(hosts[rand.IntN(len(hosts))]) } } method := "GET /" diff --git a/proxy/ssr/internal/obfs/random_head.go b/proxy/ssr/internal/obfs/random_head.go index 969977e..34fff19 100644 --- a/proxy/ssr/internal/obfs/random_head.go +++ b/proxy/ssr/internal/obfs/random_head.go @@ -1,7 +1,8 @@ package obfs import ( - "math/rand" + crand "crypto/rand" + "math/rand/v2" "github.com/nadoo/glider/proxy/ssr/internal/ssr" ) @@ -57,9 +58,9 @@ func (r *randomHead) Encode(data []byte) (encodedData []byte, err error) { r.rawTransSent = true } } else { - size := rand.Intn(96) + 8 + size := rand.IntN(96) + 8 encodedData = make([]byte, size) - rand.Read(encodedData) + crand.Read(encodedData) ssr.SetCRC32(encodedData, size) d := make([]byte, dataLength) diff --git a/proxy/ssr/internal/obfs/tls12_ticket_auth.go b/proxy/ssr/internal/obfs/tls12_ticket_auth.go index 970b9da..fb9c9d4 100644 --- a/proxy/ssr/internal/obfs/tls12_ticket_auth.go +++ b/proxy/ssr/internal/obfs/tls12_ticket_auth.go @@ -3,10 +3,11 @@ package obfs import ( "bytes" "crypto/hmac" + crand "crypto/rand" "encoding/binary" "fmt" "log" - "math/rand" + "math/rand/v2" "strings" "time" @@ -64,7 +65,7 @@ func (t *tls12TicketAuth) GetData() any { t.data = &tlsAuthData{} b := make([]byte, 32) - rand.Read(b) + crand.Read(b) copy(t.data.localClientID[:], b) } return t.data @@ -76,7 +77,7 @@ func (t *tls12TicketAuth) getHost() string { hosts := strings.Split(t.Param, ",") if len(hosts) > 0 { - host = hosts[rand.Intn(len(hosts))] + host = hosts[rand.IntN(len(hosts))] host = strings.TrimSpace(host) } } @@ -96,7 +97,6 @@ func packData(prefixData []byte, suffixData []byte) (outData []byte) { func (t *tls12TicketAuth) Encode(data []byte) (encodedData []byte, err error) { encodedData = make([]byte, 0) - rand.Seed(time.Now().UnixNano()) switch t.handshakeStatus { case 8: if len(data) < 1024 { @@ -108,7 +108,7 @@ func (t *tls12TicketAuth) Encode(data []byte) (encodedData []byte, err error) { start := 0 var l int for len(data)-start > 2048 { - l = rand.Intn(4096) + 100 + l = rand.IntN(4096) + 100 if l > len(data)-start { l = len(data) - start } @@ -129,7 +129,7 @@ func (t *tls12TicketAuth) Encode(data []byte) (encodedData []byte, err error) { start := 0 var l int for len(data)-start > 2048 { - l = rand.Intn(4096) + 100 + l = rand.IntN(4096) + 100 if l > len(data)-start { l = len(data) - start } @@ -148,7 +148,7 @@ func (t *tls12TicketAuth) Encode(data []byte) (encodedData []byte, err error) { hmacData := make([]byte, 43) handshakeFinish := []byte("\x14\x03\x03\x00\x01\x01\x16\x03\x03\x00\x20") copy(hmacData, handshakeFinish) - rand.Read(hmacData[11:33]) + crand.Read(hmacData[11:33]) h := t.hmacSHA1(hmacData[:33]) copy(hmacData[33:], h) encodedData = append(hmacData, t.sendSaver...) @@ -169,11 +169,11 @@ func (t *tls12TicketAuth) Encode(data []byte) (encodedData []byte, err error) { tlsDataLen += len(sni) copy(tlsData[tlsDataLen:], tlsData2) tlsDataLen += len(tlsData2) - ticketLen := rand.Intn(164)*2 + 64 + ticketLen := rand.IntN(164)*2 + 64 tlsData[tlsDataLen-1] = uint8(ticketLen & 0xff) tlsData[tlsDataLen-2] = uint8(ticketLen >> 8) //ticketLen := 208 - rand.Read(tlsData[tlsDataLen : tlsDataLen+ticketLen]) + crand.Read(tlsData[tlsDataLen : tlsDataLen+ticketLen]) tlsDataLen += ticketLen copy(tlsData[tlsDataLen:], tlsData3) tlsDataLen += len(tlsData3) @@ -278,7 +278,7 @@ func (t *tls12TicketAuth) packAuthData() (outData []byte) { now := time.Now().Unix() binary.BigEndian.PutUint32(outData[0:4], uint32(now)) - rand.Read(outData[4 : 4+18]) + crand.Read(outData[4 : 4+18]) hash := t.hmacSHA1(outData[:outSize-ssr.ObfsHMACSHA1Len]) copy(outData[outSize-ssr.ObfsHMACSHA1Len:], hash) diff --git a/proxy/ssr/internal/protocol/auth_aes128_md5.go b/proxy/ssr/internal/protocol/auth_aes128_md5.go index 5e47e39..b489aa7 100644 --- a/proxy/ssr/internal/protocol/auth_aes128_md5.go +++ b/proxy/ssr/internal/protocol/auth_aes128_md5.go @@ -4,9 +4,10 @@ import ( "bytes" "crypto/aes" "crypto/cipher" + crand "crypto/rand" "encoding/base64" "encoding/binary" - "math/rand" + "math/rand/v2" "strconv" "strings" "time" @@ -74,15 +75,14 @@ func (a *authAES128) GetData() any { func (a *authAES128) packData(data []byte) (outData []byte) { dataLength := len(data) randLength := 1 - rand.Seed(time.Now().UnixNano()) if dataLength <= 1200 { if a.packID > 4 { - randLength += rand.Intn(32) + randLength += rand.IntN(32) } else { if dataLength > 900 { - randLength += rand.Intn(128) + randLength += rand.IntN(128) } else { - randLength += rand.Intn(512) + randLength += rand.IntN(512) } } } @@ -98,7 +98,7 @@ func (a *authAES128) packData(data []byte) (outData []byte) { h := a.hmac(key, outData[0:2]) copy(outData[2:4], h[:2]) // 4~rand length+4, rand number - rand.Read(outData[4 : 4+randLength]) + crand.Read(outData[4 : 4+randLength]) // 4, rand length if randLength < 128 { outData[4] = byte(randLength & 0xFF) @@ -121,11 +121,10 @@ func (a *authAES128) packData(data []byte) (outData []byte) { func (a *authAES128) packAuthData(data []byte) (outData []byte) { dataLength := len(data) var randLength int - rand.Seed(time.Now().UnixNano()) if dataLength > 400 { - randLength = rand.Intn(512) + randLength = rand.IntN(512) } else { - randLength = rand.Intn(1024) + randLength = rand.IntN(1024) } dataOffset := randLength + 16 + 4 + 4 + 7 @@ -136,7 +135,7 @@ func (a *authAES128) packAuthData(data []byte) (outData []byte) { copy(key, a.IV) copy(key[a.IVLen:], a.Key) - rand.Read(outData[dataOffset-randLength:]) + crand.Read(outData[dataOffset-randLength:]) a.data.mutex.Lock() a.data.connectionID++ if a.data.connectionID > 0xFF000000 { @@ -144,9 +143,9 @@ func (a *authAES128) packAuthData(data []byte) (outData []byte) { } if len(a.data.clientID) == 0 { a.data.clientID = make([]byte, 8) - rand.Read(a.data.clientID) + crand.Read(a.data.clientID) b := make([]byte, 4) - rand.Read(b) + crand.Read(b) a.data.connectionID = binary.LittleEndian.Uint32(b) & 0xFFFFFF } copy(encrypt[4:], a.data.clientID) @@ -163,13 +162,13 @@ func (a *authAES128) packAuthData(data []byte) (outData []byte) { uid := make([]byte, 4) if len(params) >= 2 { if userID, err := strconv.ParseUint(params[0], 10, 32); err != nil { - rand.Read(uid) + crand.Read(uid) } else { binary.LittleEndian.PutUint32(uid, uint32(userID)) a.userKey = a.hashDigest([]byte(params[1])) } } else { - rand.Read(uid) + crand.Read(uid) } if a.userKey == nil { @@ -196,7 +195,7 @@ func (a *authAES128) packAuthData(data []byte) (outData []byte) { h := a.hmac(key, encrypt[0:20]) copy(encrypt[20:], h[:4]) - rand.Read(outData[0:1]) + crand.Read(outData[0:1]) h = a.hmac(key, outData[0:1]) copy(outData[1:], h[0:7-1]) diff --git a/proxy/ssr/internal/protocol/auth_chain_a.go b/proxy/ssr/internal/protocol/auth_chain_a.go index baf8628..c68c441 100644 --- a/proxy/ssr/internal/protocol/auth_chain_a.go +++ b/proxy/ssr/internal/protocol/auth_chain_a.go @@ -6,9 +6,9 @@ import ( "bytes" "crypto/aes" stdCipher "crypto/cipher" + "crypto/rand" "encoding/base64" "encoding/binary" - "math/rand" "strconv" "strings" "time" @@ -194,7 +194,7 @@ func (a *authChainA) packAuthData(data []byte) (outData []byte) { copy(a.userKey, a.Key) } } - for i := 0; i < 4; i++ { + for i := range 4 { uid[i] = a.uid[i] ^ a.lastClientHash[8+i] } base64UserKey = base64.StdEncoding.EncodeToString(a.userKey) diff --git a/proxy/ssr/internal/protocol/auth_chain_b.go b/proxy/ssr/internal/protocol/auth_chain_b.go index 90659e7..35458a2 100644 --- a/proxy/ssr/internal/protocol/auth_chain_b.go +++ b/proxy/ssr/internal/protocol/auth_chain_b.go @@ -34,14 +34,14 @@ func (a *authChainA) authChainBInitDataSize() { random.InitFromBin(a.Key) length := random.Next()%8 + 4 a.dataSizeList = make([]int, length) - for i := 0; i < int(length); i++ { + for i := range int(length) { a.dataSizeList[i] = int(random.Next() % 2340 % 2040 % 1440) } sort.Ints(a.dataSizeList) length = random.Next()%16 + 8 a.dataSizeList2 = make([]int, length) - for i := 0; i < int(length); i++ { + for i := range int(length) { a.dataSizeList2[i] = int(random.Next() % 2340 % 2040 % 1440) } sort.Ints(a.dataSizeList2) diff --git a/proxy/ssr/internal/protocol/auth_sha1_v4.go b/proxy/ssr/internal/protocol/auth_sha1_v4.go index f5b4aac..ce2dd55 100644 --- a/proxy/ssr/internal/protocol/auth_sha1_v4.go +++ b/proxy/ssr/internal/protocol/auth_sha1_v4.go @@ -2,8 +2,9 @@ package protocol import ( "bytes" + crand "crypto/rand" "encoding/binary" - "math/rand" + "math/rand/v2" "time" "github.com/nadoo/glider/proxy/ssr/internal/ssr" @@ -53,9 +54,9 @@ func (a *authSHA1v4) packData(data []byte) (outData []byte) { if dataLength <= 1300 { if dataLength > 400 { - randLength += rand.Intn(128) + randLength += rand.IntN(128) } else { - randLength += rand.Intn(1024) + randLength += rand.IntN(1024) } } @@ -90,9 +91,9 @@ func (a *authSHA1v4) packAuthData(data []byte) (outData []byte) { randLength := 1 if dataLength <= 1300 { if dataLength > 400 { - randLength += rand.Intn(128) + randLength += rand.IntN(128) } else { - randLength += rand.Intn(1024) + randLength += rand.IntN(1024) } } dataOffset := randLength + 4 + 2 @@ -104,9 +105,9 @@ func (a *authSHA1v4) packAuthData(data []byte) (outData []byte) { } if len(a.data.clientID) == 0 { a.data.clientID = make([]byte, 8) - rand.Read(a.data.clientID) + crand.Read(a.data.clientID) b := make([]byte, 4) - rand.Read(b) + crand.Read(b) a.data.connectionID = binary.LittleEndian.Uint32(b) & 0xFFFFFF } // 0-1, out length @@ -122,7 +123,7 @@ func (a *authSHA1v4) packAuthData(data []byte) (outData []byte) { // 2~6, crc of out length+salt+key binary.LittleEndian.PutUint32(outData[2:], crc32) // 6~rand length+6, rand numbers - rand.Read(outData[dataOffset-randLength : dataOffset]) + crand.Read(outData[dataOffset-randLength : dataOffset]) // 6, rand length if randLength < 128 { outData[6] = byte(randLength & 0xFF) diff --git a/proxy/ssr/internal/ssr/crc32.go b/proxy/ssr/internal/ssr/crc32.go index 9cf6cc6..a36a79c 100644 --- a/proxy/ssr/internal/ssr/crc32.go +++ b/proxy/ssr/internal/ssr/crc32.go @@ -11,7 +11,7 @@ func init() { } func createCRC32Table() { - for i := 0; i < 256; i++ { + for i := range 256 { crc := uint32(i) for j := 8; j > 0; j-- { if crc&1 == 1 { diff --git a/proxy/ssr/internal/tools/obfsutil.go b/proxy/ssr/internal/tools/obfsutil.go index 473bc22..c5d4bac 100644 --- a/proxy/ssr/internal/tools/obfsutil.go +++ b/proxy/ssr/internal/tools/obfsutil.go @@ -37,7 +37,7 @@ func (ctx *Shift128plusContext) InitFromBinDatalen(bin []byte, datalen int) { ctx.v[0] = binary.LittleEndian.Uint64(fillBin[:8]) ctx.v[1] = binary.LittleEndian.Uint64(fillBin[8:]) - for i := 0; i < 4; i++ { + for range 4 { ctx.Next() } } diff --git a/proxy/vmess/client.go b/proxy/vmess/client.go index cde95a8..e03afd2 100644 --- a/proxy/vmess/client.go +++ b/proxy/vmess/client.go @@ -5,13 +5,14 @@ import ( "crypto/cipher" "crypto/hmac" "crypto/md5" + crand "crypto/rand" "crypto/sha256" "encoding/binary" "errors" "fmt" "hash/fnv" "io" - "math/rand" + "math/rand/v2" "net" "runtime" "strings" @@ -121,7 +122,7 @@ func NewClient(uuidStr, security string, alterID int, aead bool) (*Client, error // NewConn returns a new vmess conn. func (c *Client) NewConn(rc net.Conn, target string, cmd CmdType) (*Conn, error) { - r := rand.Intn(c.count) + r := rand.IntN(c.count) conn := &Conn{user: c.users[r], opt: c.opt, aead: c.aead, security: c.security, Conn: rc} var err error @@ -131,12 +132,12 @@ func (c *Client) NewConn(rc net.Conn, target string, cmd CmdType) (*Conn, error) } randBytes := pool.GetBuffer(32) - rand.Read(randBytes) + crand.Read(randBytes) copy(conn.reqBodyIV[:], randBytes[:16]) copy(conn.reqBodyKey[:], randBytes[16:32]) pool.PutBuffer(randBytes) - conn.reqRespV = byte(rand.Intn(1 << 8)) + conn.reqRespV = byte(rand.IntN(1 << 8)) if conn.aead { bodyIV := sha256.Sum256(conn.reqBodyIV[:]) @@ -192,7 +193,7 @@ func (c *Conn) Request(cmd CmdType) error { buf.WriteByte(c.opt) // Opt // pLen and Sec - paddingLen := rand.Intn(16) + paddingLen := rand.IntN(16) pSec := byte(paddingLen<<4) | c.security // P(4bit) and Sec(4bit) buf.WriteByte(pSec) @@ -207,7 +208,7 @@ func (c *Conn) Request(cmd CmdType) error { // padding if paddingLen > 0 { padding := pool.GetBuffer(paddingLen) - rand.Read(padding) + crand.Read(padding) buf.Write(padding) pool.PutBuffer(padding) } diff --git a/proxy/vmess/user.go b/proxy/vmess/user.go index bcd06de..9250fe1 100644 --- a/proxy/vmess/user.go +++ b/proxy/vmess/user.go @@ -43,7 +43,7 @@ func nextID(oldID [16]byte) (newID [16]byte) { func (u *User) GenAlterIDUsers(alterID int) []*User { users := make([]*User, alterID) preID := u.UUID - for i := 0; i < alterID; i++ { + for i := range alterID { newID := nextID(preID) // NOTE: alterID user is a user which have a different uuid but a same cmdkey with the primary user. users[i] = &User{UUID: newID, CmdKey: u.CmdKey} diff --git a/proxy/ws/frame.go b/proxy/ws/frame.go index 02e2d83..ba982f9 100644 --- a/proxy/ws/frame.go +++ b/proxy/ws/frame.go @@ -25,7 +25,7 @@ package ws import ( "encoding/binary" "io" - "math/rand" + "math/rand/v2" "net" "github.com/nadoo/glider/pkg/pool" @@ -93,7 +93,7 @@ func (w *frameWriter) Write(b []byte) (int, error) { defer pool.PutBuffer(payload) // payload with mask - for i := 0; i < nPayload; i++ { + for i := range nPayload { payload[i] = b[i] ^ w.maskKey[i%4] } diff --git a/rule/group.go b/rule/group.go index fc9607b..4ecb3ea 100644 --- a/rule/group.go +++ b/rule/group.go @@ -225,7 +225,7 @@ func (p *FwdrGroup) Check() { log.F("[group] %s: using check config: %s", p.name, p.config.Check) - for i := 0; i < len(p.fwdrs); i++ { + for i := range p.fwdrs { go p.check(p.fwdrs[i], checker) } } diff --git a/service/dhcpd/pool.go b/service/dhcpd/pool.go index 908182f..2fbda3a 100644 --- a/service/dhcpd/pool.go +++ b/service/dhcpd/pool.go @@ -5,7 +5,7 @@ package dhcpd import ( "bytes" "errors" - "math/rand" + "math/rand/v2" "net" "net/netip" "sync" @@ -45,7 +45,7 @@ func NewPool(lease time.Duration, start, end netip.Addr) (*Pool, error) { go func() { for now := range time.Tick(time.Second) { p.mutex.Lock() - for i := 0; i < len(items); i++ { + for i := range len(items) { if !items[i].expire.IsZero() && now.After(items[i].expire) { items[i].mac = nil items[i].expire = time.Time{} @@ -83,7 +83,7 @@ func (p *Pool) LeaseIP(mac net.HardwareAddr, ip netip.Addr) (netip.Addr, error) } // lease new ip - idx := rand.Intn(len(p.items)) + idx := rand.IntN(len(p.items)) for _, item := range p.items[idx:] { if item.mac == nil { item.mac = mac