├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── ci.yml ├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cmake ├── FindCheck.cmake ├── FindLibatomic.cmake ├── FindLiburing.cmake ├── FindLz4.cmake ├── FindPandoc.cmake ├── FindPdflatex.cmake ├── FindRst2man.cmake ├── FindSystemd.cmake ├── FindTHREAD.cmake └── FindZstd.cmake ├── contrib ├── docker │ ├── Dockerfile.alpine │ ├── Dockerfile.rocky9 │ ├── pgagroal.conf │ └── pgagroal_hba.conf ├── grafana │ ├── README.md │ └── dashboard.json ├── shell_comp │ ├── pgagroal_comp.bash │ └── pgagroal_comp.zsh └── valgrind │ ├── README.md │ └── pgagroal.supp ├── doc ├── ADMIN.md ├── ARCHITECTURE.md ├── CLI.md ├── CMakeLists.txt ├── CONFIGURATION.md ├── DEVELOPERS.md ├── DISTRIBUTIONS.md ├── FAILOVER.md ├── GETTING_STARTED.md ├── PERFORMANCE.md ├── PIPELINES.md ├── RPM.md ├── SECURITY.md ├── TEST.md ├── VAULT.md ├── etc │ ├── pgagroal.conf │ ├── pgagroal.service │ ├── pgagroal.socket │ ├── pgagroal_hba.conf │ └── pgagroal_vault.conf ├── images │ ├── perf-extended.png │ ├── perf-prepared.png │ ├── perf-readonly.png │ └── perf-simple.png ├── man │ ├── pgagroal-admin.1.rst │ ├── pgagroal-cli.1.rst │ ├── pgagroal-vault.1.rst │ ├── pgagroal.1.rst │ ├── pgagroal.conf.5.rst │ ├── pgagroal_databases.conf.5.rst │ ├── pgagroal_hba.conf.5.rst │ └── pgagroal_vault.conf.5.rst ├── manual │ ├── 01-introduction.md │ ├── 02-installation.md │ ├── 97-acknowledgement.md │ ├── 98-licenses.md │ ├── 99-references.md │ ├── advanced │ │ ├── 00-frontpage.md │ │ ├── 01-preface.md │ │ ├── 02-introduction.md │ │ ├── 03-installation.md │ │ ├── 04-configuration.md │ │ ├── 05-prefill.md │ │ ├── 06-remote_management.md │ │ ├── 07-split_security.md │ │ ├── 08-tls.md │ │ ├── 09-vault.md │ │ ├── 10-prometheus.md │ │ ├── 11-docker.md │ │ ├── 97-acknowledgement.md │ │ ├── 98-licenses.md │ │ └── 99-references.md │ ├── dev-00-head.md │ ├── dev-01-git.md │ ├── dev-02-architecture.md │ ├── dev-03-rpm.md │ ├── dev-04-building.md │ ├── dev-05-codecoverage.md │ ├── dev-06-eventloop.md │ ├── user-00-head.md │ ├── user-01-quickstart.md │ ├── user-02-configuration.md │ ├── user-04-tutorials.md │ ├── user-10-cli.md │ ├── user-11-prometheus.md │ ├── user-12-vault.md │ └── user-13-docker.md └── tutorial │ ├── 01_install.md │ ├── 02_prefill.md │ ├── 03_remote_management.md │ ├── 04_prometheus.md │ ├── 05_split_security.md │ ├── 06_tls.md │ ├── 07_vault.md │ ├── 08_docker.md │ └── 09_testsuite.md ├── pgagroal.spec ├── src ├── CMakeLists.txt ├── admin.c ├── cli.c ├── include │ ├── aes.h │ ├── art.h │ ├── bzip2_compression.h │ ├── configuration.h │ ├── connection.h │ ├── deque.h │ ├── ev.h │ ├── gzip_compression.h │ ├── json.h │ ├── logging.h │ ├── lz4_compression.h │ ├── management.h │ ├── memory.h │ ├── message.h │ ├── network.h │ ├── pgagroal.h │ ├── pipeline.h │ ├── pool.h │ ├── prometheus.h │ ├── remote.h │ ├── security.h │ ├── server.h │ ├── shmem.h │ ├── status.h │ ├── tracker.h │ ├── utils.h │ ├── value.h │ ├── worker.h │ └── zstandard_compression.h ├── libpgagroal │ ├── aes.c │ ├── art.c │ ├── bzip2_compression.c │ ├── configuration.c │ ├── connection.c │ ├── deque.c │ ├── ev.c │ ├── gzip_compression.c │ ├── json.c │ ├── logging.c │ ├── lz4_compression.c │ ├── management.c │ ├── memory.c │ ├── message.c │ ├── network.c │ ├── pipeline_perf.c │ ├── pipeline_session.c │ ├── pipeline_transaction.c │ ├── pool.c │ ├── prometheus.c │ ├── remote.c │ ├── security.c │ ├── server.c │ ├── shmem.c │ ├── status.c │ ├── tracker.c │ ├── utils.c │ ├── value.c │ ├── worker.c │ └── zstandard_compression.c ├── main.c └── vault.c ├── test ├── CMakeLists.txt ├── Dockerfile.testsuite ├── conf │ ├── 01 │ │ ├── pgagroal.conf │ │ └── pgagroal_hba.conf │ ├── 02 │ │ ├── pgagroal.conf │ │ └── pgagroal_hba.conf │ ├── 03 │ │ ├── pgagroal.conf │ │ └── pgagroal_hba.conf │ └── 04 │ │ ├── pgagroal.conf │ │ └── pgagroal_hba.conf ├── coverage.sh ├── include │ └── tsclient.h ├── runner.c ├── testcases │ ├── pgagroal_test_1.c │ ├── pgagroal_test_1.h │ ├── pgagroal_test_2.c │ └── pgagroal_test_2.h ├── testsuite.sh └── tsclient.c ├── uncrustify.cfg └── uncrustify.sh /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | **To Reproduce** 15 | 16 | Steps to reproduce the behavior. 17 | 18 | **Version** 19 | 20 | What is the version of pgagroal ? 21 | 22 | **PostgreSQL** 23 | 24 | What is the version of PostgreSQL ? 25 | 26 | **liburing** 27 | 28 | What is the version of liburing ? 29 | 30 | **OpenSSL** 31 | 32 | What is the version of OpenSSL ? 33 | 34 | **Access method** 35 | 36 | Which security access method is used (trust, password, md5, scram-sha-256) ? 37 | 38 | **OS** 39 | 40 | Which Operating System (OS) is used ? 41 | 42 | **ulimit** 43 | 44 | What is the output from `ulimit -a` ? 45 | 46 | **Configuration** 47 | 48 | Can you provide the configuration pgagroal ? 49 | 50 | * pgagroal.conf 51 | * pgagroal_hba.conf 52 | * pgagroal_databases.conf 53 | * pgagroal_users.conf 54 | 55 | **Debug logs** 56 | 57 | Can you provide any debug logs (`log_level = debug5`) of the issue ? 58 | 59 | **Tip** 60 | 61 | Use \`\`\` before and after the text to keep the output as is. 62 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Additional information** 17 | Any additional information you can provide, like an overall design description 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | .cache/ 3 | _site/ 4 | build/ 5 | vendor/ 6 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | pgagroal was created by the following authors: 2 | 3 | Jesper Pedersen 4 | David Fetter 5 | Will Leinweber 6 | Junduo Dong 7 | Luca Ferrari 8 | Nikita Bugrovsky 9 | Lawrence Wu 10 | Yongting You <2010youy01@gmail.com> 11 | Ashutosh Sharma 12 | Henrique de Carvalho 13 | Yihe Lu 14 | Eugenio Gigante 15 | Haoran Zhang 16 | Mohanad Khaled 17 | Christian Englert 18 | Georg Pfuetzenreuter 19 | Tejas Tyagi 20 | Aryan Arora 21 | Sangkeun J.C. Kim 22 | Arshdeep Singh 23 | Vanes Angelo 24 | Bassam Adnan 25 | Mingzhuo Yin 26 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## pgagroal Community Code of Conduct 2 | 3 | ### Contributor Code of Conduct 4 | 5 | As contributors and maintainers of the projects under the [pgagroal](https://github.com/agroal/pgagroal) repository, 6 | and in the interest of fostering an open and welcoming community, we pledge to 7 | respect all people who contribute through reporting issues, posting feature 8 | requests, updating documentation, submitting pull requests or patches, and other 9 | activities to any of the projects under the pgagroal umbrella. 10 | 11 | We are committed to making participation in these projects a harassment-free experience for 12 | everyone, regardless of level of experience, gender, gender identity and expression, 13 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, 14 | religion, or nationality. 15 | 16 | Examples of unacceptable behavior by participants include: 17 | 18 | * The use of sexualized language or imagery. 19 | * Personal attacks. 20 | * Trolling or insulting/derogatory comments. 21 | * Public or private harassment. 22 | * Publishing other's private information, such as physical or electronic addresses, without explicit permission. 23 | * Other unethical or unprofessional conduct. 24 | 25 | Project maintainers have the right and responsibility to remove, edit, or reject 26 | comments, commits, code, wiki edits, issues, and other contributions that are not 27 | aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers 28 | commit themselves to fairly and consistently applying these principles to every aspect 29 | of managing their project. Project maintainers who do not follow or enforce the Code of 30 | Conduct may be permanently removed from the project team or teams if they are in multiple 31 | projects. 32 | 33 | This code of conduct applies both within project spaces and in public spaces 34 | when an individual is representing the project or its community. 35 | 36 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a maintainer of the project, Jesper Pedersen . 37 | 38 | ### pgagroal Events Code of Conduct 39 | 40 | pgagroal events are working conferences intended for professional networking and collaboration in the 41 | pgagroal community. Attendees are expected to behave according to professional standards and in accordance 42 | with their employer's policies on appropriate workplace behavior. 43 | 44 | While at pgagroal events or related social networking opportunities, attendees should not engage in 45 | discriminatory or offensive speech or actions regarding gender, sexuality, race, or religion. Speakers should 46 | be especially aware of these concerns. 47 | 48 | The maintainers of the pgagroal project do not condone any statements by speakers contrary to these standards. 49 | The maintainers of the pgagroal project reserves the right to deny entrance and/or eject from an event 50 | (without refund) any individual found to be engaging in discriminatory or offensive speech or actions. 51 | 52 | Please bring any concerns to the immediate attention of the pgagroal maintainers. 53 | 54 | This Code of Conduct was adapted from the [CNCF Community Code of Conduct v1.0](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). 55 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guide 2 | 3 | **Want to contribute? Great!** 4 | 5 | All contributions are more than welcome ! This includes bug reports, bug fixes, enhancements, features, questions, ideas, 6 | and documentation. 7 | 8 | This document will hopefully help you contribute to pgagroal. 9 | 10 | * [Legal](#legal) 11 | * [Reporting an issue](#reporting-an-issue) 12 | * [Setup your build environment](#setup-your-build-environment) 13 | * [Building the master branch](#building-the-master-branch) 14 | * [Before you contribute](#before-you-contribute) 15 | * [Code reviews](#code-reviews) 16 | * [Coding Guidelines](#coding-guidelines) 17 | * [Discuss a Feature](#discuss-a-feature) 18 | * [Development](#development) 19 | * [Code Style](#code-style) 20 | 21 | ## Legal 22 | 23 | All contributions to pgagroal are licensed under the [The 3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause). 24 | 25 | ## Reporting an issue 26 | 27 | This project uses GitHub issues to manage the issues. Open an issue directly in GitHub. 28 | 29 | If you believe you found a bug, and it's likely possible, please indicate a way to reproduce it, what you are seeing and what you would expect to see. 30 | Don't forget to indicate your pgagroal version. 31 | 32 | ## Setup your build environment 33 | 34 | You can use the follow command, if you are using a [Fedora](https://getfedora.org/) based platform: 35 | 36 | ``` 37 | dnf install git gcc cmake make liburing liburing-devel openssl openssl-devel systemd systemd-devel python3-docutils libasan libasan-static binutils 38 | ``` 39 | 40 | in order to get the necessary dependencies. 41 | 42 | ## Building the master branch 43 | 44 | To build the `master` branch: 45 | 46 | ``` 47 | git clone https://github.com/agroal/pgagroal.git 48 | cd pgagroal 49 | mkdir build 50 | cd build 51 | cmake -DCMAKE_BUILD_TYPE=Debug .. 52 | make 53 | cd src 54 | cp ../../doc/etc/*.conf . 55 | ./pgagroal -c pgagroal.conf -a pgagroal_hba.conf 56 | ``` 57 | 58 | and you will have a running instance. 59 | 60 | ## Before you contribute 61 | 62 | To contribute, use GitHub Pull Requests, from your **own** fork. 63 | 64 | Also, make sure you have set up your Git authorship correctly: 65 | 66 | ``` 67 | git config --global user.name "Your Full Name" 68 | git config --global user.email your.email@example.com 69 | ``` 70 | 71 | We use this information to acknowledge your contributions in release announcements. 72 | 73 | ## Code reviews 74 | 75 | GitHub pull requests can be reviewed by all such that input can be given to the author(s). 76 | 77 | See [GitHub Pull Request Review Process](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews) 78 | for more information. 79 | 80 | ## Coding Guidelines 81 | 82 | * Discuss the feature 83 | * Do development 84 | + Follow the code style 85 | * Commits should be atomic and semantic. Therefore, squash your pull request before submission and keep it rebased until merged 86 | + If your feature has independent parts submit those as separate pull requests 87 | 88 | ## Discuss a Feature 89 | 90 | You can discuss bug reports, enhancements and features in our [forum](https://github.com/agroal/pgagroal/discussions). 91 | 92 | Once there is an agreement on the development plan you can open an issue that will used for reference in the pull request. 93 | 94 | ## Development 95 | 96 | You can follow this workflow for your development. 97 | 98 | Add your repository 99 | 100 | ``` 101 | git clone git@github.com:yourname/pgagroal.git 102 | cd pgagroal 103 | git remote add upstream https://github.com/agroal/pgagroal.git 104 | ``` 105 | 106 | Create a work branch 107 | 108 | ``` 109 | git checkout -b mywork master 110 | ``` 111 | 112 | During development 113 | 114 | ``` 115 | git commit -a -m "[#issue] My feature" 116 | git push -f origin mywork 117 | ``` 118 | 119 | If you have more commits then squash them 120 | 121 | ``` 122 | git rebase -i HEAD~2 123 | git push -f origin mywork 124 | ``` 125 | 126 | If the `master` branch changes then 127 | 128 | ``` 129 | git fetch upstream 130 | git rebase -i upstream/master 131 | git push -f origin mywork 132 | ``` 133 | 134 | as all pull requests should be squashed and rebased. 135 | 136 | In your first pull request you need to add yourself to the `AUTHORS` file. 137 | 138 | ## Code Style 139 | 140 | Please, follow the coding style of the project. 141 | 142 | You can use the [uncrustify](http://uncrustify.sourceforge.net/) tool to help with the formatting, by running 143 | 144 | ``` 145 | ./uncrustify.sh 146 | ``` 147 | 148 | and verify the changes. 149 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2025 The pgagroal community 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list 8 | of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or other 12 | materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors may 15 | be used to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /cmake/FindCheck.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # check support 3 | # 4 | 5 | find_package(PkgConfig) 6 | pkg_check_modules(PC_CHECK check) 7 | 8 | find_path(CHECK_INCLUDE_DIR 9 | NAMES check.h 10 | PATHS ${PC_CHECK_INCLUDE_DIRS} 11 | PATH_SUFFIXES check 12 | ) 13 | 14 | find_library(CHECK_LIBRARY 15 | NAMES check 16 | PATHS ${PC_CHECK_LIBRARY_DIRS} 17 | ) 18 | 19 | include(FindPackageHandleStandardArgs) 20 | find_package_handle_standard_args(Check DEFAULT_MSG CHECK_INCLUDE_DIR CHECK_LIBRARY) 21 | 22 | if (CHECK_FOUND) 23 | set(CHECK_LIBRARIES ${CHECK_LIBRARY}) 24 | set(CHECK_INCLUDE_DIRS ${CHECK_INCLUDE_DIR}) 25 | else () 26 | set(check FALSE) 27 | endif () 28 | 29 | mark_as_advanced(CHECK_INCLUDE_DIR CHECK_LIBRARY) 30 | -------------------------------------------------------------------------------- /cmake/FindLibatomic.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find libatomic 2 | # Once done this will define 3 | # LIBATOMIC_FOUND - System has libatomic 4 | # LIBATOMIC_LIBRARY - The library needed to use libatomic 5 | 6 | FIND_LIBRARY(LIBATOMIC_LIBRARY NAMES atomic atomic.so.1 libatomic.so.1 7 | HINTS 8 | /usr/local/lib64 9 | /usr/local/lib 10 | /opt/local/lib64 11 | /opt/local/lib 12 | /usr/lib64 13 | /usr/lib 14 | /lib64 15 | /lib 16 | ) 17 | 18 | IF (LIBATOMIC_LIBRARY) 19 | SET(LIBATOMIC_FOUND TRUE) 20 | ELSE () 21 | SET(LIBATOMIC_FOUND FALSE) 22 | ENDIF () 23 | -------------------------------------------------------------------------------- /cmake/FindLiburing.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find liburing 2 | # Once done this will define 3 | # LIBURING_FOUND - System has liburing 4 | # LIBURING_LIBRARY - The library needed to use liburing 5 | 6 | FIND_LIBRARY(LIBURING_LIBRARY NAMES liburing liburing.a liburing.so liburing.so.2 7 | HINTS 8 | /usr/lib64 9 | /usr/lib 10 | /lib64 11 | /lib 12 | ) 13 | 14 | IF (LIBURING_LIBRARY) 15 | SET(LIBURING_FOUND TRUE) 16 | ELSE () 17 | SET(LIBURING_FOUND FALSE) 18 | ENDIF () 19 | -------------------------------------------------------------------------------- /cmake/FindLz4.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # LZ4 Support 3 | # 4 | 5 | find_path(LZ4_INCLUDE_DIR 6 | NAMES lz4.h 7 | ) 8 | find_library(LZ4_LIBRARY 9 | NAMES lz4 10 | ) 11 | 12 | include(FindPackageHandleStandardArgs) 13 | find_package_handle_standard_args(Lz4 DEFAULT_MSG 14 | LZ4_LIBRARY LZ4_INCLUDE_DIR) 15 | 16 | if(LZ4_FOUND) 17 | set(LZ4_LIBRARIES ${LZ4_LIBRARY}) 18 | set(LZ4_INCLUDE_DIRS ${LZ4_INCLUDE_DIR}) 19 | endif() 20 | 21 | mark_as_advanced(LZ4_INCLUDE_DIR LZ4_LIBRARY) 22 | -------------------------------------------------------------------------------- /cmake/FindPandoc.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # pandoc Support 3 | # 4 | 5 | find_program(PANDOC_EXECUTABLE 6 | NAMES pandoc 7 | ) 8 | 9 | include(FindPackageHandleStandardArgs) 10 | find_package_handle_standard_args(Pandoc DEFAULT_MSG 11 | PANDOC_EXECUTABLE) 12 | 13 | if(PANDOC_FOUND) 14 | # check for eisvogel.latex 15 | execute_process( 16 | COMMAND ${PANDOC_EXECUTABLE} --version 17 | OUTPUT_VARIABLE pandoc_output 18 | RESULT_VARIABLE result 19 | ) 20 | string(REGEX MATCH "User data directory: ([^\n\r]*)" _ ${pandoc_output}) 21 | 22 | if (NOT CMAKE_MATCH_COUNT) 23 | string(REGEX MATCH "Default user data directory: ([^ ]+)" _ ${pandoc_output}) 24 | set(EISVOGEL_TEMPLATE_PATH "${CMAKE_MATCH_1}/templates/eisvogel.latex") 25 | else() 26 | set(EISVOGEL_TEMPLATE_PATH "${CMAKE_MATCH_1}/templates/eisvogel.latex") 27 | endif() 28 | 29 | if(EXISTS "${EISVOGEL_TEMPLATE_PATH}") 30 | message(STATUS "Found eisvogel template at ${EISVOGEL_TEMPLATE_PATH}") 31 | else() 32 | message(STATUS "eisvogel template not found at ${EISVOGEL_TEMPLATE_PATH}. The generation process will be skipped.") 33 | set(generation FALSE) 34 | endif() 35 | 36 | endif() 37 | 38 | mark_as_advanced(PANDOC_EXECUTABLE) -------------------------------------------------------------------------------- /cmake/FindPdflatex.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # pdflatex Support 3 | # 4 | 5 | find_program(PDFLATEX_EXECUTABLE 6 | NAMES pdflatex 7 | ) 8 | 9 | include(FindPackageHandleStandardArgs) 10 | find_package_handle_standard_args(Pdflatex DEFAULT_MSG 11 | PDFLATEX_EXECUTABLE) 12 | 13 | if(PDFLATEX_FOUND) 14 | 15 | # check for kpsewhich 16 | find_program(KPSEWHICH kpsewhich) 17 | if(NOT KPSEWHICH) 18 | set(generation FALSE) 19 | message(STATUS "kpsewhich not found. The generation process will be skipped.") 20 | return() 21 | endif() 22 | 23 | # check for packages 24 | set(check_next TRUE) 25 | macro(check_latex_package PACKAGE_NAME) 26 | if(check_next) 27 | execute_process( 28 | COMMAND ${KPSEWHICH} ${PACKAGE_NAME} 29 | OUTPUT_VARIABLE PATH 30 | OUTPUT_STRIP_TRAILING_WHITESPACE 31 | ) 32 | if(NOT PATH) 33 | set(generation FALSE) 34 | message(STATUS "${PACKAGE_NAME} not found. The generation process will be skipped.") 35 | set(check_next FALSE) # Disable further checks 36 | else() 37 | message(STATUS "${PACKAGE_NAME} found at: ${PATH}") 38 | endif() 39 | endif() 40 | endmacro() 41 | 42 | # Use the macro to check for packages 43 | check_latex_package("footnote.sty") 44 | check_latex_package("footnotebackref.sty") 45 | check_latex_package("pagecolor.sty") 46 | check_latex_package("hardwrap.sty") 47 | check_latex_package("mdframed.sty") 48 | check_latex_package("sourcesanspro.sty") 49 | check_latex_package("ly1enc.def") 50 | check_latex_package("sourcecodepro.sty") 51 | check_latex_package("titling.sty") 52 | check_latex_package("csquotes.sty") 53 | check_latex_package("zref-abspage.sty") 54 | check_latex_package("needspace.sty") 55 | 56 | endif() 57 | 58 | mark_as_advanced(PDFLATEX_EXECUTABLE) -------------------------------------------------------------------------------- /cmake/FindRst2man.cmake: -------------------------------------------------------------------------------- 1 | # RST2MAN_FOUND - true if the program was found 2 | # RST2MAN_VERSION - version of rst2man 3 | # RST2MAN_EXECUTABLE - path to the rst2man program 4 | 5 | find_program(RST2MAN_EXECUTABLE 6 | NAMES rst2man rst2man.py rst2man-3 rst2man-3.py 7 | DOC "The Python Docutils generator of Unix Manpages from reStructuredText" 8 | ) 9 | 10 | if (RST2MAN_EXECUTABLE) 11 | # Get the version string 12 | execute_process( 13 | COMMAND ${RST2MAN_EXECUTABLE} --version 14 | OUTPUT_VARIABLE rst2man_version_str 15 | ) 16 | # Expected format: rst2man (Docutils 0.13.1 [release], Python 2.7.15, on linux2) 17 | string(REGEX REPLACE "^rst2man[\t ]+\\(Docutils[\t ]+([^\t ]*).*" "\\1" 18 | RST2MAN_VERSION "${rst2man_version_str}") 19 | unset(rst2man_version_str) 20 | endif() 21 | 22 | # handle the QUIETLY and REQUIRED arguments and set RST2MAN_FOUND to TRUE 23 | # if all listed variables are set 24 | include(FindPackageHandleStandardArgs) 25 | find_package_handle_standard_args(Rst2man 26 | REQUIRED_VARS RST2MAN_EXECUTABLE 27 | VERSION_VAR RST2MAN_VERSION 28 | ) 29 | 30 | mark_as_advanced(RST2MAN_EXECUTABLE RST2MAN_VERSION) 31 | -------------------------------------------------------------------------------- /cmake/FindSystemd.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find systemd 2 | # Once done this will define 3 | # SYSTEMD_FOUND - System has systemd 4 | # SYSTEMD_INCLUDE_DIRS - The systemd include directories 5 | # SYSTEMD_LIBRARIES - The libraries needed to use systemd 6 | 7 | find_path(SYSTEMD_INCLUDE_DIR 8 | NAMES systemd/sd-daemon.h 9 | ) 10 | find_library(SYSTEMD_LIBRARY 11 | NAMES systemd 12 | ) 13 | 14 | include(FindPackageHandleStandardArgs) 15 | # handle the QUIETLY and REQUIRED arguments and set SYSTEMD_FOUND to TRUE 16 | # if all listed variables are TRUE and the requested version matches. 17 | find_package_handle_standard_args(Systemd REQUIRED_VARS 18 | SYSTEMD_LIBRARY SYSTEMD_INCLUDE_DIR 19 | VERSION_VAR SYSTEMD_VERSION) 20 | 21 | if(SYSTEMD_FOUND) 22 | set(SYSTEMD_LIBRARIES ${SYSTEMD_LIBRARY}) 23 | set(SYSTEMD_INCLUDE_DIRS ${SYSTEMD_INCLUDE_DIR}) 24 | endif() 25 | 26 | mark_as_advanced(SYSTEMD_INCLUDE_DIR SYSTEMD_LIBRARY) 27 | -------------------------------------------------------------------------------- /cmake/FindTHREAD.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # pthread support 3 | # 4 | 5 | find_path(THREAD_INCLUDE_DIR 6 | NAMES 7 | pthread.h 8 | ) 9 | find_library(THREAD_LIBRARY 10 | NAMES 11 | pthread 12 | ) 13 | 14 | include(FindPackageHandleStandardArgs) 15 | find_package_handle_standard_args(THREAD DEFAULT_MSG 16 | THREAD_LIBRARY THREAD_INCLUDE_DIR) 17 | 18 | if(THREAD_FOUND) 19 | set(THREAD_LIBRARIES ${THREAD_LIBRARY}) 20 | set(THREAD_INCLUDE_DIRS ${THREAD_INCLUDE_DIR}) 21 | endif() 22 | 23 | mark_as_advanced(THREAD_INCLUDE_DIR THREAD_LIBRARY) 24 | -------------------------------------------------------------------------------- /cmake/FindZstd.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # ZSTD support 3 | # 4 | 5 | find_path(ZSTD_INCLUDE_DIR 6 | NAMES zstd.h 7 | ) 8 | find_library(ZSTD_LIBRARY 9 | NAMES zstd 10 | ) 11 | 12 | include(FindPackageHandleStandardArgs) 13 | find_package_handle_standard_args(Zstd REQUIRED_VARS 14 | ZSTD_LIBRARY ZSTD_INCLUDE_DIR) 15 | 16 | if(ZSTD_FOUND) 17 | set(ZSTD_LIBRARIES ${ZSTD_LIBRARY}) 18 | set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR}) 19 | endif() 20 | 21 | mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY) 22 | -------------------------------------------------------------------------------- /contrib/docker/Dockerfile.alpine: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 The pgagroal community 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this list 8 | # of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | # list of conditions and the following disclaimer in the documentation and/or other 12 | # materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its contributors may 15 | # be used to endorse or promote products derived from this software without specific 16 | # prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | # THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | FROM alpine:latest AS builder 29 | 30 | RUN apk add --no-cache \ 31 | git \ 32 | gcc \ 33 | cmake \ 34 | make \ 35 | postgresql-dev \ 36 | zlib \ 37 | zlib-dev \ 38 | zstd \ 39 | zstd-dev \ 40 | lz4 \ 41 | lz4-dev \ 42 | bzip2 \ 43 | bzip2-dev \ 44 | libpq \ 45 | libpq-dev \ 46 | musl-dev \ 47 | libev-dev \ 48 | py-docutils \ 49 | pandoc \ 50 | texlive texmf-dist \ 51 | doxygen graphviz \ 52 | libatomic \ 53 | yaml-dev 54 | WORKDIR /src 55 | 56 | COPY . . 57 | 58 | RUN rm -rf build && mkdir build 59 | 60 | RUN cd build && \ 61 | cmake -DCMAKE_INSTALL_PREFIX=/usr/local/ .. && \ 62 | make -j$(nproc) && \ 63 | make install 64 | 65 | FROM alpine:latest 66 | 67 | RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories && \ 68 | echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \ 69 | apk update && \ 70 | apk add --no-cache \ 71 | postgresql17 \ 72 | postgresql17-client \ 73 | bash \ 74 | ca-certificates \ 75 | libev \ 76 | yaml \ 77 | bzip2 \ 78 | bzip2-dev \ 79 | libpq \ 80 | libatomic \ 81 | zstd \ 82 | lz4-libs 83 | 84 | RUN adduser -D -s /bin/sh pgagroal 85 | 86 | WORKDIR /pgagroal 87 | 88 | COPY --from=builder /usr/local/bin/pgagroal /usr/local/bin/pgagroal-cli /usr/local/bin/pgagroal-admin /usr/local/bin/ 89 | COPY --from=builder /usr/local/lib/libpgagroal.so* /usr/local/lib/ 90 | 91 | COPY contrib/docker/pgagroal.conf contrib/docker/pgagroal_hba.conf /etc/pgagroal/ 92 | 93 | RUN chown -R pgagroal:pgagroal /pgagroal /etc/pgagroal 94 | RUN chmod +x /usr/local/bin/pgagroal /usr/local/bin/pgagroal-cli /usr/local/bin/pgagroal-admin 95 | 96 | EXPOSE 2345 2346 97 | 98 | USER pgagroal 99 | 100 | CMD ["/usr/local/bin/pgagroal", "-c", "/etc/pgagroal/pgagroal.conf", "-a", "/etc/pgagroal/pgagroal_hba.conf"] -------------------------------------------------------------------------------- /contrib/docker/Dockerfile.rocky9: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 The pgagroal community 2 | # 3 | # Redistribution and use in source and binary forms, with or without modification, 4 | # are permitted provided that the following conditions are met: 5 | # 6 | # 1. Redistributions of source code must retain the above copyright notice, this list 7 | # of conditions and the following disclaimer. 8 | # 9 | # 2. Redistributions in binary form must reproduce the above copyright notice, this 10 | # list of conditions and the following disclaimer in the documentation and/or other 11 | # materials provided with the distribution. 12 | # 13 | # 3. Neither the name of the copyright holder nor the names of its contributors may 14 | # be used to endorse or promote products derived from this software without specific 15 | # prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 18 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 20 | # THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 | # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 24 | # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | FROM rockylinux:9 AS builder 28 | 29 | RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \ 30 | dnf -y upgrade && \ 31 | dnf install -y dnf-plugins-core && \ 32 | dnf config-manager --set-enabled crb && \ 33 | dnf makecache && \ 34 | dnf install -y \ 35 | git \ 36 | gcc \ 37 | cmake \ 38 | make \ 39 | postgresql-devel \ 40 | zlib \ 41 | zlib-devel \ 42 | zstd \ 43 | libzstd-devel \ 44 | lz4 \ 45 | lz4-devel \ 46 | bzip2 \ 47 | bzip2-devel \ 48 | libpq \ 49 | libpq-devel \ 50 | libev-devel \ 51 | python3-docutils \ 52 | pandoc \ 53 | texlive \ 54 | doxygen \ 55 | graphviz \ 56 | openssl-devel \ 57 | libatomic \ 58 | libyaml-devel \ 59 | systemd-devel \ 60 | libasan \ 61 | libasan-static \ 62 | yaml-cpp-devel && \ 63 | dnf clean all 64 | 65 | WORKDIR /src 66 | 67 | COPY . . 68 | 69 | RUN rm -rf build && mkdir build 70 | 71 | RUN cd build && \ 72 | cmake .. -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_RPATH=/usr/local/lib && \ 73 | make install 74 | 75 | FROM rockylinux:9 76 | 77 | RUN dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm && \ 78 | dnf -y update && \ 79 | dnf install -y postgresql17-server \ 80 | postgresql17-contrib \ 81 | libpq5 \ 82 | libev \ 83 | libatomic && \ 84 | dnf clean all 85 | 86 | RUN useradd --create-home --shell /bin/bash pgagroal 87 | 88 | WORKDIR /pgagroal 89 | 90 | COPY --from=builder /usr/local/bin/pgagroal /usr/local/bin/pgagroal-cli /usr/local/bin/pgagroal-admin /usr/local/bin/ 91 | COPY --from=builder /usr/local/lib/libpgagroal.so* /usr/local/lib/ 92 | 93 | COPY contrib/docker/pgagroal.conf contrib/docker/pgagroal_hba.conf /etc/pgagroal/ 94 | 95 | 96 | RUN chown -R pgagroal:pgagroal /pgagroal /etc/pgagroal 97 | RUN chmod +x /usr/local/bin/pgagroal /usr/local/bin/pgagroal-cli /usr/local/bin/pgagroal-admin 98 | 99 | EXPOSE 2345 2346 100 | 101 | USER pgagroal 102 | 103 | 104 | CMD ["/usr/local/bin/pgagroal", "-c", "/etc/pgagroal/pgagroal.conf", "-a", "/etc/pgagroal/pgagroal_hba.conf"] -------------------------------------------------------------------------------- /contrib/docker/pgagroal.conf: -------------------------------------------------------------------------------- 1 | [pgagroal] 2 | host = * 3 | port = 2345 4 | metrics = 2346 5 | log_type = file 6 | log_level = info 7 | log_path = /tmp/pgagroal.log 8 | 9 | max_connections = 100 10 | idle_timeout = 600 11 | validation = off 12 | unix_socket_dir = /tmp/ 13 | 14 | [primary] 15 | host = localhost 16 | port = 5432 -------------------------------------------------------------------------------- /contrib/docker/pgagroal_hba.conf: -------------------------------------------------------------------------------- 1 | # 2 | # TYPE DATABASE USER ADDRESS METHOD 3 | # 4 | host all all all all -------------------------------------------------------------------------------- /contrib/grafana/README.md: -------------------------------------------------------------------------------- 1 | # Grafana dashboard for pgagroal 2 | 3 | ## Getting Started 4 | 5 | ### Step1: Configure the Prometheus 6 | 7 | 1. Open the prometheus metric port like `8000` in `pgagroal.conf`. 8 | 9 | 2. Add the pgagroal instance in Prometheus configuration file `prometheus.yml` like follows: 10 | ``` 11 | ... 12 | scrape_configs: 13 | - job_name: 'pgagroal' 14 | static_configs: 15 | - targets: ['localhost:8000'] 16 | ... 17 | ``` 18 | 19 | ### Step2: Start the Grafana 20 | 21 | 1. Integrate the Prometheus instance as a data source into Grafana. 22 | 2. Open Grafana web page, click + -> Import. 23 | 24 | 3. Upload JSON file `contrib/grafana/dashboard.json` with Upload JSON file, then change the options if necessary. 25 | 26 | 4. Click Import. Let's start using it! -------------------------------------------------------------------------------- /contrib/shell_comp/pgagroal_comp.bash: -------------------------------------------------------------------------------- 1 | #/usr/bin/env bash 2 | 3 | # COMP_WORDS contains 4 | # at index 0 the executable name (pgagroal-cli) 5 | # at index 1 the command name (e.g., flush) 6 | # at index 2, if required, the subcommand name (e.g., all) 7 | pgagroal_cli_completions() 8 | { 9 | 10 | if [ "${#COMP_WORDS[@]}" == "2" ]; then 11 | # main completion: the user has specified nothing at all 12 | # or a single word, that is a command 13 | COMPREPLY=($(compgen -W "flush ping enable disable shutdown status switch-to conf clear" "${COMP_WORDS[1]}")) 14 | else 15 | # the user has specified something else 16 | # subcommand required? 17 | case ${COMP_WORDS[1]} in 18 | flush) 19 | COMPREPLY+=($(compgen -W "gracefully idle all" "${COMP_WORDS[2]}")) 20 | ;; 21 | shutdown) 22 | COMPREPLY+=($(compgen -W "gracefully immediate cancel" "${COMP_WORDS[2]}")) 23 | ;; 24 | clear) 25 | COMPREPLY+=($(compgen -W "server prometheus" "${COMP_WORDS[2]}")) 26 | ;; 27 | conf) 28 | COMPREPLY+=($(compgen -W "reload get set ls" "${COMP_WORDS[2]}")) 29 | ;; 30 | status) 31 | COMPREPLY+=($(compgen -W "details" "${COMP_WORDS[2]}")) 32 | esac 33 | fi 34 | 35 | 36 | } 37 | 38 | 39 | 40 | pgagroal_admin_completions() 41 | { 42 | if [ "${#COMP_WORDS[@]}" == "2" ]; then 43 | # main completion: the user has specified nothing at all 44 | # or a single word, that is a command 45 | COMPREPLY=($(compgen -W "master-key user" "${COMP_WORDS[1]}")) 46 | else 47 | # the user has specified something else 48 | # subcommand required? 49 | case ${COMP_WORDS[1]} in 50 | user) 51 | COMPREPLY+=($(compgen -W "add del edit ls" "${COMP_WORDS[2]}")) 52 | ;; 53 | esac 54 | fi 55 | } 56 | 57 | 58 | 59 | 60 | # install the completion functions 61 | complete -F pgagroal_cli_completions pgagroal-cli 62 | complete -F pgagroal_admin_completions pgagroal-admin 63 | -------------------------------------------------------------------------------- /contrib/shell_comp/pgagroal_comp.zsh: -------------------------------------------------------------------------------- 1 | #compdef _pgagroal_cli pgagroal-cli 2 | #compdef _pgagroal_admin pgagroal-admin 3 | 4 | 5 | function _pgagroal_cli() 6 | { 7 | local line 8 | _arguments -C \ 9 | "1: :(flush ping enable disable shutdown status switch-to conf clear)" \ 10 | "*::arg:->args" 11 | 12 | case $line[1] in 13 | flush) 14 | _pgagroal_cli_flush 15 | ;; 16 | shutdown) 17 | _pgagroal_cli_shutdown 18 | ;; 19 | clear) 20 | _pgagroal_cli_clear 21 | ;; 22 | conf) 23 | _pgagroal_cli_conf 24 | ;; 25 | status) 26 | _pgagroal_cli_status 27 | ;; 28 | esac 29 | } 30 | 31 | function _pgagroal_cli_flush() 32 | { 33 | local line 34 | _arguments -C \ 35 | "1: :(gracefully idle all)" \ 36 | "*::arg:->args" 37 | } 38 | 39 | function _pgagroal_cli_conf() 40 | { 41 | local line 42 | _arguments -C \ 43 | "1: :(reload get set ls)" \ 44 | "*::arg:->args" 45 | } 46 | 47 | function _pgagroal_cli_shutdown() 48 | { 49 | local line 50 | _arguments -C \ 51 | "1: :(gracefully immediate cancel)" \ 52 | "*::arg:->args" 53 | } 54 | 55 | function _pgagroal_cli_clear() 56 | { 57 | local line 58 | _arguments -C \ 59 | "1: :(server prometheus)" \ 60 | "*::arg:->args" 61 | } 62 | 63 | 64 | function _pgagroal_admin() 65 | { 66 | local line 67 | _arguments -C \ 68 | "1: :(master-key user)" \ 69 | "*::arg:->args" 70 | 71 | case $line[1] in 72 | user) 73 | _pgagroal_admin_user 74 | ;; 75 | esac 76 | } 77 | 78 | function _pgagroal_admin_user() 79 | { 80 | _arguments -C \ 81 | "1: :(add del edit ls)" \ 82 | "*::arg:->args" 83 | } 84 | 85 | function _pgagroal_cli_status() 86 | { 87 | local line 88 | _arguments -C \ 89 | "1: :(details)" \ 90 | "*::arg:->args" 91 | } 92 | -------------------------------------------------------------------------------- /contrib/valgrind/README.md: -------------------------------------------------------------------------------- 1 | # Valgrind 2 | 3 | The [Valgrind](https://valgrind.org/) tool suite provides a number of debugging and profiling tools that help you make your programs faster and more correct. The most popular and the default of these tools is called **Memcheck**. It can detect many memory-related errors that can lead to crashes and unpredictable behaviour. 4 | 5 | # Run memory management detection 6 | 7 | ``` bash 8 | valgrind --leak-check=full --show-leak-kinds=all --log-file=%p.log --trace-children=yes --track-origins=yes --read-var-info=yes ./pgagroal -c pgagroal.conf -a pgagroal_hba.conf 9 | ``` 10 | 11 | # Use suppressions rules 12 | 13 | ``` bash 14 | valgrind --suppressions=../../contrib/valgrind/pgagroal.supp --leak-check=full --show-leak-kinds=all --log-file=%p.log --trace-children=yes --track-origins=yes --read-var-info=yes ./pgagroal -c pgagroal.conf -a pgagroal_hba.conf 15 | ``` 16 | 17 | # Generate suppressions rules 18 | 19 | ``` bash 20 | valgrind --gen-suppressions=all --leak-check=full --show-leak-kinds=all --log-file=%p.log --trace-children=yes --track-origins=yes --read-var-info=yes ./pgagroal -c pgagroal.conf -a pgagroal_hba.conf 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /doc/ADMIN.md: -------------------------------------------------------------------------------- 1 | # `pgagroal-admin` user guide 2 | 3 | `pgagroal-admin` is a command line interface to manage users known 4 | to the [**pgagroal**](https://github.com/agroal/pgagroal) connection pooler. 5 | The executable accepts a set of options, as well as a command to execute. 6 | If no command is provided, the program will show the help screen. 7 | 8 | The `pgagroal-admin` utility has the following synopsis: 9 | 10 | ``` 11 | pgagroal-admin [ OPTIONS ] [ COMMAND ] 12 | ``` 13 | 14 | 15 | ## Options 16 | 17 | Available options are the following ones: 18 | 19 | ``` 20 | -f, --file FILE Set the path to a user file 21 | -U, --user USER Set the user name 22 | -P, --password PASSWORD Set the password for the user 23 | -g, --generate Generate a password 24 | -l, --length Password length 25 | -V, --version Display version information 26 | -?, --help Display help 27 | 28 | ``` 29 | 30 | Options can be specified either in short or long form, in any position of the command line. 31 | 32 | The `-f` option is mandatory for every operation that involves user management. If no 33 | user file is specified, `pgagroal-admin` will silently use the default one (`pgagroal_users.conf`). 34 | 35 | The password can be passed using the environment variable `PGAGROAL_PASSWORD` instead of `-P`, however the command line argument will have precedence. 36 | 37 | ## Commands 38 | 39 | ### user 40 | The `user` command allows the management of the users known to the connection pooler. 41 | The command accepts the following subcommands: 42 | - `add` to add a new user to the system; 43 | - `del` to remove an existing user from the system; 44 | - `edit` to change the credentials of an existing user; 45 | - `ls` to list all known users within the system. 46 | 47 | The command will edit the `pgagroal_users.conf` file or any file specified by means of the `-f` option flag. 48 | 49 | Unless the command is run with the `-U` and/or `-P` flags, the execution will be interactive. 50 | 51 | Examples: 52 | 53 | ``` shell 54 | pgagroal-admin user add -U simon -P secret 55 | pgagroal-admin user del -U simon 56 | 57 | ``` 58 | 59 | ## master-key 60 | 61 | The `master-key` command allows the definition of a password to protect the vault of the users, 62 | that is the "container" for users' credentials. 63 | 64 | 65 | ## Deprecated commands 66 | 67 | The following commands have been deprecated and will be removed 68 | in later releases of [**pgagroal**](https://github.com/agroal/pgagroal). 69 | For each command, this is the corresponding current mapping 70 | to the working command: 71 | 72 | - `add-user` is now `user add`; 73 | - `remove-user` is now `user del`; 74 | - `update-user` is now `user edit`; 75 | - `list-users` is now `user ls`. 76 | 77 | Whenever you use a deprecated command, the `pgagroal-admin` will print on standard error a warning message. 78 | If you don't want to get any warning about deprecated commands, you 79 | can redirect the `stderr` to `/dev/null` or any other location with: 80 | 81 | ``` 82 | pgagroal-admin user-add -U luca -P strongPassword 2>/dev/null 83 | ``` 84 | 85 | 86 | ## Shell completion 87 | 88 | There is a minimal shell completion support for `pgagroal-admin`. 89 | See the [Install pgagroal](https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md) for more details. 90 | -------------------------------------------------------------------------------- /doc/DISTRIBUTIONS.md: -------------------------------------------------------------------------------- 1 | # Compiling `pgagroal` from sources 2 | 3 | [**pgagroal**](https://github.com/agroal/pgagroal) requires the following dependencies: 4 | 5 | * a C compiler like [gcc 8+](https://gcc.gnu.org) (C17) or [clang 8+](https://clang.llvm.org/) 6 | * [cmake](https://cmake.org) 7 | * [GNU make](https://www.gnu.org/software/make/) or BSD `make` 8 | * [libev](http://software.schmorp.de/pkg/libev.html) 9 | * [OpenSSL](http://www.openssl.org/) 10 | * [rst2man](https://docutils.sourceforge.io/) 11 | * [libatomic](https://gcc.gnu.org/wiki/Atomic) 12 | * [Doxygen](https://doxygen.nl/index.html) 13 | * [pdflatex](https://tug.org/texlive/) 14 | * [zlib](https://zlib.net) 15 | * [zstd](http://www.zstd.net) 16 | * [lz4](https://lz4.github.io/lz4/) 17 | * [bzip2](http://sourceware.org/bzip2/) 18 | * [binutils](https://www.gnu.org/software/binutils/) 19 | * on Linux platforms, there is also the need for 20 | * [systemd](https://www.freedesktop.org/wiki/Software/systemd/) 21 | 22 | 23 | 24 | ## Compiling on Rocky Linux 25 | 26 | All the dependencies can be installed via `dnf(8)` as follows: 27 | 28 | ```sh 29 | dnf install git gcc cmake make \ 30 | libev libev-devel \ 31 | openssl openssl-devel \ 32 | systemd systemd-devel \ 33 | python3-docutils \ 34 | libatomic \ 35 | zlib zlib-devel \ 36 | libzstd libzstd-devel \ 37 | lz4 lz4-devel \ 38 | bzip2 bzip2-devel \ 39 | binutils 40 | ``` 41 | 42 | Please note that, on Rocky Linux, in order to install the `python3-docutils` 43 | package (that provides `rst2man` executable), you need to enable the `crb` repository: 44 | 45 | ```sh 46 | dnf config-manager --set-enabled crb 47 | ``` 48 | 49 | ## Compiling on FreeBSD 50 | 51 | All the dependencies can be installed via `pkg(8)` as follows: 52 | 53 | ```sh 54 | pkg install cmake \ 55 | libev libevent \ 56 | py311-docutils \ 57 | lzlib \ 58 | liblz4 \ 59 | lbizp2 \ 60 | texlive-formats \ 61 | binutils 62 | ``` 63 | -------------------------------------------------------------------------------- /doc/FAILOVER.md: -------------------------------------------------------------------------------- 1 | # pgagroal failover 2 | 3 | pgagroal can failover a PostgreSQL instance if the clients can't write to it. 4 | 5 | In `pgagroal.conf` define 6 | 7 | ``` 8 | failover = on 9 | failover_script = /path/to/myscript.sh 10 | ``` 11 | 12 | The script will be run as the same user as the pgagroal process so proper 13 | permissions (access and execution) must be in place. 14 | 15 | The following information is passed to the script as parameters 16 | 17 | 1. Old primary host 18 | 2. Old primary port 19 | 3. New primary host 20 | 4. New primary port 21 | 22 | so a script could look like 23 | 24 | ```sh 25 | #!/bin/bash 26 | 27 | OLD_PRIMARY_HOST=$1 28 | OLD_PRIMARY_PORT=$2 29 | NEW_PRIMARY_HOST=$3 30 | NEW_PRIMARY_PORT=$4 31 | 32 | ssh -tt -o StrictHostKeyChecking=no postgres@${NEW_PRIMARY_HOST} pg_ctl promote -D /mnt/pgdata 33 | 34 | if [ $? -ne 0 ]; then 35 | exit 1 36 | fi 37 | 38 | exit 0 39 | ``` 40 | 41 | The script is assumed successful if it has an exit code of 0. Otherwise both servers will be 42 | recorded as failed. 43 | -------------------------------------------------------------------------------- /doc/PERFORMANCE.md: -------------------------------------------------------------------------------- 1 | # pgagroal performance 2 | 3 | Performance is an important goal for [**pgagroal**](https://github.com/agroal/pgagroal) and effort have been made 4 | to make [**pgagroal**](https://github.com/agroal/pgagroal) scale and use a limited number of resources. 5 | 6 | This report describe [**pgagroal**](https://github.com/agroal/pgagroal) in relationship to 3 other [PostgreSQL](https://www.postgresql.org) 7 | connection pool implementations, which we will call `a`, `b` and `c`. 8 | 9 | The [pgbench](https://www.postgresql.org/docs/11/pgbench.html) program was used in the runs. All pool 10 | configurations were made with performance in mind. 11 | 12 | All diagrams are using the same identifier for the connection pool in question, so `a` is `a` in all 13 | diagrams and so on. 14 | 15 | The runs were performed on [RHEL](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux) 7.7 / 16 | [EPEL](https://access.redhat.com/solutions/3358) / [DevTools](https://developers.redhat.com/products/developertoolset/overview) 8 17 | based machines on 10G network. All connection pools were the latest versions as of January 14, 2020. [**pgagroal**](https://github.com/agroal/pgagroal) was 18 | using the `epoll` mode of [libev](http://software.schmorp.de/pkg/libev.html). 19 | 20 | ## Simple 21 | 22 | This run uses 23 | 24 | ``` 25 | pgbench -M simple 26 | ``` 27 | 28 | ![pgbench simple](https://github.com/agroal/pgagroal/raw/master/doc/images/perf-simple.png "pgbench simple") 29 | 30 | ## Extended 31 | 32 | This run uses 33 | 34 | ``` 35 | pgbench -M extended 36 | ``` 37 | 38 | ![pgbench extended](https://github.com/agroal/pgagroal/raw/master/doc/images/perf-extended.png "pgbench extended") 39 | 40 | ## Prepared 41 | 42 | This run uses 43 | 44 | ``` 45 | pgbench -M prepared 46 | ``` 47 | 48 | ![pgbench prepared](https://github.com/agroal/pgagroal/raw/master/doc/images/perf-prepared.png "pgbench prepared") 49 | 50 | ## ReadOnly 51 | 52 | This run uses 53 | 54 | ``` 55 | pgbench -S -M prepared 56 | ``` 57 | 58 | ![pgbench readonly](https://github.com/agroal/pgagroal/raw/master/doc/images/perf-readonly.png "pgbench readonly") 59 | 60 | ## Closing 61 | 62 | **Please**, run your own benchmarks to see how [**pgagroal**](https://github.com/agroal/pgagroal) compare to your existing connection pool 63 | deployment. 64 | -------------------------------------------------------------------------------- /doc/PIPELINES.md: -------------------------------------------------------------------------------- 1 | # pgagroal pipelines 2 | 3 | pgagroal supports 3 different pipelines 4 | 5 | * Performance 6 | * Session 7 | * Transaction 8 | 9 | The pipeline is defined in `pgagroal.conf` under the setting of 10 | 11 | ``` 12 | pipeline = auto 13 | ``` 14 | 15 | pgagroal will choose either the performance or the session pipeline 16 | based on the configuration settings by default. 17 | 18 | # Performance 19 | 20 | The performance pipeline is fastest pipeline as it is a minimal implementation 21 | of the pipeline architecture. 22 | 23 | However, it doesn't support Transport Layer Security (TLS), failover support and 24 | the `disconnect_client` setting. 25 | 26 | A `DISCARD ALL` query is run after each client session. 27 | 28 | Select the performance pipeline by 29 | 30 | ``` 31 | pipeline = performance 32 | ``` 33 | 34 | # Session 35 | 36 | The session pipeline supports all features of pgagroal. 37 | 38 | A `DISCARD ALL` query is run after each client session. 39 | 40 | Select the session pipeline by 41 | 42 | ``` 43 | pipeline = session 44 | ``` 45 | 46 | # Transaction 47 | 48 | The transaction pipeline will release the connection back to the pool after each 49 | transaction completes. This feature will support many more clients than there are 50 | database connections. 51 | 52 | The transaction pipeline requires that there are users defined such that connections 53 | can be kept in the pool in all security scenarios. 54 | 55 | However, there are some session based features of PostgreSQL that can't be supported in this 56 | pipeline. 57 | 58 | * `SET` / `RESET` 59 | * `LISTEN` / `NOTIFY` 60 | * `WITH HOLD CURSOR` 61 | * `PREPARE` / `DEALLOCATE` 62 | 63 | It is assumed that all clients using the same user name and database pair share the same 64 | startup parameters towards PostgreSQL. 65 | 66 | __`SET` / `RESET`__ 67 | 68 | The `SET` functionality is a session based feature. 69 | 70 | __`LISTEN` / `NOTIFY`__ 71 | 72 | The `LISTEN` functionality is a session based feature. 73 | 74 | __`WITH HOLD CURSOR`__ 75 | 76 | The `WITH HOLD CURSOR` functionality is a session based feature. 77 | 78 | __`PREPARE` / `DEALLOCATE`__ 79 | 80 | While using `PREPARE` and `EXECUTE` can be used the prepared statements are tied to the 81 | connection they were created in which means that clients can't be sure that they created 82 | the prepared statement on the connection unless it is issued within the same transaction 83 | where it is used. 84 | 85 | pgagroal can issue a `DEALLOCATE ALL` statement before a connection is returned back to 86 | the pool if the `track_prepared_statements` setting is set to `on`. If `off` then no 87 | statement is issued. 88 | 89 | Note, that pgagroal does not issue a `DISCARD ALL` statement when using the transaction 90 | pipeline. 91 | 92 | __Performance considerations__ 93 | 94 | Clients may need to wait for a connection between transactions leading to a higher 95 | latency. 96 | 97 | __Important__ 98 | 99 | Make sure that the `blocking_timeout` settings to set to 0. Otherwise active clients 100 | may timeout during their workload. Likewise it is best to disable idle connection timeout 101 | and max connection age by setting `idle_timeout` and `max_connection_age` to 0. 102 | 103 | It is highly recommended that you prefill all connections for each user. 104 | 105 | The transaction pipeline doesn't support the `disconnect_client` or 106 | `allow_unknown_users` settings. 107 | 108 | Select the transaction pipeline by 109 | 110 | ``` 111 | pipeline = transaction 112 | ``` 113 | -------------------------------------------------------------------------------- /doc/RPM.md: -------------------------------------------------------------------------------- 1 | # pgagroal rpm 2 | 3 | [**pgagroal**](https://github.com/agroal/pgagroal) can be built into a RPM for [Fedora](https://getfedora.org/) systems. 4 | 5 | ## Requirements 6 | 7 | ```sh 8 | dnf install gcc rpm-build rpm-devel rpmlint make python bash coreutils diffutils patch rpmdevtools chrpath 9 | ``` 10 | 11 | ## Setup RPM development 12 | 13 | ```sh 14 | rpmdev-setuptree 15 | ``` 16 | 17 | ## Create source package 18 | 19 | ```sh 20 | git clone https://github.com/agroal/pgagroal.git 21 | cd pgagroal 22 | mkdir build 23 | cd build 24 | cmake -DCMAKE_BUILD_TYPE=Release .. 25 | make package_source 26 | ``` 27 | 28 | ## Create RPM package 29 | 30 | ```sh 31 | cp pgagroal-$VERSION.tar.gz ~/rpmbuild/SOURCES 32 | QA_RPATHS=0x0001 rpmbuild -bb pgagroal.spec 33 | ``` 34 | 35 | The resulting RPM will be located in `~/rpmbuild/RPMS/x86_64/`, if your architecture is `x86_64`. 36 | -------------------------------------------------------------------------------- /doc/SECURITY.md: -------------------------------------------------------------------------------- 1 | # pgagroal security 2 | 3 | ## Pass-through security 4 | 5 | pgagroal use pass-through security by default. 6 | 7 | This means that pgagroal delegates to PostgreSQL to determine if the credentials used are valid. 8 | 9 | Once a connection is obtained pgagroal will replay the previous communication sequence to verify 10 | the new client. This only works for connections using `trust`, `password` or `md5` authentication 11 | methods, so `scram-sha-256` based connections are not cached. 12 | 13 | Note, that this can lead to replay attacks against the `md5` based connections since the hash 14 | doesn't change. Make sure that pgagroal is deployed on a private trusted network, but consider 15 | using either a user vault or authentication query instead. 16 | 17 | ## User vault 18 | 19 | A user vault is a vault which defines the known users and their password. 20 | 21 | The vault is static, and is managed through the `pgagroal-admin` tool. 22 | 23 | The user vault is specified using the `-u` or `--users` command line parameter. 24 | 25 | ### Frontend users 26 | 27 | The `-F` or `--frontend` command line parameter allows users to be defined for the client to 28 | [**pgagroal**](https://github.com/agroal/pgagroal) authentication. This allows the setup to use different passwords for the [**pgagroal**](https://github.com/agroal/pgagroal) to 29 | PostgreSQL authentication. 30 | 31 | All users defined in the frontend authentication must be defined in the user vault (`-u`). 32 | 33 | Frontend users (`-F`) requires a user vault (`-u`) to be defined. 34 | 35 | ## Authentication query 36 | 37 | Authentication query will use the below defined function to query the database 38 | for the user password 39 | 40 | ``` 41 | CREATE FUNCTION public.pgagroal_get_password( 42 | IN p_user name, 43 | OUT p_password text 44 | ) RETURNS text 45 | LANGUAGE sql SECURITY DEFINER SET search_path = pg_catalog AS 46 | $$SELECT passwd FROM pg_shadow WHERE usename = p_user$$; 47 | ``` 48 | 49 | This function needs to be installed in each database. 50 | 51 | The function requires a user that is able to execute it, like 52 | 53 | ``` 54 | -- Create a role used for the authentication query 55 | CREATE ROLE pgagroal LOGIN; 56 | -- Set the password 57 | \password pgagroal 58 | 59 | -- Only allow access to "pgagroal" 60 | REVOKE EXECUTE ON FUNCTION public.pgagroal_get_password(name) FROM PUBLIC; 61 | GRANT EXECUTE ON FUNCTION public.pgagroal_get_password(name) TO pgagroal; 62 | ``` 63 | 64 | Make sure that the user is different from the actual application users accessing 65 | the database. The user accessing the function needs to have its credential present 66 | in the vault passed to the `-S` or `--superuser` command line parameter. 67 | 68 | The user executing the authentication query must use either a MD5 or a SCRAM-SHA-256 69 | password protected based account. 70 | 71 | Note, that authentication query doesn't support user vaults - user vault (`-u`) and frontend users (`-F`) - 72 | as well as limits (`-l`). 73 | -------------------------------------------------------------------------------- /doc/TEST.md: -------------------------------------------------------------------------------- 1 | # pgagroal Test Suite Instructions 2 | 3 | ## Overview 4 | 5 | This document explains how to run the pgagroal test suite, generate code coverage, and use containerized testing. The main entry point for all tests is the `testsuite.sh` script. 6 | 7 | ## Quick Start 8 | 9 | 1. **Build the Project** (with GCC for coverage): 10 | 11 | ```sh 12 | git clone https://github.com/pgagroal/pgagroal.git 13 | cd pgagroal 14 | mkdir build 15 | cd build 16 | cmake -DCMAKE_BUILD_TYPE=Debug .. 17 | make 18 | ``` 19 | 20 | 2. **Run the Test Suite**: 21 | 22 | ```sh 23 | ./testsuite.sh 24 | ``` 25 | 26 | - This script sets up temporary PostgreSQL and pgagroal environments in the build directory, runs all tests, and produces logs and (if enabled) coverage data. 27 | 28 | 3. **Clean Up** (before re-running): 29 | 30 | ```sh 31 | ./testsuite.sh clean 32 | ``` 33 | 34 | 4. **Run Configuration Tests** (multiple config scenarios): 35 | 36 | ```sh 37 | ./testsuite.sh run-configs 38 | ``` 39 | 40 | 5. **Generate Coverage Reports** (if built with GCC and coverage enabled): 41 | 42 | ```sh 43 | # From inside the build directory, after running tests 44 | mkdir -p ./coverage 45 | gcovr -r ../src --object-directory . --html --html-details -o ./coverage/index.html 46 | gcovr -r ../src --object-directory . > ./coverage/summary.txt 47 | ``` 48 | 49 | 6. **Containerized Testing** (Optional, requires Docker or Podman): 50 | 51 | - **Run all tests in a container:** 52 | ```sh 53 | ctest -V 54 | ``` 55 | - **Or run and generate coverage in a container:** 56 | ```sh 57 | ./coverage.sh 58 | ``` 59 | 60 | ## Artifacts 61 | 62 | After running tests, you will find: 63 | 64 | - Test logs: `build/log/` 65 | - Coverage reports: `build/coverage/` 66 | - CTest logs: `build/testing/` 67 | 68 | ## Adding New Test Cases 69 | 70 | - Add new `.c` and `.h` files in `test/testcases/`. 71 | - Register your test suite in `test/testcases/runner.c`. 72 | - Add your test source to `test/CMakeLists.txt`: 73 | 74 | ```cmake 75 | set(SOURCES 76 | testcases/common.c 77 | testcases/your_new_test.c 78 | testcases/runner.c 79 | ) 80 | ``` 81 | 82 | ## Prerequisites 83 | 84 | - PostgreSQL 17.x installed and available in your PATH 85 | - The `initdb`, `pg_ctl`, and `psql` binaries in your PATH 86 | - The `check` library installed for C unit tests 87 | - **Docker or Podman** installed (for containerized tests) 88 | - **gcov** and **gcovr** installed (for coverage reports) 89 | 90 | ## Notes 91 | 92 | - Always clean up (`./testsuite.sh clean`) before re-running tests to avoid stale environments. 93 | - If you want to test multiple configuration scenarios, add directories with `pgagroal.conf` and `pgagroal_hba.conf` under `test/conf/` and use `./testsuite.sh run-configs`. 94 | - For more details, see the comments and logic in [`test/testsuite.sh`](../test/testsuite.sh). 95 | 96 | --- -------------------------------------------------------------------------------- /doc/etc/pgagroal.conf: -------------------------------------------------------------------------------- 1 | [pgagroal] 2 | host = localhost 3 | port = 2345 4 | 5 | log_type = console 6 | log_level = info 7 | log_path = 8 | 9 | max_connections = 100 10 | idle_timeout = 600 11 | validation = off 12 | unix_socket_dir = /tmp/ 13 | ev_backend = auto 14 | 15 | [primary] 16 | host = localhost 17 | port = 5432 18 | -------------------------------------------------------------------------------- /doc/etc/pgagroal.service: -------------------------------------------------------------------------------- 1 | # systemd service unit for pgagroal 2 | # 3 | # - Adjust the user running the service in User 4 | # - Adjust the path in ExecStart 5 | # 6 | [Unit] 7 | Description=High-performance connection pool for PostgreSQL 8 | Documentation=man:pgagroal(1) 9 | Documentation=https://agroal.github.io/pgagroal/ 10 | After=network.target 11 | 12 | [Service] 13 | Type=exec 14 | User=pgagroal 15 | ExecStart=/usr/bin/pgagroal 16 | ExecReload=/bin/kill -HUP $MAINPID 17 | KillSignal=SIGINT 18 | #LimitNOFILE=1024 19 | 20 | [Install] 21 | WantedBy=multi-user.target 22 | -------------------------------------------------------------------------------- /doc/etc/pgagroal.socket: -------------------------------------------------------------------------------- 1 | # systemd socket unit for pgagroal 2 | # 3 | # See pgagroal.service for more information. 4 | # 5 | [Unit] 6 | Description=Sockets for pgagroal 7 | 8 | [Socket] 9 | ListenStream=/tmp/.s.PGSQL.2345 10 | #ListenStream=2345 11 | 12 | [Install] 13 | WantedBy=sockets.target 14 | -------------------------------------------------------------------------------- /doc/etc/pgagroal_hba.conf: -------------------------------------------------------------------------------- 1 | # 2 | # TYPE DATABASE USER ADDRESS METHOD 3 | # 4 | host all all all all 5 | -------------------------------------------------------------------------------- /doc/etc/pgagroal_vault.conf: -------------------------------------------------------------------------------- 1 | [pgagroal-vault] 2 | host = localhost 3 | port = 2500 4 | 5 | log_type = console 6 | log_level = info 7 | log_path = 8 | 9 | [main] 10 | host = localhost 11 | port = 2347 12 | user = admin 13 | -------------------------------------------------------------------------------- /doc/images/perf-extended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agroal/pgagroal/31cfe06ebd5889edcda4c4ca95f0c9c02a02982e/doc/images/perf-extended.png -------------------------------------------------------------------------------- /doc/images/perf-prepared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agroal/pgagroal/31cfe06ebd5889edcda4c4ca95f0c9c02a02982e/doc/images/perf-prepared.png -------------------------------------------------------------------------------- /doc/images/perf-readonly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agroal/pgagroal/31cfe06ebd5889edcda4c4ca95f0c9c02a02982e/doc/images/perf-readonly.png -------------------------------------------------------------------------------- /doc/images/perf-simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agroal/pgagroal/31cfe06ebd5889edcda4c4ca95f0c9c02a02982e/doc/images/perf-simple.png -------------------------------------------------------------------------------- /doc/man/pgagroal-admin.1.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | pgagroal-admin 3 | ============== 4 | 5 | ----------------------------------- 6 | Administration utility for pgagroal 7 | ----------------------------------- 8 | 9 | :Manual section: 1 10 | 11 | SYNOPSIS 12 | ======== 13 | 14 | pgagroal-admin [ -f FILE ] [ COMMAND ] 15 | 16 | DESCRIPTION 17 | =========== 18 | 19 | pgagroal-admin is an administration utility for pgagroal. 20 | 21 | OPTIONS 22 | ======= 23 | 24 | -f, --file FILE 25 | Set the path to a user file 26 | 27 | -U, --user USER 28 | Set the user name 29 | 30 | -P, --password PASSWORD 31 | Set the password for the user 32 | 33 | -g, --generate 34 | Generate a password 35 | 36 | -l, --length 37 | Password length 38 | 39 | -V, --version 40 | Display version information 41 | 42 | -?, --help 43 | Display help 44 | 45 | COMMANDS 46 | ======== 47 | 48 | master-key 49 | Create or update the master key. The master key will be created in the pgagroal user home directory under ~/.pgagroal 50 | 51 | user add 52 | Add a user 53 | 54 | user edit 55 | Update a user 56 | 57 | user del 58 | Delete a user 59 | 60 | user ls 61 | List all users 62 | 63 | ENVIRONMENT VARIABLES 64 | ===================== 65 | 66 | PGAGROAL_PASSWORD 67 | Provide either a key for use with the `master-key` command, or a user password for use with the `user add` or `user edit` commands. 68 | If provided, `pgagroal-admin` will not ask for the key/password interactively. 69 | Note that a password provided using the `--password` command line argument will have precedence over this variable. 70 | 71 | REPORTING BUGS 72 | ============== 73 | 74 | pgagroal is maintained on GitHub at https://github.com/agroal/pgagroal 75 | 76 | COPYRIGHT 77 | ========= 78 | 79 | pgagroal is licensed under the 3-clause BSD License. 80 | 81 | SEE ALSO 82 | ======== 83 | 84 | pgagroal.conf(5), pgagroal_hba.conf(5), pgagroal_databases.conf(5), pgagroal_vault.conf(5), pgagroal(1), pgagroal-cli(1), pgagroal-vault(1) 85 | -------------------------------------------------------------------------------- /doc/man/pgagroal-cli.1.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | pgagroal-cli 3 | ============ 4 | 5 | --------------------------------- 6 | Command line utility for pgagroal 7 | --------------------------------- 8 | 9 | :Manual section: 1 10 | 11 | SYNOPSIS 12 | ======== 13 | 14 | pgagroal-cli [ -c CONFIG_FILE ] [ COMMAND ] 15 | 16 | DESCRIPTION 17 | =========== 18 | 19 | pgagroal-cli is a command line utility for pgagroal. 20 | 21 | OPTIONS 22 | ======= 23 | 24 | -c, --config CONFIG_FILE 25 | Set the path to the pgagroal.conf file 26 | 27 | -h, --host HOST 28 | Set the host name 29 | 30 | -p, --port PORT 31 | Set the port number 32 | 33 | -U, --user USERNAME 34 | Set the user name 35 | 36 | -P, --password PASSWORD 37 | Set the password 38 | 39 | -L, --logfile FILE 40 | Set the logfile 41 | 42 | -v, --verbose 43 | Output text string of result 44 | 45 | -V, --version 46 | Display version information 47 | 48 | -?, --help 49 | Display help 50 | 51 | COMMANDS 52 | ======== 53 | 54 | flush-idle 55 | Flush idle connections 56 | 57 | flush-gracefully 58 | Flush all connections gracefully 59 | 60 | flush-all 61 | Flush all connections. USE WITH CAUTION ! 62 | 63 | is-alive 64 | Is pgagroal alive 65 | 66 | enable 67 | Enable a database. Optional parameter with the 68 | database name, if not specified all will be enabled 69 | 70 | disable 71 | Disable a database. Optional parameter with the 72 | database name, if not specified all will be disabled 73 | 74 | gracefully 75 | Stop pgagroal gracefully 76 | 77 | stop 78 | Stop pgagroal 79 | 80 | cancel-shutdown 81 | Cancel the graceful shutdown 82 | 83 | status 84 | Status of pgagroal 85 | 86 | details 87 | Detailed status of pgagroal 88 | 89 | switch-to 90 | Switch to another primary 91 | 92 | reset 93 | Reset the Prometheus statistics 94 | 95 | reset-server 96 | Reset the state of a server. Requires a server name as an argument 97 | 98 | REPORTING BUGS 99 | ============== 100 | 101 | pgagroal is maintained on GitHub at https://github.com/agroal/pgagroal 102 | 103 | COPYRIGHT 104 | ========= 105 | 106 | pgagroal is licensed under the 3-clause BSD License. 107 | 108 | SEE ALSO 109 | ======== 110 | 111 | pgagroal.conf(5), pgagroal_hba.conf(5), pgagroal_databases.conf(5), pgagroal_vault.conf(5), pgagroal(1), pgagroal-admin(1), pgagroal-vault(1) 112 | -------------------------------------------------------------------------------- /doc/man/pgagroal-vault.1.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | pgagroal-vault 3 | ============== 4 | 5 | -------------------------------------------------------------------------------- 6 | Simple vault that hosts an HTTP server to handle user frontend password requests 7 | -------------------------------------------------------------------------------- 8 | 9 | :Manual section: 1 10 | 11 | SYNOPSIS 12 | ======== 13 | 14 | pgagroal-vault [ -c CONFIG_FILE ] [ -u USERS_FILE ] 15 | 16 | DESCRIPTION 17 | =========== 18 | 19 | **pgagroal-vault** is a basic HTTP server designed to handle special HTTP GET requests for retrieving pgagroal user passwords. When a client sends an HTTP GET request to ``http://:/users/``, the vault extracts ```` from the URL. It then connects to the pgagroal main process to fetch the current ```` corresponding to the ````. 20 | 21 | If the vault successfully fetches the ````, it responds with an HTTP status code 200 and includes ```` in the response body. Otherwise, the server responds with an HTTP 404 error indicating that the password for the specified user could not be found. 22 | 23 | **Note:** For pgagroal-vault to operate correctly, the management port of the pgagroal server must be open and functional. 24 | 25 | OPTIONS 26 | ======= 27 | 28 | -c, --config CONFIG_FILE 29 | Set the path to the pgagroal_vault.conf file 30 | 31 | -u, --users USERS_FILE 32 | Set the path to the pgagroal_vault_users.conf file 33 | 34 | -?, --help 35 | Display help 36 | 37 | REPORTING BUGS 38 | ============== 39 | 40 | pgagroal is maintained on GitHub at https://github.com/agroal/pgagroal 41 | 42 | COPYRIGHT 43 | ========= 44 | 45 | pgagroal is licensed under the 3-clause BSD License. 46 | 47 | SEE ALSO 48 | ======== 49 | 50 | pgagroal.conf(5), pgagroal_hba.conf(5), pgagroal_databases.conf(5), pgagroal_vault.conf(5), pgagroal-cli(1), pgagroal-admin(1), pgagroal(1) 51 | -------------------------------------------------------------------------------- /doc/man/pgagroal.1.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | pgagroal 3 | ======== 4 | 5 | ----------------------------------------------- 6 | High-performance connection pool for PostgreSQL 7 | ----------------------------------------------- 8 | 9 | :Manual section: 1 10 | 11 | SYNOPSIS 12 | ======== 13 | 14 | pgagroal [ -c CONFIG_FILE ] [ -a HBA_FILE ] [ -d ] 15 | 16 | DESCRIPTION 17 | =========== 18 | 19 | pgagroal is a high-performance protocol-native connection pool for PostgreSQL. 20 | 21 | OPTIONS 22 | ======= 23 | 24 | -c, --config CONFIG_FILE 25 | Set the path to the pgagroal.conf file 26 | 27 | -a, --hba HBA_FILE 28 | Set the path to the pgagroal_hba.conf file 29 | 30 | -l, --limit LIMIT_FILE 31 | Set the path to the pgagroal_databases.conf file 32 | 33 | -u, --users USERS_FILE 34 | Set the path to the pgagroal_users.conf file 35 | 36 | -A, --admins ADMINS_FILE 37 | Set the path to the pgagroal_admins.conf file 38 | 39 | -S, --superuser SUPERUSER_FILE 40 | Set the path to the pgagroal_superuser.conf file 41 | 42 | -d, --daemon 43 | Run as a daemon 44 | 45 | -V, --version 46 | Display version information 47 | 48 | -?, --help 49 | Display help 50 | 51 | REPORTING BUGS 52 | ============== 53 | 54 | pgagroal is maintained on GitHub at https://github.com/agroal/pgagroal 55 | 56 | COPYRIGHT 57 | ========= 58 | 59 | pgagroal is licensed under the 3-clause BSD License. 60 | 61 | SEE ALSO 62 | ======== 63 | 64 | pgagroal.conf(5), pgagroal_hba.conf(5), pgagroal_databases.conf(5), pgagroal_vault.conf(5), pgagroal-cli(1), pgagroal-admin(1), pgagroal-vault(1) 65 | -------------------------------------------------------------------------------- /doc/man/pgagroal_databases.conf.5.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | pgagroal_databases.conf 3 | ======================= 4 | 5 | ------------------------------------------------ 6 | Limits for databases, users or both for pgagroal 7 | ------------------------------------------------ 8 | 9 | :Manual section: 5 10 | 11 | DESCRIPTION 12 | =========== 13 | 14 | The pgagroal_databases.conf configuration file defines limits for a database or a user or both. 15 | 16 | FORMAT 17 | ====== 18 | 19 | DATABASE 20 | Specifies the database for the rule. Either specific name or all for all databases 21 | 22 | USER 23 | Specifies the user for the rule. Either specific name or all for all users 24 | 25 | MAX_SIZE 26 | Specifies the maximum pool size for the entry. all for all connections 27 | 28 | INITIAL_SIZE 29 | Specifies the initial pool size for the entry. Default is 0. Requires a pgagroal_users.conf configuration 30 | 31 | MIN_SIZE 32 | Specifies the minimum pool size for the entry. Default is 0. Requires a pgagroal_users.conf configuration 33 | 34 | EXAMPLE 35 | ======= 36 | 37 | :: 38 | 39 | # 40 | # DATABASE USER MAX_SIZE INITIAL_SIZE MIN_SIZE 41 | # 42 | all all all 43 | 44 | 45 | REPORTING BUGS 46 | ============== 47 | 48 | pgagroal is maintained on GitHub at https://github.com/agroal/pgagroal 49 | 50 | COPYRIGHT 51 | ========= 52 | 53 | pgagroal is licensed under the 3-clause BSD License. 54 | 55 | SEE ALSO 56 | ======== 57 | 58 | pgagroal.conf(5), pgagroal_hba.conf(5), pgagroal_vault.conf(5), pgagroal(1), pgagroal-cli(1), pgagroal-admin(1), pgagroal-vault(1) 59 | -------------------------------------------------------------------------------- /doc/man/pgagroal_hba.conf.5.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | pgagroal_hba.conf 3 | ================= 4 | 5 | ------------------------------------------------- 6 | Host based access configuration file for pgagroal 7 | ------------------------------------------------- 8 | 9 | :Manual section: 5 10 | 11 | DESCRIPTION 12 | =========== 13 | 14 | pgagroal_hba.conf specifies the host based access pattern for pgagroal. 15 | 16 | FORMAT 17 | ====== 18 | 19 | TYPE 20 | Specifies the access method for clients. Only host supported 21 | 22 | DATABASE 23 | Specifies the database for the rule. Either specific name or all for all databases 24 | 25 | USER 26 | Specifies the user for the rule. Either specific name or all for all users 27 | 28 | ADDRESS 29 | Specifies the network for the rule. all for all networks, or IPv4 address with a mask (0.0.0.0/0) or IPv6 address with a mask (::0/0) 30 | 31 | METHOD 32 | Specifies the authentication mode for the user. all for all methods, otherwise trust, reject, password, md5 or scram-sha-256 33 | 34 | EXAMPLE 35 | ======= 36 | 37 | :: 38 | 39 | # 40 | # TYPE DATABASE USER ADDRESS METHOD 41 | # 42 | host all all all all 43 | 44 | 45 | REPORTING BUGS 46 | ============== 47 | 48 | pgagroal is maintained on GitHub at https://github.com/agroal/pgagroal 49 | 50 | COPYRIGHT 51 | ========= 52 | 53 | pgagroal is licensed under the 3-clause BSD License. 54 | 55 | SEE ALSO 56 | ======== 57 | 58 | pgagroal.conf(5), pgagroal_databases.conf(5), pgagroal_vault.conf(5), pgagroal(1), pgagroal-cli(1), pgagroal-admin(1), pgagroal-vault(1) 59 | -------------------------------------------------------------------------------- /doc/manual/01-introduction.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Introduction 4 | 5 | [**pgagroal**][pgagroal] is a high-performance protocol-native connection pool for [PostgreSQL][postgresql]. 6 | 7 | ## Features 8 | 9 | * High performance 10 | * Connection pool 11 | * Limit connections for users and databases 12 | * Prefill support 13 | * Remove idle connections 14 | * Perform connection validation 15 | * Enable / disable database access 16 | * Graceful / fast shutdown 17 | * Prometheus support 18 | * Grafana 8 dashboard 19 | * Remote management 20 | * Authentication query support 21 | * Failover support 22 | * Transport Layer Security (TLS) v1.2+ support 23 | * Daemon mode 24 | * User vault 25 | 26 | ## Platforms 27 | 28 | The supported platforms are 29 | 30 | * [Fedora][fedora] 32+ 31 | * [RHEL][rhel] 8 / RockyLinux 8 32 | * [RHEL][rhel] 9 / RockyLinux 9 33 | * [FreeBSD][freebsd] 34 | * [OpenBSD][openbsd] 35 | -------------------------------------------------------------------------------- /doc/manual/97-acknowledgement.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Acknowledgement 4 | 5 | ## Authors 6 | 7 | [**pgagroal**][pgagroal] was created by the following authors: 8 | 9 | ``` 10 | Jesper Pedersen 11 | David Fetter 12 | Will Leinweber 13 | Junduo Dong 14 | Luca Ferrari 15 | Nikita Bugrovsky 16 | Lawrence Wu 17 | Yongting You <2010youy01@gmail.com> 18 | Ashutosh Sharma 19 | Henrique de Carvalho 20 | Yihe Lu 21 | Eugenio Gigante 22 | Mohanad Khaled 23 | Haoran Zhang 24 | Christian Englert 25 | Georg Pfuetzenreuter 26 | Tejas Tyagi 27 | Aryan Arora 28 | Sangkeun J.C. Kim 29 | Arshdeep Singh 30 | Vanes Angelo 31 | Bassam Adnan 32 | ``` 33 | 34 | ## Committers 35 | 36 | ``` 37 | Jesper Pedersen 38 | Luca Ferrari 39 | ``` 40 | 41 | ## Contributing 42 | 43 | Contributions to [**pgagroal**][pgagroal] are managed on [GitHub][pgagroal] 44 | 45 | * [Ask a question][ask] 46 | * [Raise an issue][issue] 47 | * [Feature request][request] 48 | * [Code submission][submission] 49 | 50 | Contributions are most welcome! 51 | 52 | Please, consult our [Code of Conduct][conduct] policies for interacting in our 53 | community. 54 | 55 | Consider giving the project a [star][star] on 56 | [GitHub][pgagroal] if you find it useful. And, feel free to follow 57 | the project on [Twitter][twitter] as well. 58 | -------------------------------------------------------------------------------- /doc/manual/98-licenses.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # License 4 | 5 | ``` 6 | Copyright (C) 2025 The pgagroal community 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above 16 | copyright notice, this list of conditions and the following 17 | disclaimer in the documentation and/or other materials provided 18 | with the distribution. 19 | 20 | 3. Neither the name of the copyright holder nor the names of 21 | its contributors may be used to endorse or promote products 22 | derived from this software without specific prior written 23 | permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 33 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 37 | OF SUCH DAMAGE. 38 | ``` 39 | 40 | [BSD-3-Clause][license] 41 | 42 | 43 | ## libart 44 | Our adaptive radix tree (ART) implementation is based on 45 | [The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases][ART_paper] 46 | and [libart][libart] which has a [3-BSD license][license] as 47 | 48 | ``` 49 | Copyright (c) 2012, Armon Dadgar 50 | All rights reserved. 51 | 52 | Redistribution and use in source and binary forms, with or without 53 | modification, are permitted provided that the following conditions 54 | are met: 55 | 56 | * Redistributions of source code must retain the above copyright 57 | notice, this list of conditions and the following disclaimer. 58 | 59 | * Redistributions in binary form must reproduce the above copyright 60 | notice, this list of conditions and the following disclaimer in the 61 | documentation and/or other materials provided with the distribution. 62 | 63 | * Neither the name of the organization nor the 64 | names of its contributors may be used to endorse or promote products 65 | derived from this software without specific prior written permission. 66 | 67 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 68 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 69 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 70 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARMON DADGAR 71 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 72 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 73 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 74 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 75 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 76 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 77 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 78 | ``` 79 | -------------------------------------------------------------------------------- /doc/manual/99-references.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [pgagroal]: https://github.com/agroal/pgagroal 4 | [postgresql]: https://www.postgresql.org 5 | [fedora]: https://getfedora.org/ 6 | [rhel]: https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux 7 | [appstram]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/installing_managing_and_removing_user-space_components/using-appstream_using-appstream 8 | [freebsd]: https://www.freebsd.org/ 9 | [openbsd]: http://www.openbsd.org/ 10 | [gcc]: https://gcc.gnu.org 11 | [cmake]: https://cmake.org 12 | [make]: https://www.gnu.org/software/make/ 13 | [liburing]: https://github.com/axboe/liburing 14 | [openssl]: http://www.openssl.org/ 15 | [systemd]: https://www.freedesktop.org/wiki/Software/systemd/ 16 | [rst2man]: https://docutils.sourceforge.io/ 17 | [pandoc]: https://pandoc.org/ 18 | [pandoc_latex_template]: https://github.com/Wandmalfarbe/pandoc-latex-template 19 | [texlive]: https://www.tug.org/texlive/ 20 | [clang]: https://clang.llvm.org/ 21 | [git_squash]: https://www.git-tower.com/learn/git/faq/git-squash 22 | [progit]: https://github.com/progit/progit2/releases 23 | [prometheus]: https://prometheus.io/ 24 | [wireshark]: https://www.wireshark.org/ 25 | [pgprtdbg]: https://github.com/jesperpedersen/pgprtdbg 26 | [ART_paper]: http://www-db.in.tum.de/~leis/papers/ART.pdf 27 | [libart]: https://github.com/armon/libart 28 | 29 | 30 | [rpm]: https://github.com/agroal/pgagroal/blob/master/doc/RPM.md 31 | [configuration]: https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md 32 | 33 | [t_install]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md 34 | [t_prefill]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/02_prefill.md 35 | [t_remote_management]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/03_remote_management.md 36 | [t_prometheus]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/04_prometheus.md 37 | [t_split_security]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/05_split_security.md 38 | [t_tls]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/06_tls.md 39 | [t_vault]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/07_vault.md 40 | [t_docker]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/08_docker.md 41 | 42 | [sample]: https://github.com/agroal/pgagroal/blob/master/doc/etc/pgagroal.conf 43 | 44 | 45 | [main_c]: https://github.com/agroal/pgagroal/blob/master/src/main.c 46 | [cli_c]: https://github.com/agroal/pgagroal/blob/master/src/cli.c 47 | [admin_c]: https://github.com/agroal/pgagroal/blob/master/src/admin.c 48 | [vault_c]: https://github.com/agroal/pgagroal/blob/master/src/vault.c 49 | 50 | [shmem_h]: https://github.com/agroal/pgagroal/blob/master/src/include/shmem.h 51 | [pgagroal_h]: https://github.com/agroal/pgagroal/blob/master/src/include/pgagroal.h 52 | [messge_h]: https://github.com/agroal/pgagroal/blob/master/src/include/message.h 53 | [network_h]: https://github.com/agroal/pgagroal/blob/master/src/include/network.h 54 | [memory_h]: https://github.com/agroal/pgagroal/blob/master/src/include/memory.h 55 | [management_h]: https://github.com/agroal/pgagroal/blob/master/src/include/management.h 56 | [remote_h]: https://github.com/agroal/pgagroal/blob/master/src/include/remote.h 57 | [prometheus_h]: https://github.com/agroal/pgagroal/blob/master/src/include/prometheus.h 58 | [logging_h]: https://github.com/agroal/pgagroal/blob/master/src/include/logging.h 59 | 60 | [message_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/message.c 61 | [network_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/network.c 62 | [memory_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/memory.c 63 | [remote_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/remote.c 64 | [prometheus_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/prometheus.c 65 | [logging_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/logging.c 66 | 67 | [ask]: https://github.com/agroal/pgagroal/discussions 68 | [issue]: https://github.com/agroal/pgagroal/issues 69 | [request]: https://github.com/agroal/pgagroal/issues 70 | [submission]: https://github.com/agroal/pgagroal/pulls 71 | [conduct]: https://github.com/agroal/pgagroal/blob/master/CODE_OF_CONDUCT.md 72 | [star]: https://github.com/agroal/pgagroal/stargazers 73 | [twitter]: https://twitter.com/pgagroal/ 74 | [license]: https://opensource.org/licenses/BSD-3-Clause 75 | -------------------------------------------------------------------------------- /doc/manual/advanced/00-frontpage.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Advanced connection management with pgagroal" 3 | keywords: [pgagroal, PostgreSQL] 4 | lang: "en" 5 | titlepage: true, 6 | titlepage-color: "0064A5" 7 | titlepage-text-color: "FFFFFF" 8 | titlepage-rule-color: "360049" 9 | titlepage-rule-height: 0 10 | toc-own-page: true 11 | listings-disable-line-numbers: true 12 | table-use-row-colors: true 13 | ... 14 | -------------------------------------------------------------------------------- /doc/manual/advanced/01-preface.md: -------------------------------------------------------------------------------- 1 | # Preface 2 | 3 | Acme Boot is a startup company that have decided to use [**PostgreSQL**][postgresql] as 4 | its database technology. 5 | 6 | The following technologies will be used for the database cluster 7 | 8 | * [**Rocky Linux**][rocky] **9.x** 9 | * [**PostgreSQL**][postgresql] **17.x** 10 | * [**pgagroal**][pgagroal] 11 | 12 | Note, that this guide will focus on the [**pgagroal**][pgagroal] aspect of the platform. 13 | -------------------------------------------------------------------------------- /doc/manual/advanced/02-introduction.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Introduction 4 | 5 | [**pgagroal**][pgagroal] is a high-performance protocol-native connection pool for [PostgreSQL][postgresql]. 6 | 7 | ## Features 8 | 9 | * High performance 10 | * Connection pool 11 | * Limit connections for users and databases 12 | * Prefill support 13 | * Remove idle connections 14 | * Perform connection validation 15 | * Enable / disable database access 16 | * Graceful / fast shutdown 17 | * Prometheus support 18 | * Grafana 8 dashboard 19 | * Remote management 20 | * Authentication query support 21 | * Failover support 22 | * Transport Layer Security (TLS) v1.2+ support 23 | * Daemon mode 24 | * User vault 25 | 26 | ## Platforms 27 | 28 | The supported platforms are 29 | 30 | * [Fedora][fedora] 32+ 31 | * [RHEL][rhel] 8 / RockyLinux 8 32 | * [RHEL][rhel] 9 / RockyLinux 9 33 | * [FreeBSD][freebsd] 34 | * [OpenBSD][openbsd] 35 | -------------------------------------------------------------------------------- /doc/manual/advanced/03-installation.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Installation 4 | 5 | ## Rocky Linux 9.x 6 | 7 | We can download the [Rocky Linux](https://www.rockylinux.org/) distruction from their web site 8 | 9 | ``` 10 | https://rockylinux.org/download 11 | ``` 12 | 13 | The installation and setup is beyond the scope of this guide. 14 | 15 | Ideally, you would use dedicated user accounts to run [**PostgreSQL**][postgresql] and [**pgagroal**][pgagroal] 16 | 17 | ``` 18 | useradd postgres 19 | usermod -a -G wheel postgres 20 | useradd pgagroal 21 | usermod -a -G wheel pgagroal 22 | ``` 23 | 24 | Add a configuration directory for [**pgagroal**][pgagroal] 25 | 26 | ``` 27 | mkdir /etc/pgagroal 28 | chown -R pgagroal:pgagroal /etc/pgagroal 29 | ``` 30 | 31 | and lets open the ports in the firewall that we will need 32 | 33 | ``` 34 | firewall-cmd --permanent --zone=public --add-port=2345/tcp 35 | firewall-cmd --permanent --zone=public --add-port=2346/tcp 36 | ``` 37 | 38 | ## PostgreSQL 17 39 | 40 | We will install PostgreSQL 17 from the official [YUM repository][yum] with the community binaries, 41 | 42 | **x86_64** 43 | 44 | ``` 45 | dnf -qy module disable postgresql 46 | dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm 47 | ``` 48 | 49 | **aarch64** 50 | 51 | ``` 52 | dnf -qy module disable postgresql 53 | dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-aarch64/pgdg-redhat-repo-latest.noarch.rpm 54 | ``` 55 | 56 | and do the install via 57 | 58 | ``` 59 | dnf install -y postgresql17 postgresql17-server postgresql17-contrib 60 | ``` 61 | 62 | First, we will update `~/.bashrc` with 63 | 64 | ``` 65 | cat >> ~/.bashrc 66 | export PGHOST=/tmp 67 | export PATH=/usr/pgsql-17/bin/:$PATH 68 | ``` 69 | 70 | then Ctrl-d to save, and 71 | 72 | ``` 73 | source ~/.bashrc 74 | ``` 75 | 76 | to reload the Bash environment. 77 | 78 | Then we can do the PostgreSQL initialization 79 | 80 | ``` 81 | mkdir DB 82 | initdb -k DB 83 | ``` 84 | 85 | and update configuration - for a 8 GB memory machine. 86 | 87 | **postgresql.conf** 88 | ``` 89 | listen_addresses = '*' 90 | port = 5432 91 | max_connections = 100 92 | unix_socket_directories = '/tmp' 93 | password_encryption = scram-sha-256 94 | shared_buffers = 2GB 95 | huge_pages = try 96 | max_prepared_transactions = 100 97 | work_mem = 16MB 98 | dynamic_shared_memory_type = posix 99 | wal_level = replica 100 | wal_log_hints = on 101 | max_wal_size = 16GB 102 | min_wal_size = 2GB 103 | log_destination = 'stderr' 104 | logging_collector = on 105 | log_directory = 'log' 106 | log_filename = 'postgresql.log' 107 | log_rotation_age = 0 108 | log_rotation_size = 0 109 | log_truncate_on_rotation = on 110 | log_line_prefix = '%p [%m] [%x] ' 111 | log_timezone = UTC 112 | datestyle = 'iso, mdy' 113 | timezone = UTC 114 | lc_messages = 'en_US.UTF-8' 115 | lc_monetary = 'en_US.UTF-8' 116 | lc_numeric = 'en_US.UTF-8' 117 | lc_time = 'en_US.UTF-8' 118 | ``` 119 | 120 | Please, check with other sources in order to create a setup for your local setup. 121 | 122 | Now, we are ready to start PostgreSQL 123 | 124 | ``` 125 | pg_ctl -D DB -l /tmp/ start 126 | ``` 127 | 128 | ## pgagroal 129 | 130 | We will install [**pgagroal**][pgagroal] from the official [YUM repository][yum] as well, 131 | 132 | ``` 133 | dnf install -y pgagroal 134 | ``` 135 | 136 | First, we will need to create a master security key for the [**pgagroal**][pgagroal] installation, by 137 | 138 | ``` 139 | pgagroal-admin -g master-key 140 | ``` 141 | 142 | By default, this will ask for a key interactively. Alternatively, a key can be provided using either the 143 | `--password` command line argument, or the `PGAGROAL_PASSWORD` environment variable. Note that passing the 144 | key using the command line might not be secure. 145 | 146 | Then we will create the configuration for [**pgagroal**][pgagroal], 147 | 148 | ``` 149 | cat > /etc/pgagroal/pgagroal.conf 150 | [pgagroal] 151 | host = * 152 | port = 2345 153 | 154 | metrics = 2346 155 | 156 | log_type = file 157 | log_level = info 158 | log_path = /tmp/pgagroal.log 159 | 160 | max_connections = 100 161 | idle_timeout = 600 162 | validation = off 163 | unix_socket_dir = /tmp/ 164 | 165 | [primary] 166 | host = localhost 167 | port = 5432 168 | ``` 169 | 170 | and end with a Ctrl-d to save the file. 171 | 172 | Start [**pgagroal**][pgagroal] now, by 173 | 174 | ``` 175 | pgagroal -d 176 | ``` 177 | -------------------------------------------------------------------------------- /doc/manual/advanced/05-prefill.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Prefill 4 | 5 | ## Create prefill configuration 6 | 7 | Prefill is instrumented by the `pgagroal_databases.conf` configuration file, where you need 8 | to list databases, usernames, and limits. Every username/database pair has to be specified on a separated line. 9 | 10 | The limits are assumed as: 11 | 12 | * *max number of allowed connections* for that username/database 13 | * *initial number of connections*, that is the effective prefill; 14 | * *minimum number of connections* to always keep open for the pair username/database. 15 | 16 | Assuming you want to configure the prefill for the `mydb` database with the `myuser` username, 17 | you have to edit the file `/etc/pgagroal/pgagroal_databases.conf` with your editor of choice 18 | or using `cat` from the command line, as follows: 19 | 20 | ``` 21 | cd /etc/pgagroal 22 | cat > pgagroal_databases.conf 23 | mydb myuser 2 1 0 24 | ``` 25 | 26 | and press `Ctrl-d` to save the file. 27 | 28 | This will create a configuration where `mydb` will have a maximum connection size of 2, 29 | an initial connection size of 1 and a minimum connection size of 0 for the `myuser` user. 30 | 31 | The file must be owned by the operating system user [**pgagroal**](https://github.com/agroal/pgagroal). 32 | 33 | The `max_size` value is mandatory, while the `initial_size` and `min_size` are optional and if not explicitly set are assumed to be `0`. 34 | See [the `pgagroal_databases.conf` file documentation](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal_databases-configuration) for more details. 35 | 36 | ## Restart pgagroal 37 | 38 | In order to apply changes to the prefill configuration, you need to restart [**pgagroal**](https://github.com/agroal/pgagroal). 39 | You can do so by stopping it and then re-launch the daemon, as [**pgagroal**](https://github.com/agroal/pgagroal) operating system user: 40 | 41 | ``` 42 | pgagroal-cli shutdown 43 | pgagroal -d 44 | ``` 45 | 46 | ## Check the prefill 47 | 48 | You can check the prefill by running, as the [**pgagroal**](https://github.com/agroal/pgagroal) operating system user, the `status` command: 49 | 50 | ``` 51 | pgagroal-cli status 52 | Status: Running 53 | Active connections: 0 54 | Total connections: 1 55 | Max connections: 100 56 | 57 | ``` 58 | 59 | where the `Total connections` is set by the *initial* connection specified in the limit file. 60 | -------------------------------------------------------------------------------- /doc/manual/advanced/06-remote_management.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Remote administration 4 | 5 | ## Enable remote management 6 | 7 | On the pooler machine, you need to enable the remote management. In order to do so, 8 | add the `management` setting to the main `pgagroal.conf` configuration file. 9 | The value of setting is the number of a free TCP/IP port to which the remote 10 | management will connect to. 11 | 12 | With your editor of choice, edit the `/etc/pgagroal/pgagroal.conf` file and add the 13 | `management` option likely the following: 14 | 15 | ``` 16 | management = 2347 17 | ``` 18 | 19 | under the `[pgagroal]` section, so that the configuration file looks like: 20 | 21 | ``` 22 | [pgagroal] 23 | ... 24 | management = 2347 25 | ``` 26 | 27 | See [the pgagroal configuration settings](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal) for more details. 28 | 29 | ## Add remote admin user 30 | 31 | Remote management is done via a specific admin user, that has to be created within the pooler vault. 32 | As the [**pgagroal**][pgagroal] operating system user, run the following command: 33 | 34 | ``` 35 | cd /etc/pgagroal 36 | pgagroal-admin -f /etc/pgagroal/pgagroal_admins.conf -U admin -P admin1234 add-user 37 | ``` 38 | 39 | The above will create the `admin` username with the `admin1234` password. 40 | 41 | **We strongly encourage you to choose non trivial usernames and passwords!** 42 | 43 | 44 | ## Restart pgagroal 45 | 46 | In order to make the changes available, and therefore activate the remote management, you have to restart [**pgagroal**][pgagroal], for example by issuing the following commands from the [**pgagroal**][pgagroal] operatng system user: 47 | 48 | ``` 49 | pgagroal-cli shutdown 50 | pgagroal -d 51 | ``` 52 | 53 | ## Connect via remote administration interface 54 | 55 | In order to connect remotely, you need to specify at least the `-h` and `-p` flags on the `pgagroal-cli` command line. Such flags will tell `pgagroal-cli` to connect to a remote host. You can also specify the username you want to connect with by specifying the `-U` flag. 56 | So, to get the status of the pool remotely, you can issue: 57 | 58 | ``` 59 | pgagroal-cli -h localhost -p 2347 -U admin status 60 | ``` 61 | 62 | and type the password `admin1234` when asked for it. 63 | 64 | If you don't specify the `-U` flag on the command line, you will be asked for a username too. 65 | 66 | Please note that the above example uses `localhost` as the remote host, but clearly you can specify any *real* remote host you want to manage. 67 | -------------------------------------------------------------------------------- /doc/manual/advanced/07-split_security.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Split security model 4 | 5 | ## Create frontend users 6 | 7 | Frontend users are stored into the `pgagroal_frontend_users.conf` file, that can be managed via the `pgagroal-admin` command line tool. 8 | See [the documentation on frontend users](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal_frontend_users-configuration) for more details. 9 | 10 | As an example, consider the user `myuser` that has the `mypassword` password defined on the PostgreSQL side. It is possible to *remap* the user password on the [**pgagroal**][pgagroal] side, 11 | so that an application can connect to the [**pgagroal**][pgagroal] using a different password, like `application_password`. In turn, [**pgagroal**][pgagroal] will connect to PostgreSQL 12 | using the `mypassword` password. Therefore, the application doesn't not know the *real* password used to connect to PostgreSQL. 13 | 14 | To achieve this, as [**pgagroal**][pgagroal] operating system run the following command: 15 | 16 | ``` 17 | pgagroal-admin -f /etc/pgagroal/pgagroal_frontend_users.conf -U myuser -P application_password user add 18 | ``` 19 | 20 | You will need a password mapping for each user defined in the `pgagroal_users.conf` configuration file. 21 | 22 | ## Restart pgagroal 23 | 24 | In order to apply changes, you need to restart [**pgagroal**][pgagroal] so do: 25 | 26 | ``` 27 | pgagroal-cli shutdown 28 | pgagroal -d 29 | ``` 30 | 31 | ## Connect to PostgreSQL 32 | 33 | You can now use the "application password" to access the PostgreSQL instance. As an example, 34 | run the following as any operatng system user: 35 | 36 | ``` 37 | psql -h localhost -p 2345 -U myuser mydb 38 | ``` 39 | 40 | using `application_password` as the password. 41 | As already explained, [**pgagroal**][pgagroal] will then use the `mypassword` password against PostgreSQL. 42 | 43 | This **split security model** allows you to avoid sharing password between applications and PostgreSQL, 44 | letting the [**pgagroal**][pgagroal] to be the secret-keeper. This not only improves security, but also allows you 45 | to change the PostgreSQL password without having the application change its configuration. 46 | -------------------------------------------------------------------------------- /doc/manual/advanced/08-tls.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Transport Level Security (TLS) 4 | 5 | ## Creating Certificates 6 | 7 | This tutorial will show you how to create self-signed certificate for the server, valid for 365 days, use the following OpenSSL command, replacing `dbhost.yourdomain.com` with the server's host name, here `localhost`: 8 | 9 | ``` 10 | openssl req -new -x509 -days 365 -nodes -text -out server.crt \ 11 | -keyout server.key -subj "/CN=dbhost.yourdomain.com" 12 | ``` 13 | 14 | then do - 15 | 16 | ``` 17 | chmod og-rwx server.key 18 | ``` 19 | 20 | because the server will reject the file if its permissions are more liberal than this. For more details on how to create your server private key and certificate, refer to the OpenSSL documentation. 21 | 22 | For the purpose of this tutorial we will assume the client certificate and key same as the server certificate and server key and therefore, these equations always holds - 23 | 24 | * `` = `` 25 | * `` = `` 26 | * `` = `` 27 | * `` = `` 28 | 29 | ## TLS in `pgagroal` 30 | 31 | ### Modify the `pgagroal` configuration 32 | 33 | It is now time to modify the [pgagroal] section of configuration file `/etc/pgagroal/pgagroal_vault.conf`, with your editor of choice by adding the following lines in the [pgagroal] section. 34 | 35 | ``` 36 | tls = on 37 | tls_cert_file = 38 | tls_key_file = 39 | ``` 40 | 41 | ### Only Server Authentication 42 | 43 | If you wish to do only server authentication the aforementioned configuration suffice. 44 | 45 | **Client Request** 46 | 47 | ``` 48 | PGSSLMODE=verify-full PGSSLROOTCERT= psql -h localhost -p 2345 -U 49 | ``` 50 | 51 | ### Full Client and Server Authentication 52 | 53 | To enable the server to request the client certificates add the following configuration lines 54 | 55 | ``` 56 | tls = on 57 | tls_cert_file = 58 | tls_key_file = 59 | tls_ca_file = 60 | ``` 61 | 62 | **Client Request** 63 | 64 | ``` 65 | PGSSLMODE=verify-full PGSSLCERT= PGSSLKEY= PGSSLROOTCERT= psql -h localhost -p 2345 -U 66 | ``` 67 | -------------------------------------------------------------------------------- /doc/manual/advanced/10-prometheus.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Prometheus metrics 4 | 5 | ## pgagroal 6 | 7 | Once [**pgagroal**][pgagroal] is running you can access the metrics with a browser at the pooler address, specifying the `metrics` port number and routing to the `/metrics` page. For example, point your web browser at: 8 | 9 | ``` 10 | http://localhost:2346/metrics 11 | ``` 12 | 13 | It is also possible to get an explaination of what is the meaning of each metric by pointing your web browser at: 14 | 15 | ``` 16 | http://localhost:2346/ 17 | ``` 18 | 19 | ## pgagroal-vault 20 | 21 | Once [**pgagroal-vault**][pgagroal] is running you can access the metrics with a browser at the pooler address, specifying the `metrics` port number and routing to the `/metrics` page. For example, point your web browser at: 22 | 23 | ``` 24 | http://localhost:2501/metrics 25 | ``` 26 | 27 | It is also possible to get an explaination of what is the meaning of each metric by pointing your web browser at: 28 | 29 | ``` 30 | http://localhost:2501/ 31 | ``` 32 | -------------------------------------------------------------------------------- /doc/manual/advanced/97-acknowledgement.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Acknowledgement 4 | 5 | ## Authors 6 | 7 | [**pgagroal**][pgagroal] was created by the following authors: 8 | 9 | ``` 10 | Jesper Pedersen 11 | David Fetter 12 | Will Leinweber 13 | Junduo Dong 14 | Luca Ferrari 15 | Nikita Bugrovsky 16 | Lawrence Wu 17 | Yongting You <2010youy01@gmail.com> 18 | Ashutosh Sharma 19 | Henrique de Carvalho 20 | Yihe Lu 21 | Eugenio Gigante 22 | Mohanad Khaled 23 | Haoran Zhang 24 | Christian Englert 25 | Georg Pfuetzenreuter 26 | Tejas Tyagi 27 | Aryan Arora 28 | Sangkeun J.C. Kim 29 | Arshdeep Singh 30 | Vanes Angelo 31 | Bassam Adnan 32 | ``` 33 | 34 | ## Committers 35 | 36 | ``` 37 | Jesper Pedersen 38 | Luca Ferrari 39 | ``` 40 | 41 | ## Contributing 42 | 43 | Contributions to [**pgagroal**][pgagroal] are managed on [GitHub][pgagroal] 44 | 45 | * [Ask a question][ask] 46 | * [Raise an issue][issue] 47 | * [Feature request][request] 48 | * [Code submission][submission] 49 | 50 | Contributions are most welcome! 51 | 52 | Please, consult our [Code of Conduct][conduct] policies for interacting in our 53 | community. 54 | 55 | Consider giving the project a [star][star] on 56 | [GitHub][pgagroal] if you find it useful. And, feel free to follow 57 | the project on [Twitter][twitter] as well. 58 | -------------------------------------------------------------------------------- /doc/manual/advanced/98-licenses.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # License 4 | 5 | ``` 6 | Copyright (C) 2025 The pgagroal community 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above 16 | copyright notice, this list of conditions and the following 17 | disclaimer in the documentation and/or other materials provided 18 | with the distribution. 19 | 20 | 3. Neither the name of the copyright holder nor the names of 21 | its contributors may be used to endorse or promote products 22 | derived from this software without specific prior written 23 | permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 30 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 33 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 36 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 37 | OF SUCH DAMAGE. 38 | ``` 39 | 40 | [BSD-3-Clause][license] 41 | 42 | 43 | ## libart 44 | Our adaptive radix tree (ART) implementation is based on 45 | [The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases][ART_paper] 46 | and [libart][libart] which has a [3-BSD license][license] as 47 | 48 | ``` 49 | Copyright (c) 2012, Armon Dadgar 50 | All rights reserved. 51 | 52 | Redistribution and use in source and binary forms, with or without 53 | modification, are permitted provided that the following conditions 54 | are met: 55 | 56 | * Redistributions of source code must retain the above copyright 57 | notice, this list of conditions and the following disclaimer. 58 | 59 | * Redistributions in binary form must reproduce the above copyright 60 | notice, this list of conditions and the following disclaimer in the 61 | documentation and/or other materials provided with the distribution. 62 | 63 | * Neither the name of the organization nor the 64 | names of its contributors may be used to endorse or promote products 65 | derived from this software without specific prior written permission. 66 | 67 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 68 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 69 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 70 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARMON DADGAR 71 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 72 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 73 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 74 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 75 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 76 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 77 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 78 | ``` 79 | -------------------------------------------------------------------------------- /doc/manual/advanced/99-references.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [pgagroal]: https://github.com/agroal/pgagroal 4 | [postgresql]: https://www.postgresql.org 5 | [rocky]: https://www.rockylinux.org 6 | [fedora]: https://getfedora.org/ 7 | [rhel]: https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux 8 | [appstram]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/installing_managing_and_removing_user-space_components/using-appstream_using-appstream 9 | [freebsd]: https://www.freebsd.org/ 10 | [openbsd]: http://www.openbsd.org/ 11 | [gcc]: https://gcc.gnu.org 12 | [cmake]: https://cmake.org 13 | [make]: https://www.gnu.org/software/make/ 14 | [libev]: http://software.schmorp.de/pkg/libev.html 15 | [openssl]: http://www.openssl.org/ 16 | [systemd]: https://www.freedesktop.org/wiki/Software/systemd/ 17 | [rst2man]: https://docutils.sourceforge.io/ 18 | [pandoc]: https://pandoc.org/ 19 | [pandoc_latex_template]: https://github.com/Wandmalfarbe/pandoc-latex-template 20 | [texlive]: https://www.tug.org/texlive/ 21 | [clang]: https://clang.llvm.org/ 22 | [git_squash]: https://www.git-tower.com/learn/git/faq/git-squash 23 | [progit]: https://github.com/progit/progit2/releases 24 | [prometheus]: https://prometheus.io/ 25 | [wireshark]: https://www.wireshark.org/ 26 | [pgprtdbg]: https://github.com/jesperpedersen/pgprtdbg 27 | [ART_paper]: http://www-db.in.tum.de/~leis/papers/ART.pdf 28 | [libart]: https://github.com/armon/libart 29 | 30 | 31 | [rpm]: https://github.com/agroal/pgagroal/blob/master/doc/RPM.md 32 | [configuration]: https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md 33 | 34 | [t_install]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md 35 | [t_prefill]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/02_prefill.md 36 | [t_remote_management]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/03_remote_management.md 37 | [t_prometheus]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/04_prometheus.md 38 | [t_split_security]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/05_split_security.md 39 | [t_tls]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/06_tls.md 40 | [t_vault]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/07_vault.md 41 | [t_docker]: https://github.com/agroal/pgagroal/blob/master/doc/tutorial/08_docker.md 42 | 43 | [sample]: https://github.com/agroal/pgagroal/blob/master/doc/etc/pgagroal.conf 44 | 45 | 46 | [main_c]: https://github.com/agroal/pgagroal/blob/master/src/main.c 47 | [cli_c]: https://github.com/agroal/pgagroal/blob/master/src/cli.c 48 | [admin_c]: https://github.com/agroal/pgagroal/blob/master/src/admin.c 49 | [vault_c]: https://github.com/agroal/pgagroal/blob/master/src/vault.c 50 | 51 | [shmem_h]: https://github.com/agroal/pgagroal/blob/master/src/include/shmem.h 52 | [pgagroal_h]: https://github.com/agroal/pgagroal/blob/master/src/include/pgagroal.h 53 | [messge_h]: https://github.com/agroal/pgagroal/blob/master/src/include/message.h 54 | [network_h]: https://github.com/agroal/pgagroal/blob/master/src/include/network.h 55 | [memory_h]: https://github.com/agroal/pgagroal/blob/master/src/include/memory.h 56 | [management_h]: https://github.com/agroal/pgagroal/blob/master/src/include/management.h 57 | [remote_h]: https://github.com/agroal/pgagroal/blob/master/src/include/remote.h 58 | [prometheus_h]: https://github.com/agroal/pgagroal/blob/master/src/include/prometheus.h 59 | [logging_h]: https://github.com/agroal/pgagroal/blob/master/src/include/logging.h 60 | 61 | [message_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/message.c 62 | [network_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/network.c 63 | [memory_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/memory.c 64 | [remote_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/remote.c 65 | [prometheus_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/prometheus.c 66 | [logging_c]: https://github.com/agroal/pgagroal/blob/master/src/libpgagroal/logging.c 67 | 68 | 69 | [ask]: https://github.com/agroal/pgagroal/discussions 70 | [issue]: https://github.com/agroal/pgagroal/issues 71 | [request]: https://github.com/agroal/pgagroal/issues 72 | [submission]: https://github.com/agroal/pgagroal/pulls 73 | [conduct]: https://github.com/agroal/pgagroal/blob/master/CODE_OF_CONDUCT.md 74 | [star]: https://github.com/agroal/pgagroal/stargazers 75 | [twitter]: https://twitter.com/pgagroal/ 76 | [license]: https://opensource.org/licenses/BSD-3-Clause 77 | -------------------------------------------------------------------------------- /doc/manual/dev-00-head.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "pgagroal" 3 | keywords: [pgagroal, PostgreSQL] 4 | subtitle: "Developer Guide" 5 | lang: "en" 6 | titlepage: true, 7 | titlepage-color: "0064A5" 8 | titlepage-text-color: "FFFFFF" 9 | titlepage-rule-color: "360049" 10 | titlepage-rule-height: 0 11 | toc-own-page: true 12 | listings-disable-line-numbers: true 13 | table-use-row-colors: true 14 | ... 15 | -------------------------------------------------------------------------------- /doc/manual/dev-01-git.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Git guide 4 | 5 | Here are some links that will help you 6 | 7 | * [How to Squash Commits in Git][git_squash] 8 | * [ProGit book][progit] 9 | 10 | ## Basic steps 11 | 12 | ### Start by forking the repository 13 | 14 | This is done by the "Fork" button on GitHub. 15 | 16 | ## Clone your repository locally 17 | 18 | This is done by 19 | 20 | ```sh 21 | git clone git@github.com:/pgagroal.git 22 | ``` 23 | 24 | ### Add upstream 25 | 26 | Do 27 | 28 | ```sh 29 | cd pgagroal 30 | git remote add upstream https://github.com/agroal/pgagroal.git 31 | ``` 32 | 33 | ### Do a work branch 34 | 35 | ```sh 36 | git checkout -b mywork main 37 | ``` 38 | 39 | ### Make the changes 40 | 41 | Remember to verify the compile and execution of the code. 42 | 43 | Use 44 | 45 | ``` 46 | [#xyz] Description 47 | ``` 48 | 49 | as the commit message where `[#xyz]` is the issue number for the work, and 50 | `Description` is a short description of the issue in the first line 51 | 52 | ### Multiple commits 53 | 54 | If you have multiple commits on your branch then squash them 55 | 56 | ``` sh 57 | git rebase -i HEAD~2 58 | ``` 59 | 60 | for example. It is `p` for the first one, then `s` for the rest 61 | 62 | ### Rebase 63 | 64 | Always rebase 65 | 66 | ``` sh 67 | git fetch upstream 68 | git rebase -i upstream/main 69 | ``` 70 | 71 | ### Force push 72 | 73 | When you are done with your changes force push your branch 74 | 75 | ``` sh 76 | git push -f origin mywork 77 | ``` 78 | 79 | and then create a pull request for it 80 | 81 | ### Format source code 82 | 83 | Use 84 | 85 | ``` sh 86 | ./uncrustify.sh 87 | ``` 88 | 89 | to format the source code 90 | 91 | ### Repeat 92 | 93 | Based on feedback keep making changes, squashing, rebasing and force pushing 94 | 95 | ### Undo 96 | 97 | Normally you can reset to an earlier commit using `git reset --hard`. 98 | 99 | But if you accidentally squashed two or more commits, and you want to undo that, you need to know where to reset to, and the commit seems to have lost after you rebased. 100 | 101 | But they are not actually lost - using `git reflog`, you can find every commit the HEAD pointer has ever pointed to. Find the commit you want to reset to, and do `git reset --hard`. 102 | -------------------------------------------------------------------------------- /doc/manual/dev-03-rpm.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # RPM 4 | 5 | [**pgagroal**][pgagroal] can be built into a RPM for [Fedora][fedora] systems. 6 | 7 | ## Requirements 8 | 9 | ```sh 10 | dnf install gcc rpm-build rpm-devel rpmlint make python bash coreutils diffutils patch rpmdevtools chrpath 11 | ``` 12 | 13 | ## Setup RPM development 14 | 15 | ```sh 16 | rpmdev-setuptree 17 | ``` 18 | 19 | ## Create source package 20 | 21 | ```sh 22 | git clone https://github.com/agroal/pgagroal.git 23 | cd pgagroal 24 | mkdir build 25 | cd build 26 | cmake -DCMAKE_BUILD_TYPE=Release .. 27 | make package_source 28 | ``` 29 | 30 | ## Create RPM package 31 | 32 | ```sh 33 | cp pgagroal-$VERSION.tar.gz ~/rpmbuild/SOURCES 34 | QA_RPATHS=0x0001 rpmbuild -bb pgagroal.spec 35 | ``` 36 | 37 | The resulting RPM will be located in `~/rpmbuild/RPMS/x86_64/`, if your architecture is `x86_64`. 38 | -------------------------------------------------------------------------------- /doc/manual/dev-05-codecoverage.md: -------------------------------------------------------------------------------- 1 | # Code Coverage 2 | 3 | ## Overview 4 | 5 | Code coverage helps you understand which parts of the codebase are exercised by your tests. This project supports both local and containerized coverage workflows. 6 | 7 | ## When is Coverage Available? 8 | 9 | - Coverage is only available if you **build the project with GCC** and have both `gcov` and `gcovr` installed. 10 | - If you use Clang, coverage reports will **not** be generated. 11 | - Coverage is enabled automatically during the build if the requirements are met. 12 | 13 | ## How to Generate Coverage Reports 14 | 15 | ### 1. Run the Test Suite 16 | 17 | First, run the test suite to generate coverage data. From your `build` directory: 18 | 19 | ```sh 20 | ./testsuite.sh 21 | ``` 22 | 23 | - This script sets up temporary PostgreSQL and pgagroal environments, runs all tests, and produces coverage data if enabled. 24 | 25 | ### 2. Generate Coverage Reports (Local) 26 | 27 | After running the tests, generate the coverage reports: 28 | 29 | ```sh 30 | # Run these commands from inside the build directory 31 | mkdir -p ./coverage 32 | 33 | gcovr -r ../src --object-directory . --html --html-details -o ./coverage/index.html 34 | gcovr -r ../src --object-directory . > ./coverage/summary.txt 35 | ``` 36 | 37 | - The HTML report will be available at `build/coverage/index.html` 38 | - A summary text report will be available at `build/coverage/summary.txt` 39 | 40 | > **Note:** If the `coverage` directory does not exist, create it first using `mkdir -p ./coverage`. 41 | > 42 | > **Important:** `gcovr` only works with GCC builds. 43 | 44 | ### 3. Containerized Coverage (Optional) 45 | 46 | If you have **Docker** or **Podman** installed, you can run tests and generate coverage in a container for a clean, isolated environment. 47 | 48 | You have two options: 49 | 50 | #### a. Using CTest 51 | 52 | ```sh 53 | ctest -V 54 | ``` 55 | 56 | This will run all tests in a container if configured. 57 | 58 | #### b. Using the Coverage Script 59 | 60 | ```sh 61 | ./coverage.sh 62 | ``` 63 | 64 | This script will: 65 | - Build and run the tests in a container 66 | - Generate coverage reports automatically in `build/coverage/` 67 | - Copy logs and coverage data back to your host 68 | 69 | ## Summary Table 70 | 71 | | Task | Command(s) | Prerequisites | 72 | |-----------------------------|-----------------------------------|------------------------------| 73 | | Run tests locally | `./testsuite.sh` | Built with GCC, PostgreSQL | 74 | | Generate coverage locally | See commands above | `gcov`, `gcovr` installed | 75 | | Run containerized tests | `ctest -V` or `./coverage.sh` | Docker or Podman installed | 76 | 77 | ## Notes 78 | 79 | - Always run the coverage commands from the `build` directory. 80 | - If coverage tools are not found, or the compiler is not GCC, coverage generation will be skipped and a message will be shown. 81 | - You can always re-run the coverage commands manually if needed. 82 | 83 | --- -------------------------------------------------------------------------------- /doc/manual/user-00-head.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "pgagroal" 3 | keywords: [pgagroal, PostgreSQL] 4 | subtitle: "User Guide" 5 | lang: "en" 6 | titlepage: true, 7 | titlepage-color: "0064A5" 8 | titlepage-text-color: "FFFFFF" 9 | titlepage-rule-color: "360049" 10 | titlepage-rule-height: 0 11 | toc-own-page: true 12 | listings-disable-line-numbers: true 13 | table-use-row-colors: true 14 | ... 15 | -------------------------------------------------------------------------------- /doc/manual/user-04-tutorials.md: -------------------------------------------------------------------------------- 1 | \newpage 2 | 3 | # Tutorials 4 | -------------------------------------------------------------------------------- /doc/manual/user-13-docker.md: -------------------------------------------------------------------------------- 1 | # Running pgagroal with Docker 2 | 3 | You can run `pgagroal` using Docker instead of compiling it manually. 4 | 5 | ## Prerequisites 6 | 7 | - **Docker** or **Podman** must be installed on the server where PostgreSQL is running. 8 | - Ensure PostgreSQL is configured to allow external connections. 9 | 10 | --- 11 | 12 | ## Step 1: Enable External PostgreSQL Access 13 | 14 | Modify the local PostgreSQL server's `postgresql.conf` file to allow connections from outside: 15 | ```ini 16 | listen_addresses = '*' 17 | ``` 18 | 19 | Update `pg_hba.conf` to allow remote connections: 20 | ```ini 21 | host all all 0.0.0.0/0 scram-sha-256 22 | ``` 23 | 24 | Follow [GETTING STARTED](https://github.com/agroal/pgagroal/blob/main/doc/GETTING_STARTED.md) for further server setup 25 | 26 | 27 | Then, restart PostgreSQL for the changes to take effect: 28 | ```sh 29 | sudo systemctl restart postgresql 30 | ``` 31 | 32 | --- 33 | 34 | ## Step 2: Clone the Repository 35 | ```sh 36 | git clone https://github.com/agroal/pgagroal.git 37 | cd pgagroal 38 | ``` 39 | 40 | --- 41 | 42 | ## Step 3: Build the Docker Image 43 | 44 | There are two Dockerfiles available: 45 | 1. **Alpine-based image** 46 | **Using Docker** 47 | ```sh 48 | docker build -t pgagroal:latest -f ./contrib/docker/Dockerfile.alpine . 49 | ``` 50 | **Using Podman** 51 | ```sh 52 | podman build -t pgagroal:latest -f ./contrib/docker/Dockerfile.alpine . 53 | ``` 54 | 55 | 2. **Rocky Linux 9-based image** 56 | ```sh 57 | docker build -t pgagroal:latest -f ./contrib/docker/Dockerfile.rocky9 . 58 | ``` 59 | **Using Podman** 60 | ```sh 61 | podman build -t pgagroal:latest -f ./contrib/docker/Dockerfile.rocky9 . 62 | ``` 63 | 64 | --- 65 | 66 | ## Step 4: Run pgagroal as a Docker Container 67 | 68 | Once the image is built, run the container using: 69 | - **Using Docker** 70 | ```sh 71 | docker run -d --name pgagroal --network host pgagroal:latest 72 | ``` 73 | - **Using Podman** 74 | ```sh 75 | podman run -d --name pgagroal --network host pgagroal:latest 76 | ``` 77 | 78 | --- 79 | 80 | ## Step 5: Verify the Container 81 | 82 | Check if the container is running: 83 | 84 | - **Using Docker** 85 | ```sh 86 | docker ps | grep pgagroal 87 | ``` 88 | - **Using Podman** 89 | ```sh 90 | podman ps | grep pgagroal 91 | ``` 92 | 93 | Check logs for any errors: 94 | - **Using Docker** 95 | ```sh 96 | docker logs pgagroal 97 | ``` 98 | - **Using Podman** 99 | ```sh 100 | podman logs pgagroal 101 | ``` 102 | 103 | 104 | We will assume that we have a user called `test` with the password `test` in our 105 | [PostgreSQL](https://www.postgresql.org) instance. See their 106 | [documentation](https://www.postgresql.org/docs/current/index.html) on how to setup 107 | [PostgreSQL](https://www.postgresql.org), [add a user](https://www.postgresql.org/docs/current/app-createuser.html) 108 | and [add a database](https://www.postgresql.org/docs/current/app-createdb.html). 109 | 110 | We will connect to [**pgagroal**](https://github.com/agroal/pgagroal) using the [psql](https://www.postgresql.org/docs/current/app-psql.html) 111 | application. 112 | 113 | ``` 114 | psql -h localhost -p 2345 -U test test 115 | ``` 116 | -------------------------------------------------------------------------------- /doc/tutorial/02_prefill.md: -------------------------------------------------------------------------------- 1 | ## Enable prefill for pgagroal 2 | 3 | This tutorial will show you how to do enable *prefill* for [**pgagroal**](https://github.com/agroal/pgagroal). 4 | 5 | The prefill is the capability to activate connections against a specific database 6 | even if no one has been actively requested by a user or an application. This allows the pooler 7 | to serve a connection faster once it is effectively requested, since the connection is already 8 | established. 9 | 10 | Prefill is done by making [**pgagroal**](https://github.com/agroal/pgagroal) to open the specified amount of connections to a specific database with a specific username, 11 | therefore you need to know credentials used on the [PostgreSQL](https://www.postgresql.org) side. 12 | 13 | ### Preface 14 | 15 | This tutorial assumes that you have already an installation of [PostgreSQL](https://www.postgresql.org) 13 (or higher) and [**pgagroal**](https://github.com/agroal/pgagroal). 16 | 17 | In particular, this tutorial refers to the configuration done in [Install pgagroal](https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md). 18 | 19 | ### Create prefill configuration 20 | 21 | Prefill is instrumented by the `pgagroal_databases.conf` configuration file, where you need 22 | to list databases, usernames, and limits. 23 | 24 | Every username/database pair has to be specified on a separated line. 25 | 26 | The limits are assumed as: 27 | 28 | * *max number of allowed connections* for that username/database 29 | * *initial number of connections* that is the effective prefill; 30 | * *minimum number of connections* to always keep open for the pair username/database. 31 | 32 | Assuming you want to configure the prefill for the `mydb` database with the `myuser` username, 33 | you have to edit the file `/etc/pgagroal/pgagroal_databases.conf` with your editor of choice 34 | or using `cat` from the command line, as follows: 35 | 36 | ``` 37 | cd /etc/pgagroal 38 | cat > pgagroal_databases.conf 39 | mydb myuser 2 1 0 40 | ``` 41 | 42 | and press `Ctrl-d` to save the file. 43 | 44 | This will create a configuration where `mydb` will have a maximum connection size of 2, 45 | an initial connection size of 1 and a minimum connection size of 0 for the `myuser` user using the `mydb` database. 46 | 47 | The file must be owned by the operating system user [**pgagroal**](https://github.com/agroal/pgagroal). 48 | 49 | The `max_size` value is mandatory, while the `initial_size` and `min_size` are optional and if not explicitly set are assumed to be `0`. 50 | 51 | See [the `pgagroal_databases.conf` file documentation](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal_databases-configuration) for more details. 52 | 53 | ### Restart pgagroal 54 | 55 | In order to apply changes to the prefill configuration, you need to restart [**pgagroal**](https://github.com/agroal/pgagroal). 56 | You can do so by stopping it and then re-launch the daemon, as [**pgagroal**](https://github.com/agroal/pgagroal) operating system user: 57 | 58 | ``` 59 | pgagroal-cli shutdown 60 | pgagroal -d 61 | ``` 62 | 63 | Since the default configuration files are usually searched into the `/etc/pgagroal/` directory, and have well defined names, you can omit the files 64 | from the command line if you named them `pgagroal.conf`, `pgagroal_hba.conf`, `pgagroal_users.conf` and `pgagroal_databases.conf`. 65 | 66 | ### Check the prefill 67 | 68 | You can check the prefill by running, as the [**pgagroal**](https://github.com/agroal/pgagroal) operating system user, the `status` command: 69 | 70 | ``` 71 | pgagroal-cli status 72 | Status: Running 73 | Active connections: 0 74 | Total connections: 1 75 | Max connections: 100 76 | ``` 77 | 78 | where the `Total connections` is set by the *initial* connection specified in the limit file. 79 | -------------------------------------------------------------------------------- /doc/tutorial/03_remote_management.md: -------------------------------------------------------------------------------- 1 | ## Remote administration for pgagroal 2 | 3 | This tutorial will show you how to do setup remote management for [**pgagroal**](https://github.com/agroal/pgagroal). 4 | 5 | [**pgagroal**](https://github.com/agroal/pgagroal) is managed via a command line tool named `pgagroal-cli`. Such tool 6 | connects via a local Unix socket if running on the same machine the pooler is 7 | running on, but it is possible to use `pgagroal-cli` from a different machine 8 | and make it to connect to the pooler machine via *remote management*. 9 | 10 | ## Preface 11 | 12 | This tutorial assumes that you have already an installation of [PostgreSQL](https://www.postgresql.org) 13 (or higher) and [**pgagroal**](https://github.com/agroal/pgagroal). 13 | 14 | In particular, this tutorial refers to the configuration done in [Install pgagroal](https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md). 15 | 16 | ### Enable remote management 17 | 18 | On the pooler machine, you need to enable the remote management. In order to do so, 19 | add the `management` setting to the main `pgagroal.conf` configuration file. 20 | The value of setting is the number of a free TCP/IP port to which the remote 21 | management will connect to. 22 | 23 | With your editor of choice, edit the `/etc/pgagroal/pgagroal.conf` file and add the 24 | `management` option likely the following: 25 | 26 | ``` 27 | management = 2347 28 | ``` 29 | 30 | under the `[pgagroal]` section, so that the configuration file looks like: 31 | 32 | ``` 33 | [pgagroal] 34 | ... 35 | management = 2347 36 | ``` 37 | 38 | See [the pgagroal configuration settings](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal) for more details. 39 | 40 | ### Add remote admin user 41 | 42 | Remote management is done via a specific admin user, that has to be created within the pooler vault. 43 | 44 | As the [**pgagroal**](https://github.com/agroal/pgagroal) operating system user, run the following command: 45 | 46 | ``` 47 | cd /etc/pgagroal 48 | pgagroal-admin -f pgagroal_admins.conf -U admin -P admin1234 add-user 49 | ``` 50 | 51 | The above will create the `admin` username with the `admin1234` password. 52 | 53 | **We strongly encourage you to choose non trivial usernames and passwords!** 54 | 55 | ### Restart pgagroal 56 | 57 | In order to make the changes available, and therefore activate the remote management, you have to restart [**pgagroal**](https://github.com/agroal/pgagroal), for example by issuing the following commands from the [**pgagroal**](https://github.com/agroal/pgagroal) operatng system user: 58 | 59 | ``` 60 | pgagroal-cli shutdown 61 | pgagroal -d 62 | ``` 63 | 64 | Since the default configuration files are usually searched into the `/etc/pgagroal/` directory, and have well defined names, you can omit the files from the command line 65 | if you named them `pgagroal.conf`, `pgagroal_hba.conf`, `pgagroal_users.conf` and `pgagroal_admins.conf`. 66 | 67 | ### Connect via remote administration interface 68 | 69 | In order to connect remotely, you need to specify at least the `-h` and `-p` flags on the `pgagroal-cli` command line. Such flags will tell `pgagroal-cli` to connect to a remote host. You can also specify the username you want to connect with by specifying the `-U` flag. 70 | So, to get the status of the pool remotely, you can issue: 71 | 72 | ``` 73 | pgagroal-cli -h localhost -p 2347 -U admin status 74 | ``` 75 | 76 | and type the password `admin1234` when asked for it. 77 | 78 | If you don't specify the `-U` flag on the command line, you will be asked for a username too. 79 | 80 | Please note that the above example uses `localhost` as the remote host, but clearly you can specify any *real* remote host you want to manage. 81 | -------------------------------------------------------------------------------- /doc/tutorial/05_split_security.md: -------------------------------------------------------------------------------- 1 | ## Split security model in pgagroal 2 | 3 | This tutorial will show you how to split the security model of [**pgagroal**](https://github.com/agroal/pgagroal). 4 | 5 | The idea is that the pooler can act as a *user proxy* between your application and 6 | the [PostgreSQL](https://www.postgresql.org) instance, so that your application does not need to know the exact password 7 | to use to connect to [PostgreSQL](https://www.postgresql.org). 8 | [**pgagroal**](https://github.com/agroal/pgagroal) will authenticate the connection request with its credentials, and then will 9 | authenticate against [PostgreSQL](https://www.postgresql.org) with the correct password. 10 | 11 | This *user mapping* is named *frontend users*. 12 | 13 | ### Preface 14 | 15 | This tutorial assumes that you have already an installation of [PostgreSQL](https://www.postgresql.org) 13 (or higher) and [**pgagroal**](https://github.com/agroal/pgagroal). 16 | 17 | In particular, this tutorial refers to the configuration done in [Install pgagroal](https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md). 18 | 19 | ### Create frontend users 20 | 21 | Frontend users are stored into the `pgagroal_frontend_users.conf` file, that can be managed via the `pgagroal-admin` command line tool. 22 | See [the documentation on frontend users](https://github.com/agroal/pgagroal/blob/master/doc/CONFIGURATION.md#pgagroal_frontend_users-configuration) for more details. 23 | 24 | As an example, consider the user `myuser` created in the [Installing pgagroal tutorial](https://github.com/agroal/pgagroal/blob/master/doc/tutorial/01_install.md)): such user has the `mypassword` password defined on the [PostgreSQL](https://www.postgresql.org) side. It is possible to *remap* the user password on the [**pgagroal**](https://github.com/agroal/pgagroal) side, so that an application can connect to the [**pgagroal**](https://github.com/agroal/pgagroal) using a different password, like `application_password`. In turn, [**pgagroal**](https://github.com/agroal/pgagroal) will connect to [PostgreSQL](https://www.postgresql.org) using the `mypassword` password. Therefore, the application could not know the *real* password used to connect to [PostgreSQL](https://www.postgresql.org). 25 | 26 | To achieve this, as [**pgagroal**](https://github.com/agroal/pgagroal) operating system run the following command: 27 | 28 | ``` 29 | PGAGROAL_PASSWORD=application_password pgagroal-admin -f /etc/pgagroal/pgagroal_frontend_users.conf -U myuser user add 30 | ``` 31 | 32 | ([**pgagroal**](https://github.com/agroal/pgagroal) user) 33 | 34 | You will need a password mapping for each user defined in the `pgagroal_users.conf` configuration file. 35 | 36 | ### Restart pgagroal 37 | 38 | In order to apply changes, you need to restart [**pgagroal**](https://github.com/agroal/pgagroal), so as the [**pgagroal**](https://github.com/agroal/pgagroal) operating system user do: 39 | 40 | ``` 41 | pgagroal-cli shutdown 42 | pgagroal -d 43 | ``` 44 | 45 | ### Connect to PostgreSQL 46 | 47 | You can now use the "application password" to access the [PostgreSQL](https://www.postgresql.org) instance. As an example, 48 | run the following as any operatng system user: 49 | 50 | ``` 51 | psql -h localhost -p 2345 -U myuser mydb 52 | ``` 53 | 54 | using `application_password` as the password. 55 | As already explained, [**pgagroal**](https://github.com/agroal/pgagroal) will then use the `mypassword` password against [PostgreSQL](https://www.postgresql.org). 56 | 57 | This **split security model** allows you to avoid sharing password between applications and [PostgreSQL](https://www.postgresql.org), 58 | letting the [**pgagroal**](https://github.com/agroal/pgagroal) to be the secret-keeper. This not only improves security, but also allows you 59 | to change the [PostgreSQL](https://www.postgresql.org) password without having the application to note it. 60 | -------------------------------------------------------------------------------- /doc/tutorial/08_docker.md: -------------------------------------------------------------------------------- 1 | # Running pgagroal with Docker 2 | 3 | You can run `pgagroal` using Docker instead of compiling it manually. 4 | 5 | ## Prerequisites 6 | 7 | - **Docker** or **Podman** must be installed on the server where PostgreSQL is running. 8 | - Ensure PostgreSQL is configured to allow external connections. 9 | 10 | --- 11 | 12 | ## Step 1: Enable External PostgreSQL Access 13 | 14 | Modify the local PostgreSQL server's `postgresql.conf` file to allow connections from outside: 15 | ```ini 16 | listen_addresses = '*' 17 | ``` 18 | 19 | Update `pg_hba.conf` to allow remote connections: 20 | ```ini 21 | host all all 0.0.0.0/0 scram-sha-256 22 | ``` 23 | 24 | Follow [GETTING STARTED](https://github.com/agroal/pgagroal/blob/main/doc/GETTING_STARTED.md) for further server setup 25 | 26 | 27 | Then, restart PostgreSQL for the changes to take effect: 28 | ```sh 29 | sudo systemctl restart postgresql 30 | ``` 31 | 32 | --- 33 | 34 | ## Step 2: Clone the Repository 35 | ```sh 36 | git clone https://github.com/agroal/pgagroal.git 37 | cd pgagroal 38 | ``` 39 | 40 | --- 41 | 42 | ## Step 3: Build the Docker Image 43 | 44 | There are two Dockerfiles available: 45 | 1. **Alpine-based image** 46 | **Using Docker** 47 | ```sh 48 | docker build -t pgagroal:latest -f ./contrib/docker/Dockerfile.alpine . 49 | ``` 50 | **Using Podman** 51 | ```sh 52 | podman build -t pgagroal:latest -f ./contrib/docker/Dockerfile.alpine . 53 | ``` 54 | 55 | 2. **Rocky Linux 9-based image** 56 | ```sh 57 | docker build -t pgagroal:latest -f ./contrib/docker/Dockerfile.rocky9 . 58 | ``` 59 | **Using Podman** 60 | ```sh 61 | podman build -t pgagroal:latest -f ./contrib/docker/Dockerfile.rocky9 . 62 | ``` 63 | 64 | --- 65 | 66 | ## Step 4: Run pgagroal as a Docker Container 67 | 68 | Once the image is built, run the container using: 69 | - **Using Docker** 70 | ```sh 71 | docker run -d --name pgagroal --network host pgagroal:latest 72 | ``` 73 | - **Using Podman** 74 | ```sh 75 | podman run -d --name pgagroal --network host pgagroal:latest 76 | ``` 77 | 78 | --- 79 | 80 | ## Step 5: Verify the Container 81 | 82 | Check if the container is running: 83 | 84 | - **Using Docker** 85 | ```sh 86 | docker ps | grep pgagroal 87 | ``` 88 | - **Using Podman** 89 | ```sh 90 | podman ps | grep pgagroal 91 | ``` 92 | 93 | Check logs for any errors: 94 | - **Using Docker** 95 | ```sh 96 | docker logs pgagroal 97 | ``` 98 | - **Using Podman** 99 | ```sh 100 | podman logs pgagroal 101 | ``` 102 | 103 | 104 | We will assume that we have a user called `test` with the password `test` in our 105 | [PostgreSQL](https://www.postgresql.org) instance. See their 106 | [documentation](https://www.postgresql.org/docs/current/index.html) on how to setup 107 | [PostgreSQL](https://www.postgresql.org), [add a user](https://www.postgresql.org/docs/current/app-createuser.html) 108 | and [add a database](https://www.postgresql.org/docs/current/app-createdb.html). 109 | 110 | We will connect to [**pgagroal**](https://github.com/agroal/pgagroal) using the [psql](https://www.postgresql.org/docs/current/app-psql.html) 111 | application. 112 | 113 | ``` 114 | psql -h localhost -p 2345 -U test test 115 | ``` 116 | -------------------------------------------------------------------------------- /doc/tutorial/09_testsuite.md: -------------------------------------------------------------------------------- 1 | # Test 2 | 3 | ## Local Environment 4 | 5 | To ensure the test suite works well, please make sure you have installed PostgreSQL 17.x version installed 6 | 7 | For RPM based distributions such as Fedora and RHEL you can add the 8 | [PostgreSQL YUM repository](https://yum.postgresql.org/) and do the install via 9 | 10 | ``` 11 | dnf -qy module disable postgresql 12 | dnf install -y postgresql17 postgresql17-server pgagroal 13 | ``` 14 | 15 | also make sure that the `initdb`, `pg_ctl`, `pgbench` and `psql` are in PATH variable. 16 | 17 | ### Add Path variable 18 | 19 | Add the `initdb`, `pg_ctl`, `pgbench` and `psql` binaries into the environment path. 20 | 21 | ``` 22 | export PATH=$PATH:$(dirname $(which initdb)) 23 | export PATH=$PATH:$(dirname $(which psql)) 24 | ``` 25 | 26 | **Note:** `initdb` and `pg_ctl` belongs to same binary directory 27 | 28 | ### Install check library 29 | 30 | Before you test, you need to install the `check` library. If there is no package for `check`, the `CMakeLists.txt` will not compile the test suite. Only after you have installed `check` will it compile the test suite. 31 | 32 | ``` sh 33 | dnf install -y check check-devel check-static 34 | ``` 35 | 36 | ### Build the project 37 | 38 | Make sure to execute the test script inside the project build. Run the following commands if project is not already built. 39 | 40 | ``` 41 | git clone https://github.com/agroal/pgagroal.git 42 | cd pgagroal 43 | mkdir build 44 | cd build 45 | cmake -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug .. 46 | make 47 | ``` 48 | 49 | ### Run test suites 50 | 51 | To run the testsuites get inside your build and just execute - 52 | 53 | ``` 54 | ./testsuite.sh 55 | ``` 56 | 57 | The script creates the PostgreSQL and pgagroal environment inside the build itself for example - 58 | - the PostgreSQL related files like the data directory and PostgreSQL configuration will be stored in `pgagroal-postgres` 59 | - the pgagroal related files like pgagroal configuration and users file will be stored in `pgagroal-testsiute` 60 | 61 | It will be the responsibility of the script to clean up the setup environment. 62 | 63 | **Note:** You can however view the PostgreSQL and pgagroal server logs in a separate `log` directory inside build. 64 | 65 | In case you see those setup directories like `pgagroal-postgres` and `pgagroal-testsiute` in build after successfully executing the script, you should probably run 66 | 67 | ``` 68 | ./testsuite.sh clean 69 | ``` 70 | 71 | before running the script again to avoid any inconsistency or errors. The clean subcommand will however clean the logs as well. 72 | 73 | ### Run tests on multiple `pgagroal` configuration 74 | 75 | #### Setup 76 | 77 | The testsuite enables us to run all the bunch of testcases on multiple `pgagroal` configurations, to support this, the `test` directory has a subdirectory `conf`. Now to add a new set of configurations, just create a new directory under `conf/` and add two files naming `pgagroal.conf` and `pg_hba.conf` inside that new diretory (populate both the files as per requirement). Remember the file name should be as specified and both the files must be present for it to be considered in the testsuite. 78 | 79 | **Note:** Some samples configuration has been provided and it is recommended to follow the numeric progression directory convention. 80 | 81 | #### Execution 82 | 83 | To execute the command simply `cd` to the build directory and run 84 | 85 | ``` 86 | ./testsuite.sh run-configs 87 | ``` 88 | 89 | ### Add testcases 90 | 91 | To add an additional testcase go to [testcases](https://github.com/agroal/pgagroal/tree/main/test/testcases) directory inside the `pgagroal` project. 92 | 93 | Create a `.c` file that contains the test suite and its corresponding `.h` file (see [pgagroal_test_1.c](https://github.com/agroal/pgagroal/tree/main/test/testcases/pgagroal_test_1.c) or [pgagroal_test_2.c](https://github.com/agroal/pgagroal/tree/main/test/testcases/pgagroal_test_2.c) for reference). Add the above created suite to the test runner in [runner.c](https://github.com/agroal/pgagroal/tree/main/test/testcases/runner.c) 94 | 95 | Also remember to link the new test suite in [CMakeLists](https://github.com/agroal/pgagroal/blob/main/test/CMakeLists.txt) file inside test directory 96 | 97 | ``` 98 | 30: set(SOURCES 99 | 31: testcases/common.c 100 | 32: testcases/pgagroal_test_1.c 101 | 33: testcases/pgagroal_test_2.c 102 | 34: testcases/runner.c 103 | 35: ) 104 | ``` -------------------------------------------------------------------------------- /src/include/aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_AES_H 30 | #define PGAGROAL_AES_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | /** 42 | * Encrypt a string 43 | * @param plaintext The string 44 | * @param password The master password 45 | * @param ciphertext The ciphertext output 46 | * @param ciphertext_length The length of the ciphertext 47 | * @return 0 upon success, otherwise 1 48 | */ 49 | int 50 | pgagroal_encrypt(char* plaintext, char* password, char** ciphertext, int* ciphertext_length, int mode); 51 | 52 | /** 53 | * Decrypt a string 54 | * @param ciphertext The string 55 | * @param ciphertext_length The length of the ciphertext 56 | * @param password The master password 57 | * @param plaintext The plaintext output 58 | * @return 0 upon success, otherwise 1 59 | */ 60 | int 61 | pgagroal_decrypt(char* ciphertext, int ciphertext_length, char* password, char** plaintext, int mode); 62 | 63 | /** 64 | * 65 | * Encrypt a buffer 66 | * @param origin_buffer The original buffer 67 | * @param origin_size The size of the buffer 68 | * @param enc_buffer The result buffer 69 | * @param enc_size The result buffer size 70 | * @param mode The aes mode 71 | * @return 0 upon success, otherwise 1 72 | */ 73 | int 74 | pgagroal_encrypt_buffer(unsigned char* origin_buffer, size_t origin_size, unsigned char** enc_buffer, size_t* enc_size, int mode); 75 | 76 | /** 77 | * 78 | * Decrypt a buffer 79 | * @param origin_buffer The original buffer 80 | * @param origin_size The size of the buffer 81 | * @param dec_buffer The result buffer 82 | * @param dec_size The result buffer size 83 | * @param mode The aes mode 84 | * @return 0 upon success, otherwise 1 85 | */ 86 | int 87 | pgagroal_decrypt_buffer(unsigned char* origin_buffer, size_t origin_size, unsigned char** dec_buffer, size_t* dec_size, int mode); 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/include/bzip2_compression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_BZIP_H 30 | #define PGAGROAL_BZIP_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | /** 39 | * BZip compress a string 40 | * @param s The original string 41 | * @param buffer The point to the compressed data buffer 42 | * @param buffer_size The size of the compressed buffer will be stored. 43 | * @return 0 upon success, otherwise 1 44 | */ 45 | int 46 | pgagroal_bzip2_string(char* s, unsigned char** buffer, size_t* buffer_size); 47 | 48 | /** 49 | * BUNZip decompress a buffer to string 50 | * @param compressed_buffer The buffer containing the GZIP compressed data 51 | * @param compressed_size The size of the compressed buffer 52 | * @param output_string The pointer to a string where the decompressed data will be stored 53 | * @return 0 upon success, otherwise 1 54 | */ 55 | int 56 | pgagroal_bunzip2_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/include/gzip_compression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_GZIP_H 30 | #define PGAGROAL_GZIP_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | /** 39 | * GZip a string 40 | * @param s The original string 41 | * @param buffer The point to the compressed data buffer 42 | * @param buffer_size The size of the compressed buffer will be stored. 43 | * @return 0 upon success, otherwise 1 44 | */ 45 | int 46 | pgagroal_gzip_string(char* s, unsigned char** buffer, size_t* buffer_size); 47 | 48 | /** 49 | * GUNZip a buffer to string 50 | * @param compressed_buffer The buffer containing the GZIP compressed data 51 | * @param compressed_size The size of the compressed buffer 52 | * @param output_string The pointer to a string where the decompressed data will be stored 53 | * @return 0 upon success, otherwise 1 54 | */ 55 | int 56 | pgagroal_gunzip_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/include/lz4_compression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_LZ4_H 30 | #define PGAGROAL_LZ4_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | #define BLOCK_BYTES 1024 * 4 39 | 40 | /** 41 | * LZ4 compress a string 42 | * @param s The original string 43 | * @param buffer The point to the compressed data buffer 44 | * @param buffer_size The size of the compressed buffer will be stored. 45 | * @return 0 upon success, otherwise 1 46 | */ 47 | int 48 | pgagroal_lz4c_string(char* s, unsigned char** buffer, size_t* buffer_size); 49 | 50 | /** 51 | * LZ4 decompress a buffer to string 52 | * @param compressed_buffer The buffer containing the GZIP compressed data 53 | * @param compressed_size The size of the compressed buffer 54 | * @param output_string The pointer to a string where the decompressed data will be stored 55 | * @return 0 upon success, otherwise 1 56 | */ 57 | int 58 | pgagroal_lz4d_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string); 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/include/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_MEMORY_H 30 | #define PGAGROAL_MEMORY_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | /** 42 | * Initialize a memory segment for the process local message structure 43 | */ 44 | void 45 | pgagroal_memory_init(void); 46 | 47 | /** 48 | * Get the message structure 49 | * @return The structure 50 | */ 51 | struct message* 52 | pgagroal_memory_message(void); 53 | 54 | /** 55 | * Free the memory segment 56 | */ 57 | void 58 | pgagroal_memory_free(void); 59 | 60 | /** 61 | * Destroy the memory segment 62 | */ 63 | void 64 | pgagroal_memory_destroy(void); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/include/pipeline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_PIPELINE_H 30 | #define PGAGROAL_PIPELINE_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #define PIPELINE_AUTO -1 42 | #define PIPELINE_PERFORMANCE 0 43 | #define PIPELINE_SESSION 1 44 | #define PIPELINE_TRANSACTION 2 45 | 46 | typedef int (* initialize)(void*, void**, size_t*); 47 | typedef void (* start)(struct event_loop*, struct worker_io*); 48 | typedef void (* callback)(struct io_watcher*); 49 | typedef void (* stop)(struct event_loop*, struct worker_io*); 50 | typedef void (* destroy)(void*, size_t); 51 | typedef void (* periodic)(void); 52 | 53 | /** @struct pipeline 54 | * Define the structure for a pipeline 55 | */ 56 | struct pipeline 57 | { 58 | initialize initialize; /**< The initialize function for the pipeline */ 59 | start start; /**< The start function */ 60 | callback client; /**< The callback for the client */ 61 | callback server; /**< The callback for the server */ 62 | stop stop; /**< The stop function */ 63 | destroy destroy; /**< The destroy function for the pipeline */ 64 | periodic periodic; /**< The periodic function for the pipeline */ 65 | }; 66 | 67 | /** 68 | * Get the performance pipeline 69 | * @return The structure 70 | */ 71 | struct pipeline performance_pipeline(void); 72 | 73 | /** 74 | * Get the session pipeline 75 | * @return The structure 76 | */ 77 | struct pipeline session_pipeline(void); 78 | 79 | /** 80 | * Get the transaction pipeline 81 | * @return The structure 82 | */ 83 | struct pipeline transaction_pipeline(void); 84 | 85 | #ifdef __cplusplus 86 | } 87 | #endif 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/include/remote.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_REMOTE_H 30 | #define PGAGROAL_REMOTE_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | #include 38 | 39 | /** 40 | * Create a remote management instance 41 | * @param fd The client descriptor 42 | * @param address The client address 43 | */ 44 | void 45 | pgagroal_remote_management(int fd, char* address); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/include/server.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_SERVER_H 30 | #define PGAGROAL_SERVER_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | #include 39 | #include 40 | 41 | /** 42 | * Get the primary server 43 | * @param server The resulting server identifier 44 | * @return 0 upon success, otherwise 1 45 | */ 46 | int 47 | pgagroal_get_primary(int* server); 48 | 49 | /** 50 | * Update the server state 51 | * @param slot The slot 52 | * @param socket The descriptor 53 | * @param ssl The SSL connection 54 | * @return 0 upon success, otherwise 1 55 | */ 56 | int 57 | pgagroal_update_server_state(int slot, int socket, SSL* ssl); 58 | 59 | /** 60 | * Print the state of the servers 61 | * @return 0 upon success, otherwise 1 62 | */ 63 | int 64 | pgagroal_server_status(void); 65 | 66 | /** 67 | * Failover 68 | * @param slot The slot 69 | * @return 0 upon success, otherwise 1 70 | */ 71 | int 72 | pgagroal_server_failover(int slot); 73 | 74 | /** 75 | * Force failover 76 | * @param server The server 77 | * @return 0 upon success, otherwise 1 78 | */ 79 | int 80 | pgagroal_server_force_failover(int server); 81 | 82 | /** 83 | * Clear server 84 | * @param server The server 85 | * @return 0 upon success, otherwise 1 86 | */ 87 | int 88 | pgagroal_server_clear(char* server); 89 | 90 | /** 91 | * Switch server 92 | * @param server The server 93 | * @return 0 upon success, otherwise 1 94 | */ 95 | int 96 | pgagroal_server_switch(char* server); 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/include/shmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_SHMEM_H 30 | #define PGAGROAL_SHMEM_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | /** 39 | * Create a shared memory segment 40 | * @param size The size of the segment 41 | * @param hp Huge page value 42 | * @parma shmem The shared memory segment 43 | * @return 0 upon success, otherwise 1 44 | */ 45 | int 46 | pgagroal_create_shared_memory(size_t size, unsigned char hp, void** shmem); 47 | 48 | /** 49 | * Resize a shared memory segment 50 | * @param size The size of the segment 51 | * @param shmem The pointer to the segment 52 | * @param new_size The size of the new segment 53 | * @param new_shmem The pointer to the new segment 54 | * @return 0 upon success, otherwise 1 55 | */ 56 | int 57 | pgagroal_resize_shared_memory(size_t size, void* shmem, size_t* new_size, void** new_shmem); 58 | 59 | /** 60 | * Destroy a shared memory segment 61 | * @param shmem The shared memory segment 62 | * @param size The size 63 | * @return 0 upon success, otherwise 1 64 | */ 65 | int 66 | pgagroal_destroy_shared_memory(void* shmem, size_t size); 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/include/status.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_STATUS_H 30 | #define PGAGROAL_STATUS_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | #include 39 | 40 | /** 41 | * Create an status 42 | * @param ssl The SSL connection 43 | * @param client_fd The client 44 | * @param compression The compress method for wire protocol 45 | * @param encryption The encrypt method for wire protocol 46 | * @param payload The payload 47 | */ 48 | void 49 | pgagroal_status(SSL* ssl, int client_fd, uint8_t compression, uint8_t encryption, struct json* payload); 50 | 51 | /** 52 | * Create an status details 53 | * @param ssl The SSL connection 54 | * @param client_fd The client 55 | * @param compression The compress method for wire protocol 56 | * @param encryption The encrypt method for wire protocol 57 | * @param payload The payload 58 | */ 59 | void 60 | pgagroal_status_details(SSL* ssl, int client_fd, uint8_t compression, uint8_t encryption, struct json* payload); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/include/tracker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_TRACKER_H 30 | #define PGAGROAL_TRACKER_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | #include 39 | 40 | #define TRACKER_CLIENT_START 0 41 | #define TRACKER_CLIENT_STOP 1 42 | 43 | #define TRACKER_GET_CONNECTION_SUCCESS 2 44 | #define TRACKER_GET_CONNECTION_TIMEOUT 3 45 | #define TRACKER_GET_CONNECTION_ERROR 4 46 | #define TRACKER_RETURN_CONNECTION_SUCCESS 5 47 | #define TRACKER_RETURN_CONNECTION_KILL 6 48 | #define TRACKER_KILL_CONNECTION 7 49 | 50 | #define TRACKER_AUTHENTICATE 8 51 | 52 | #define TRACKER_BAD_CONNECTION 9 53 | #define TRACKER_IDLE_TIMEOUT 10 54 | #define TRACKER_MAX_CONNECTION_AGE 11 55 | #define TRACKER_INVALID_CONNECTION 12 56 | #define TRACKER_FLUSH 13 57 | #define TRACKER_REMOVE_CONNECTION 14 58 | 59 | #define TRACKER_PREFILL 15 60 | #define TRACKER_PREFILL_RETURN 16 61 | #define TRACKER_PREFILL_KILL 17 62 | #define TRACKER_WORKER_RETURN1 18 63 | #define TRACKER_WORKER_RETURN2 19 64 | #define TRACKER_WORKER_KILL1 20 65 | #define TRACKER_WORKER_KILL2 21 66 | 67 | #define TRACKER_TX_RETURN_CONNECTION_START 30 68 | #define TRACKER_TX_RETURN_CONNECTION_STOP 31 69 | #define TRACKER_TX_GET_CONNECTION 32 70 | #define TRACKER_TX_RETURN_CONNECTION 33 71 | 72 | #define TRACKER_SOCKET_ASSOCIATE_CLIENT 100 73 | #define TRACKER_SOCKET_ASSOCIATE_SERVER 101 74 | #define TRACKER_SOCKET_DISASSOCIATE_CLIENT 102 75 | #define TRACKER_SOCKET_DISASSOCIATE_SERVER 103 76 | 77 | /** 78 | * Tracking event: Basic 79 | * @param id The event identifier 80 | * @param username The user name 81 | * @param database The database 82 | */ 83 | void 84 | pgagroal_tracking_event_basic(int id, char* username, char* database); 85 | 86 | /** 87 | * Tracking event: Slot 88 | * @param id The event identifier 89 | * @param slot The slot 90 | */ 91 | void 92 | pgagroal_tracking_event_slot(int id, int slot); 93 | 94 | /** 95 | * Tracking event: Socket 96 | * @param id The event identifier 97 | * @param socket The socket 98 | */ 99 | void 100 | pgagroal_tracking_event_socket(int id, int socket); 101 | 102 | #ifdef __cplusplus 103 | } 104 | #endif 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/include/worker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_WORKER_H 30 | #define PGAGROAL_WORKER_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #define WORKER_SUCCESS 0 42 | #define WORKER_FAILURE 1 43 | #define WORKER_SHUTDOWN 2 44 | #define WORKER_CLIENT_FAILURE 3 45 | #define WORKER_SERVER_FAILURE 4 46 | #define WORKER_SERVER_FATAL 5 47 | #define WORKER_FAILOVER 6 48 | 49 | /** @struct worker_io 50 | * The worker structure for each IO event 51 | */ 52 | struct worker_io 53 | { 54 | struct io_watcher io; /**< The I/O watcher */ 55 | int client_fd; /**< The client descriptor */ 56 | int server_fd; /**< The server descriptor */ 57 | int slot; /**< The slot */ 58 | SSL* client_ssl; /**< The client SSL context */ 59 | SSL* server_ssl; /**< The server SSL context */ 60 | }; 61 | 62 | extern volatile int running; 63 | extern volatile int exit_code; 64 | 65 | /** 66 | * Create a worker instance 67 | * @param fd The client descriptor 68 | * @param address The client address 69 | * @param argv The argv 70 | */ 71 | void 72 | pgagroal_worker(int fd, char* address, char** argv); 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/include/zstandard_compression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_ZSTANDARD_H 30 | #define PGAGROAL_ZSTANDARD_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | /** 39 | * ZSTD compress a string 40 | * @param s The original string 41 | * @param buffer The point to the compressed data buffer 42 | * @param buffer_size The size of the compressed buffer will be stored. 43 | * @return 0 upon success, otherwise 1 44 | */ 45 | int 46 | pgagroal_zstdc_string(char* s, unsigned char** buffer, size_t* buffer_size); 47 | 48 | /** 49 | * ZSTD decompress a buffer to string 50 | * @param compressed_buffer The buffer containing the GZIP compressed data 51 | * @param compressed_size The size of the compressed buffer 52 | * @param output_string The pointer to a string where the decompressed data will be stored 53 | * @return 0 upon success, otherwise 1 54 | */ 55 | int 56 | pgagroal_zstdd_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/libpgagroal/bzip2_compression.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* pgagroal */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /* system */ 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #define BUFFER_LENGTH 8192 47 | 48 | int 49 | pgagroal_bzip2_string(char* s, unsigned char** buffer, size_t* buffer_size) 50 | { 51 | size_t source_len; 52 | unsigned int dest_len; 53 | int bzip2_err; 54 | 55 | source_len = strlen(s); 56 | dest_len = source_len + (source_len * 0.01) + 600; 57 | 58 | *buffer = (unsigned char*)malloc(dest_len); 59 | if (!*buffer) 60 | { 61 | pgagroal_log_error("Bzip2: Allocation failed"); 62 | return 1; 63 | } 64 | 65 | bzip2_err = BZ2_bzBuffToBuffCompress((char*)(*buffer), &dest_len, s, source_len, 9, 0, 0); 66 | if (bzip2_err != BZ_OK) 67 | { 68 | pgagroal_log_error("Bzip2: Compress failed"); 69 | free(*buffer); 70 | return 1; 71 | } 72 | 73 | *buffer_size = dest_len; 74 | return 0; 75 | } 76 | 77 | int 78 | pgagroal_bunzip2_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string) 79 | { 80 | int bzip2_err; 81 | unsigned int estimated_size = compressed_size * 10; 82 | unsigned int new_size; 83 | 84 | *output_string = (char*)malloc(estimated_size); 85 | if (!*output_string) 86 | { 87 | pgagroal_log_error("Bzip2: Allocation failed"); 88 | return 1; 89 | } 90 | 91 | bzip2_err = BZ2_bzBuffToBuffDecompress(*output_string, &estimated_size, (char*)compressed_buffer, compressed_size, 0, 0); 92 | 93 | if (bzip2_err == BZ_OUTBUFF_FULL) 94 | { 95 | new_size = estimated_size * 2; 96 | char* temp = realloc(*output_string, new_size); 97 | 98 | if (!temp) 99 | { 100 | pgagroal_log_error("Bzip2: Reallocation failed"); 101 | free(*output_string); 102 | return 1; 103 | } 104 | 105 | *output_string = temp; 106 | 107 | bzip2_err = BZ2_bzBuffToBuffDecompress(*output_string, &new_size, (char*)compressed_buffer, compressed_size, 0, 0); 108 | if (bzip2_err != BZ_OK) 109 | { 110 | pgagroal_log_error("Bzip2: Decompress failed"); 111 | free(*output_string); 112 | return 1; 113 | } 114 | estimated_size = new_size; 115 | } 116 | else if (bzip2_err != BZ_OK) 117 | { 118 | pgagroal_log_error("Bzip2: Decompress failed"); 119 | free(*output_string); 120 | return 1; 121 | } 122 | 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /src/libpgagroal/lz4_compression.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Red Hat 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* pgagroal */ 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /* system */ 38 | #include 39 | #include "lz4.h" 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | int 48 | pgagroal_lz4c_string(char* s, unsigned char** buffer, size_t* buffer_size) 49 | { 50 | size_t input_size; 51 | size_t max_compressed_size; 52 | int compressed_size; 53 | 54 | input_size = strlen(s); 55 | max_compressed_size = LZ4_compressBound(input_size); 56 | 57 | *buffer = (unsigned char*)malloc(max_compressed_size); 58 | if (*buffer == NULL) 59 | { 60 | pgagroal_log_error("LZ4: Allocation failed"); 61 | return 1; 62 | } 63 | 64 | compressed_size = LZ4_compress_default(s, (char*)*buffer, input_size, max_compressed_size); 65 | if (compressed_size <= 0) 66 | { 67 | pgagroal_log_error("LZ4: Compress failed"); 68 | free(*buffer); 69 | return 1; 70 | } 71 | 72 | *buffer_size = (size_t)compressed_size; 73 | 74 | return 0; 75 | } 76 | 77 | int 78 | pgagroal_lz4d_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string) 79 | { 80 | size_t max_decompressed_size; 81 | int decompressed_size; 82 | 83 | max_decompressed_size = compressed_size * 4; 84 | 85 | *output_string = (char*)malloc(max_decompressed_size); 86 | if (*output_string == NULL) 87 | { 88 | pgagroal_log_error("LZ4: Allocation failed"); 89 | return 1; 90 | } 91 | 92 | decompressed_size = LZ4_decompress_safe((const char*)compressed_buffer, *output_string, compressed_size, max_decompressed_size); 93 | if (decompressed_size < 0) 94 | { 95 | pgagroal_log_error("LZ4: Decompress failed"); 96 | free(*output_string); 97 | return 1; 98 | } 99 | 100 | (*output_string)[decompressed_size] = '\0'; 101 | 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /src/libpgagroal/memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* pgagroal */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifdef DEBUG 35 | #include 36 | #endif 37 | 38 | /* system */ 39 | #ifdef DEBUG 40 | #include 41 | #endif 42 | #include 43 | #include 44 | #include 45 | 46 | static struct message* message = NULL; 47 | static void* data = NULL; 48 | 49 | /** 50 | * 51 | */ 52 | void 53 | pgagroal_memory_init(void) 54 | { 55 | #ifdef DEBUG 56 | assert(shmem != NULL); 57 | #endif 58 | 59 | if (message == NULL) 60 | { 61 | message = (struct message*)calloc(1, sizeof(struct message)); 62 | if (message == NULL) 63 | { 64 | goto error; 65 | } 66 | } 67 | 68 | if (data == NULL) 69 | { 70 | data = calloc(1, DEFAULT_BUFFER_SIZE); 71 | if (data == NULL) 72 | { 73 | goto error; 74 | } 75 | } 76 | 77 | message->kind = 0; 78 | message->length = 0; 79 | message->data = data; 80 | 81 | return; 82 | 83 | error: 84 | 85 | pgagroal_log_fatal("Unable to allocate memory"); 86 | 87 | #ifdef DEBUG 88 | pgagroal_backtrace(); 89 | #endif 90 | 91 | errno = 0; 92 | } 93 | 94 | /** 95 | * 96 | */ 97 | struct message* 98 | pgagroal_memory_message(void) 99 | { 100 | #ifdef DEBUG 101 | assert(message != NULL); 102 | assert(data != NULL); 103 | #endif 104 | 105 | return message; 106 | } 107 | 108 | /** 109 | * 110 | */ 111 | void 112 | pgagroal_memory_free(void) 113 | { 114 | #ifdef DEBUG 115 | assert(message != NULL); 116 | assert(data != NULL); 117 | #endif 118 | 119 | memset(message, 0, sizeof(struct message)); 120 | memset(data, 0, DEFAULT_BUFFER_SIZE); 121 | 122 | message->kind = 0; 123 | message->length = 0; 124 | message->data = data; 125 | } 126 | 127 | /** 128 | * 129 | */ 130 | void 131 | pgagroal_memory_destroy(void) 132 | { 133 | free(data); 134 | free(message); 135 | 136 | data = NULL; 137 | message = NULL; 138 | } 139 | -------------------------------------------------------------------------------- /src/libpgagroal/remote.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* pgagroal */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | /* system */ 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | void 48 | pgagroal_remote_management(int client_fd, char* address) 49 | { 50 | int server_fd = -1; 51 | int exit_code; 52 | int auth_status; 53 | uint8_t compression; 54 | uint8_t encryption; 55 | SSL* client_ssl = NULL; 56 | struct json* payload = NULL; 57 | struct main_configuration* config; 58 | 59 | pgagroal_start_logging(); 60 | pgagroal_memory_init(); 61 | 62 | exit_code = 0; 63 | 64 | config = (struct main_configuration*)shmem; 65 | 66 | pgagroal_log_debug("pgagroal_remote_management: connect %d", client_fd); 67 | 68 | auth_status = pgagroal_remote_management_auth(client_fd, address, &client_ssl); 69 | if (auth_status == AUTH_SUCCESS) 70 | { 71 | if (pgagroal_connect_unix_socket(config->unix_socket_dir, MAIN_UDS, &server_fd)) 72 | { 73 | goto done; 74 | } 75 | 76 | if (pgagroal_management_read_json(client_ssl, client_fd, &compression, &encryption, &payload)) 77 | { 78 | goto done; 79 | } 80 | 81 | if (pgagroal_management_write_json(NULL, server_fd, compression, encryption, payload)) 82 | { 83 | goto done; 84 | } 85 | 86 | pgagroal_json_destroy(payload); 87 | payload = NULL; 88 | 89 | if (pgagroal_management_read_json(NULL, server_fd, &compression, &encryption, &payload)) 90 | { 91 | goto done; 92 | } 93 | 94 | if (pgagroal_management_write_json(client_ssl, client_fd, compression, encryption, payload)) 95 | { 96 | goto done; 97 | } 98 | } 99 | else 100 | { 101 | exit_code = 1; 102 | } 103 | 104 | done: 105 | 106 | pgagroal_json_destroy(payload); 107 | payload = NULL; 108 | 109 | if (client_ssl != NULL) 110 | { 111 | int res; 112 | SSL_CTX* ctx = SSL_get_SSL_CTX(client_ssl); 113 | res = SSL_shutdown(client_ssl); 114 | if (res == 0) 115 | { 116 | SSL_shutdown(client_ssl); 117 | } 118 | SSL_free(client_ssl); 119 | SSL_CTX_free(ctx); 120 | } 121 | 122 | pgagroal_log_debug("pgagroal_remote_management: disconnect %d", client_fd); 123 | pgagroal_disconnect(client_fd); 124 | pgagroal_disconnect(server_fd); 125 | 126 | free(address); 127 | 128 | pgagroal_memory_destroy(); 129 | pgagroal_stop_logging(); 130 | 131 | exit(exit_code); 132 | } 133 | -------------------------------------------------------------------------------- /src/libpgagroal/shmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* pgagroal */ 30 | #include 31 | #include 32 | 33 | /* system */ 34 | #include 35 | #include 36 | #include 37 | 38 | void* shmem = NULL; 39 | void* pipeline_shmem = NULL; 40 | void* prometheus_shmem = NULL; 41 | void* prometheus_cache_shmem = NULL; 42 | 43 | int 44 | pgagroal_create_shared_memory(size_t size, unsigned char hp, void** shmem) 45 | { 46 | void* s = NULL; 47 | int protection = PROT_READ | PROT_WRITE; 48 | int visibility = MAP_ANONYMOUS | MAP_SHARED; 49 | 50 | *shmem = NULL; 51 | 52 | #ifdef HAVE_LINUX 53 | if (hp == HUGEPAGE_TRY || hp == HUGEPAGE_ON) 54 | { 55 | visibility = visibility | MAP_HUGETLB; 56 | } 57 | 58 | #endif 59 | 60 | s = mmap(NULL, size, protection, visibility, -1, 0); 61 | if (s == (void*)-1) 62 | { 63 | errno = 0; 64 | s = NULL; 65 | 66 | if (hp == HUGEPAGE_OFF || hp == HUGEPAGE_ON) 67 | { 68 | return 1; 69 | } 70 | } 71 | 72 | if (s == NULL) 73 | { 74 | visibility = MAP_ANONYMOUS | MAP_SHARED; 75 | s = mmap(NULL, size, protection, visibility, 0, 0); 76 | 77 | if (s == (void*)-1) 78 | { 79 | errno = 0; 80 | return 1; 81 | } 82 | } 83 | 84 | memset(s, 0, size); 85 | 86 | *shmem = s; 87 | 88 | return 0; 89 | } 90 | 91 | int 92 | pgagroal_resize_shared_memory(size_t size, void* shmem, size_t* new_size, void** new_shmem) 93 | { 94 | struct main_configuration* config; 95 | 96 | config = (struct main_configuration*)shmem; 97 | 98 | *new_size = size + (config->max_connections * sizeof(struct connection)); 99 | if (pgagroal_create_shared_memory(*new_size, config->common.hugepage, new_shmem)) 100 | { 101 | return 1; 102 | } 103 | 104 | memset(*new_shmem, 0, *new_size); 105 | memcpy(*new_shmem, shmem, size); 106 | 107 | return 0; 108 | } 109 | 110 | int 111 | pgagroal_destroy_shared_memory(void* shmem, size_t size) 112 | { 113 | return munmap(shmem, size); 114 | } 115 | -------------------------------------------------------------------------------- /src/libpgagroal/zstandard_compression.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /* pgagroal */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | /* system */ 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #define ZSTD_DEFAULT_NUMBER_OF_WORKERS 4 46 | 47 | int 48 | pgagroal_zstdc_string(char* s, unsigned char** buffer, size_t* buffer_size) 49 | { 50 | size_t input_size; 51 | size_t max_compressed_size; 52 | size_t compressed_size; 53 | 54 | input_size = strlen(s); 55 | max_compressed_size = ZSTD_compressBound(input_size); 56 | 57 | *buffer = (unsigned char*)malloc(max_compressed_size); 58 | if (*buffer == NULL) 59 | { 60 | pgagroal_log_error("ZSTD: Allocation failed"); 61 | return 1; 62 | } 63 | 64 | compressed_size = ZSTD_compress(*buffer, max_compressed_size, s, input_size, 1); 65 | if (ZSTD_isError(compressed_size)) 66 | { 67 | pgagroal_log_error("ZSTD: Compression error: %s", ZSTD_getErrorName(compressed_size)); 68 | free(*buffer); 69 | return 1; 70 | } 71 | 72 | *buffer_size = compressed_size; 73 | 74 | return 0; 75 | } 76 | 77 | int 78 | pgagroal_zstdd_string(unsigned char* compressed_buffer, size_t compressed_size, char** output_string) 79 | { 80 | size_t decompressed_size; 81 | size_t result; 82 | 83 | decompressed_size = ZSTD_getFrameContentSize(compressed_buffer, compressed_size); 84 | 85 | if (decompressed_size == ZSTD_CONTENTSIZE_ERROR) 86 | { 87 | pgagroal_log_error("ZSTD: Not a valid compressed buffer"); 88 | return 1; 89 | } 90 | if (decompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) 91 | { 92 | pgagroal_log_error("ZSTD: Unknown decompressed size"); 93 | return 1; 94 | } 95 | 96 | *output_string = (char*)malloc(decompressed_size + 1); 97 | if (*output_string == NULL) 98 | { 99 | pgagroal_log_error("ZSTD: Allocation failed"); 100 | return 1; 101 | } 102 | 103 | result = ZSTD_decompress(*output_string, decompressed_size, compressed_buffer, compressed_size); 104 | if (ZSTD_isError(result)) 105 | { 106 | pgagroal_log_error("ZSTD: Compression error: %s", ZSTD_getErrorName(result)); 107 | free(*output_string); 108 | return 1; 109 | } 110 | 111 | (*output_string)[decompressed_size] = '\0'; 112 | 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /test/Dockerfile.testsuite: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2025 The pgagroal community 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this list 8 | # of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | # list of conditions and the following disclaimer in the documentation and/or other 12 | # materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its contributors may 15 | # be used to endorse or promote products derived from this software without specific 16 | # prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | # THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | FROM rockylinux:9 29 | 30 | ENV TERM=xterm 31 | ENV PGVERSION=17 32 | ENV PATH="/usr/pgsql-${PGVERSION}/bin:${PATH}" 33 | 34 | # Enable EPEL & CRB repositories 35 | RUN dnf -y update && \ 36 | dnf -y install --allowerasing epel-release dnf-plugins-core && \ 37 | dnf config-manager --set-enabled epel crb && \ 38 | dnf clean all 39 | 40 | RUN dnf -y update && \ 41 | dnf -y install --allowerasing \ 42 | git gcc clang cmake make \ 43 | libev libev-devel openssl-devel systemd-devel \ 44 | zlib zlib-devel libzstd-devel lz4-devel \ 45 | libssh-devel libcurl-devel libatomic \ 46 | python3-docutils bzip2-devel libarchive-devel \ 47 | net-tools check check-devel graphviz \ 48 | doxygen pandoc texlive texlive-latex \ 49 | python3-pip curl ca-certificates wget \ 50 | libasan libubsan libstdc++-devel libgcc glibc-devel \ 51 | gawk coreutils findutils iproute && \ 52 | dnf clean all 53 | 54 | RUN pip3 install --no-cache-dir gcovr 55 | 56 | RUN dnf -y install --allowerasing \ 57 | https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm && \ 58 | dnf -qy module disable postgresql && \ 59 | dnf -y install --allowerasing \ 60 | postgresql${PGVERSION} \ 61 | postgresql${PGVERSION}-server \ 62 | postgresql${PGVERSION}-contrib && \ 63 | dnf clean all 64 | 65 | # Prepare PGDATA 66 | RUN mkdir -p /var/lib/pgsql/data && \ 67 | chown -R postgres:postgres /var/lib/pgsql/data 68 | 69 | # Copy source and fix permissions 70 | COPY --chown=postgres:postgres . /pgagroal 71 | USER postgres 72 | 73 | # Build directory 74 | RUN rm -rf /pgagroal/build && \ 75 | mkdir -p /pgagroal/build /pgagroal/build/log 76 | WORKDIR /pgagroal/build 77 | 78 | 79 | RUN cmake \ 80 | -DCMAKE_C_COMPILER=gcc \ 81 | -DCMAKE_BUILD_TYPE=Debug \ 82 | -DCMAKE_C_FLAGS="-fsanitize=address -fsanitize=undefined -ftls-model=initial-exec" \ 83 | -DCMAKE_EXE_LINKER_FLAGS="-lasan -lubsan" \ 84 | .. && \ 85 | make -j$(nproc) 86 | 87 | 88 | CMD ["/bin/bash"] 89 | -------------------------------------------------------------------------------- /test/conf/01/pgagroal.conf: -------------------------------------------------------------------------------- 1 | [pgagroal] 2 | host = localhost 3 | port = 2345 4 | 5 | log_type = file 6 | log_level = debug5 7 | log_path = test.log 8 | 9 | max_connections = 100 10 | idle_timeout = 600 11 | validation = off 12 | unix_socket_dir = /tmp/ 13 | pipeline = 'pipeline' 14 | 15 | [primary] 16 | host = localhost 17 | port = 5432 -------------------------------------------------------------------------------- /test/conf/01/pgagroal_hba.conf: -------------------------------------------------------------------------------- 1 | # 2 | # TYPE DATABASE USER ADDRESS METHOD 3 | # 4 | host all all all all -------------------------------------------------------------------------------- /test/conf/02/pgagroal.conf: -------------------------------------------------------------------------------- 1 | [pgagroal] 2 | host = localhost 3 | port = 2345 4 | 5 | log_type = file 6 | log_level = debug5 7 | log_path = test.log 8 | 9 | max_connections = 200 10 | idle_timeout = 600 11 | validation = off 12 | unix_socket_dir = /tmp/ 13 | pipeline = 'performance' 14 | 15 | [primary] 16 | host = localhost 17 | port = 5432 -------------------------------------------------------------------------------- /test/conf/02/pgagroal_hba.conf: -------------------------------------------------------------------------------- 1 | # 2 | # TYPE DATABASE USER ADDRESS METHOD 3 | # 4 | host all all all all -------------------------------------------------------------------------------- /test/conf/03/pgagroal.conf: -------------------------------------------------------------------------------- 1 | [pgagroal] 2 | host = localhost 3 | port = 2345 4 | 5 | log_type = file 6 | log_level = debug5 7 | log_path = test.log 8 | 9 | max_connections = 200 10 | idle_timeout = 600 11 | validation = off 12 | unix_socket_dir = /tmp/ 13 | pipeline = 'session' 14 | 15 | [primary] 16 | host = localhost 17 | port = 5432 -------------------------------------------------------------------------------- /test/conf/03/pgagroal_hba.conf: -------------------------------------------------------------------------------- 1 | # 2 | # TYPE DATABASE USER ADDRESS METHOD 3 | # 4 | host all all all all -------------------------------------------------------------------------------- /test/conf/04/pgagroal.conf: -------------------------------------------------------------------------------- 1 | [pgagroal] 2 | host = localhost 3 | port = 2345 4 | 5 | log_type = file 6 | log_level = debug5 7 | log_path = test.log 8 | 9 | max_connections = 200 10 | idle_timeout = 600 11 | validation = off 12 | unix_socket_dir = /tmp/ 13 | pipeline = 'session' 14 | 15 | [primary] 16 | host = localhost 17 | port = 5432 -------------------------------------------------------------------------------- /test/conf/04/pgagroal_hba.conf: -------------------------------------------------------------------------------- 1 | # 2 | # TYPE DATABASE USER ADDRESS METHOD 3 | # 4 | host all all all all -------------------------------------------------------------------------------- /test/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2025 The pgagroal community 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, 6 | # are permitted provided that the following conditions are met: 7 | # 8 | # 1. Redistributions of source code must retain the above copyright notice, this list 9 | # of conditions and the following disclaimer. 10 | # 11 | # 2. Redistributions in binary form must reproduce the above copyright notice, this 12 | # list of conditions and the following disclaimer in the documentation and/or other 13 | # materials provided with the distribution. 14 | # 15 | # 3. Neither the name of the copyright holder nor the names of its contributors may 16 | # be used to endorse or promote products derived from this software without specific 17 | # prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | # THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 24 | # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 | # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euo pipefail 31 | 32 | # Go to the root of the project (script is in test/, go one level up) 33 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 34 | cd "$SCRIPT_DIR/.." 35 | 36 | # Detect container engine: Docker or Podman 37 | if command -v docker &> /dev/null; then 38 | CONTAINER_ENGINE="docker" 39 | elif command -v podman &> /dev/null; then 40 | CONTAINER_ENGINE="podman" 41 | else 42 | echo "Neither Docker nor Podman is installed. Please install one to proceed." 43 | exit 1 44 | fi 45 | 46 | # Variables 47 | IMAGE_NAME="pgagroal-test" 48 | CONTAINER_NAME="pgagroal_test_container" 49 | DOCKERFILE="./test/Dockerfile.testsuite" 50 | LOG_DIR="./build/log" 51 | COVERAGE_DIR="./build/coverage" 52 | 53 | # Clean up any old container 54 | $CONTAINER_ENGINE rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true 55 | 56 | # Build the image 57 | $CONTAINER_ENGINE build -f "$DOCKERFILE" -t "$IMAGE_NAME" . 58 | 59 | # Run it, generate & invoke the in-container script 60 | $CONTAINER_ENGINE run --name "$CONTAINER_NAME" "$IMAGE_NAME" bash -c ' 61 | set -e 62 | cd /pgagroal/build/ 63 | ./testsuite.sh 64 | ./testsuite.sh run-configs 65 | echo "Generating coverage reports…" 66 | mkdir -p coverage 67 | find . -name "*.gcda" -o -name "*.gcno" 68 | gcovr -r /pgagroal/src --object-directory . --html --html-details -o coverage/index.html 69 | gcovr -r /pgagroal/src --object-directory . > coverage/summary.txt 70 | gcovr -r /pgagroal/src --object-directory . --xml -o coverage/coverage.xml 71 | echo "Coverage in /pgagroal/build/coverage" 72 | ' 73 | 74 | # Copy back logs and coverage 75 | mkdir -p "$LOG_DIR" "$COVERAGE_DIR" 76 | $CONTAINER_ENGINE cp "$CONTAINER_NAME:/pgagroal/build/log/." "$LOG_DIR" 77 | $CONTAINER_ENGINE cp "$CONTAINER_NAME:/pgagroal/build/coverage/." "$COVERAGE_DIR" 78 | 79 | echo " Fixing file ownership for host user" 80 | if ! sudo chown -R "$(id -u):$(id -g)" "$LOG_DIR" "$COVERAGE_DIR"; then 81 | echo " Could not change ownership. You might need to clean manually." 82 | fi 83 | 84 | echo "Logs --> $LOG_DIR" 85 | echo "Coverage --> $COVERAGE_DIR" 86 | -------------------------------------------------------------------------------- /test/include/tsclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_TSCLIENT_H 30 | #define PGAGROAL_TSCLIENT_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | #define BUFFER_SIZE 8192 43 | 44 | #define PGBENCH_LOG_FILE_TRAIL "/log/pgbench.log" 45 | #define PGAGROAL_CONFIGURATION_TRAIL "/pgagroal-testsuite/conf/pgagroal.conf" 46 | 47 | extern char project_directory[BUFFER_SIZE]; 48 | 49 | /** 50 | * Initialize the tsclient API 51 | * @param base_dir path to base 52 | * @return 0 upon success, otherwise 1 53 | */ 54 | int 55 | pgagroal_tsclient_init(char* base_dir); 56 | 57 | /** 58 | * Destroy the tsclient (must be used after pgagroal_tsclient_init) 59 | * @return 0 upon success, otherwise 1 60 | */ 61 | int 62 | pgagroal_tsclient_destroy(); 63 | 64 | /** 65 | * A wrapper around pgbench specific to our usecase [benchmark options supported: '-c', '-j', '-t'] 66 | * Execute a pgbench command for a set of instructions, assuming we are connecting to the 1st server 67 | * @param database name of the database 68 | * @param select_only true if we are only doing selects 69 | * @param client_count number of clients 70 | * @param thread_count number of threads 71 | * @param transaction_count number of transactions 72 | * @return 0 upon success, otherwise 1 73 | */ 74 | int 75 | pgagroal_tsclient_execute_pgbench(char* database, bool select_only, int client_count, int thread_count, int transaction_count); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif -------------------------------------------------------------------------------- /test/runner.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | 31 | #include "testcases/pgagroal_test_1.h" 32 | #include "testcases/pgagroal_test_2.h" 33 | 34 | int 35 | main(int argc, char* argv[]) 36 | { 37 | 38 | if (argc != 2) 39 | { 40 | printf("Usage: %s \n", argv[0]); 41 | return 1; 42 | } 43 | 44 | int number_failed; 45 | Suite* s1; 46 | Suite* s2; 47 | SRunner* sr; 48 | 49 | if (pgagroal_tsclient_init(argv[1])) 50 | { 51 | goto error; 52 | } 53 | 54 | s1 = pgagroal_test1_suite(); 55 | s2 = pgagroal_test2_suite(); 56 | 57 | sr = srunner_create(s1); 58 | srunner_add_suite(sr, s2); 59 | 60 | // Run the tests in verbose mode 61 | srunner_run_all(sr, CK_VERBOSE); 62 | number_failed = srunner_ntests_failed(sr); 63 | srunner_free(sr); 64 | 65 | pgagroal_tsclient_destroy(); 66 | return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 67 | 68 | error: 69 | pgagroal_tsclient_destroy(); 70 | return EXIT_FAILURE; 71 | } -------------------------------------------------------------------------------- /test/testcases/pgagroal_test_1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | 31 | #include "pgagroal_test_1.h" 32 | 33 | // simple 34 | START_TEST(test_pgagroal_simple) 35 | { 36 | int found = 0; 37 | found = !pgagroal_tsclient_execute_pgbench("postgres", true, 0, 0, 0); 38 | ck_assert_msg(found, "success status not found"); 39 | } 40 | 41 | Suite* 42 | pgagroal_test1_suite() 43 | { 44 | Suite* s; 45 | TCase* tc_core; 46 | 47 | s = suite_create("pgagroal_test1"); 48 | 49 | tc_core = tcase_create("Core"); 50 | 51 | tcase_set_timeout(tc_core, 60); 52 | tcase_add_test(tc_core, test_pgagroal_simple); 53 | suite_add_tcase(s, tc_core); 54 | 55 | return s; 56 | } -------------------------------------------------------------------------------- /test/testcases/pgagroal_test_1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_TEST1_H 30 | #define PGAGROAL_TEST1_H 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /** 38 | * Set up a suite of test cases for pgagroal 39 | * @return The result 40 | */ 41 | Suite* 42 | pgagroal_test1_suite(); 43 | 44 | #endif // PGAGROAL_TEST1_H 45 | -------------------------------------------------------------------------------- /test/testcases/pgagroal_test_2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | 31 | #include "pgagroal_test_2.h" 32 | 33 | // baseline 34 | START_TEST(test_pgagroal_baseline) 35 | { 36 | int found = 0; 37 | found = !pgagroal_tsclient_execute_pgbench("postgres", true, 8, 0, 1000); 38 | ck_assert_msg(found, "success status not found"); 39 | } 40 | 41 | // high_clients template 42 | // START_TEST(test_pgagroal_high_clients) 43 | // { 44 | // int found = 0; 45 | // found = !pgagroal_tsclient_execute_pgbench("postgres", true, 50, 0, 1000); 46 | // ck_assert_msg(found, "success status not found"); 47 | // } 48 | 49 | // high_transactions template 50 | // START_TEST(test_pgagroal_high_transactions) 51 | // { 52 | // int found = 0; 53 | // found = !pgagroal_tsclient_execute_pgbench("postgres", true, 10, 0, 5000); 54 | // ck_assert_msg(found, "success status not found"); 55 | // } 56 | 57 | // combined template 58 | // START_TEST(test_pgagroal_combined) 59 | // { 60 | // int found = 0; 61 | // found = !pgagroal_tsclient_execute_pgbench("postgres", true, 50, 0, 5000); 62 | // ck_assert_msg(found, "success status not found"); 63 | // } 64 | 65 | Suite* 66 | pgagroal_test2_suite() 67 | { 68 | Suite* s; 69 | TCase* tc_core; 70 | 71 | s = suite_create("pgagroal_test2"); 72 | 73 | tc_core = tcase_create("Core"); 74 | 75 | tcase_set_timeout(tc_core, 60); 76 | tcase_add_test(tc_core, test_pgagroal_baseline); 77 | suite_add_tcase(s, tc_core); 78 | 79 | return s; 80 | } -------------------------------------------------------------------------------- /test/testcases/pgagroal_test_2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 The pgagroal community 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, 5 | * are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list 8 | * of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | * list of conditions and the following disclaimer in the documentation and/or other 12 | * materials provided with the distribution. 13 | * 14 | * 3. Neither the name of the copyright holder nor the names of its contributors may 15 | * be used to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef PGAGROAL_TEST2_H 30 | #define PGAGROAL_TEST2_H 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | /** 38 | * Set up a suite of test cases for pgagroal 39 | * @return The result 40 | */ 41 | Suite* 42 | pgagroal_test2_suite(); 43 | 44 | #endif // PGAGROAL_TEST2_H 45 | -------------------------------------------------------------------------------- /uncrustify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function indent() 4 | { 5 | for f in $1 6 | do 7 | uncrustify -c uncrustify.cfg -q --replace --no-backup $f 8 | rm -f $f.uncrustify 9 | done 10 | } 11 | 12 | indent "src/*.c" 13 | indent "src/include/*.h" 14 | indent "src/libpgagroal/*.c" 15 | --------------------------------------------------------------------------------