package ldap import ( "net" "net/netip" "time" "tug/internal/platform/ratelimit" fk "tug/internal/transport/ldap/internal/glauthldap" ) const ( peerBurst = 20 peerEvery = 6 * time.Second peerEntries = 10000 ) type peerLimit struct { table *ratelimit.Table[netip.Prefix] rate ratelimit.Rate } func newPeerLimit(now func() time.Time, rate ratelimit.Rate, max int) *peerLimit { return &peerLimit{table: ratelimit.New[netip.Prefix](max, now), rate: rate} } func peerAddr(conn net.Conn) netip.Addr { ap, err := netip.ParseAddrPort(conn.RemoteAddr().String()) if err != nil { return netip.Addr{} } return ap.Addr().WithZone("").Unmap() } func (s *Server) bindFrom(addr netip.Addr, bindDN, bindSimplePw string) (fk.LDAPResultCode, string) { peer := ratelimit.Prefix(addr) if _, ok := s.peers.table.Allowed(peer, s.peers.rate); !ok { return fk.LDAPResultBusy, bindLimited } code, result, userID := s.bind(bindDN, bindSimplePw) s.auditBind(addr, result, userID) if result == bindRejected { s.peers.table.Take(peer, s.peers.rate) } return code, result }