├── .clang-format ├── .gitignore ├── LICENSE.md ├── Makefile ├── README.md ├── THIRD-PARTY ├── nextgres_idcp.conf ├── nextgres_idcp.control ├── sql └── nextgres_idcp--0.1.0.sql └── src ├── backend ├── libpq │ └── pqcomm.c ├── port │ └── socket.c ├── postmaster │ ├── controller.c │ ├── postmaster.c │ └── proxy.c └── utils │ ├── init │ └── globals.c │ └── misc │ └── guc.c ├── extension └── entrypoint.c └── include └── nextgres ├── idcp.h └── idcp ├── libpq └── libpq.h ├── postmaster ├── postmaster.h └── proxy.h └── util └── guc.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignArrayOfStructures: None 7 | AlignConsecutiveMacros: None 8 | AlignConsecutiveAssignments: None 9 | AlignConsecutiveBitFields: None 10 | AlignConsecutiveDeclarations: None 11 | AlignEscapedNewlines: Right 12 | AlignOperands: Align 13 | AlignTrailingComments: true 14 | AllowAllArgumentsOnNextLine: true 15 | AllowAllParametersOfDeclarationOnNextLine: true 16 | AllowShortEnumsOnASingleLine: true 17 | AllowShortBlocksOnASingleLine: Never 18 | AllowShortCaseLabelsOnASingleLine: false 19 | AllowShortFunctionsOnASingleLine: All 20 | AllowShortLambdasOnASingleLine: All 21 | AllowShortIfStatementsOnASingleLine: Never 22 | AllowShortLoopsOnASingleLine: false 23 | AlwaysBreakAfterDefinitionReturnType: None 24 | AlwaysBreakAfterReturnType: None 25 | AlwaysBreakBeforeMultilineStrings: false 26 | AlwaysBreakTemplateDeclarations: MultiLine 27 | AttributeMacros: 28 | - __capability 29 | BinPackArguments: true 30 | BinPackParameters: true 31 | BraceWrapping: 32 | AfterCaseLabel: false 33 | AfterClass: false 34 | AfterControlStatement: Never 35 | AfterEnum: false 36 | AfterFunction: false 37 | AfterNamespace: false 38 | AfterObjCDeclaration: false 39 | AfterStruct: false 40 | AfterUnion: false 41 | AfterExternBlock: false 42 | BeforeCatch: false 43 | BeforeElse: false 44 | BeforeLambdaBody: false 45 | BeforeWhile: false 46 | IndentBraces: false 47 | SplitEmptyFunction: true 48 | SplitEmptyRecord: true 49 | SplitEmptyNamespace: true 50 | BreakBeforeBinaryOperators: None 51 | BreakBeforeConceptDeclarations: true 52 | BreakBeforeBraces: Attach 53 | BreakBeforeInheritanceComma: false 54 | BreakInheritanceList: BeforeColon 55 | BreakBeforeTernaryOperators: true 56 | BreakConstructorInitializersBeforeComma: false 57 | BreakConstructorInitializers: BeforeColon 58 | BreakAfterJavaFieldAnnotations: false 59 | BreakStringLiterals: true 60 | ColumnLimit: 79 61 | CommentPragmas: '^ IWYU pragma:' 62 | QualifierAlignment: Leave 63 | CompactNamespaces: false 64 | ConstructorInitializerIndentWidth: 4 65 | ContinuationIndentWidth: 4 66 | Cpp11BracedListStyle: true 67 | DeriveLineEnding: true 68 | DerivePointerAlignment: false 69 | DisableFormat: false 70 | EmptyLineAfterAccessModifier: Never 71 | EmptyLineBeforeAccessModifier: LogicalBlock 72 | ExperimentalAutoDetectBinPacking: false 73 | PackConstructorInitializers: BinPack 74 | BasedOnStyle: '' 75 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 76 | AllowAllConstructorInitializersOnNextLine: true 77 | FixNamespaceComments: true 78 | ForEachMacros: 79 | - foreach 80 | - Q_FOREACH 81 | - BOOST_FOREACH 82 | IfMacros: 83 | - KJ_IF_MAYBE 84 | IncludeBlocks: Preserve 85 | IncludeCategories: 86 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 87 | Priority: 2 88 | SortPriority: 0 89 | CaseSensitive: false 90 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 91 | Priority: 3 92 | SortPriority: 0 93 | CaseSensitive: false 94 | - Regex: '.*' 95 | Priority: 1 96 | SortPriority: 0 97 | CaseSensitive: false 98 | IncludeIsMainRegex: '(Test)?$' 99 | IncludeIsMainSourceRegex: '' 100 | IndentAccessModifiers: false 101 | IndentCaseLabels: false 102 | IndentCaseBlocks: false 103 | IndentGotoLabels: true 104 | IndentPPDirectives: None 105 | IndentExternBlock: AfterExternBlock 106 | IndentRequires: false 107 | IndentWidth: 2 108 | IndentWrappedFunctionNames: false 109 | InsertTrailingCommas: None 110 | JavaScriptQuotes: Leave 111 | JavaScriptWrapImports: true 112 | KeepEmptyLinesAtTheStartOfBlocks: true 113 | LambdaBodyIndentation: Signature 114 | MacroBlockBegin: '' 115 | MacroBlockEnd: '' 116 | MaxEmptyLinesToKeep: 1 117 | NamespaceIndentation: None 118 | ObjCBinPackProtocolList: Auto 119 | ObjCBlockIndentWidth: 2 120 | ObjCBreakBeforeNestedBlockParam: true 121 | ObjCSpaceAfterProperty: false 122 | ObjCSpaceBeforeProtocolList: true 123 | PenaltyBreakAssignment: 2 124 | PenaltyBreakBeforeFirstCallParameter: 19 125 | PenaltyBreakComment: 300 126 | PenaltyBreakFirstLessLess: 120 127 | PenaltyBreakOpenParenthesis: 0 128 | PenaltyBreakString: 1000 129 | PenaltyBreakTemplateDeclaration: 10 130 | PenaltyExcessCharacter: 1000000 131 | PenaltyReturnTypeOnItsOwnLine: 60 132 | PenaltyIndentedWhitespace: 0 133 | PointerAlignment: Right 134 | PPIndentWidth: -1 135 | ReferenceAlignment: Pointer 136 | ReflowComments: true 137 | RemoveBracesLLVM: false 138 | SeparateDefinitionBlocks: Leave 139 | ShortNamespaceLines: 1 140 | SortIncludes: CaseSensitive 141 | SortJavaStaticImport: Before 142 | SortUsingDeclarations: true 143 | SpaceAfterCStyleCast: false 144 | SpaceAfterLogicalNot: false 145 | SpaceAfterTemplateKeyword: true 146 | SpaceBeforeAssignmentOperators: true 147 | SpaceBeforeCaseColon: false 148 | SpaceBeforeCpp11BracedList: false 149 | SpaceBeforeCtorInitializerColon: true 150 | SpaceBeforeInheritanceColon: true 151 | SpaceBeforeParens: ControlStatements 152 | SpaceBeforeParensOptions: 153 | AfterControlStatements: true 154 | AfterForeachMacros: true 155 | AfterFunctionDefinitionName: false 156 | AfterFunctionDeclarationName: false 157 | AfterIfMacros: true 158 | AfterOverloadedOperator: false 159 | BeforeNonEmptyParentheses: false 160 | SpaceAroundPointerQualifiers: Default 161 | SpaceBeforeRangeBasedForLoopColon: true 162 | SpaceInEmptyBlock: false 163 | SpaceInEmptyParentheses: false 164 | SpacesBeforeTrailingComments: 1 165 | SpacesInAngles: Never 166 | SpacesInConditionalStatement: false 167 | SpacesInContainerLiterals: true 168 | SpacesInCStyleCastParentheses: false 169 | SpacesInLineCommentPrefix: 170 | Minimum: 1 171 | Maximum: -1 172 | SpacesInParentheses: false 173 | SpacesInSquareBrackets: false 174 | SpaceBeforeSquareBrackets: false 175 | BitFieldColonSpacing: Both 176 | Standard: Latest 177 | StatementAttributeLikeMacros: 178 | - Q_EMIT 179 | StatementMacros: 180 | - Q_UNUSED 181 | - QT_REQUIRE_VERSION 182 | TabWidth: 8 183 | UseCRLF: false 184 | UseTab: Never 185 | WhitespaceSensitiveMacros: 186 | - STRINGIZE 187 | - PP_STRINGIZE 188 | - BOOST_PP_STRINGIZE 189 | - NS_SWIFT_NAME 190 | - CF_SWIFT_NAME 191 | ... 192 | 193 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /aclocal.m4 2 | /config.guess 3 | /config.log 4 | /config.mak 5 | /config.status 6 | /config.sub 7 | /configure 8 | /install-sh 9 | /pgbouncer 10 | /.objs 11 | /third-party/libusual/* 12 | /third-party/uthash/* 13 | 14 | # Object files 15 | *.o 16 | 17 | # Coverage files 18 | *.gcno 19 | *.gcda 20 | 21 | # Libraries 22 | *.lib 23 | *.a 24 | 25 | # LLVM bitcode 26 | *.bc 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.app 37 | 38 | # Dependencies 39 | .deps 40 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## NEXTGRES Community License Agreement 1.0 2 | 3 | _Please note: this license is derived from the Confluent Community License Agreement 1.0. None of the terms of the Confluent license have been materially changed._ 4 | 5 | This NEXTGRES Community License Agreement Version 1.0 (the "**Agreement**") sets forth the terms on which NEXTGRES, INC. ("**NEXTGRES**") makes available certain software made available by NEXTGRES under this Agreement (the "**Software**"). BY INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT ON BEHALF OF SUCH ENTITY. "**Licensee**" means you, an individual, or the entity on whose behalf you are receiving the Software. 6 | 7 | ### 1. LICENSE GRANT AND CONDITIONS. 8 | 9 | **1.1 License**. Subject to the terms and conditions of this Agreement, NEXTGRES hereby grants to Licensee a non-exclusive, royalty-free, worldwide, non-transferable, non-sublicenseable license during the term of this Agreement to: (a) use the Software; (b) prepare modifications and derivative works of the Software; (c) distribute the Software (including without limitation in source code or object code form); and (d) reproduce copies of the Software (the "**License**"). Licensee is not granted the right to, and Licensee shall not, exercise the License for an Excluded Purpose. For purposes of this Agreement, "**Excluded Purpose**" means making available any software-as-a-service, platform-as-a-service, infrastructure-as-a-service or other similar online service that competes with NEXTGRES products or services that provide the Software. 10 | 11 | **1.2 Conditions**. In consideration of the License, Licensee's distribution of the Software is subject to the following conditions: 12 | 13 | **a.** Licensee must cause any Software modified by Licensee to carry prominent notices stating that Licensee modified the Software. 14 | 15 | **b.** On each Software copy, Licensee shall reproduce and not remove or alter all NEXTGRES or third party copyright or other proprietary notices contained in the Software, and Licensee must provide the notice below with each copy. 16 | 17 | "This software is made available by NEXTGRES, INC., under the terms of the NEXTGRES Community License Agreement, Version 1.0 located at https://nextgres.com/nextgres-community-license. BY INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT." 18 | 19 | **1.3 Licensee Modifications**. Licensee may add its own copyright notices to modifications made by Licensee and may provide additional or different license terms and conditions for use, reproduction, or distribution of Licensee's modifications. While redistributing the Software or modifications thereof, Licensee may choose to offer, for a fee or free of charge, support, warranty, indemnity, or other obligations.Licensee, and not NEXTGRES, will be responsible for any such obligations. 20 | 21 | **1.4 No Sublicensing**. The License does not include the right to sublicense the Software, however, each recipient to which Licensee provides the Software may exercise the Licenses so long as such recipient agrees to and abides by the terms and conditions of this Agreement. 22 | 23 | ### 2. TERM AND TERMINATION. 24 | 25 | This Agreement will continue unless and until earlier terminated as set forth herein. If Licensee breaches any of its conditions or obligations under this Agreement, this Agreement will terminate automatically and the License will terminate automatically and permanently. 26 | 27 | ### 3. INTELLECTUAL PROPERTY. 28 | 29 | As between the parties, NEXTGRES will retain all right, title, and interest in the Software, and all intellectual property rights therein. NEXTGRES hereby reserves all rights not expressly granted to Licensee in this Agreement. NEXTGRES hereby reserves all rights in its trademarks and service marks, and no licenses therein are granted in this Agreement. 30 | 31 | ### 4. DISCLAIMER. 32 | 33 | NEXTGRES HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE SOFTWARE. 34 | 35 | ### 5. LIMITATION OF LIABILITY. 36 | 37 | NEXTGRES WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW. 38 | 39 | ### 6. GENERAL. 40 | 41 | **6.1 Governing Law**. This Agreement will be governed by and interpreted in accordance with the laws of the state of Delaware, without reference to its conflict of laws principles. If Licensee is located within the United States, all disputes arising out of this Agreement are subject to the exclusive jurisdiction of courts located in Delaware. If Licensee is located outside of the United States, any dispute, controversy or claim arising out of or relating to this Agreement will be referred to and finally determined by arbitration in accordance with the JAMS International Arbitration Rules. The tribunal will consist of one arbitrator. The place of arbitration will be Washington, DC. The language to be used in the arbitral proceedings will be English. Judgment upon the award rendered by the arbitrator may be entered in any court having jurisdiction thereof. 42 | 43 | **6.2 Assignment**. Licensee is not authorized to assign its rights under this Agreement to any third party. NEXTGRES may freely assign its rights under this Agreement to any third party. 44 | 45 | **6.3 Other**. This Agreement is the entire agreement between the parties regarding the subject matter hereof. No amendment or modification of this Agreement will be valid or binding upon the parties unless made in writing and signed by the duly authorized representatives of both parties. In the event that any provision, including without limitation any condition, of this Agreement is held to be unenforceable, this Agreement and all licenses and rights granted hereunder will immediately terminate. Waiver by NEXTGRES of a breach of any provision of this Agreement or the failure by NEXTGRES to exercise any right hereunder will not be construed as a waiver of any subsequent breach of that right or as a waiver of any other right. 46 | 47 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MODULE_big = nextgres_idcp 2 | 3 | EXTENSION = nextgres_idcp 4 | DATA = sql/nextgres_idcp--0.1.0.sql 5 | PGFILEDESC = "nextgres_idcp - in-database connection pool" 6 | 7 | OBJS = \ 8 | src/backend/libpq/pqcomm.o \ 9 | src/backend/port/socket.o \ 10 | src/backend/postmaster/controller.o \ 11 | src/backend/postmaster/postmaster.o \ 12 | src/backend/postmaster/proxy.o \ 13 | src/backend/utils/init/globals.o \ 14 | src/backend/utils/misc/guc.o \ 15 | src/extension/entrypoint.o 16 | 17 | REGRESS = nextgres_idcp 18 | 19 | # enable our module in shared_preload_libraries for dynamic bgworkers 20 | REGRESS_OPTS = --temp-config $(srcdir)/st/modules/nextgres_idcp/dynamic.conf 21 | 22 | # Disable installcheck to ensure we cover dynamic bgworkers. 23 | NO_INSTALLCHECK = 1 24 | 25 | PG_CPPFLAGS += -I$(includedir) -I$(srcdir)/src/include 26 | 27 | PG_CPPFLAGS += -DNEXTGRES_EMBEDDED_LIBRARY 28 | PG_LDFLAGS += -lssl -lpq 29 | 30 | ifdef USE_PGXS 31 | PG_CONFIG = pg_config 32 | PGXS := $(shell $(PG_CONFIG) --pgxs) 33 | include $(PGXS) 34 | else 35 | subdir = src/test/modules/nextgres_idcp 36 | top_builddir = ../../../.. 37 | include $(top_builddir)/src/Makefile.global 38 | include $(top_srcdir)/contrib/contrib-global.mk 39 | endif 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NEXTGRES In-Database Connection Pool Extension 2 | 3 | ## Overview 4 | This **ALPHA** release of the NEXTGRES PostgreSQL extension introduces in-database connection pooling to significantly enhance PostgreSQL's ability to handle large numbers of concurrent connections. This solution integrates advanced connection pooling directly within PostgreSQL, eliminating the need for external poolers like PgBouncer and reducing latency issues. 5 | 6 | ## Features 7 | - **In-Database Connection Pooling** - Reuses existing connections, conserving resources and minimizing the need to spawn new processes for each connection. 8 | - **Enhanced Resource Efficiency** - Reduces memory and CPU usage by decreasing the number of processes and connections. 9 | - **Improved Load Management** - Distributes incoming connections intelligently across the available pool to enhance performance during peak loads. 10 | 11 | ## Architecture 12 | - **Background Worker-Based Connection Proxy** - Manages incoming connections before they reach the server, routing them to the most appropriate database session. 13 | - **Embedded PgBouncer Elements** - Integrates elements of PgBouncer's connection management directly within the extension for improved efficiency. 14 | - **Seamless Integration** - Designed as an embedded PostgreSQL extension, simplifying deployment and scalability without external dependencies. 15 | 16 | ## Installation and Usage 17 | - Currently supports PostgreSQL 16, developed and tested on Ubuntu 22.04. 18 | - This is an alpha release intended for early-performance testing and not for production use. 19 | 20 | ## Limitations 21 | - Not designed for read/write load balancing or sharding. 22 | - Lacks query cancellation, event loop cleanup, some GUCs are hardcoded. 23 | 24 | ## Future Developments 25 | - Features under development include zero-copy packet handling, true multithreading, prioritization, and more optimized connection management features. 26 | 27 | ## Disclaimer 28 | - This extension is in alpha stage. Do not use in production environments. 29 | 30 | ## License 31 | - We are currently in a fundraising round, which licensing greatly affects. At present, we are releasing under a license derived from the Confluent Community License Agreement 1.0, found [here](LICENSE.md). 32 | 33 | ## Contact 34 | - For support and more information, reach out to us at info@nextgres.com. 35 | 36 | -------------------------------------------------------------------------------- /THIRD-PARTY: -------------------------------------------------------------------------------- 1 | Portions Copyright (C) NEXTGRES, INC. 2 | Portions Copyright (C) PostgresPro 3 | Portions Copyright (C) Konstantin Knizhnik 4 | Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group 5 | Portions Copyright (c) 1994, Regents of the University of California 6 | -------------------------------------------------------------------------------- /nextgres_idcp.conf: -------------------------------------------------------------------------------- 1 | ## ========================================================================= ## 2 | ## NEXTGRES IN-DATABASE CONNECTION POOLING EXTENSION ## 3 | ## ========================================================================= ## 4 | 5 | #proxy_port = 6543 # TCP port for the connection pooler 6 | #connection_proxies = 0 # number of connection proxies. Setting it to non-zero value enables builtin connection proxy. 7 | #idle_pool_worker_timeout = 0 # maximum allowed duration of any idling connection pool worker. 8 | #session_pool_size = 10 # number of backends serving client sessions. 9 | #restart_pooler_on_reload = off # restart session pool workers on pg_reload_conf(). 10 | #proxying_gucs = off # support setting parameters in connection pooler sessions. 11 | #multitenant_proxy = off # one pool worker can serve clients with different roles (otherwise separate pool is created for each database/role pair 12 | #max_sessions = 1000 # maximum number of client sessions which can be handled by one connection proxy. 13 | #session_schedule = 'round-robin' # session schedule policy for connection pool. 14 | 15 | # Restart session pool workers on pg_reload_conf() 16 | #nextgres_idcp.restart_pooler_on_reload = 0 17 | 18 | # Support setting parameters in connection pooler sessions. 19 | #nextgres_idcp.proxying_gucs = 0 20 | 21 | # One pool worker can serve clients with different roles 22 | #nextgres_idcp.multitenant_proxy = 0 23 | 24 | # Empty 25 | #nextgres_idcp.application_name_add_host = 0 26 | 27 | # Empty 28 | #nextgres_idcp.autodb_idle_timeout = 0 29 | 30 | # Empty 31 | #nextgres_idcp.cancel_wait_timeout = 0 32 | 33 | # Empty 34 | #nextgres_idcp.client_idle_timeout = 0 35 | 36 | # Empty 37 | #nextgres_idcp.client_login_timeout = 0 38 | 39 | # Empty 40 | #nextgres_idcp.default_pool_size = 0 41 | 42 | # Empty 43 | #nextgres_idcp.disable_pqexec = 0 44 | 45 | # Empty 46 | #nextgres_idcp.dns_max_ttl = 0 47 | 48 | # Empty 49 | #nextgres_idcp.dns_nxdomain_ttl = 0 50 | 51 | # Empty 52 | #nextgres_idcp.dns_zone_check_period = 0 53 | 54 | # Empty 55 | #nextgres_idcp.idle_transaction_timeout = 0 56 | 57 | # Empty 58 | #nextgres_idcp.listen_backlog = 0 59 | 60 | # Empty 61 | #nextgres_idcp.listen_port = 0 62 | 63 | # Empty 64 | #nextgres_idcp.log_connections = 0 65 | 66 | # Empty 67 | #nextgres_idcp.log_disconnections = 0 68 | 69 | # Empty 70 | #nextgres_idcp.log_pooler_errors = 0 71 | 72 | # Empty 73 | #nextgres_idcp.log_stats = 0 74 | 75 | # Empty 76 | #nextgres_idcp.max_client_conn = 0 77 | 78 | # Empty 79 | #nextgres_idcp.max_db_connections = 0 80 | 81 | # Empty 82 | #nextgres_idcp.max_packet_size = 0 83 | 84 | # Empty 85 | #nextgres_idcp.max_prepared_statements = 0 86 | 87 | # Empty 88 | #nextgres_idcp.max_user_connections = 0 89 | 90 | # Empty 91 | #nextgres_idcp.min_pool_size = 0 92 | 93 | # Empty 94 | #nextgres_idcp.peer_id = 0 95 | 96 | # Empty 97 | #nextgres_idcp.pkt_buf = 0 98 | 99 | # Empty 100 | #nextgres_idcp.query_timeout = 0 101 | 102 | # Empty 103 | #nextgres_idcp.query_wait_timeout = 0 104 | 105 | # Empty 106 | #nextgres_idcp.reserve_pool_size = 0 107 | 108 | # Empty 109 | #nextgres_idcp.reserve_pool_timeout = 0 110 | 111 | # Empty 112 | #nextgres_idcp.sbuf_loopcnt = 0 113 | 114 | # Empty 115 | #nextgres_idcp.server_check_delay = 0 116 | 117 | # Empty 118 | #nextgres_idcp.server_connect_timeout = 0 119 | 120 | # Empty 121 | #nextgres_idcp.server_fast_close = 0 122 | 123 | # Empty 124 | #nextgres_idcp.server_idle_timeout = 0 125 | 126 | # Empty 127 | #nextgres_idcp.server_lifetime = 0 128 | 129 | # Empty 130 | #nextgres_idcp.server_login_retry = 0 131 | 132 | # Empty 133 | #nextgres_idcp.server_reset_query_always = 0 134 | 135 | # Empty 136 | #nextgres_idcp.server_round_robin = 0 137 | 138 | # Empty 139 | #nextgres_idcp.so_reuseport = 0 140 | 141 | # Empty 142 | #nextgres_idcp.stats_period = 0 143 | 144 | # Empty 145 | #nextgres_idcp.suspend_timeout = 0 146 | 147 | # Empty 148 | #nextgres_idcp.tcp_defer_accept = 0 149 | 150 | # Empty 151 | #nextgres_idcp.tcp_keepcnt = 0 152 | 153 | # Empty 154 | #nextgres_idcp.tcp_keepidle = 0 155 | 156 | # Empty 157 | #nextgres_idcp.tcp_keepintvl = 0 158 | 159 | # Empty 160 | #nextgres_idcp.tcp_socket_buffer = 0 161 | 162 | # Empty 163 | #nextgres_idcp.tcp_user_timeout = 0 164 | 165 | # Empty 166 | #nextgres_idcp.unix_socket_mode = 0 167 | 168 | # Empty 169 | #nextgres_idcp.verbose = 0 170 | 171 | # Sets number of backends serving client sessions. 172 | #nextgres_idcp.session_pool_size = 0 173 | 174 | # Sets the maximum allowed duration of any idling connection pool worker. 175 | #nextgres_idcp.idle_pool_worker_timeout = 0 176 | 177 | # Sets number of connection proxies. 178 | #nextgres_idcp.thread_count = 0 179 | 180 | # Sets the maximum number of client session. 181 | #nextgres_idcp.max_sessions_per_thread = 0 182 | 183 | # Sets the TCP port for the connection pooler. 184 | #nextgres_idcp.port = 0 185 | 186 | # Empty 187 | #nextgres_idcp.auth_dbname = 0 188 | 189 | # Empty 190 | #nextgres_idcp.auth_file = 0 191 | 192 | # Empty 193 | #nextgres_idcp.auth_hba_file = 0 194 | 195 | # Empty 196 | #nextgres_idcp.auth_ident_file = 0 197 | 198 | # Empty 199 | #nextgres_idcp.auth_query = 0 200 | 201 | # Empty 202 | #nextgres_idcp.auth_type = 0 203 | 204 | # Empty 205 | #nextgres_idcp.client_tls_ca_file = 0 206 | 207 | # Empty 208 | #nextgres_idcp.client_tls_cert_file = 0 209 | 210 | # Empty 211 | #nextgres_idcp.client_tls_ciphers = 0 212 | 213 | # Empty 214 | #nextgres_idcp.client_tls_dheparams = 0 215 | 216 | # Empty 217 | #nextgres_idcp.client_tls_ecdhcurve = 0 218 | 219 | # Empty 220 | #nextgres_idcp.client_tls_key_file = 0 221 | 222 | # Empty 223 | #nextgres_idcp.client_tls_protocols = 0 224 | 225 | # Empty 226 | #nextgres_idcp.client_tls_sslmode = 0 227 | 228 | # Empty 229 | #nextgres_idcp.ignore_startup_parameters = 0 230 | 231 | # Empty 232 | #nextgres_idcp.job_name = 0 233 | 234 | # Empty 235 | #nextgres_idcp.listen_addr = 0 236 | 237 | # Empty 238 | #nextgres_idcp.logfile = 0 239 | 240 | # Empty 241 | #nextgres_idcp.pidfile = 0 242 | 243 | # Empty 244 | #nextgres_idcp.resolv_conf = 0 245 | 246 | # Empty 247 | #nextgres_idcp.server_check_query = 0 248 | 249 | # Empty 250 | #nextgres_idcp.server_reset_query = 0 251 | 252 | # Empty 253 | #nextgres_idcp.server_tls_ca_file = 0 254 | 255 | # Empty 256 | #nextgres_idcp.server_tls_cert_file = 0 257 | 258 | # Empty 259 | #nextgres_idcp.server_tls_ciphers = 0 260 | 261 | # Empty 262 | #nextgres_idcp.server_tls_key_file = 0 263 | 264 | # Empty 265 | #nextgres_idcp.server_tls_protocols = 0 266 | 267 | # Empty 268 | #nextgres_idcp.server_tls_sslmode = 0 269 | 270 | # Empty 271 | #nextgres_idcp.service_name = 0 272 | 273 | # Empty 274 | #nextgres_idcp.tcp_keepalive = 0 275 | 276 | # Empty 277 | #nextgres_idcp.track_extra_parameters = 0 278 | 279 | # Empty 280 | #nextgres_idcp.unix_socket_dir = 0 281 | 282 | # Empty 283 | #nextgres_idcp.unix_socket_group = 0 284 | -------------------------------------------------------------------------------- /nextgres_idcp.control: -------------------------------------------------------------------------------- 1 | comment = 'NEXTGRES In-Database Connection Pool' 2 | default_version = '0.1.0' 3 | module_pathname = '$libdir/nextgres_idcp' 4 | relocatable = true 5 | -------------------------------------------------------------------------------- /sql/nextgres_idcp--0.1.0.sql: -------------------------------------------------------------------------------- 1 | 2 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 3 | --\echo Use CREATE EXTENSION worker_spi to load this file. \quit 4 | 5 | CREATE SCHEMA _nextgres_idcp; 6 | GRANT USAGE ON SCHEMA _nextgres_idcp TO PUBLIC; 7 | 8 | SET SEARCH_PATH TO _nextgres_idcp; 9 | CREATE TYPE _nextgres_idcp.nextgres_idcp_pool_mode AS ENUM ('session', 'transaction', 'statement'); 10 | 11 | /* 12 | CREATE TABLE IF NOT EXISTS _nextgres_idcp.nextgres_idcp ( 13 | application_name_add_host BIGINT, 14 | auth_dbname TEXT, 15 | auth_file TEXT, 16 | auth_hba_file TEXT, 17 | auth_ident_file TEXT, 18 | auth_query TEXT, 19 | auth_type TEXT, 20 | autodb_idle_timeout BIGINT, 21 | cancel_wait_timeout BIGINT, 22 | client_idle_timeout BIGINT, 23 | client_login_timeout BIGINT, 24 | client_tls_ca_file TEXT, 25 | client_tls_cert_file TEXT, 26 | client_tls_ciphers TEXT, 27 | client_tls_dheparams TEXT, 28 | client_tls_ecdhcurve TEXT, 29 | client_tls_key_file TEXT, 30 | client_tls_protocols TEXT, 31 | client_tls_sslmode TEXT, 32 | default_pool_size BIGINT, 33 | disable_pqexec BIGINT, 34 | dns_max_ttl BIGINT, 35 | dns_nxdomain_ttl BIGINT, 36 | dns_zone_check_period BIGINT, 37 | idle_transaction_timeout BIGINT, 38 | ignore_startup_parameters TEXT, 39 | job_name TEXT, 40 | listen_addr TEXT, 41 | listen_backlog BIGINT, 42 | listen_port BIGINT, 43 | log_connections BIGINT, 44 | log_disconnections BIGINT, 45 | log_pooler_errors BIGINT, 46 | log_stats BIGINT, 47 | logfile TEXT, 48 | max_client_conn BIGINT, 49 | max_db_connections BIGINT, 50 | max_packet_size BIGINT, 51 | max_prepared_statements BIGINT, 52 | max_user_connections BIGINT, 53 | min_pool_size BIGINT, 54 | peer_id BIGINT, 55 | pidfile TEXT, 56 | pkt_buf BIGINT, 57 | pool_mode nextgres_idcp_pool_mode, 58 | query_timeout BIGINT, 59 | query_wait_timeout BIGINT, 60 | reserve_pool_size BIGINT, 61 | reserve_pool_timeout BIGINT, 62 | resolv_conf TEXT, 63 | sbuf_loopcnt BIGINT, 64 | server_check_delay BIGINT, 65 | server_check_query TEXT, 66 | server_connect_timeout BIGINT, 67 | server_fast_close BIGINT, 68 | server_idle_timeout BIGINT, 69 | server_lifetime BIGINT, 70 | server_login_retry BIGINT, 71 | server_reset_query TEXT, 72 | server_reset_query_always BIGINT, 73 | server_round_robin BIGINT, 74 | server_tls_ca_file TEXT, 75 | server_tls_cert_file TEXT, 76 | server_tls_ciphers TEXT, 77 | server_tls_key_file TEXT, 78 | server_tls_protocols TEXT, 79 | server_tls_sslmode TEXT, 80 | service_name TEXT, 81 | so_reuseport BIGINT, 82 | stats_period BIGINT, 83 | suspend_timeout BIGINT, 84 | tcp_defer_accept BIGINT, 85 | tcp_keepalive TEXT, 86 | tcp_keepcnt BIGINT, 87 | tcp_keepidle BIGINT, 88 | tcp_keepintvl BIGINT, 89 | tcp_socket_buffer BIGINT, 90 | tcp_user_timeout BIGINT, 91 | track_extra_parameters TEXT, 92 | unix_socket_dir TEXT, 93 | unix_socket_group TEXT, 94 | unix_socket_mode BIGINT, 95 | verbosity BIGINT 96 | ); 97 | */ 98 | 99 | CREATE TABLE IF NOT EXISTS _nextgres_idcp.databases ( 100 | database_name NAME NOT NULL, 101 | auth_database_name NAME, 102 | auth_query TEXT, 103 | auth_user NAME, 104 | backend_database_name NAME NOT NULL, 105 | client_encoding TEXT, 106 | connect_query TEXT, 107 | host TEXT, 108 | max_db_connections INTEGER, 109 | min_pool_size INTEGER, 110 | pool_mode _nextgres_idcp.nextgres_idcp_pool_mode, 111 | pool_size INTEGER, 112 | port BIGINT, 113 | reserve_pool BIGINT, 114 | specific_datestyle TEXT, 115 | specific_timezone TEXT, 116 | specific_user NAME, 117 | PRIMARY KEY (database_name), 118 | FOREIGN KEY (auth_database_name) 119 | REFERENCES _nextgres_idcp.databases (database_name)); 120 | 121 | CREATE TABLE IF NOT EXISTS _nextgres_idcp.admin_users ( 122 | user_name NAME NOT NULL, 123 | PRIMARY KEY (user_name)); 124 | 125 | CREATE TABLE IF NOT EXISTS _nextgres_idcp.stats_users ( 126 | user_name NAME NOT NULL, 127 | PRIMARY KEY (user_name)); 128 | 129 | CREATE TABLE IF NOT EXISTS _nextgres_idcp.users ( 130 | user_name NAME NOT NULL, 131 | max_user_connections BIGINT, 132 | pool_mode nextgres_idcp_pool_mode, 133 | PRIMARY KEY (user_name)); 134 | 135 | -------------------------------------------------------------------------------- /src/backend/port/socket.c: -------------------------------------------------------------------------------- 1 | #include "postgres.h" 2 | #include "port.h" 3 | 4 | #ifdef WIN32 5 | int pgwin32_socketpair(int domain, int type, int protocol, SOCKET socks[2]) 6 | { 7 | union { 8 | struct sockaddr_in inaddr; 9 | struct sockaddr addr; 10 | } a; 11 | SOCKET listener; 12 | int e; 13 | socklen_t addrlen = sizeof(a.inaddr); 14 | DWORD flags = 0; 15 | int reuse = 1; 16 | 17 | socks[0] = socks[1] = -1; 18 | 19 | listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 20 | if (listener == -1) 21 | return SOCKET_ERROR; 22 | 23 | memset(&a, 0, sizeof(a)); 24 | a.inaddr.sin_family = AF_INET; 25 | a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 26 | a.inaddr.sin_port = 0; 27 | 28 | for (;;) { 29 | if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, 30 | (char*) &reuse, (socklen_t) sizeof(reuse)) == -1) 31 | break; 32 | if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) 33 | break; 34 | 35 | memset(&a, 0, sizeof(a)); 36 | if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR) 37 | break; 38 | a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 39 | a.inaddr.sin_family = AF_INET; 40 | 41 | if (listen(listener, 1) == SOCKET_ERROR) 42 | break; 43 | 44 | socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags); 45 | if (socks[0] == -1) 46 | break; 47 | if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) 48 | break; 49 | 50 | socks[1] = accept(listener, NULL, NULL); 51 | if (socks[1] == -1) 52 | break; 53 | 54 | closesocket(listener); 55 | return 0; 56 | } 57 | 58 | e = WSAGetLastError(); 59 | closesocket(listener); 60 | closesocket(socks[0]); 61 | closesocket(socks[1]); 62 | WSASetLastError(e); 63 | socks[0] = socks[1] = -1; 64 | return SOCKET_ERROR; 65 | } 66 | #endif /* WIN32 */ 67 | 68 | -------------------------------------------------------------------------------- /src/backend/postmaster/controller.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= ** 2 | ** _ _______ ________________ ________ ** 3 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 4 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 5 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 6 | ** ** 7 | ** ========================================================================= ** 8 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 9 | ** ========================================================================= ** 10 | ** NEXTGRES Database Compatibility System ** 11 | ** Portions Copyright (C) NEXTGRES, INC. ** 12 | ** Portions Copyright (C) PostgresPro ** 13 | ** Portions Copyright (C) Konstantin Knizhnik ** 14 | ** All Rights Reserved. ** 15 | ** ** 16 | ** Permission to use, copy, modify, and/or distribute this software for any ** 17 | ** purpose is subject to the terms specified in the License Agreement. ** 18 | ** ========================================================================= */ 19 | 20 | /* 21 | * OVERVIEW 22 | * 23 | * This file represents a background worker that coordinates individual 24 | * connection pool listeners responsible for handling incoming requests. 25 | */ 26 | 27 | /* ========================================================================= */ 28 | /* -- INCLUSIONS ----------------------------------------------------------- */ 29 | /* ========================================================================= */ 30 | 31 | /* -------------------------- Interface Inclusions ------------------------- */ 32 | 33 | #include "postgres.h" 34 | 35 | /* These are always necessary for a bgworker */ 36 | #include "miscadmin.h" 37 | #include "pgstat.h" 38 | #include "postmaster/bgworker.h" 39 | #include "postmaster/interrupt.h" 40 | #include "storage/ipc.h" 41 | #include "storage/latch.h" 42 | #include "storage/lwlock.h" 43 | #include "storage/proc.h" 44 | #include "storage/shmem.h" 45 | 46 | /* these headers are used by this particular worker's code */ 47 | #include "access/xact.h" 48 | #include "executor/spi.h" 49 | #include "fmgr.h" 50 | #include "lib/stringinfo.h" 51 | #include "utils/builtins.h" 52 | #include "utils/snapmgr.h" 53 | 54 | /* --------------------------- System Inclusions --------------------------- */ 55 | 56 | /* --------------------------- Project Inclusions -------------------------- */ 57 | 58 | #include "nextgres/idcp.h" 59 | 60 | /* ========================================================================= */ 61 | /* -- LOCAL DEFINITIONS ---------------------------------------------------- */ 62 | /* ========================================================================= */ 63 | 64 | /* ========================================================================= */ 65 | /* -- LOCAL MACROS --------------------------------------------------------- */ 66 | /* ========================================================================= */ 67 | 68 | /* ========================================================================= */ 69 | /* -- LOCAL TYPEDEFS ------------------------------------------------------- */ 70 | /* ========================================================================= */ 71 | 72 | /* ========================================================================= */ 73 | /* -- LOCAL STRUCTURES ----------------------------------------------------- */ 74 | /* ========================================================================= */ 75 | 76 | /* ========================================================================= */ 77 | /* -- PRIVATE FUNCTION PROTOTYPES ------------------------------------------ */ 78 | /* ========================================================================= */ 79 | 80 | /* ========================================================================= */ 81 | /* -- LOCAL FUNCTION PROTOTYPES -------------------------------------------- */ 82 | /* ========================================================================= */ 83 | 84 | static void idcp_controller_sighup_handler (SIGNAL_ARGS); 85 | static void idcp_controller_sigterm_handler (SIGNAL_ARGS); 86 | 87 | PGDLLEXPORT void ng_idcp_controller_main(Datum main_arg) 88 | pg_attribute_noreturn(); 89 | 90 | /* ========================================================================= */ 91 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 92 | /* ========================================================================= */ 93 | 94 | /* ========================================================================= */ 95 | /* -- PRIVATE VARIABLES ---------------------------------------------------- */ 96 | /* ========================================================================= */ 97 | 98 | /* ========================================================================= */ 99 | /* -- LOCAL VARIABLES ------------------------------------------------------ */ 100 | /* ========================================================================= */ 101 | 102 | /** Flag indicating the coordinator should be reloaded. */ 103 | static volatile sig_atomic_t got_sighup = true; 104 | 105 | /** Flag indicating the coordinator should be terminated. */ 106 | static volatile sig_atomic_t got_sigterm = false; 107 | 108 | /* ========================================================================= */ 109 | /* -- STATIC ASSERTIONS ---------------------------------------------------- */ 110 | /* ========================================================================= */ 111 | 112 | /* ========================================================================= */ 113 | /* -- PUBLIC FUNCTION DEFINITIONS ------------------------------------------ */ 114 | /* ========================================================================= */ 115 | 116 | void 117 | ng_idcp_controller_main ( 118 | Datum db_oid 119 | ) { 120 | bool proxy_workers_started = false; 121 | 122 | /* Register functions for SIGTERM/SIGHUP management */ 123 | pqsignal(SIGHUP, idcp_controller_sighup_handler); 124 | pqsignal(SIGTERM, idcp_controller_sigterm_handler); 125 | 126 | /* We're now ready to receive signals */ 127 | BackgroundWorkerUnblockSignals(); 128 | 129 | /* Connect to our database */ 130 | BackgroundWorkerInitializeConnectionByOid(db_oid, InvalidOid, 0); 131 | 132 | while (!got_sigterm) { 133 | while (got_sighup) { 134 | got_sighup = false; 135 | (void)WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, 136 | 1000L, PG_WAIT_EXTENSION); 137 | ResetLatch(MyLatch); 138 | } 139 | 140 | /* Run the background process main loop interrupt handler */ 141 | HandleMainLoopInterrupts(); 142 | 143 | /* Signal our workers */ 144 | if (proxy_workers_started) { 145 | } 146 | 147 | /* Wait on worker responses */ 148 | if (proxy_workers_started) { 149 | } 150 | 151 | if (!proxy_workers_started) { 152 | BackgroundWorker worker = { 153 | .bgw_name = NEXTGRES_EXTNAME "_worker", 154 | .bgw_type = NEXTGRES_EXTNAME, 155 | .bgw_function_name = "ng_idcp_proxy_main", 156 | .bgw_notify_pid = MyProcPid, 157 | .bgw_main_arg = db_oid, 158 | .bgw_restart_time = BGW_NEVER_RESTART, 159 | .bgw_flags = 160 | BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION, 161 | .bgw_start_time = BgWorkerStart_RecoveryFinished}; 162 | strncpy(worker.bgw_library_name, MyBgworkerEntry->bgw_library_name, 163 | BGW_MAXLEN - 1); 164 | for (int ii = 0; ii < g_ng_idcp_cfg_thread_count; ++ii) { 165 | BackgroundWorkerHandle *handle; 166 | pid_t worker_pid; 167 | 168 | RegisterDynamicBackgroundWorker(&worker, &handle); 169 | if (WaitForBackgroundWorkerStartup(handle, &worker_pid) == 170 | BGWH_POSTMASTER_DIED) { 171 | goto main_loop_exit; 172 | } 173 | 174 | /* We should put these puppies into a list for later signal handling */ 175 | } 176 | 177 | /* 178 | * We should check to make sure all started, but they always do in our 179 | * evaluation, so this is a later addition. 180 | */ 181 | 182 | proxy_workers_started = true; 183 | } 184 | 185 | (void)WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, 186 | 1000L, PG_WAIT_EXTENSION); 187 | ResetLatch(MyLatch); 188 | } 189 | 190 | main_loop_exit: 191 | if (proxy_workers_started) { 192 | ereport(LOG, errmsg("Shutting down proxy workers")); 193 | 194 | /* 195 | * Per earlier comment, we should iterate the dynamic bgworker list and 196 | * signal each one accordingly... 197 | */ 198 | } 199 | 200 | ereport(LOG, errmsg("Exiting " NEXTGRES_EXTNAME)); 201 | 202 | proc_exit(0); 203 | } /* ng_idcp_controller_main() */ 204 | 205 | /* ========================================================================= */ 206 | /* -- PRIVATE FUNCTION DEFINITIONS ----------------------------------------- */ 207 | /* ========================================================================= */ 208 | 209 | /* ========================================================================= */ 210 | /* -- LOCAL FUNCTION DEFINITIONS ------------------------------------------- */ 211 | /* ========================================================================= */ 212 | 213 | static void 214 | idcp_controller_sighup_handler ( 215 | SIGNAL_ARGS 216 | ) { 217 | elog(LOG, "received SIGHUP"); 218 | 219 | got_sighup = true; 220 | 221 | if (MyProc) { 222 | SetLatch(&MyProc->procLatch); 223 | } 224 | 225 | } /* idcp_controller_sighup_handler() */ 226 | 227 | /* ------------------------------------------------------------------------- */ 228 | 229 | static void 230 | idcp_controller_sigterm_handler ( 231 | SIGNAL_ARGS 232 | ) { 233 | int save_errno = errno; 234 | 235 | got_sigterm = true; 236 | 237 | if (MyProc) { 238 | SetLatch(&MyProc->procLatch); 239 | } 240 | 241 | errno = save_errno; 242 | 243 | } /* idcp_controller_sigterm_handler() */ 244 | 245 | /* vim: set ts=2 et sw=2 ft=c: */ 246 | 247 | -------------------------------------------------------------------------------- /src/backend/postmaster/postmaster.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= ** 2 | ** _ _______ ________________ ________ ** 3 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 4 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 5 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 6 | ** ** 7 | ** ========================================================================= ** 8 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 9 | ** ========================================================================= ** 10 | ** NEXTGRES Database Compatibility System ** 11 | ** Portions Copyright (C) NEXTGRES, INC. ** 12 | ** Portions Copyright (C) PostgresPro ** 13 | ** Portions Copyright (C) Konstantin Knizhnik ** 14 | ** All Rights Reserved. ** 15 | ** ** 16 | ** Permission to use, copy, modify, and/or distribute this software for any ** 17 | ** purpose is subject to the terms specified in the License Agreement. ** 18 | ** ========================================================================= */ 19 | 20 | /* 21 | * OVERVIEW 22 | * 23 | * This is basically a verbatim copy of core postmaster functions required for 24 | * connection startup handling. 25 | */ 26 | 27 | /* ========================================================================= */ 28 | /* -- INCLUSIONS ----------------------------------------------------------- */ 29 | /* ========================================================================= */ 30 | 31 | /* -------------------------- Interface Inclusions ------------------------- */ 32 | 33 | #include "postgres.h" 34 | 35 | #include "access/htup_details.h" 36 | #include "access/xlog.h" 37 | #include "commands/defrem.h" 38 | #include "common/ip.h" 39 | #include "common/string.h" 40 | #include "funcapi.h" 41 | #include "internal/libpq-int.h" 42 | #include "libpq-fe.h" 43 | #include "libpq/libpq-be.h" 44 | #include "libpq/libpq.h" 45 | #include "libpq/pqformat.h" 46 | #include "libpq/pqsignal.h" 47 | #include "miscadmin.h" 48 | #include "parser/parse_expr.h" 49 | #include "pgstat.h" 50 | #include "postmaster/fork_process.h" 51 | #include "postmaster/interrupt.h" 52 | #include "postmaster/postmaster.h" 53 | #include "replication/walsender.h" 54 | #include "storage/ipc.h" 55 | #include "storage/latch.h" 56 | #include "storage/proc.h" 57 | #include "storage/procarray.h" 58 | #include "tcop/pquery.h" 59 | #include "tcop/tcopprot.h" 60 | #include "utils/builtins.h" 61 | #include "utils/guc_hooks.h" 62 | #include "utils/memutils.h" 63 | #include "utils/pidfile.h" 64 | #include "utils/portal.h" 65 | #include "utils/ps_status.h" 66 | #include "utils/timeout.h" 67 | #include "utils/timestamp.h" 68 | #include "utils/varlena.h" 69 | 70 | /* --------------------------- System Inclusions --------------------------- */ 71 | 72 | #include 73 | #include 74 | #include 75 | #include 76 | 77 | /* --------------------------- Project Inclusions -------------------------- */ 78 | 79 | #include "nextgres/idcp.h" 80 | #include "nextgres/idcp/libpq/libpq.h" 81 | #include "nextgres/idcp/postmaster/postmaster.h" 82 | 83 | /* ========================================================================= */ 84 | /* -- LOCAL DEFINITIONS ---------------------------------------------------- */ 85 | /* ========================================================================= */ 86 | 87 | /* ========================================================================= */ 88 | /* -- LOCAL MACROS --------------------------------------------------------- */ 89 | /* ========================================================================= */ 90 | 91 | /* ========================================================================= */ 92 | /* -- LOCAL TYPEDEFS ------------------------------------------------------- */ 93 | /* ========================================================================= */ 94 | 95 | /* ========================================================================= */ 96 | /* -- LOCAL STRUCTURES ----------------------------------------------------- */ 97 | /* ========================================================================= */ 98 | 99 | /* ========================================================================= */ 100 | /* -- PRIVATE FUNCTION PROTOTYPES ------------------------------------------ */ 101 | /* ========================================================================= */ 102 | 103 | /* ========================================================================= */ 104 | /* -- LOCAL FUNCTION PROTOTYPES -------------------------------------------- */ 105 | /* ========================================================================= */ 106 | 107 | static void processCancelRequest (Port *port, void *pkt); 108 | static int ProcessStartupPacket (Port *port, bool ssl_done, bool gss_done); 109 | static void SendNegotiateProtocolVersion (List *unrecognized_protocol_options); 110 | 111 | /* ========================================================================= */ 112 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 113 | /* ========================================================================= */ 114 | 115 | /* ========================================================================= */ 116 | /* -- PRIVATE VARIABLES ---------------------------------------------------- */ 117 | /* ========================================================================= */ 118 | 119 | /* ========================================================================= */ 120 | /* -- LOCAL VARIABLES ------------------------------------------------------ */ 121 | /* ========================================================================= */ 122 | 123 | /* ========================================================================= */ 124 | /* -- STATIC ASSERTIONS ---------------------------------------------------- */ 125 | /* ========================================================================= */ 126 | 127 | /* ========================================================================= */ 128 | /* -- PUBLIC FUNCTION DEFINITIONS ------------------------------------------ */ 129 | /* ========================================================================= */ 130 | 131 | int 132 | ng_idcp_parse_startup_packet ( 133 | Port *port, 134 | MemoryContext memctx, 135 | char *buf, 136 | int len, 137 | bool ssl_done, 138 | bool gss_done 139 | ) { 140 | ProtocolVersion proto; 141 | MemoryContext oldcontext; 142 | 143 | am_walsender = false; 144 | am_db_walsender = false; 145 | 146 | /* 147 | * The first field is either a protocol version number or a special 148 | * request code. 149 | */ 150 | port->proto = proto = pg_ntoh32(*((ProtocolVersion *)buf)); 151 | 152 | if (proto == CANCEL_REQUEST_CODE) { 153 | if (len != sizeof(CancelRequestPacket)) { 154 | ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), 155 | errmsg("invalid length of startup packet"))); 156 | return STATUS_ERROR; 157 | } 158 | processCancelRequest(port, buf); 159 | /* Not really an error, but we don't want to proceed further */ 160 | return STATUS_ERROR; 161 | } 162 | 163 | if (proto == NEGOTIATE_SSL_CODE && !ssl_done) { 164 | char SSLok; 165 | 166 | #ifdef USE_SSL 167 | /* No SSL when disabled or on Unix sockets */ 168 | if (!LoadedSSL || port->laddr.addr.ss_family == AF_UNIX) 169 | SSLok = 'N'; 170 | else 171 | SSLok = 'S'; /* Support for SSL */ 172 | #else 173 | SSLok = 'N'; /* No support for SSL */ 174 | #endif 175 | 176 | retry1: 177 | if (send(port->sock, &SSLok, 1, 0) != 1) { 178 | if (errno == EINTR) 179 | goto retry1; /* if interrupted, just retry */ 180 | ereport(COMMERROR, 181 | (errcode_for_socket_access(), 182 | errmsg("failed to send SSL negotiation response: %m"))); 183 | return STATUS_ERROR; /* close the connection */ 184 | } 185 | 186 | #ifdef USE_SSL 187 | if (SSLok == 'S' && secure_open_server(port) == -1) 188 | return STATUS_ERROR; 189 | #endif 190 | 191 | /* 192 | * At this point we should have no data already buffered. If we do, 193 | * it was received before we performed the SSL handshake, so it wasn't 194 | * encrypted and indeed may have been injected by a man-in-the-middle. 195 | * We report this case to the client. 196 | */ 197 | if (ng_idcp_pq_buffer_has_data()) 198 | ereport( 199 | FATAL, 200 | (errcode(ERRCODE_PROTOCOL_VIOLATION), 201 | errmsg("received unencrypted data after SSL request"), 202 | errdetail("This could be either a client-software bug or evidence " 203 | "of an attempted man-in-the-middle attack."))); 204 | 205 | /* 206 | * regular startup packet, cancel, etc packet should follow, but not 207 | * another SSL negotiation request, and a GSS request should only 208 | * follow if SSL was rejected (client may negotiate in either order) 209 | */ 210 | return ProcessStartupPacket(port, true, SSLok == 'S'); 211 | } else if (proto == NEGOTIATE_GSS_CODE && !gss_done) { 212 | char GSSok = 'N'; 213 | 214 | #ifdef ENABLE_GSS 215 | /* No GSSAPI encryption when on Unix socket */ 216 | if (port->laddr.addr.ss_family != AF_UNIX) 217 | GSSok = 'G'; 218 | #endif 219 | 220 | while (send(port->sock, &GSSok, 1, 0) != 1) { 221 | if (errno == EINTR) 222 | continue; 223 | ereport(COMMERROR, 224 | (errcode_for_socket_access(), 225 | errmsg("failed to send GSSAPI negotiation response: %m"))); 226 | return STATUS_ERROR; /* close the connection */ 227 | } 228 | 229 | #ifdef ENABLE_GSS 230 | if (GSSok == 'G' && secure_open_gssapi(port) == -1) 231 | return STATUS_ERROR; 232 | #endif 233 | 234 | /* 235 | * At this point we should have no data already buffered. If we do, 236 | * it was received before we performed the GSS handshake, so it wasn't 237 | * encrypted and indeed may have been injected by a man-in-the-middle. 238 | * We report this case to the client. 239 | */ 240 | if (ng_idcp_pq_buffer_has_data()) 241 | ereport( 242 | FATAL, 243 | (errcode(ERRCODE_PROTOCOL_VIOLATION), 244 | errmsg("received unencrypted data after GSSAPI encryption request"), 245 | errdetail("This could be either a client-software bug or evidence " 246 | "of an attempted man-in-the-middle attack."))); 247 | 248 | /* 249 | * regular startup packet, cancel, etc packet should follow, but not 250 | * another GSS negotiation request, and an SSL request should only 251 | * follow if GSS was rejected (client may negotiate in either order) 252 | */ 253 | return ProcessStartupPacket(port, GSSok == 'G', true); 254 | } 255 | 256 | /* Could add additional special packet types here */ 257 | 258 | /* 259 | * Set FrontendProtocol now so that ereport() knows what format to send if 260 | * we fail during startup. 261 | */ 262 | FrontendProtocol = proto; 263 | 264 | /* Check that the major protocol version is in range. */ 265 | if (PG_PROTOCOL_MAJOR(proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) || 266 | PG_PROTOCOL_MAJOR(proto) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST)) 267 | ereport(FATAL, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), 268 | errmsg("unsupported frontend protocol %u.%u: server " 269 | "supports %u.0 to %u.%u", 270 | PG_PROTOCOL_MAJOR(proto), PG_PROTOCOL_MINOR(proto), 271 | PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST), 272 | PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST), 273 | PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)))); 274 | 275 | /* 276 | * Now fetch parameters out of startup packet and save them into the Port 277 | * structure. All data structures attached to the Port struct must be 278 | * allocated in TopMemoryContext so that they will remain available in a 279 | * running backend (even after PostmasterContext is destroyed). We need 280 | * not worry about leaking this storage on failure, since we aren't in the 281 | * postmaster process anymore. 282 | */ 283 | oldcontext = MemoryContextSwitchTo(TopMemoryContext); 284 | 285 | /* Handle protocol version 3 startup packet */ 286 | { 287 | int32 offset = sizeof(ProtocolVersion); 288 | List *unrecognized_protocol_options = NIL; 289 | 290 | /* 291 | * Scan packet body for name/option pairs. We can assume any string 292 | * beginning within the packet body is null-terminated, thanks to 293 | * zeroing extra byte above. 294 | */ 295 | port->guc_options = NIL; 296 | 297 | while (offset < len) { 298 | char *nameptr = buf + offset; 299 | int32 valoffset; 300 | char *valptr; 301 | 302 | if (*nameptr == '\0') 303 | break; /* found packet terminator */ 304 | valoffset = offset + strlen(nameptr) + 1; 305 | if (valoffset >= len) 306 | break; /* missing value, will complain below */ 307 | valptr = buf + valoffset; 308 | 309 | if (strcmp(nameptr, "database") == 0) 310 | port->database_name = pstrdup(valptr); 311 | else if (strcmp(nameptr, "user") == 0) 312 | port->user_name = pstrdup(valptr); 313 | else if (strcmp(nameptr, "options") == 0) 314 | port->cmdline_options = pstrdup(valptr); 315 | else if (strcmp(nameptr, "replication") == 0) { 316 | /* 317 | * Due to backward compatibility concerns the replication 318 | * parameter is a hybrid beast which allows the value to be 319 | * either boolean or the string 'database'. The latter 320 | * connects to a specific database which is e.g. required for 321 | * logical decoding while. 322 | */ 323 | if (strcmp(valptr, "database") == 0) { 324 | am_walsender = true; 325 | am_db_walsender = true; 326 | } else if (!parse_bool(valptr, &am_walsender)) 327 | ereport(FATAL, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 328 | errmsg("invalid value for parameter \"%s\": \"%s\"", 329 | "replication", valptr), 330 | errhint("Valid values are: \"false\", 0, \"true\", " 331 | "1, \"database\"."))); 332 | } else if (strncmp(nameptr, "_pq_.", 5) == 0) { 333 | /* 334 | * Any option beginning with _pq_. is reserved for use as a 335 | * protocol-level option, but at present no such options are 336 | * defined. 337 | */ 338 | unrecognized_protocol_options = 339 | lappend(unrecognized_protocol_options, pstrdup(nameptr)); 340 | } else { 341 | /* Assume it's a generic GUC option */ 342 | port->guc_options = lappend(port->guc_options, pstrdup(nameptr)); 343 | port->guc_options = lappend(port->guc_options, pstrdup(valptr)); 344 | 345 | /* 346 | * Copy application_name to port if we come across it. This 347 | * is done so we can log the application_name in the 348 | * connection authorization message. Note that the GUC would 349 | * be used but we haven't gone through GUC setup yet. 350 | */ 351 | if (strcmp(nameptr, "application_name") == 0) { 352 | port->application_name = pg_clean_ascii(valptr, 0); 353 | } 354 | } 355 | offset = valoffset + strlen(valptr) + 1; 356 | } 357 | 358 | /* 359 | * If we didn't find a packet terminator exactly at the end of the 360 | * given packet length, complain. 361 | */ 362 | if (offset != len - 1) 363 | ereport(FATAL, (errcode(ERRCODE_PROTOCOL_VIOLATION), 364 | errmsg("invalid startup packet layout: expected " 365 | "terminator as last byte"))); 366 | 367 | /* 368 | * If the client requested a newer protocol version or if the client 369 | * requested any protocol options we didn't recognize, let them know 370 | * the newest minor protocol version we do support and the names of 371 | * any unrecognized options. 372 | */ 373 | if (PG_PROTOCOL_MINOR(proto) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST) || 374 | unrecognized_protocol_options != NIL) 375 | SendNegotiateProtocolVersion(unrecognized_protocol_options); 376 | } 377 | 378 | /* Check a user name was given. */ 379 | if (port->user_name == NULL || port->user_name[0] == '\0') 380 | ereport(FATAL, 381 | (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), 382 | errmsg("no PostgreSQL user name specified in startup packet"))); 383 | 384 | /* The database defaults to the user name. */ 385 | if (port->database_name == NULL || port->database_name[0] == '\0') 386 | port->database_name = pstrdup(port->user_name); 387 | 388 | if (Db_user_namespace) { 389 | /* 390 | * If user@, it is a global user, remove '@'. We only want to do this 391 | * if there is an '@' at the end and no earlier in the user string or 392 | * they may fake as a local user of another database attaching to this 393 | * database. 394 | */ 395 | if (strchr(port->user_name, '@') == 396 | port->user_name + strlen(port->user_name) - 1) 397 | *strchr(port->user_name, '@') = '\0'; 398 | else { 399 | /* Append '@' and dbname */ 400 | port->user_name = 401 | psprintf("%s@%s", port->user_name, port->database_name); 402 | } 403 | } 404 | 405 | /* 406 | * Truncate given database and user names to length of a Postgres name. 407 | * This avoids lookup failures when overlength names are given. 408 | */ 409 | if (strlen(port->database_name) >= NAMEDATALEN) 410 | port->database_name[NAMEDATALEN - 1] = '\0'; 411 | if (strlen(port->user_name) >= NAMEDATALEN) 412 | port->user_name[NAMEDATALEN - 1] = '\0'; 413 | 414 | if (am_walsender) 415 | MyBackendType = B_WAL_SENDER; 416 | else 417 | MyBackendType = B_BACKEND; 418 | 419 | /* 420 | * Normal walsender backends, e.g. for streaming replication, are not 421 | * connected to a particular database. But walsenders used for logical 422 | * replication need to connect to a specific database. We allow streaming 423 | * replication commands to be issued even if connected to a database as it 424 | * can make sense to first make a basebackup and then stream changes 425 | * starting from that. 426 | */ 427 | if (am_walsender && !am_db_walsender) 428 | port->database_name[0] = '\0'; 429 | 430 | /* 431 | * Done putting stuff in TopMemoryContext. 432 | */ 433 | MemoryContextSwitchTo(oldcontext); 434 | 435 | /* 436 | * If we're going to reject the connection due to database state, say so 437 | * now instead of wasting cycles on an authentication exchange. (This also 438 | * allows a pg_ping utility to be written.) 439 | */ 440 | switch (port->canAcceptConnections) { 441 | case CAC_STARTUP: 442 | ereport(FATAL, (errcode(ERRCODE_CANNOT_CONNECT_NOW), 443 | errmsg("the database system is starting up"))); 444 | break; 445 | case CAC_NOTCONSISTENT: 446 | if (EnableHotStandby) 447 | ereport( 448 | FATAL, 449 | (errcode(ERRCODE_CANNOT_CONNECT_NOW), 450 | errmsg("the database system is not yet accepting connections"), 451 | errdetail("Consistent recovery state has not been yet reached."))); 452 | else 453 | ereport(FATAL, 454 | (errcode(ERRCODE_CANNOT_CONNECT_NOW), 455 | errmsg("the database system is not accepting connections"), 456 | errdetail("Hot standby mode is disabled."))); 457 | break; 458 | case CAC_SHUTDOWN: 459 | ereport(FATAL, (errcode(ERRCODE_CANNOT_CONNECT_NOW), 460 | errmsg("the database system is shutting down"))); 461 | break; 462 | case CAC_RECOVERY: 463 | ereport(FATAL, (errcode(ERRCODE_CANNOT_CONNECT_NOW), 464 | errmsg("the database system is in recovery mode"))); 465 | break; 466 | case CAC_TOOMANY: 467 | ereport(FATAL, (errcode(ERRCODE_TOO_MANY_CONNECTIONS), 468 | errmsg("sorry, too many clients already"))); 469 | break; 470 | case CAC_OK: 471 | break; 472 | } 473 | 474 | return STATUS_OK; 475 | } /* ng_idcp_parse_startup_packet() */ 476 | 477 | /* ========================================================================= */ 478 | /* -- PRIVATE FUNCTION DEFINITIONS ----------------------------------------- */ 479 | /* ========================================================================= */ 480 | 481 | /* ========================================================================= */ 482 | /* -- LOCAL FUNCTION DEFINITIONS ------------------------------------------- */ 483 | /* ========================================================================= */ 484 | 485 | /* 486 | * The client has sent a cancel request packet, not a normal 487 | * start-a-new-connection packet. Perform the necessary processing. 488 | * Nothing is sent back to the client. 489 | */ 490 | static void 491 | processCancelRequest ( 492 | Port *port, 493 | void *pkt 494 | ) { 495 | #if 0 496 | CancelRequestPacket *canc = (CancelRequestPacket *) pkt; 497 | int backendPID; 498 | int32 cancelAuthCode; 499 | Backend *bp; 500 | 501 | #ifndef EXEC_BACKEND 502 | dlist_iter iter; 503 | #else 504 | int i; 505 | #endif 506 | 507 | backendPID = (int) pg_ntoh32(canc->backendPID); 508 | cancelAuthCode = (int32) pg_ntoh32(canc->cancelAuthCode); 509 | 510 | /* 511 | * See if we have a matching backend. In the EXEC_BACKEND case, we can no 512 | * longer access the postmaster's own backend list, and must rely on the 513 | * duplicate array in shared memory. 514 | */ 515 | #ifndef EXEC_BACKEND 516 | dlist_foreach(iter, &BackendList) 517 | { 518 | bp = dlist_container(Backend, elem, iter.cur); 519 | #else 520 | for (i = MaxLivePostmasterChildren() - 1; i >= 0; i--) 521 | { 522 | bp = (Backend *) &ShmemBackendArray[i]; 523 | #endif 524 | if (bp->pid == backendPID) 525 | { 526 | if (bp->cancel_key == cancelAuthCode) 527 | { 528 | /* Found a match; signal that backend to cancel current op */ 529 | ereport(DEBUG2, 530 | (errmsg_internal("processing cancel request: sending SIGINT to process %d", 531 | backendPID))); 532 | signal_child(bp->pid, SIGINT); 533 | } 534 | else 535 | /* Right PID, wrong key: no way, Jose */ 536 | ereport(LOG, 537 | (errmsg("wrong key in cancel request for process %d", 538 | backendPID))); 539 | return; 540 | } 541 | #ifndef EXEC_BACKEND /* make GNU Emacs 26.1 see brace balance */ 542 | } 543 | #else 544 | } 545 | #endif 546 | 547 | /* No matching backend */ 548 | ereport(LOG, 549 | (errmsg("PID %d in cancel request did not match any process", 550 | backendPID))); 551 | #endif 552 | } /* func() */ 553 | 554 | /* ------------------------------------------------------------------------- */ 555 | 556 | static int 557 | ProcessStartupPacket ( 558 | Port *port, 559 | bool ssl_done, 560 | bool gss_done 561 | ) { 562 | int32 len; 563 | char *buf; 564 | 565 | ng_idcp_pq_startmsgread(); 566 | 567 | /* 568 | * Grab the first byte of the length word separately, so that we can tell 569 | * whether we have no data at all or an incomplete packet. (This might 570 | * sound inefficient, but it's not really, because of buffering in 571 | * pqcomm.c.) 572 | */ 573 | if (ng_idcp_pq_getbytes((char *)&len, 1) == EOF) { 574 | /* 575 | * If we get no data at all, don't clutter the log with a complaint; 576 | * such cases often occur for legitimate reasons. An example is that 577 | * we might be here after responding to NEGOTIATE_SSL_CODE, and if the 578 | * client didn't like our response, it'll probably just drop the 579 | * connection. Service-monitoring software also often just opens and 580 | * closes a connection without sending anything. (So do port 581 | * scanners, which may be less benign, but it's not really our job to 582 | * notice those.) 583 | */ 584 | return STATUS_ERROR; 585 | } 586 | 587 | if (ng_idcp_pq_getbytes(((char *)&len) + 1, 3) == EOF) { 588 | /* Got a partial length word, so bleat about that */ 589 | if (!ssl_done && !gss_done) 590 | ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), 591 | errmsg("incomplete startup packet"))); 592 | return STATUS_ERROR; 593 | } 594 | 595 | len = pg_ntoh32(len); 596 | len -= 4; 597 | 598 | if (len < (int32)sizeof(ProtocolVersion) || 599 | len > MAX_STARTUP_PACKET_LENGTH) { 600 | ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), 601 | errmsg("invalid length of startup packet"))); 602 | return STATUS_ERROR; 603 | } 604 | 605 | /* 606 | * Allocate space to hold the startup packet, plus one extra byte that's 607 | * initialized to be zero. This ensures we will have null termination of 608 | * all strings inside the packet. 609 | */ 610 | buf = palloc(len + 1); 611 | buf[len] = '\0'; 612 | 613 | if (ng_idcp_pq_getbytes(buf, len) == EOF) { 614 | ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), 615 | errmsg("incomplete startup packet"))); 616 | return STATUS_ERROR; 617 | } 618 | ng_idcp_pq_endmsgread(); 619 | 620 | return ng_idcp_parse_startup_packet(port, TopMemoryContext, buf, len, 621 | ssl_done, gss_done); 622 | } /* ProcessStartupPacket() */ 623 | 624 | /* ------------------------------------------------------------------------- */ 625 | 626 | void 627 | SendNegotiateProtocolVersion ( 628 | List *unrecognized_protocol_options 629 | ) { 630 | StringInfoData buf; 631 | ListCell *lc; 632 | 633 | pq_beginmessage(&buf, 'v'); /* NegotiateProtocolVersion */ 634 | pq_sendint32(&buf, PG_PROTOCOL_LATEST); 635 | pq_sendint32(&buf, list_length(unrecognized_protocol_options)); 636 | foreach (lc, unrecognized_protocol_options) { 637 | pq_sendstring(&buf, lfirst(lc)); 638 | } 639 | pq_endmessage(&buf); 640 | 641 | /* no need to flush, some other message will follow */ 642 | 643 | } /* SendNegotiateProtocolVersion() */ 644 | 645 | /* vim: set ts=2 et sw=2 ft=c: */ 646 | 647 | -------------------------------------------------------------------------------- /src/backend/utils/init/globals.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= ** 2 | ** _ _______ ________________ ________ ** 3 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 4 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 5 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 6 | ** ** 7 | ** ========================================================================= ** 8 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 9 | ** ========================================================================= ** 10 | ** NEXTGRES Database Compatibility System ** 11 | ** Portions Copyright (C) NEXTGRES, INC. ** 12 | ** Portions Copyright (C) PostgresPro ** 13 | ** Portions Copyright (C) Konstantin Knizhnik ** 14 | ** All Rights Reserved. ** 15 | ** ** 16 | ** Permission to use, copy, modify, and/or distribute this software for any ** 17 | ** purpose is subject to the terms specified in the License Agreement. ** 18 | ** ========================================================================= */ 19 | 20 | /* 21 | * OVERVIEW 22 | * 23 | * Just as in core Postgres, globals used all over the place should be 24 | * declared here; not in other modules. 25 | */ 26 | 27 | /* ========================================================================= */ 28 | /* -- INCLUSIONS ----------------------------------------------------------- */ 29 | /* ========================================================================= */ 30 | 31 | /* -------------------------- Interface Inclusions ------------------------- */ 32 | 33 | #include "postgres.h" 34 | 35 | /* --------------------------- System Inclusions --------------------------- */ 36 | 37 | /* --------------------------- Project Inclusions -------------------------- */ 38 | 39 | #include "nextgres/idcp.h" 40 | 41 | /* ========================================================================= */ 42 | /* -- LOCAL DEFINITIONS ---------------------------------------------------- */ 43 | /* ========================================================================= */ 44 | 45 | /* ========================================================================= */ 46 | /* -- LOCAL MACROS --------------------------------------------------------- */ 47 | /* ========================================================================= */ 48 | 49 | /* ========================================================================= */ 50 | /* -- LOCAL TYPEDEFS ------------------------------------------------------- */ 51 | /* ========================================================================= */ 52 | 53 | /* ========================================================================= */ 54 | /* -- LOCAL STRUCTURES ----------------------------------------------------- */ 55 | /* ========================================================================= */ 56 | 57 | /* ========================================================================= */ 58 | /* -- PRIVATE FUNCTION PROTOTYPES ------------------------------------------ */ 59 | /* ========================================================================= */ 60 | 61 | /* ========================================================================= */ 62 | /* -- LOCAL FUNCTION PROTOTYPES -------------------------------------------- */ 63 | /* ========================================================================= */ 64 | 65 | /* ========================================================================= */ 66 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 67 | /* ========================================================================= */ 68 | 69 | int SessionPoolSize = 10; 70 | int IdlePoolWorkerTimeout = 0; 71 | int ConnectionProxiesNumber = 0; 72 | int SessionSchedule = SESSION_SCHED_ROUND_ROBIN; 73 | int MaxSessions = 20000; 74 | bool RestartPoolerOnReload = false; 75 | bool ProxyingGUCs = false; 76 | bool MultitenantProxy = false; 77 | 78 | /* ---------------------------- Enumerated GUCs ---------------------------- */ 79 | 80 | /* ------------------------------ Boolean GUCs ----------------------------- */ 81 | 82 | bool g_ng_idcp_multitenant_proxy = false; 83 | bool g_ng_idcp_proxying_gucs = false; 84 | bool g_ng_idcp_restart_pooler_on_reload = false; 85 | 86 | /* ------------------------------ Integer GUCs ----------------------------- */ 87 | 88 | int g_ng_idcp_cfg_port = 0; 89 | int g_ng_idcp_cfg_session_pool_size = 0; 90 | int g_ng_idcp_cfg_session_scheduler = 0; 91 | int g_ng_idcp_cfg_idle_worker_timeout_in_ms = 0; 92 | int g_ng_idcp_cfg_thread_count = 0; 93 | int g_ng_idcp_cfg_max_sessions_per_thread = 0; 94 | int g_ng_idcp_cfg_pool_mode = NG_IDCP_POOL_MODE_SESSION; 95 | int g_ng_idcp_cfg_application_name_add_host = 0; 96 | int g_ng_idcp_cfg_autodb_idle_timeout = 0; 97 | int g_ng_idcp_cfg_cancel_wait_timeout = 0; 98 | int g_ng_idcp_cfg_client_idle_timeout = 0; 99 | int g_ng_idcp_cfg_client_login_timeout = 0; 100 | int g_ng_idcp_cfg_default_pool_size = 0; 101 | int g_ng_idcp_cfg_disable_pqexec = 0; 102 | int g_ng_idcp_cfg_dns_max_ttl = 0; 103 | int g_ng_idcp_cfg_dns_nxdomain_ttl = 0; 104 | int g_ng_idcp_cfg_dns_zone_check_period = 0; 105 | int g_ng_idcp_cfg_idle_transaction_timeout = 0; 106 | int g_ng_idcp_cfg_listen_backlog = 0; 107 | int g_ng_idcp_cfg_listen_port = 0; 108 | int g_ng_idcp_cfg_log_connections = 0; 109 | int g_ng_idcp_cfg_log_disconnections = 0; 110 | int g_ng_idcp_cfg_log_pooler_errors = 0; 111 | int g_ng_idcp_cfg_log_stats = 0; 112 | int g_ng_idcp_cfg_max_client_conn = 0; 113 | int g_ng_idcp_cfg_max_db_connections = 0; 114 | int g_ng_idcp_cfg_max_packet_size = 0; 115 | int g_ng_idcp_cfg_max_prepared_statements = 0; 116 | int g_ng_idcp_cfg_max_user_connections = 0; 117 | int g_ng_idcp_cfg_min_pool_size = 0; 118 | int g_ng_idcp_cfg_peer_id = 0; 119 | int g_ng_idcp_cfg_pkt_buf = 0; 120 | int g_ng_idcp_cfg_query_timeout = 0; 121 | int g_ng_idcp_cfg_query_wait_timeout = 0; 122 | int g_ng_idcp_cfg_reserve_pool_size = 0; 123 | int g_ng_idcp_cfg_reserve_pool_timeout = 0; 124 | int g_ng_idcp_cfg_sbuf_loopcnt = 0; 125 | int g_ng_idcp_cfg_server_check_delay = 0; 126 | int g_ng_idcp_cfg_server_connect_timeout = 0; 127 | int g_ng_idcp_cfg_server_fast_close = 0; 128 | int g_ng_idcp_cfg_server_idle_timeout = 0; 129 | int g_ng_idcp_cfg_server_lifetime = 0; 130 | int g_ng_idcp_cfg_server_login_retry = 0; 131 | int g_ng_idcp_cfg_server_reset_query_always = 0; 132 | int g_ng_idcp_cfg_server_round_robin = 0; 133 | int g_ng_idcp_cfg_so_reuseport = 0; 134 | int g_ng_idcp_cfg_stats_period = 0; 135 | int g_ng_idcp_cfg_suspend_timeout = 0; 136 | int g_ng_idcp_cfg_tcp_defer_accept = 0; 137 | int g_ng_idcp_cfg_tcp_keepcnt = 0; 138 | int g_ng_idcp_cfg_tcp_keepidle = 0; 139 | int g_ng_idcp_cfg_tcp_keepintvl = 0; 140 | int g_ng_idcp_cfg_tcp_socket_buffer = 0; 141 | int g_ng_idcp_cfg_tcp_user_timeout = 0; 142 | int g_ng_idcp_cfg_unix_socket_mode = 0; 143 | int g_ng_idcp_cfg_verbose = 0; 144 | 145 | /* ------------------------------ String GUCs ------------------------------ */ 146 | 147 | char *gp_ng_idcp_cfg_auth_dbname = NULL; 148 | char *gp_ng_idcp_cfg_auth_file = NULL; 149 | char *gp_ng_idcp_cfg_auth_hba_file = NULL; 150 | char *gp_ng_idcp_cfg_auth_ident_file = NULL; 151 | char *gp_ng_idcp_cfg_auth_query = NULL; 152 | char *gp_ng_idcp_cfg_auth_type = NULL; 153 | char *gp_ng_idcp_cfg_client_tls_ca_file = NULL; 154 | char *gp_ng_idcp_cfg_client_tls_cert_file = NULL; 155 | char *gp_ng_idcp_cfg_client_tls_ciphers = NULL; 156 | char *gp_ng_idcp_cfg_client_tls_dheparams = NULL; 157 | char *gp_ng_idcp_cfg_client_tls_ecdhcurve = NULL; 158 | char *gp_ng_idcp_cfg_client_tls_key_file = NULL; 159 | char *gp_ng_idcp_cfg_client_tls_protocols = NULL; 160 | char *gp_ng_idcp_cfg_client_tls_sslmode = NULL; 161 | char *gp_ng_idcp_cfg_ignore_startup_parameters = NULL; 162 | char *gp_ng_idcp_cfg_job_name = NULL; 163 | char *gp_ng_idcp_cfg_listen_addr = NULL; 164 | char *gp_ng_idcp_cfg_logfile = NULL; 165 | char *gp_ng_idcp_cfg_pidfile = NULL; 166 | char *gp_ng_idcp_cfg_resolv_conf = NULL; 167 | char *gp_ng_idcp_cfg_server_check_query = NULL; 168 | char *gp_ng_idcp_cfg_server_reset_query = NULL; 169 | char *gp_ng_idcp_cfg_server_tls_ca_file = NULL; 170 | char *gp_ng_idcp_cfg_server_tls_cert_file = NULL; 171 | char *gp_ng_idcp_cfg_server_tls_ciphers = NULL; 172 | char *gp_ng_idcp_cfg_server_tls_key_file = NULL; 173 | char *gp_ng_idcp_cfg_server_tls_protocols = NULL; 174 | char *gp_ng_idcp_cfg_server_tls_sslmode = NULL; 175 | char *gp_ng_idcp_cfg_service_name = NULL; 176 | char *gp_ng_idcp_cfg_tcp_keepalive = NULL; 177 | char *gp_ng_idcp_cfg_track_extra_parameters = NULL; 178 | char *gp_ng_idcp_cfg_unix_socket_dir = NULL; 179 | char *gp_ng_idcp_cfg_unix_socket_group = NULL; 180 | 181 | /* ========================================================================= */ 182 | /* -- PRIVATE VARIABLES ---------------------------------------------------- */ 183 | /* ========================================================================= */ 184 | 185 | /* ========================================================================= */ 186 | /* -- LOCAL VARIABLES ------------------------------------------------------ */ 187 | /* ========================================================================= */ 188 | 189 | /* ========================================================================= */ 190 | /* -- STATIC ASSERTIONS ---------------------------------------------------- */ 191 | /* ========================================================================= */ 192 | 193 | /* ========================================================================= */ 194 | /* -- PUBLIC FUNCTION DEFINITIONS ------------------------------------------ */ 195 | /* ========================================================================= */ 196 | 197 | /* ========================================================================= */ 198 | /* -- PRIVATE FUNCTION DEFINITIONS ----------------------------------------- */ 199 | /* ========================================================================= */ 200 | 201 | /* ========================================================================= */ 202 | /* -- LOCAL FUNCTION DEFINITIONS ------------------------------------------- */ 203 | /* ========================================================================= */ 204 | 205 | /* vim: set ts=2 et sw=2 ft=c: */ 206 | 207 | -------------------------------------------------------------------------------- /src/backend/utils/misc/guc.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= ** 2 | ** _ _______ ________________ ________ ** 3 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 4 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 5 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 6 | ** ** 7 | ** ========================================================================= ** 8 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 9 | ** ========================================================================= ** 10 | ** NEXTGRES Database Compatibility System ** 11 | ** Portions Copyright (C) NEXTGRES, INC. ** 12 | ** Portions Copyright (C) PostgresPro ** 13 | ** Portions Copyright (C) Konstantin Knizhnik ** 14 | ** All Rights Reserved. ** 15 | ** ** 16 | ** Permission to use, copy, modify, and/or distribute this software for any ** 17 | ** purpose is subject to the terms specified in the License Agreement. ** 18 | ** ========================================================================= */ 19 | 20 | /* 21 | * OVERVIEW 22 | * 23 | * ... 24 | * 25 | */ 26 | 27 | /* ========================================================================= */ 28 | /* -- INCLUSIONS ----------------------------------------------------------- */ 29 | /* ========================================================================= */ 30 | 31 | /* -------------------------- Interface Inclusions ------------------------- */ 32 | 33 | #include "postgres.h" 34 | #include "utils/guc.h" 35 | 36 | /* --------------------------- System Inclusions --------------------------- */ 37 | 38 | #include 39 | 40 | /* --------------------------- Project Inclusions -------------------------- */ 41 | 42 | #include "nextgres/idcp.h" 43 | #include "nextgres/idcp/util/guc.h" 44 | 45 | /* ========================================================================= */ 46 | /* -- LOCAL DEFINITIONS ---------------------------------------------------- */ 47 | /* ========================================================================= */ 48 | 49 | #define DEFAULT_IDCP_APPLICATION_NAME_ADD_HOST 0 50 | #define DEFAULT_IDCP_AUTH_DBNAME NULL 51 | #define DEFAULT_IDCP_AUTH_FILE NULL 52 | #define DEFAULT_IDCP_AUTH_HBA_FILE "pg_hba.conf" 53 | #define DEFAULT_IDCP_AUTH_IDENT_FILE NULL 54 | #define DEFAULT_IDCP_AUTH_QUERY "SELECT usename, passwd FROM pg_shadow WHERE usename=$1" 55 | #define DEFAULT_IDCP_AUTH_TYPE "md5" 56 | #define DEFAULT_IDCP_AUTODB_IDLE_TIMEOUT 3600 57 | #define DEFAULT_IDCP_CANCEL_WAIT_TIMEOUT 10 58 | #define DEFAULT_IDCP_CLIENT_IDLE_TIMEOUT 0 59 | #define DEFAULT_IDCP_CLIENT_LOGIN_TIMEOUT 60 60 | #define DEFAULT_IDCP_CLIENT_TLS_CA_FILE NULL 61 | #define DEFAULT_IDCP_CLIENT_TLS_CERT_FILE NULL 62 | #define DEFAULT_IDCP_CLIENT_TLS_CIPHERS "default" 63 | #define DEFAULT_IDCP_CLIENT_TLS_DHEPARAMS "auto" 64 | #define DEFAULT_IDCP_CLIENT_TLS_ECDHCURVE "auto" 65 | #define DEFAULT_IDCP_CLIENT_TLS_KEY_FILE NULL 66 | #define DEFAULT_IDCP_CLIENT_TLS_PROTOCOLS "secure" 67 | #define DEFAULT_IDCP_CLIENT_TLS_SSLMODE "disable" 68 | #define DEFAULT_IDCP_DEFAULT_POOL_SIZE 20 69 | #define DEFAULT_IDCP_DISABLE_PQEXEC 0 70 | #define DEFAULT_IDCP_DNS_MAX_TTL 15 71 | #define DEFAULT_IDCP_DNS_NXDOMAIN_TTL 15 72 | #define DEFAULT_IDCP_DNS_ZONE_CHECK_PERIOD 0 73 | #define DEFAULT_IDCP_IDLE_TRANSACTION_TIMEOUT 0 74 | #define DEFAULT_IDCP_IDLE_WORKER_TIMEOUT_IN_MS 0 75 | #define DEFAULT_IDCP_IGNORE_STARTUP_PARAMETERS NULL 76 | #define DEFAULT_IDCP_JOB_NAME "pgbouncer" 77 | #define DEFAULT_IDCP_LISTEN_ADDR NULL 78 | #define DEFAULT_IDCP_LISTEN_BACKLOG 128 79 | #define DEFAULT_IDCP_LISTEN_PORT 6432 80 | #define DEFAULT_IDCP_LOGFILE NULL 81 | #define DEFAULT_IDCP_LOG_CONNECTIONS 1 82 | #define DEFAULT_IDCP_LOG_DISCONNECTIONS 1 83 | #define DEFAULT_IDCP_LOG_POOLER_ERRORS 1 84 | #define DEFAULT_IDCP_LOG_STATS 1 85 | #define DEFAULT_IDCP_MAX_CLIENT_CONN 100 86 | #define DEFAULT_IDCP_MAX_DB_CONNECTIONS 0 87 | #define DEFAULT_IDCP_MAX_PACKET_SIZE 2147483647 88 | #define DEFAULT_IDCP_MAX_PREPARED_STATEMENTS 0 89 | #define DEFAULT_IDCP_MAX_SESSIONS_PER_THREAD 1000 90 | #define DEFAULT_IDCP_MAX_USER_CONNECTIONS 0 91 | #define DEFAULT_IDCP_MIN_POOL_SIZE 0 92 | #define DEFAULT_IDCP_MULTITENANT_PROXY false 93 | #define DEFAULT_IDCP_PEER_ID 0 94 | #define DEFAULT_IDCP_PIDFILE NULL 95 | #define DEFAULT_IDCP_PKT_BUF 4096 96 | #define DEFAULT_IDCP_POOL_MODE NG_IDCP_POOL_MODE_SESSION 97 | #define DEFAULT_IDCP_PORT 6543 98 | #define DEFAULT_IDCP_PROXYING_GUCS false 99 | #define DEFAULT_IDCP_QUERY_TIMEOUT 0 100 | #define DEFAULT_IDCP_QUERY_WAIT_TIMEOUT 120 101 | #define DEFAULT_IDCP_RESERVE_POOL_SIZE 0 102 | #define DEFAULT_IDCP_RESERVE_POOL_TIMEOUT 5 103 | #define DEFAULT_IDCP_RESOLV_CONF NULL 104 | #define DEFAULT_IDCP_RESTART_POOLER_ON_RELOAD false 105 | #define DEFAULT_IDCP_SBUF_LOOPCNT 5 106 | #define DEFAULT_IDCP_SERVER_CHECK_DELAY 30 107 | #define DEFAULT_IDCP_SERVER_CHECK_QUERY "SELECT 1" 108 | #define DEFAULT_IDCP_SERVER_CONNECT_TIMEOUT 15 109 | #define DEFAULT_IDCP_SERVER_FAST_CLOSE 0 110 | #define DEFAULT_IDCP_SERVER_IDLE_TIMEOUT 600 111 | #define DEFAULT_IDCP_SERVER_LIFETIME 3600 112 | #define DEFAULT_IDCP_SERVER_LOGIN_RETRY 15 113 | #define DEFAULT_IDCP_SERVER_RESET_QUERY "DISCARD ALL" 114 | #define DEFAULT_IDCP_SERVER_RESET_QUERY_ALWAYS 0 115 | #define DEFAULT_IDCP_SERVER_ROUND_ROBIN 0 116 | #define DEFAULT_IDCP_SERVER_TLS_CA_FILE NULL 117 | #define DEFAULT_IDCP_SERVER_TLS_CERT_FILE NULL 118 | #define DEFAULT_IDCP_SERVER_TLS_CIPHERS "default" 119 | #define DEFAULT_IDCP_SERVER_TLS_KEY_FILE NULL 120 | #define DEFAULT_IDCP_SERVER_TLS_PROTOCOLS "secure" 121 | #define DEFAULT_IDCP_SERVER_TLS_SSLMODE "prefer" 122 | #define DEFAULT_IDCP_SERVICE_NAME NULL 123 | #define DEFAULT_IDCP_SESSION_POOL_SIZE 10 124 | #define DEFAULT_IDCP_SESSION_SCHEDULER NG_IDCP_SESSION_SCHED_ROUND_ROBIN 125 | #define DEFAULT_IDCP_SO_REUSEPORT 0 126 | #define DEFAULT_IDCP_STATS_PERIOD 60 127 | #define DEFAULT_IDCP_SUSPEND_TIMEOUT 10 128 | #define DEFAULT_IDCP_TCP_DEFER_ACCEPT 0 129 | #define DEFAULT_IDCP_TCP_KEEPALIVE NULL 130 | #define DEFAULT_IDCP_TCP_KEEPCNT 0 131 | #define DEFAULT_IDCP_TCP_KEEPIDLE 0 132 | #define DEFAULT_IDCP_TCP_KEEPINTVL 0 133 | #define DEFAULT_IDCP_TCP_SOCKET_BUFFER 0 134 | #define DEFAULT_IDCP_TCP_USER_TIMEOUT 0 135 | #define DEFAULT_IDCP_THREAD_COUNT 0 136 | #define DEFAULT_IDCP_TRACK_EXTRA_PARAMETERS "IntervalStyle" 137 | #define DEFAULT_IDCP_UNIX_SOCKET_DIR "/tmp" 138 | #define DEFAULT_IDCP_UNIX_SOCKET_GROUP NULL 139 | #define DEFAULT_IDCP_UNIX_SOCKET_MODE 0777 140 | #define DEFAULT_IDCP_VERBOSE 0 141 | 142 | /* ========================================================================= */ 143 | /* -- LOCAL MACROS --------------------------------------------------------- */ 144 | /* ========================================================================= */ 145 | 146 | /* ========================================================================= */ 147 | /* -- LOCAL TYPEDEFS ------------------------------------------------------- */ 148 | /* ========================================================================= */ 149 | 150 | /* ========================================================================= */ 151 | /* -- LOCAL STRUCTURES ----------------------------------------------------- */ 152 | /* ========================================================================= */ 153 | 154 | /* ========================================================================= */ 155 | /* -- PRIVATE FUNCTION PROTOTYPES ------------------------------------------ */ 156 | /* ========================================================================= */ 157 | 158 | /* ========================================================================= */ 159 | /* -- LOCAL FUNCTION PROTOTYPES -------------------------------------------- */ 160 | /* ========================================================================= */ 161 | 162 | /* ========================================================================= */ 163 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 164 | /* ========================================================================= */ 165 | 166 | /* ========================================================================= */ 167 | /* -- PRIVATE VARIABLES ---------------------------------------------------- */ 168 | /* ========================================================================= */ 169 | 170 | /* ========================================================================= */ 171 | /* -- LOCAL VARIABLES ------------------------------------------------------ */ 172 | /* ========================================================================= */ 173 | 174 | /* ---------------------------- Enumerated GUCs ---------------------------- */ 175 | 176 | static const struct config_enum_entry ng_idcp_session_schedulers[] = { 177 | { "round-robin", NG_IDCP_SESSION_SCHED_ROUND_ROBIN, false }, 178 | { "random", NG_IDCP_SESSION_SCHED_RANDOM, false }, 179 | { "load-balancing", NG_IDCP_SESSION_SCHED_LOAD_BALANCING, false }, 180 | { NULL, 0, false } 181 | }; 182 | 183 | static const struct config_enum_entry ng_idcp_pool_modes[] = { 184 | { "session", NG_IDCP_POOL_MODE_SESSION, false }, 185 | { "transaction", NG_IDCP_POOL_MODE_TRANSACTION, false }, 186 | { "statement", NG_IDCP_POOL_MODE_STATEMENT, false }, 187 | { NULL, 0, false } 188 | }; 189 | 190 | /* ------------------------------ Boolean GUCs ----------------------------- */ 191 | 192 | static const struct ng_idcp_bool_guc_s { 193 | const char *name; 194 | const char *short_desc; 195 | const char *long_desc; 196 | bool *valueAddr; 197 | bool bootValue; 198 | GucContext context; 199 | int flags; 200 | GucBoolCheckHook check_hook; 201 | GucBoolAssignHook assign_hook; 202 | GucShowHook show_hook; 203 | } ng_idcp_bool_gucs[] = { 204 | { 205 | .name = "nextgres_idcp.restart_pooler_on_reload", 206 | .short_desc = gettext_noop("Restart session pool workers on pg_reload_conf()"), 207 | .long_desc = gettext_noop("Restart session pool workers on pg_reload_conf()"), 208 | .valueAddr = &g_ng_idcp_restart_pooler_on_reload, 209 | .bootValue = DEFAULT_IDCP_RESTART_POOLER_ON_RELOAD, 210 | .context = PGC_POSTMASTER, 211 | .flags = 0, 212 | .check_hook = NULL, 213 | .assign_hook = NULL, 214 | .show_hook = NULL, 215 | }, 216 | { 217 | .name = "nextgres_idcp.proxying_gucs", 218 | .short_desc = gettext_noop("Support setting parameters in connection pooler sessions."), 219 | .long_desc = gettext_noop("Support setting parameters in connection pooler sessions."), 220 | .valueAddr = &g_ng_idcp_proxying_gucs, 221 | .bootValue = DEFAULT_IDCP_PROXYING_GUCS, 222 | .context = PGC_POSTMASTER, 223 | .flags = 0, 224 | .check_hook = NULL, 225 | .assign_hook = NULL, 226 | .show_hook = NULL, 227 | }, 228 | { 229 | .name = "nextgres_idcp.multitenant_proxy", 230 | .short_desc = gettext_noop("One pool worker can serve clients with different roles"), 231 | .long_desc = gettext_noop("One pool worker can serve clients with different roles"), 232 | .valueAddr = &g_ng_idcp_multitenant_proxy, 233 | .bootValue = DEFAULT_IDCP_MULTITENANT_PROXY, 234 | .context = PGC_POSTMASTER, 235 | .flags = 0, 236 | .check_hook = NULL, 237 | .assign_hook = NULL, 238 | .show_hook = NULL, 239 | }, 240 | }; /* ng_idcp_bool_gucs */ 241 | 242 | /* ------------------------------ Integer GUCs ----------------------------- */ 243 | 244 | static const struct ng_idcp_int_guc_s { 245 | const char *name; 246 | const char *short_desc; 247 | const char *long_desc; 248 | int *valueAddr; 249 | int bootValue; 250 | int minValue; 251 | int maxValue; 252 | GucContext context; 253 | int flags; 254 | GucIntCheckHook check_hook; 255 | GucIntAssignHook assign_hook; 256 | GucShowHook show_hook; 257 | } ng_idcp_int_gucs[] = { 258 | { 259 | .name = "nextgres_idcp.application_name_add_host", 260 | .short_desc = gettext_noop(""), 261 | .long_desc = gettext_noop(""), 262 | .valueAddr = &g_ng_idcp_cfg_application_name_add_host, 263 | .bootValue = DEFAULT_IDCP_APPLICATION_NAME_ADD_HOST, 264 | .minValue = 0, 265 | .maxValue = 65535, 266 | .context = PGC_POSTMASTER, 267 | .flags = 0, 268 | .check_hook = NULL, 269 | .assign_hook = NULL, 270 | .show_hook = NULL 271 | }, 272 | { 273 | .name = "nextgres_idcp.autodb_idle_timeout", 274 | .short_desc = gettext_noop(""), 275 | .long_desc = gettext_noop(""), 276 | .valueAddr = &g_ng_idcp_cfg_autodb_idle_timeout, 277 | .bootValue = DEFAULT_IDCP_AUTODB_IDLE_TIMEOUT, 278 | .minValue = 0, 279 | .maxValue = 65535, 280 | .context = PGC_POSTMASTER, 281 | .flags = 0, 282 | .check_hook = NULL, 283 | .assign_hook = NULL, 284 | .show_hook = NULL 285 | }, 286 | { 287 | .name = "nextgres_idcp.cancel_wait_timeout", 288 | .short_desc = gettext_noop(""), 289 | .long_desc = gettext_noop(""), 290 | .valueAddr = &g_ng_idcp_cfg_cancel_wait_timeout, 291 | .bootValue = DEFAULT_IDCP_CANCEL_WAIT_TIMEOUT, 292 | .minValue = 0, 293 | .maxValue = 65535, 294 | .context = PGC_POSTMASTER, 295 | .flags = 0, 296 | .check_hook = NULL, 297 | .assign_hook = NULL, 298 | .show_hook = NULL 299 | }, 300 | { 301 | .name = "nextgres_idcp.client_idle_timeout", 302 | .short_desc = gettext_noop(""), 303 | .long_desc = gettext_noop(""), 304 | .valueAddr = &g_ng_idcp_cfg_client_idle_timeout, 305 | .bootValue = DEFAULT_IDCP_CLIENT_IDLE_TIMEOUT, 306 | .minValue = 0, 307 | .maxValue = 65535, 308 | .context = PGC_POSTMASTER, 309 | .flags = 0, 310 | .check_hook = NULL, 311 | .assign_hook = NULL, 312 | .show_hook = NULL 313 | }, 314 | { 315 | .name = "nextgres_idcp.client_login_timeout", 316 | .short_desc = gettext_noop(""), 317 | .long_desc = gettext_noop(""), 318 | .valueAddr = &g_ng_idcp_cfg_client_login_timeout, 319 | .bootValue = DEFAULT_IDCP_CLIENT_LOGIN_TIMEOUT, 320 | .minValue = 0, 321 | .maxValue = 65535, 322 | .context = PGC_POSTMASTER, 323 | .flags = 0, 324 | .check_hook = NULL, 325 | .assign_hook = NULL, 326 | .show_hook = NULL 327 | }, 328 | { 329 | .name = "nextgres_idcp.default_pool_size", 330 | .short_desc = gettext_noop(""), 331 | .long_desc = gettext_noop(""), 332 | .valueAddr = &g_ng_idcp_cfg_default_pool_size, 333 | .bootValue = DEFAULT_IDCP_DEFAULT_POOL_SIZE, 334 | .minValue = 0, 335 | .maxValue = 65535, 336 | .context = PGC_POSTMASTER, 337 | .flags = 0, 338 | .check_hook = NULL, 339 | .assign_hook = NULL, 340 | .show_hook = NULL 341 | }, 342 | { 343 | .name = "nextgres_idcp.disable_pqexec", 344 | .short_desc = gettext_noop(""), 345 | .long_desc = gettext_noop(""), 346 | .valueAddr = &g_ng_idcp_cfg_disable_pqexec, 347 | .bootValue = DEFAULT_IDCP_DISABLE_PQEXEC, 348 | .minValue = 0, 349 | .maxValue = 65535, 350 | .context = PGC_POSTMASTER, 351 | .flags = 0, 352 | .check_hook = NULL, 353 | .assign_hook = NULL, 354 | .show_hook = NULL 355 | }, 356 | { 357 | .name = "nextgres_idcp.dns_max_ttl", 358 | .short_desc = gettext_noop(""), 359 | .long_desc = gettext_noop(""), 360 | .valueAddr = &g_ng_idcp_cfg_dns_max_ttl, 361 | .bootValue = DEFAULT_IDCP_DNS_MAX_TTL, 362 | .minValue = 0, 363 | .maxValue = 65535, 364 | .context = PGC_POSTMASTER, 365 | .flags = 0, 366 | .check_hook = NULL, 367 | .assign_hook = NULL, 368 | .show_hook = NULL 369 | }, 370 | { 371 | .name = "nextgres_idcp.dns_nxdomain_ttl", 372 | .short_desc = gettext_noop(""), 373 | .long_desc = gettext_noop(""), 374 | .valueAddr = &g_ng_idcp_cfg_dns_nxdomain_ttl, 375 | .bootValue = DEFAULT_IDCP_DNS_NXDOMAIN_TTL, 376 | .minValue = 0, 377 | .maxValue = 65535, 378 | .context = PGC_POSTMASTER, 379 | .flags = 0, 380 | .check_hook = NULL, 381 | .assign_hook = NULL, 382 | .show_hook = NULL 383 | }, 384 | { 385 | .name = "nextgres_idcp.dns_zone_check_period", 386 | .short_desc = gettext_noop(""), 387 | .long_desc = gettext_noop(""), 388 | .valueAddr = &g_ng_idcp_cfg_dns_zone_check_period, 389 | .bootValue = DEFAULT_IDCP_DNS_ZONE_CHECK_PERIOD, 390 | .minValue = 0, 391 | .maxValue = 65535, 392 | .context = PGC_POSTMASTER, 393 | .flags = 0, 394 | .check_hook = NULL, 395 | .assign_hook = NULL, 396 | .show_hook = NULL 397 | }, 398 | { 399 | .name = "nextgres_idcp.idle_transaction_timeout", 400 | .short_desc = gettext_noop(""), 401 | .long_desc = gettext_noop(""), 402 | .valueAddr = &g_ng_idcp_cfg_idle_transaction_timeout, 403 | .bootValue = DEFAULT_IDCP_IDLE_TRANSACTION_TIMEOUT, 404 | .minValue = 0, 405 | .maxValue = 65535, 406 | .context = PGC_POSTMASTER, 407 | .flags = 0, 408 | .check_hook = NULL, 409 | .assign_hook = NULL, 410 | .show_hook = NULL 411 | }, 412 | { 413 | .name = "nextgres_idcp.listen_backlog", 414 | .short_desc = gettext_noop(""), 415 | .long_desc = gettext_noop(""), 416 | .valueAddr = &g_ng_idcp_cfg_listen_backlog, 417 | .bootValue = DEFAULT_IDCP_LISTEN_BACKLOG, 418 | .minValue = 0, 419 | .maxValue = 65535, 420 | .context = PGC_POSTMASTER, 421 | .flags = 0, 422 | .check_hook = NULL, 423 | .assign_hook = NULL, 424 | .show_hook = NULL 425 | }, 426 | { 427 | .name = "nextgres_idcp.listen_port", 428 | .short_desc = gettext_noop(""), 429 | .long_desc = gettext_noop(""), 430 | .valueAddr = &g_ng_idcp_cfg_listen_port, 431 | .bootValue = DEFAULT_IDCP_LISTEN_PORT, 432 | .minValue = 0, 433 | .maxValue = 65535, 434 | .context = PGC_POSTMASTER, 435 | .flags = 0, 436 | .check_hook = NULL, 437 | .assign_hook = NULL, 438 | .show_hook = NULL 439 | }, 440 | { 441 | .name = "nextgres_idcp.log_connections", 442 | .short_desc = gettext_noop(""), 443 | .long_desc = gettext_noop(""), 444 | .valueAddr = &g_ng_idcp_cfg_log_connections, 445 | .bootValue = DEFAULT_IDCP_LOG_CONNECTIONS, 446 | .minValue = 0, 447 | .maxValue = 65535, 448 | .context = PGC_POSTMASTER, 449 | .flags = 0, 450 | .check_hook = NULL, 451 | .assign_hook = NULL, 452 | .show_hook = NULL 453 | }, 454 | { 455 | .name = "nextgres_idcp.log_disconnections", 456 | .short_desc = gettext_noop(""), 457 | .long_desc = gettext_noop(""), 458 | .valueAddr = &g_ng_idcp_cfg_log_disconnections, 459 | .bootValue = DEFAULT_IDCP_LOG_DISCONNECTIONS, 460 | .minValue = 0, 461 | .maxValue = 65535, 462 | .context = PGC_POSTMASTER, 463 | .flags = 0, 464 | .check_hook = NULL, 465 | .assign_hook = NULL, 466 | .show_hook = NULL 467 | }, 468 | { 469 | .name = "nextgres_idcp.log_pooler_errors", 470 | .short_desc = gettext_noop(""), 471 | .long_desc = gettext_noop(""), 472 | .valueAddr = &g_ng_idcp_cfg_log_pooler_errors, 473 | .bootValue = DEFAULT_IDCP_LOG_POOLER_ERRORS, 474 | .minValue = 0, 475 | .maxValue = 65535, 476 | .context = PGC_POSTMASTER, 477 | .flags = 0, 478 | .check_hook = NULL, 479 | .assign_hook = NULL, 480 | .show_hook = NULL 481 | }, 482 | { 483 | .name = "nextgres_idcp.log_stats", 484 | .short_desc = gettext_noop(""), 485 | .long_desc = gettext_noop(""), 486 | .valueAddr = &g_ng_idcp_cfg_log_stats, 487 | .bootValue = DEFAULT_IDCP_LOG_STATS, 488 | .minValue = 0, 489 | .maxValue = 65535, 490 | .context = PGC_POSTMASTER, 491 | .flags = 0, 492 | .check_hook = NULL, 493 | .assign_hook = NULL, 494 | .show_hook = NULL 495 | }, 496 | { 497 | .name = "nextgres_idcp.max_client_conn", 498 | .short_desc = gettext_noop(""), 499 | .long_desc = gettext_noop(""), 500 | .valueAddr = &g_ng_idcp_cfg_max_client_conn, 501 | .bootValue = DEFAULT_IDCP_MAX_CLIENT_CONN, 502 | .minValue = 0, 503 | .maxValue = 65535, 504 | .context = PGC_POSTMASTER, 505 | .flags = 0, 506 | .check_hook = NULL, 507 | .assign_hook = NULL, 508 | .show_hook = NULL 509 | }, 510 | { 511 | .name = "nextgres_idcp.max_db_connections", 512 | .short_desc = gettext_noop(""), 513 | .long_desc = gettext_noop(""), 514 | .valueAddr = &g_ng_idcp_cfg_max_db_connections, 515 | .bootValue = DEFAULT_IDCP_MAX_DB_CONNECTIONS, 516 | .minValue = 0, 517 | .maxValue = 65535, 518 | .context = PGC_POSTMASTER, 519 | .flags = 0, 520 | .check_hook = NULL, 521 | .assign_hook = NULL, 522 | .show_hook = NULL 523 | }, 524 | { 525 | .name = "nextgres_idcp.max_packet_size", 526 | .short_desc = gettext_noop(""), 527 | .long_desc = gettext_noop(""), 528 | .valueAddr = &g_ng_idcp_cfg_max_packet_size, 529 | .bootValue = DEFAULT_IDCP_MAX_PACKET_SIZE, 530 | .minValue = 0, 531 | .maxValue = INT_MAX, 532 | .context = PGC_POSTMASTER, 533 | .flags = 0, 534 | .check_hook = NULL, 535 | .assign_hook = NULL, 536 | .show_hook = NULL 537 | }, 538 | { 539 | .name = "nextgres_idcp.max_prepared_statements", 540 | .short_desc = gettext_noop(""), 541 | .long_desc = gettext_noop(""), 542 | .valueAddr = &g_ng_idcp_cfg_max_prepared_statements, 543 | .bootValue = DEFAULT_IDCP_MAX_PREPARED_STATEMENTS, 544 | .minValue = 0, 545 | .maxValue = 65535, 546 | .context = PGC_POSTMASTER, 547 | .flags = 0, 548 | .check_hook = NULL, 549 | .assign_hook = NULL, 550 | .show_hook = NULL 551 | }, 552 | { 553 | .name = "nextgres_idcp.max_user_connections", 554 | .short_desc = gettext_noop(""), 555 | .long_desc = gettext_noop(""), 556 | .valueAddr = &g_ng_idcp_cfg_max_user_connections, 557 | .bootValue = DEFAULT_IDCP_MAX_USER_CONNECTIONS, 558 | .minValue = 0, 559 | .maxValue = 65535, 560 | .context = PGC_POSTMASTER, 561 | .flags = 0, 562 | .check_hook = NULL, 563 | .assign_hook = NULL, 564 | .show_hook = NULL 565 | }, 566 | { 567 | .name = "nextgres_idcp.min_pool_size", 568 | .short_desc = gettext_noop(""), 569 | .long_desc = gettext_noop(""), 570 | .valueAddr = &g_ng_idcp_cfg_min_pool_size, 571 | .bootValue = DEFAULT_IDCP_MIN_POOL_SIZE, 572 | .minValue = 0, 573 | .maxValue = 65535, 574 | .context = PGC_POSTMASTER, 575 | .flags = 0, 576 | .check_hook = NULL, 577 | .assign_hook = NULL, 578 | .show_hook = NULL 579 | }, 580 | { 581 | .name = "nextgres_idcp.peer_id", 582 | .short_desc = gettext_noop(""), 583 | .long_desc = gettext_noop(""), 584 | .valueAddr = &g_ng_idcp_cfg_peer_id, 585 | .bootValue = DEFAULT_IDCP_PEER_ID, 586 | .minValue = 0, 587 | .maxValue = 65535, 588 | .context = PGC_POSTMASTER, 589 | .flags = 0, 590 | .check_hook = NULL, 591 | .assign_hook = NULL, 592 | .show_hook = NULL 593 | }, 594 | { 595 | .name = "nextgres_idcp.pkt_buf", 596 | .short_desc = gettext_noop(""), 597 | .long_desc = gettext_noop(""), 598 | .valueAddr = &g_ng_idcp_cfg_pkt_buf, 599 | .bootValue = DEFAULT_IDCP_PKT_BUF, 600 | .minValue = 0, 601 | .maxValue = 65535, 602 | .context = PGC_POSTMASTER, 603 | .flags = 0, 604 | .check_hook = NULL, 605 | .assign_hook = NULL, 606 | .show_hook = NULL 607 | }, 608 | { 609 | .name = "nextgres_idcp.query_timeout", 610 | .short_desc = gettext_noop(""), 611 | .long_desc = gettext_noop(""), 612 | .valueAddr = &g_ng_idcp_cfg_query_timeout, 613 | .bootValue = DEFAULT_IDCP_QUERY_TIMEOUT, 614 | .minValue = 0, 615 | .maxValue = 65535, 616 | .context = PGC_POSTMASTER, 617 | .flags = 0, 618 | .check_hook = NULL, 619 | .assign_hook = NULL, 620 | .show_hook = NULL 621 | }, 622 | { 623 | .name = "nextgres_idcp.query_wait_timeout", 624 | .short_desc = gettext_noop(""), 625 | .long_desc = gettext_noop(""), 626 | .valueAddr = &g_ng_idcp_cfg_query_wait_timeout, 627 | .bootValue = DEFAULT_IDCP_QUERY_WAIT_TIMEOUT, 628 | .minValue = 0, 629 | .maxValue = 65535, 630 | .context = PGC_POSTMASTER, 631 | .flags = 0, 632 | .check_hook = NULL, 633 | .assign_hook = NULL, 634 | .show_hook = NULL 635 | }, 636 | { 637 | .name = "nextgres_idcp.reserve_pool_size", 638 | .short_desc = gettext_noop(""), 639 | .long_desc = gettext_noop(""), 640 | .valueAddr = &g_ng_idcp_cfg_reserve_pool_size, 641 | .bootValue = DEFAULT_IDCP_RESERVE_POOL_SIZE, 642 | .minValue = 0, 643 | .maxValue = 65535, 644 | .context = PGC_POSTMASTER, 645 | .flags = 0, 646 | .check_hook = NULL, 647 | .assign_hook = NULL, 648 | .show_hook = NULL 649 | }, 650 | { 651 | .name = "nextgres_idcp.reserve_pool_timeout", 652 | .short_desc = gettext_noop(""), 653 | .long_desc = gettext_noop(""), 654 | .valueAddr = &g_ng_idcp_cfg_reserve_pool_timeout, 655 | .bootValue = DEFAULT_IDCP_RESERVE_POOL_TIMEOUT, 656 | .minValue = 0, 657 | .maxValue = 65535, 658 | .context = PGC_POSTMASTER, 659 | .flags = 0, 660 | .check_hook = NULL, 661 | .assign_hook = NULL, 662 | .show_hook = NULL 663 | }, 664 | { 665 | .name = "nextgres_idcp.sbuf_loopcnt", 666 | .short_desc = gettext_noop(""), 667 | .long_desc = gettext_noop(""), 668 | .valueAddr = &g_ng_idcp_cfg_sbuf_loopcnt, 669 | .bootValue = DEFAULT_IDCP_SBUF_LOOPCNT, 670 | .minValue = 0, 671 | .maxValue = 65535, 672 | .context = PGC_POSTMASTER, 673 | .flags = 0, 674 | .check_hook = NULL, 675 | .assign_hook = NULL, 676 | .show_hook = NULL 677 | }, 678 | { 679 | .name = "nextgres_idcp.server_check_delay", 680 | .short_desc = gettext_noop(""), 681 | .long_desc = gettext_noop(""), 682 | .valueAddr = &g_ng_idcp_cfg_server_check_delay, 683 | .bootValue = DEFAULT_IDCP_SERVER_CHECK_DELAY, 684 | .minValue = 0, 685 | .maxValue = 65535, 686 | .context = PGC_POSTMASTER, 687 | .flags = 0, 688 | .check_hook = NULL, 689 | .assign_hook = NULL, 690 | .show_hook = NULL 691 | }, 692 | { 693 | .name = "nextgres_idcp.server_connect_timeout", 694 | .short_desc = gettext_noop(""), 695 | .long_desc = gettext_noop(""), 696 | .valueAddr = &g_ng_idcp_cfg_server_connect_timeout, 697 | .bootValue = DEFAULT_IDCP_SERVER_CONNECT_TIMEOUT, 698 | .minValue = 0, 699 | .maxValue = 65535, 700 | .context = PGC_POSTMASTER, 701 | .flags = 0, 702 | .check_hook = NULL, 703 | .assign_hook = NULL, 704 | .show_hook = NULL 705 | }, 706 | { 707 | .name = "nextgres_idcp.server_fast_close", 708 | .short_desc = gettext_noop(""), 709 | .long_desc = gettext_noop(""), 710 | .valueAddr = &g_ng_idcp_cfg_server_fast_close, 711 | .bootValue = DEFAULT_IDCP_SERVER_FAST_CLOSE, 712 | .minValue = 0, 713 | .maxValue = 65535, 714 | .context = PGC_POSTMASTER, 715 | .flags = 0, 716 | .check_hook = NULL, 717 | .assign_hook = NULL, 718 | .show_hook = NULL 719 | }, 720 | { 721 | .name = "nextgres_idcp.server_idle_timeout", 722 | .short_desc = gettext_noop(""), 723 | .long_desc = gettext_noop(""), 724 | .valueAddr = &g_ng_idcp_cfg_server_idle_timeout, 725 | .bootValue = DEFAULT_IDCP_SERVER_IDLE_TIMEOUT, 726 | .minValue = 0, 727 | .maxValue = 65535, 728 | .context = PGC_POSTMASTER, 729 | .flags = 0, 730 | .check_hook = NULL, 731 | .assign_hook = NULL, 732 | .show_hook = NULL 733 | }, 734 | { 735 | .name = "nextgres_idcp.server_lifetime", 736 | .short_desc = gettext_noop(""), 737 | .long_desc = gettext_noop(""), 738 | .valueAddr = &g_ng_idcp_cfg_server_lifetime, 739 | .bootValue = DEFAULT_IDCP_SERVER_LIFETIME, 740 | .minValue = 0, 741 | .maxValue = 65535, 742 | .context = PGC_POSTMASTER, 743 | .flags = 0, 744 | .check_hook = NULL, 745 | .assign_hook = NULL, 746 | .show_hook = NULL 747 | }, 748 | { 749 | .name = "nextgres_idcp.server_login_retry", 750 | .short_desc = gettext_noop(""), 751 | .long_desc = gettext_noop(""), 752 | .valueAddr = &g_ng_idcp_cfg_server_login_retry, 753 | .bootValue = DEFAULT_IDCP_SERVER_LOGIN_RETRY, 754 | .minValue = 0, 755 | .maxValue = 65535, 756 | .context = PGC_POSTMASTER, 757 | .flags = 0, 758 | .check_hook = NULL, 759 | .assign_hook = NULL, 760 | .show_hook = NULL 761 | }, 762 | { 763 | .name = "nextgres_idcp.server_reset_query_always", 764 | .short_desc = gettext_noop(""), 765 | .long_desc = gettext_noop(""), 766 | .valueAddr = &g_ng_idcp_cfg_server_reset_query_always, 767 | .bootValue = DEFAULT_IDCP_SERVER_RESET_QUERY_ALWAYS, 768 | .minValue = 0, 769 | .maxValue = 65535, 770 | .context = PGC_POSTMASTER, 771 | .flags = 0, 772 | .check_hook = NULL, 773 | .assign_hook = NULL, 774 | .show_hook = NULL 775 | }, 776 | { 777 | .name = "nextgres_idcp.server_round_robin", 778 | .short_desc = gettext_noop(""), 779 | .long_desc = gettext_noop(""), 780 | .valueAddr = &g_ng_idcp_cfg_server_round_robin, 781 | .bootValue = DEFAULT_IDCP_SERVER_ROUND_ROBIN, 782 | .minValue = 0, 783 | .maxValue = 65535, 784 | .context = PGC_POSTMASTER, 785 | .flags = 0, 786 | .check_hook = NULL, 787 | .assign_hook = NULL, 788 | .show_hook = NULL 789 | }, 790 | { 791 | .name = "nextgres_idcp.so_reuseport", 792 | .short_desc = gettext_noop(""), 793 | .long_desc = gettext_noop(""), 794 | .valueAddr = &g_ng_idcp_cfg_so_reuseport, 795 | .bootValue = DEFAULT_IDCP_SO_REUSEPORT, 796 | .minValue = 0, 797 | .maxValue = 65535, 798 | .context = PGC_POSTMASTER, 799 | .flags = 0, 800 | .check_hook = NULL, 801 | .assign_hook = NULL, 802 | .show_hook = NULL 803 | }, 804 | { 805 | .name = "nextgres_idcp.stats_period", 806 | .short_desc = gettext_noop(""), 807 | .long_desc = gettext_noop(""), 808 | .valueAddr = &g_ng_idcp_cfg_stats_period, 809 | .bootValue = DEFAULT_IDCP_STATS_PERIOD, 810 | .minValue = 0, 811 | .maxValue = 65535, 812 | .context = PGC_POSTMASTER, 813 | .flags = 0, 814 | .check_hook = NULL, 815 | .assign_hook = NULL, 816 | .show_hook = NULL 817 | }, 818 | { 819 | .name = "nextgres_idcp.suspend_timeout", 820 | .short_desc = gettext_noop(""), 821 | .long_desc = gettext_noop(""), 822 | .valueAddr = &g_ng_idcp_cfg_suspend_timeout, 823 | .bootValue = DEFAULT_IDCP_SUSPEND_TIMEOUT, 824 | .minValue = 0, 825 | .maxValue = 65535, 826 | .context = PGC_POSTMASTER, 827 | .flags = 0, 828 | .check_hook = NULL, 829 | .assign_hook = NULL, 830 | .show_hook = NULL 831 | }, 832 | { 833 | .name = "nextgres_idcp.tcp_defer_accept", 834 | .short_desc = gettext_noop(""), 835 | .long_desc = gettext_noop(""), 836 | .valueAddr = &g_ng_idcp_cfg_tcp_defer_accept, 837 | .bootValue = DEFAULT_IDCP_TCP_DEFER_ACCEPT, 838 | .minValue = 0, 839 | .maxValue = 65535, 840 | .context = PGC_POSTMASTER, 841 | .flags = 0, 842 | .check_hook = NULL, 843 | .assign_hook = NULL, 844 | .show_hook = NULL 845 | }, 846 | { 847 | .name = "nextgres_idcp.tcp_keepcnt", 848 | .short_desc = gettext_noop(""), 849 | .long_desc = gettext_noop(""), 850 | .valueAddr = &g_ng_idcp_cfg_tcp_keepcnt, 851 | .bootValue = DEFAULT_IDCP_TCP_KEEPCNT, 852 | .minValue = 0, 853 | .maxValue = 65535, 854 | .context = PGC_POSTMASTER, 855 | .flags = 0, 856 | .check_hook = NULL, 857 | .assign_hook = NULL, 858 | .show_hook = NULL 859 | }, 860 | { 861 | .name = "nextgres_idcp.tcp_keepidle", 862 | .short_desc = gettext_noop(""), 863 | .long_desc = gettext_noop(""), 864 | .valueAddr = &g_ng_idcp_cfg_tcp_keepidle, 865 | .bootValue = DEFAULT_IDCP_TCP_KEEPIDLE, 866 | .minValue = 0, 867 | .maxValue = 65535, 868 | .context = PGC_POSTMASTER, 869 | .flags = 0, 870 | .check_hook = NULL, 871 | .assign_hook = NULL, 872 | .show_hook = NULL 873 | }, 874 | { 875 | .name = "nextgres_idcp.tcp_keepintvl", 876 | .short_desc = gettext_noop(""), 877 | .long_desc = gettext_noop(""), 878 | .valueAddr = &g_ng_idcp_cfg_tcp_keepintvl, 879 | .bootValue = DEFAULT_IDCP_TCP_KEEPINTVL, 880 | .minValue = 0, 881 | .maxValue = 65535, 882 | .context = PGC_POSTMASTER, 883 | .flags = 0, 884 | .check_hook = NULL, 885 | .assign_hook = NULL, 886 | .show_hook = NULL 887 | }, 888 | { 889 | .name = "nextgres_idcp.tcp_socket_buffer", 890 | .short_desc = gettext_noop(""), 891 | .long_desc = gettext_noop(""), 892 | .valueAddr = &g_ng_idcp_cfg_tcp_socket_buffer, 893 | .bootValue = DEFAULT_IDCP_TCP_SOCKET_BUFFER, 894 | .minValue = 0, 895 | .maxValue = 65535, 896 | .context = PGC_POSTMASTER, 897 | .flags = 0, 898 | .check_hook = NULL, 899 | .assign_hook = NULL, 900 | .show_hook = NULL 901 | }, 902 | { 903 | .name = "nextgres_idcp.tcp_user_timeout", 904 | .short_desc = gettext_noop(""), 905 | .long_desc = gettext_noop(""), 906 | .valueAddr = &g_ng_idcp_cfg_tcp_user_timeout, 907 | .bootValue = DEFAULT_IDCP_TCP_USER_TIMEOUT, 908 | .minValue = 0, 909 | .maxValue = 65535, 910 | .context = PGC_POSTMASTER, 911 | .flags = 0, 912 | .check_hook = NULL, 913 | .assign_hook = NULL, 914 | .show_hook = NULL 915 | }, 916 | { 917 | .name = "nextgres_idcp.unix_socket_mode", 918 | .short_desc = gettext_noop(""), 919 | .long_desc = gettext_noop(""), 920 | .valueAddr = &g_ng_idcp_cfg_unix_socket_mode, 921 | .bootValue = DEFAULT_IDCP_UNIX_SOCKET_MODE, 922 | .minValue = 0, 923 | .maxValue = 65535, 924 | .context = PGC_POSTMASTER, 925 | .flags = 0, 926 | .check_hook = NULL, 927 | .assign_hook = NULL, 928 | .show_hook = NULL 929 | }, 930 | { 931 | .name = "nextgres_idcp.verbose", 932 | .short_desc = gettext_noop(""), 933 | .long_desc = gettext_noop(""), 934 | .valueAddr = &g_ng_idcp_cfg_verbose, 935 | .bootValue = DEFAULT_IDCP_VERBOSE, 936 | .minValue = 0, 937 | .maxValue = 65535, 938 | .context = PGC_POSTMASTER, 939 | .flags = 0, 940 | .check_hook = NULL, 941 | .assign_hook = NULL, 942 | .show_hook = NULL 943 | }, 944 | 945 | { 946 | .name = "nextgres_idcp.session_pool_size", 947 | .short_desc = gettext_noop("Sets number of backends serving client sessions."), 948 | .long_desc = gettext_noop("If non-zero then session pooling will be used: " 949 | "client connections will be redirected to one of the backends and " 950 | "maximal number of backends is determined by this parameter." 951 | "Launched backend are never terminated even in case of no active sessions."), 952 | .valueAddr = &g_ng_idcp_cfg_session_pool_size, 953 | .bootValue = DEFAULT_IDCP_SESSION_POOL_SIZE, 954 | .minValue = 0, 955 | .maxValue = INT_MAX, 956 | .context = PGC_POSTMASTER, 957 | .flags = 0, 958 | .check_hook = NULL, 959 | .assign_hook = NULL, 960 | .show_hook = NULL 961 | }, 962 | { 963 | .name = "nextgres_idcp.idle_pool_worker_timeout", 964 | .short_desc = gettext_noop("Sets the maximum allowed duration of any idling connection pool worker."), 965 | .long_desc = gettext_noop("A value of 0 turns off the timeout."), 966 | .valueAddr = &g_ng_idcp_cfg_idle_worker_timeout_in_ms, 967 | .bootValue = DEFAULT_IDCP_IDLE_WORKER_TIMEOUT_IN_MS, 968 | .minValue = 0, 969 | .maxValue = INT_MAX, 970 | .context = PGC_POSTMASTER, 971 | .flags = 0, 972 | .check_hook = NULL, 973 | .assign_hook = NULL, 974 | .show_hook = NULL 975 | }, 976 | { 977 | .name = "nextgres_idcp.thread_count", 978 | .short_desc = gettext_noop("Sets number of connection proxies."), 979 | .long_desc = gettext_noop("Postmaster spawns separate worker process for each proxy. Postmaster scatters connections between proxies using one of scheduling policies (round-robin, random, load-balancing)." 980 | "Each proxy launches its own subset of backends. So maximal number of non-tainted backends is " 981 | "session_pool_size*connection_proxies*databases*roles."), 982 | .valueAddr = &g_ng_idcp_cfg_thread_count, 983 | .bootValue = DEFAULT_IDCP_THREAD_COUNT, 984 | .minValue = 0, 985 | .maxValue = INT_MAX, 986 | .context = PGC_POSTMASTER, 987 | .flags = 0, 988 | .check_hook = NULL, 989 | .assign_hook = NULL, 990 | .show_hook = NULL 991 | }, 992 | { 993 | .name = "nextgres_idcp.max_sessions_per_thread", 994 | .short_desc = gettext_noop("Sets the maximum number of client session."), 995 | .long_desc = gettext_noop("Maximal number of client sessions which can be handled by one connection proxy." 996 | "It can be greater than max_connections and actually be arbitrary large."), 997 | .valueAddr = &g_ng_idcp_cfg_max_sessions_per_thread, 998 | .bootValue = DEFAULT_IDCP_MAX_SESSIONS_PER_THREAD, 999 | .minValue = 1, 1000 | .maxValue = INT_MAX, 1001 | .context = PGC_POSTMASTER, 1002 | .flags = 0, 1003 | .check_hook = NULL, 1004 | .assign_hook = NULL, 1005 | .show_hook = NULL 1006 | }, 1007 | { 1008 | .name = "nextgres_idcp.port", 1009 | .short_desc = gettext_noop("Sets the TCP port for the connection pooler."), 1010 | .long_desc = gettext_noop("Sets the TCP port for the connection pooler."), 1011 | .valueAddr = &g_ng_idcp_cfg_port, 1012 | .bootValue = DEFAULT_IDCP_PORT, 1013 | .minValue = 1, 1014 | .maxValue = INT_MAX, 1015 | .context = PGC_POSTMASTER, 1016 | .flags = 0, 1017 | .check_hook = NULL, 1018 | .assign_hook = NULL, 1019 | .show_hook = NULL 1020 | } 1021 | }; /* ng_idcp_int_gucs */ 1022 | 1023 | /* ------------------------------ String GUCs ------------------------------ */ 1024 | 1025 | static const struct ng_idcp_string_guc_s { 1026 | const char *name; 1027 | const char *short_desc; 1028 | const char *long_desc; 1029 | char **valueAddr; 1030 | const char *bootValue; 1031 | GucContext context; 1032 | int flags; 1033 | GucStringCheckHook check_hook; 1034 | GucStringAssignHook assign_hook; 1035 | GucShowHook show_hook; 1036 | const char *original_name; 1037 | } ng_idcp_string_gucs[] = { 1038 | { 1039 | .name = "nextgres_idcp.auth_dbname", 1040 | .short_desc = gettext_noop(""), 1041 | .long_desc = gettext_noop(""), 1042 | .valueAddr = &gp_ng_idcp_cfg_auth_dbname, 1043 | .bootValue = DEFAULT_IDCP_AUTH_DBNAME, 1044 | .context = PGC_POSTMASTER, 1045 | .flags = 0, 1046 | .check_hook = NULL, 1047 | .assign_hook = NULL, 1048 | .show_hook = NULL, 1049 | .original_name = "auth_dbname" 1050 | }, 1051 | { 1052 | .name = "nextgres_idcp.auth_file", 1053 | .short_desc = gettext_noop(""), 1054 | .long_desc = gettext_noop(""), 1055 | .valueAddr = &gp_ng_idcp_cfg_auth_file, 1056 | .bootValue = DEFAULT_IDCP_AUTH_FILE, 1057 | .context = PGC_POSTMASTER, 1058 | .flags = 0, 1059 | .check_hook = NULL, 1060 | .assign_hook = NULL, 1061 | .show_hook = NULL, 1062 | .original_name = "auth_file" 1063 | }, 1064 | { 1065 | .name = "nextgres_idcp.auth_hba_file", 1066 | .short_desc = gettext_noop(""), 1067 | .long_desc = gettext_noop(""), 1068 | .valueAddr = &gp_ng_idcp_cfg_auth_hba_file, 1069 | .bootValue = DEFAULT_IDCP_AUTH_HBA_FILE, 1070 | .context = PGC_POSTMASTER, 1071 | .flags = 0, 1072 | .check_hook = NULL, 1073 | .assign_hook = NULL, 1074 | .show_hook = NULL, 1075 | .original_name = "auth_hba_file" 1076 | }, 1077 | { 1078 | .name = "nextgres_idcp.auth_ident_file", 1079 | .short_desc = gettext_noop(""), 1080 | .long_desc = gettext_noop(""), 1081 | .valueAddr = &gp_ng_idcp_cfg_auth_ident_file, 1082 | .bootValue = DEFAULT_IDCP_AUTH_IDENT_FILE, 1083 | .context = PGC_POSTMASTER, 1084 | .flags = 0, 1085 | .check_hook = NULL, 1086 | .assign_hook = NULL, 1087 | .show_hook = NULL, 1088 | .original_name = "auth_ident_file" 1089 | }, 1090 | { 1091 | .name = "nextgres_idcp.auth_query", 1092 | .short_desc = gettext_noop(""), 1093 | .long_desc = gettext_noop(""), 1094 | .valueAddr = &gp_ng_idcp_cfg_auth_query, 1095 | .bootValue = DEFAULT_IDCP_AUTH_QUERY, 1096 | .context = PGC_POSTMASTER, 1097 | .flags = 0, 1098 | .check_hook = NULL, 1099 | .assign_hook = NULL, 1100 | .show_hook = NULL, 1101 | .original_name = "auth_query" 1102 | }, 1103 | { 1104 | .name = "nextgres_idcp.auth_type", 1105 | .short_desc = gettext_noop(""), 1106 | .long_desc = gettext_noop(""), 1107 | .valueAddr = &gp_ng_idcp_cfg_auth_type, 1108 | .bootValue = DEFAULT_IDCP_AUTH_TYPE, 1109 | .context = PGC_POSTMASTER, 1110 | .flags = 0, 1111 | .check_hook = NULL, 1112 | .assign_hook = NULL, 1113 | .show_hook = NULL, 1114 | .original_name = "auth_type" 1115 | }, 1116 | { 1117 | .name = "nextgres_idcp.client_tls_ca_file", 1118 | .short_desc = gettext_noop(""), 1119 | .long_desc = gettext_noop(""), 1120 | .valueAddr = &gp_ng_idcp_cfg_client_tls_ca_file, 1121 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_CA_FILE, 1122 | .context = PGC_POSTMASTER, 1123 | .flags = 0, 1124 | .check_hook = NULL, 1125 | .assign_hook = NULL, 1126 | .show_hook = NULL, 1127 | .original_name = "client_tls_ca_file" 1128 | }, 1129 | { 1130 | .name = "nextgres_idcp.client_tls_cert_file", 1131 | .short_desc = gettext_noop(""), 1132 | .long_desc = gettext_noop(""), 1133 | .valueAddr = &gp_ng_idcp_cfg_client_tls_cert_file, 1134 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_CERT_FILE, 1135 | .context = PGC_POSTMASTER, 1136 | .flags = 0, 1137 | .check_hook = NULL, 1138 | .assign_hook = NULL, 1139 | .show_hook = NULL, 1140 | .original_name = "client_tls_cert_file" 1141 | }, 1142 | { 1143 | .name = "nextgres_idcp.client_tls_ciphers", 1144 | .short_desc = gettext_noop(""), 1145 | .long_desc = gettext_noop(""), 1146 | .valueAddr = &gp_ng_idcp_cfg_client_tls_ciphers, 1147 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_CIPHERS, 1148 | .context = PGC_POSTMASTER, 1149 | .flags = 0, 1150 | .check_hook = NULL, 1151 | .assign_hook = NULL, 1152 | .show_hook = NULL, 1153 | .original_name = "client_tls_ciphers" 1154 | }, 1155 | { 1156 | .name = "nextgres_idcp.client_tls_dheparams", 1157 | .short_desc = gettext_noop(""), 1158 | .long_desc = gettext_noop(""), 1159 | .valueAddr = &gp_ng_idcp_cfg_client_tls_dheparams, 1160 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_DHEPARAMS, 1161 | .context = PGC_POSTMASTER, 1162 | .flags = 0, 1163 | .check_hook = NULL, 1164 | .assign_hook = NULL, 1165 | .show_hook = NULL, 1166 | .original_name = "client_tls_dheparams" 1167 | }, 1168 | { 1169 | .name = "nextgres_idcp.client_tls_ecdhcurve", 1170 | .short_desc = gettext_noop(""), 1171 | .long_desc = gettext_noop(""), 1172 | .valueAddr = &gp_ng_idcp_cfg_client_tls_ecdhcurve, 1173 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_ECDHCURVE, 1174 | .context = PGC_POSTMASTER, 1175 | .flags = 0, 1176 | .check_hook = NULL, 1177 | .assign_hook = NULL, 1178 | .show_hook = NULL, 1179 | .original_name = "client_tls_ecdhcurve" 1180 | }, 1181 | { 1182 | .name = "nextgres_idcp.client_tls_key_file", 1183 | .short_desc = gettext_noop(""), 1184 | .long_desc = gettext_noop(""), 1185 | .valueAddr = &gp_ng_idcp_cfg_client_tls_key_file, 1186 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_KEY_FILE, 1187 | .context = PGC_POSTMASTER, 1188 | .flags = 0, 1189 | .check_hook = NULL, 1190 | .assign_hook = NULL, 1191 | .show_hook = NULL, 1192 | .original_name = "client_tls_key_file" 1193 | }, 1194 | { 1195 | .name = "nextgres_idcp.client_tls_protocols", 1196 | .short_desc = gettext_noop(""), 1197 | .long_desc = gettext_noop(""), 1198 | .valueAddr = &gp_ng_idcp_cfg_client_tls_protocols, 1199 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_PROTOCOLS, 1200 | .context = PGC_POSTMASTER, 1201 | .flags = 0, 1202 | .check_hook = NULL, 1203 | .assign_hook = NULL, 1204 | .show_hook = NULL, 1205 | .original_name = "client_tls_protocols" 1206 | }, 1207 | { 1208 | .name = "nextgres_idcp.client_tls_sslmode", 1209 | .short_desc = gettext_noop(""), 1210 | .long_desc = gettext_noop(""), 1211 | .valueAddr = &gp_ng_idcp_cfg_client_tls_sslmode, 1212 | .bootValue = DEFAULT_IDCP_CLIENT_TLS_SSLMODE, 1213 | .context = PGC_POSTMASTER, 1214 | .flags = 0, 1215 | .check_hook = NULL, 1216 | .assign_hook = NULL, 1217 | .show_hook = NULL, 1218 | .original_name = "client_tls_sslmode" 1219 | }, 1220 | { 1221 | .name = "nextgres_idcp.ignore_startup_parameters", 1222 | .short_desc = gettext_noop(""), 1223 | .long_desc = gettext_noop(""), 1224 | .valueAddr = &gp_ng_idcp_cfg_ignore_startup_parameters, 1225 | .bootValue = DEFAULT_IDCP_IGNORE_STARTUP_PARAMETERS, 1226 | .context = PGC_POSTMASTER, 1227 | .flags = 0, 1228 | .check_hook = NULL, 1229 | .assign_hook = NULL, 1230 | .show_hook = NULL, 1231 | .original_name = "ignore_startup_parameters" 1232 | }, 1233 | { 1234 | .name = "nextgres_idcp.job_name", 1235 | .short_desc = gettext_noop(""), 1236 | .long_desc = gettext_noop(""), 1237 | .valueAddr = &gp_ng_idcp_cfg_job_name, 1238 | .bootValue = DEFAULT_IDCP_JOB_NAME, 1239 | .context = PGC_POSTMASTER, 1240 | .flags = 0, 1241 | .check_hook = NULL, 1242 | .assign_hook = NULL, 1243 | .show_hook = NULL, 1244 | .original_name = "job_name" 1245 | }, 1246 | { 1247 | .name = "nextgres_idcp.listen_addr", 1248 | .short_desc = gettext_noop(""), 1249 | .long_desc = gettext_noop(""), 1250 | .valueAddr = &gp_ng_idcp_cfg_listen_addr, 1251 | .bootValue = DEFAULT_IDCP_LISTEN_ADDR, 1252 | .context = PGC_POSTMASTER, 1253 | .flags = 0, 1254 | .check_hook = NULL, 1255 | .assign_hook = NULL, 1256 | .show_hook = NULL, 1257 | .original_name = "listen_addr" 1258 | }, 1259 | { 1260 | .name = "nextgres_idcp.logfile", 1261 | .short_desc = gettext_noop(""), 1262 | .long_desc = gettext_noop(""), 1263 | .valueAddr = &gp_ng_idcp_cfg_logfile, 1264 | .bootValue = DEFAULT_IDCP_LOGFILE, 1265 | .context = PGC_POSTMASTER, 1266 | .flags = 0, 1267 | .check_hook = NULL, 1268 | .assign_hook = NULL, 1269 | .show_hook = NULL, 1270 | .original_name = "logfile" 1271 | }, 1272 | { 1273 | .name = "nextgres_idcp.pidfile", 1274 | .short_desc = gettext_noop(""), 1275 | .long_desc = gettext_noop(""), 1276 | .valueAddr = &gp_ng_idcp_cfg_pidfile, 1277 | .bootValue = DEFAULT_IDCP_PIDFILE, 1278 | .context = PGC_POSTMASTER, 1279 | .flags = 0, 1280 | .check_hook = NULL, 1281 | .assign_hook = NULL, 1282 | .show_hook = NULL, 1283 | .original_name = "pidfile" 1284 | }, 1285 | { 1286 | .name = "nextgres_idcp.resolv_conf", 1287 | .short_desc = gettext_noop(""), 1288 | .long_desc = gettext_noop(""), 1289 | .valueAddr = &gp_ng_idcp_cfg_resolv_conf, 1290 | .bootValue = DEFAULT_IDCP_RESOLV_CONF, 1291 | .context = PGC_POSTMASTER, 1292 | .flags = 0, 1293 | .check_hook = NULL, 1294 | .assign_hook = NULL, 1295 | .show_hook = NULL, 1296 | .original_name = "resolv_conf" 1297 | }, 1298 | { 1299 | .name = "nextgres_idcp.server_check_query", 1300 | .short_desc = gettext_noop(""), 1301 | .long_desc = gettext_noop(""), 1302 | .valueAddr = &gp_ng_idcp_cfg_server_check_query, 1303 | .bootValue = DEFAULT_IDCP_SERVER_CHECK_QUERY, 1304 | .context = PGC_POSTMASTER, 1305 | .flags = 0, 1306 | .check_hook = NULL, 1307 | .assign_hook = NULL, 1308 | .show_hook = NULL, 1309 | .original_name = "server_check_query" 1310 | }, 1311 | { 1312 | .name = "nextgres_idcp.server_reset_query", 1313 | .short_desc = gettext_noop(""), 1314 | .long_desc = gettext_noop(""), 1315 | .valueAddr = &gp_ng_idcp_cfg_server_reset_query, 1316 | .bootValue = DEFAULT_IDCP_SERVER_RESET_QUERY, 1317 | .context = PGC_POSTMASTER, 1318 | .flags = 0, 1319 | .check_hook = NULL, 1320 | .assign_hook = NULL, 1321 | .show_hook = NULL, 1322 | .original_name = "server_reset_query" 1323 | }, 1324 | { 1325 | .name = "nextgres_idcp.server_tls_ca_file", 1326 | .short_desc = gettext_noop(""), 1327 | .long_desc = gettext_noop(""), 1328 | .valueAddr = &gp_ng_idcp_cfg_server_tls_ca_file, 1329 | .bootValue = DEFAULT_IDCP_SERVER_TLS_CA_FILE, 1330 | .context = PGC_POSTMASTER, 1331 | .flags = 0, 1332 | .check_hook = NULL, 1333 | .assign_hook = NULL, 1334 | .show_hook = NULL, 1335 | .original_name = "server_tls_ca_file" 1336 | }, 1337 | { 1338 | .name = "nextgres_idcp.server_tls_cert_file", 1339 | .short_desc = gettext_noop(""), 1340 | .long_desc = gettext_noop(""), 1341 | .valueAddr = &gp_ng_idcp_cfg_server_tls_cert_file, 1342 | .bootValue = DEFAULT_IDCP_SERVER_TLS_CERT_FILE, 1343 | .context = PGC_POSTMASTER, 1344 | .flags = 0, 1345 | .check_hook = NULL, 1346 | .assign_hook = NULL, 1347 | .show_hook = NULL, 1348 | .original_name = "server_tls_cert_file" 1349 | }, 1350 | { 1351 | .name = "nextgres_idcp.server_tls_ciphers", 1352 | .short_desc = gettext_noop(""), 1353 | .long_desc = gettext_noop(""), 1354 | .valueAddr = &gp_ng_idcp_cfg_server_tls_ciphers, 1355 | .bootValue = DEFAULT_IDCP_SERVER_TLS_CIPHERS, 1356 | .context = PGC_POSTMASTER, 1357 | .flags = 0, 1358 | .check_hook = NULL, 1359 | .assign_hook = NULL, 1360 | .show_hook = NULL, 1361 | .original_name = "server_tls_ciphers" 1362 | }, 1363 | { 1364 | .name = "nextgres_idcp.server_tls_key_file", 1365 | .short_desc = gettext_noop(""), 1366 | .long_desc = gettext_noop(""), 1367 | .valueAddr = &gp_ng_idcp_cfg_server_tls_key_file, 1368 | .bootValue = DEFAULT_IDCP_SERVER_TLS_KEY_FILE, 1369 | .context = PGC_POSTMASTER, 1370 | .flags = 0, 1371 | .check_hook = NULL, 1372 | .assign_hook = NULL, 1373 | .show_hook = NULL, 1374 | .original_name = "server_tls_key_file" 1375 | }, 1376 | { 1377 | .name = "nextgres_idcp.server_tls_protocols", 1378 | .short_desc = gettext_noop(""), 1379 | .long_desc = gettext_noop(""), 1380 | .valueAddr = &gp_ng_idcp_cfg_server_tls_protocols, 1381 | .bootValue = DEFAULT_IDCP_SERVER_TLS_PROTOCOLS, 1382 | .context = PGC_POSTMASTER, 1383 | .flags = 0, 1384 | .check_hook = NULL, 1385 | .assign_hook = NULL, 1386 | .show_hook = NULL, 1387 | .original_name = "server_tls_protocols" 1388 | }, 1389 | { 1390 | .name = "nextgres_idcp.server_tls_sslmode", 1391 | .short_desc = gettext_noop(""), 1392 | .long_desc = gettext_noop(""), 1393 | .valueAddr = &gp_ng_idcp_cfg_server_tls_sslmode, 1394 | .bootValue = DEFAULT_IDCP_SERVER_TLS_SSLMODE, 1395 | .context = PGC_POSTMASTER, 1396 | .flags = 0, 1397 | .check_hook = NULL, 1398 | .assign_hook = NULL, 1399 | .show_hook = NULL, 1400 | .original_name = "server_tls_sslmode" 1401 | }, 1402 | { 1403 | .name = "nextgres_idcp.service_name", 1404 | .short_desc = gettext_noop(""), 1405 | .long_desc = gettext_noop(""), 1406 | .valueAddr = &gp_ng_idcp_cfg_service_name, 1407 | .bootValue = DEFAULT_IDCP_SERVICE_NAME, 1408 | .context = PGC_POSTMASTER, 1409 | .flags = 0, 1410 | .check_hook = NULL, 1411 | .assign_hook = NULL, 1412 | .show_hook = NULL, 1413 | .original_name = "service_name" 1414 | }, 1415 | { 1416 | .name = "nextgres_idcp.tcp_keepalive", 1417 | .short_desc = gettext_noop(""), 1418 | .long_desc = gettext_noop(""), 1419 | .valueAddr = &gp_ng_idcp_cfg_tcp_keepalive, 1420 | .bootValue = DEFAULT_IDCP_TCP_KEEPALIVE, 1421 | .context = PGC_POSTMASTER, 1422 | .flags = 0, 1423 | .check_hook = NULL, 1424 | .assign_hook = NULL, 1425 | .show_hook = NULL, 1426 | .original_name = "tcp_keepalive" 1427 | }, 1428 | { 1429 | .name = "nextgres_idcp.track_extra_parameters", 1430 | .short_desc = gettext_noop(""), 1431 | .long_desc = gettext_noop(""), 1432 | .valueAddr = &gp_ng_idcp_cfg_track_extra_parameters, 1433 | .bootValue = DEFAULT_IDCP_TRACK_EXTRA_PARAMETERS, 1434 | .context = PGC_POSTMASTER, 1435 | .flags = 0, 1436 | .check_hook = NULL, 1437 | .assign_hook = NULL, 1438 | .show_hook = NULL, 1439 | .original_name = "track_extra_parameters" 1440 | }, 1441 | { 1442 | .name = "nextgres_idcp.unix_socket_dir", 1443 | .short_desc = gettext_noop(""), 1444 | .long_desc = gettext_noop(""), 1445 | .valueAddr = &gp_ng_idcp_cfg_unix_socket_dir, 1446 | .bootValue = DEFAULT_IDCP_UNIX_SOCKET_DIR, 1447 | .context = PGC_POSTMASTER, 1448 | .flags = 0, 1449 | .check_hook = NULL, 1450 | .assign_hook = NULL, 1451 | .show_hook = NULL, 1452 | .original_name = "unix_socket_dir" 1453 | }, 1454 | { 1455 | .name = "nextgres_idcp.unix_socket_group", 1456 | .short_desc = gettext_noop(""), 1457 | .long_desc = gettext_noop(""), 1458 | .valueAddr = &gp_ng_idcp_cfg_unix_socket_group, 1459 | .bootValue = DEFAULT_IDCP_UNIX_SOCKET_GROUP, 1460 | .context = PGC_POSTMASTER, 1461 | .flags = 0, 1462 | .check_hook = NULL, 1463 | .assign_hook = NULL, 1464 | .show_hook = NULL, 1465 | .original_name = "unix_socket_group" 1466 | }, 1467 | }; /* ng_idcp_string_guc_s */ 1468 | 1469 | /* ========================================================================= */ 1470 | /* -- STATIC ASSERTIONS ---------------------------------------------------- */ 1471 | /* ========================================================================= */ 1472 | 1473 | /* ========================================================================= */ 1474 | /* -- PUBLIC FUNCTION DEFINITIONS ------------------------------------------ */ 1475 | /* ========================================================================= */ 1476 | 1477 | void 1478 | ng_idcp_guc_define ( 1479 | void 1480 | ) { 1481 | 1482 | DefineCustomEnumVariable("nextgres_idcp.pool_mode", 1483 | gettext_noop("Specifies when a server connection can be reused by other clients."), 1484 | gettext_noop("Specifies when a server connection can be reused by other clients."), 1485 | &g_ng_idcp_cfg_pool_mode, 1486 | DEFAULT_IDCP_POOL_MODE, 1487 | ng_idcp_pool_modes, 1488 | PGC_POSTMASTER, 1489 | 0, 1490 | NULL, 1491 | NULL, 1492 | NULL); 1493 | 1494 | DefineCustomEnumVariable("nextgres_idcp.session_schedule", 1495 | gettext_noop("Session schedule policy for connection pool."), 1496 | gettext_noop("Session schedule policy for connection pool."), 1497 | &g_ng_idcp_cfg_session_scheduler, 1498 | DEFAULT_IDCP_SESSION_SCHEDULER, 1499 | ng_idcp_session_schedulers, 1500 | PGC_POSTMASTER, 1501 | 0, 1502 | NULL, 1503 | NULL, 1504 | NULL); 1505 | 1506 | /* Iterate & define the boolean GUCs */ 1507 | for (int ii = 0; ii < lengthof(ng_idcp_bool_gucs); ++ii) { 1508 | const struct ng_idcp_bool_guc_s *guc = &ng_idcp_bool_gucs[ii]; 1509 | 1510 | elog(LOG, "Setting bool GUC %s", guc->name); 1511 | DefineCustomBoolVariable(guc->name, guc->short_desc, guc->long_desc, 1512 | guc->valueAddr, guc->bootValue, guc->context, guc->flags, 1513 | guc->check_hook, guc->assign_hook, guc->show_hook); 1514 | } 1515 | 1516 | /* Iterate & define the integer GUCs */ 1517 | for (int ii = 0; ii < lengthof(ng_idcp_int_gucs); ++ii) { 1518 | const struct ng_idcp_int_guc_s *guc = &ng_idcp_int_gucs[ii]; 1519 | 1520 | elog(LOG, "Setting int GUC %s", guc->name); 1521 | DefineCustomIntVariable(guc->name, guc->short_desc, guc->long_desc, 1522 | guc->valueAddr, guc->bootValue, guc->minValue, guc->maxValue, 1523 | guc->context, guc->flags, guc->check_hook, guc->assign_hook, 1524 | guc->show_hook); 1525 | } 1526 | 1527 | /* Iterate & define the string GUCs */ 1528 | for (int ii = 0; ii < lengthof(ng_idcp_string_gucs); ++ii) { 1529 | const struct ng_idcp_string_guc_s *guc = 1530 | &ng_idcp_string_gucs[ii]; 1531 | 1532 | elog(LOG, "Setting string GUC %s", guc->name); 1533 | DefineCustomStringVariable(guc->name, guc->short_desc, guc->long_desc, 1534 | guc->valueAddr, guc->bootValue, guc->context, guc->flags, 1535 | guc->check_hook, guc->assign_hook, guc->show_hook); 1536 | } 1537 | 1538 | /* You kids get off my lawn! */ 1539 | MarkGUCPrefixReserved("nextgres_idcp"); 1540 | 1541 | } /* ng_idcp_guc_define() */ 1542 | 1543 | /* ========================================================================= */ 1544 | /* -- PRIVATE FUNCTION DEFINITIONS ----------------------------------------- */ 1545 | /* ========================================================================= */ 1546 | 1547 | /* ========================================================================= */ 1548 | /* -- LOCAL FUNCTION DEFINITIONS ------------------------------------------- */ 1549 | /* ========================================================================= */ 1550 | 1551 | /* vim: set ts=2 et sw=2 ft=c: */ 1552 | 1553 | -------------------------------------------------------------------------------- /src/extension/entrypoint.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= ** 2 | ** _ _______ ________________ ________ ** 3 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 4 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 5 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 6 | ** ** 7 | ** ========================================================================= ** 8 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 9 | ** ========================================================================= ** 10 | ** NEXTGRES Database Compatibility System ** 11 | ** Portions Copyright (C) NEXTGRES, INC. ** 12 | ** Portions Copyright (C) PostgresPro ** 13 | ** Portions Copyright (C) Konstantin Knizhnik ** 14 | ** All Rights Reserved. ** 15 | ** ** 16 | ** Permission to use, copy, modify, and/or distribute this software for any ** 17 | ** purpose is subject to the terms specified in the License Agreement. ** 18 | ** ========================================================================= */ 19 | 20 | /* 21 | * OVERVIEW 22 | * 23 | * This file represents the entrypoint of our extension, spawning a background 24 | * worker that coordinates individual connection pool listeners responsible for 25 | * handling incoming requests. 26 | */ 27 | 28 | /* ========================================================================= */ 29 | /* -- INCLUSIONS ----------------------------------------------------------- */ 30 | /* ========================================================================= */ 31 | 32 | /* -------------------------- Interface Inclusions ------------------------- */ 33 | #include "postgres.h" 34 | 35 | /* These are always necessary for a bgworker */ 36 | #include "miscadmin.h" 37 | #include "pgstat.h" 38 | #include "miscadmin.h" 39 | #include "postmaster/bgworker.h" 40 | #include "postmaster/interrupt.h" 41 | #include "storage/ipc.h" 42 | #include "storage/latch.h" 43 | #include "storage/lwlock.h" 44 | #include "storage/proc.h" 45 | #include "storage/shmem.h" 46 | 47 | /* --------------------------- System Inclusions --------------------------- */ 48 | 49 | /* --------------------------- Project Inclusions -------------------------- */ 50 | 51 | #include "nextgres/idcp.h" /* Our base extension header */ 52 | #include "nextgres/idcp/util/guc.h" /* Our extension's GUC handling */ 53 | 54 | /* ========================================================================= */ 55 | /* -- PRIVATE DEFINITIONS -------------------------------------------------- */ 56 | /* ========================================================================= */ 57 | 58 | /* ========================================================================= */ 59 | /* -- PRIVATE MACROS ------------------------------------------------------- */ 60 | /* ========================================================================= */ 61 | 62 | /* ========================================================================= */ 63 | /* -- PRIVATE TYPEDEFS ----------------------------------------------------- */ 64 | /* ========================================================================= */ 65 | 66 | /* ========================================================================= */ 67 | /* -- PRIVATE STRUCTURES --------------------------------------------------- */ 68 | /* ========================================================================= */ 69 | 70 | /* ========================================================================= */ 71 | /* -- INTERNAL FUNCTION PROTOTYPES ----------------------------------------- */ 72 | /* ========================================================================= */ 73 | 74 | void _PG_init(void); 75 | 76 | /* ========================================================================= */ 77 | /* -- STATIC FUNCTION PROTOTYPES ------------------------------------------- */ 78 | /* ========================================================================= */ 79 | 80 | /* ========================================================================= */ 81 | /* -- PRIVATE DATA --------------------------------------------------------- */ 82 | /* ========================================================================= */ 83 | 84 | /* We define our module's magic in the entrypoint, rather than globals. */ 85 | PG_MODULE_MAGIC; 86 | 87 | /* ========================================================================= */ 88 | /* -- EXPORTED DATA -------------------------------------------------------- */ 89 | /* ========================================================================= */ 90 | 91 | /* ========================================================================= */ 92 | /* -- STATIC ASSERTIONS ---------------------------------------------------- */ 93 | /* ========================================================================= */ 94 | 95 | /* ========================================================================= */ 96 | /* -- EXPORTED FUNCTION DEFINITIONS ---------------------------------------- */ 97 | /* ========================================================================= */ 98 | 99 | void 100 | _PG_init ( 101 | void 102 | ) { 103 | BackgroundWorker ng_idcp_controller_bgworker = { 104 | .bgw_name = NEXTGRES_EXTNAME "_controller", 105 | .bgw_type = NEXTGRES_EXTNAME, 106 | .bgw_library_name = NEXTGRES_LIBNAME, 107 | .bgw_function_name = "ng_idcp_controller_main", 108 | .bgw_restart_time = BGW_NEVER_RESTART, 109 | .bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION, 110 | .bgw_main_arg = (Datum) 0, 111 | .bgw_notify_pid = 0, 112 | .bgw_start_time = BgWorkerStart_RecoveryFinished 113 | }; 114 | 115 | /* Make sure we're in the right state. */ 116 | if (!process_shared_preload_libraries_in_progress) { 117 | return; 118 | } 119 | 120 | /* Define our extension's custom GUC variables. */ 121 | ng_idcp_guc_define(); 122 | 123 | /* Since we're disabled by default, inform the user. */ 124 | if (0 >= g_ng_idcp_cfg_thread_count) { 125 | ereport(WARNING, 126 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), 127 | errmsg("In-database connection pool loaded, but not enabled."), 128 | errhint("You need to set nextgres_idcp.thread_count > 0."))); 129 | 130 | return; 131 | } 132 | 133 | /* Register the Background Worker */ 134 | RegisterBackgroundWorker(&ng_idcp_controller_bgworker); 135 | 136 | } /* _PG_init() */ 137 | 138 | /* ========================================================================= */ 139 | /* -- INTERNAL FUNCTION DEFINITIONS ---------------------------------------- */ 140 | /* ========================================================================= */ 141 | 142 | /* ========================================================================= */ 143 | /* -- STATIC FUNCTION DEFINITIONS ------------------------------------------ */ 144 | /* ========================================================================= */ 145 | 146 | /* :vi set ts=2 et sw=2: */ 147 | 148 | -------------------------------------------------------------------------------- /src/include/nextgres/idcp.h: -------------------------------------------------------------------------------- 1 | #ifndef NG_IDCP_H /* Multiple Inclusion Guard */ 2 | #define NG_IDCP_H 3 | /* ========================================================================= ** 4 | ** _ _______ ________________ ________ ** 5 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 6 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 7 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 8 | ** ** 9 | ** ========================================================================= ** 10 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 11 | ** ========================================================================= ** 12 | ** NEXTGRES Database Compatibility System ** 13 | ** Portions Copyright (C) NEXTGRES, INC. ** 14 | ** Portions Copyright (C) PostgresPro ** 15 | ** Portions Copyright (C) Konstantin Knizhnik ** 16 | ** All Rights Reserved. ** 17 | ** ** 18 | ** Permission to use, copy, modify, and/or distribute this software for any ** 19 | ** purpose is subject to the terms specified in the License Agreement. ** 20 | ** ========================================================================= */ 21 | 22 | /* ========================================================================= */ 23 | /* -- INCLUSIONS ----------------------------------------------------------- */ 24 | /* ========================================================================= */ 25 | 26 | /* ========================================================================= */ 27 | /* -- PUBLIC DEFINITIONS --------------------------------------------------- */ 28 | /* ========================================================================= */ 29 | 30 | #define NEXTGRES_EXTNAME "nextgres_idcp" 31 | #define NEXTGRES_LIBNAME NEXTGRES_EXTNAME 32 | 33 | /* ========================================================================= */ 34 | /* -- PUBLIC MACROS -------------------------------------------------------- */ 35 | /* ========================================================================= */ 36 | 37 | /* ========================================================================= */ 38 | /* -- PUBLIC TYPEDEFS ------------------------------------------------------ */ 39 | /* ========================================================================= */ 40 | 41 | typedef enum ng_idcp_pool_mode_t { 42 | NG_IDCP_POOL_MODE_SESSION = 0, /** Session Pooling */ 43 | NG_IDCP_POOL_MODE_TRANSACTION, /** Transaction Pooling */ 44 | NG_IDCP_POOL_MODE_STATEMENT /** Statement Pooling */ 45 | } ng_idcp_pool_mode_t; 46 | 47 | typedef enum ng_idcp_session_scheduler_t { 48 | NG_IDCP_SESSION_SCHED_ROUND_ROBIN = 0, /** Round Robin Assignment Strategy */ 49 | NG_IDCP_SESSION_SCHED_RANDOM, /** Random Assignment Strategy */ 50 | NG_IDCP_SESSION_SCHED_LOAD_BALANCING /** Least-Used Assignment Strategy */ 51 | } ng_idcp_session_scheduler_t; 52 | 53 | enum SessionSchedulePolicy 54 | { 55 | SESSION_SCHED_ROUND_ROBIN, 56 | SESSION_SCHED_RANDOM, 57 | SESSION_SCHED_LOAD_BALANCING 58 | }; 59 | 60 | /* 61 | * Information in share dmemory about connection proxy state (used for session scheduling and monitoring) 62 | */ 63 | typedef struct ConnectionProxyState 64 | { 65 | int pid; /* proxy worker pid */ 66 | int n_clients; /* total number of clients */ 67 | int n_ssl_clients; /* number of clients using SSL connection */ 68 | int n_pools; /* nubmer of dbname/role combinations */ 69 | int n_backends; /* totatal number of launched backends */ 70 | int n_dedicated_backends; /* number of tainted backends */ 71 | int n_idle_backends; /* number of idle backends */ 72 | int n_idle_clients; /* number of idle clients */ 73 | uint64 tx_bytes; /* amount of data sent to client */ 74 | uint64 rx_bytes; /* amount of data send to server */ 75 | uint64 n_transactions; /* total number of proroceeded transactions */ 76 | } ConnectionProxyState; 77 | 78 | /* ========================================================================= */ 79 | /* -- PUBLIC STRUCTURES ---------------------------------------------------- */ 80 | /* ========================================================================= */ 81 | 82 | /* ========================================================================= */ 83 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 84 | /* ========================================================================= */ 85 | 86 | extern PGDLLIMPORT int MaxSessions; 87 | extern PGDLLIMPORT int SessionPoolSize; 88 | extern PGDLLIMPORT int IdlePoolWorkerTimeout; 89 | extern PGDLLIMPORT int ConnectionProxiesNumber; 90 | extern PGDLLIMPORT int SessionSchedule; 91 | extern PGDLLIMPORT bool RestartPoolerOnReload; 92 | extern PGDLLIMPORT bool ProxyingGUCs; 93 | extern PGDLLIMPORT bool MultitenantProxy; 94 | 95 | extern ConnectionProxyState* ProxyState; 96 | extern PGDLLIMPORT int MyProxyId; 97 | extern PGDLLIMPORT pgsocket MyProxySocket; 98 | 99 | /* ---------------------------- Enumerated GUCs ---------------------------- */ 100 | 101 | /* ------------------------------ Boolean GUCs ----------------------------- */ 102 | 103 | extern bool g_ng_idcp_multitenant_proxy; 104 | extern bool g_ng_idcp_proxying_gucs; 105 | extern bool g_ng_idcp_restart_pooler_on_reload; 106 | 107 | /* ------------------------------ Integer GUCs ----------------------------- */ 108 | 109 | extern int g_ng_idcp_cfg_port; 110 | extern int g_ng_idcp_cfg_session_pool_size; 111 | extern int g_ng_idcp_cfg_session_scheduler; 112 | extern int g_ng_idcp_cfg_idle_worker_timeout_in_ms; 113 | extern int g_ng_idcp_cfg_thread_count; 114 | extern int g_ng_idcp_cfg_max_sessions_per_thread; 115 | extern int g_ng_idcp_cfg_pool_mode; 116 | extern int g_ng_idcp_cfg_application_name_add_host; 117 | extern int g_ng_idcp_cfg_autodb_idle_timeout; 118 | extern int g_ng_idcp_cfg_cancel_wait_timeout; 119 | extern int g_ng_idcp_cfg_client_idle_timeout; 120 | extern int g_ng_idcp_cfg_client_login_timeout; 121 | extern int g_ng_idcp_cfg_default_pool_size; 122 | extern int g_ng_idcp_cfg_disable_pqexec; 123 | extern int g_ng_idcp_cfg_dns_max_ttl; 124 | extern int g_ng_idcp_cfg_dns_nxdomain_ttl; 125 | extern int g_ng_idcp_cfg_dns_zone_check_period; 126 | extern int g_ng_idcp_cfg_idle_transaction_timeout; 127 | extern int g_ng_idcp_cfg_listen_backlog; 128 | extern int g_ng_idcp_cfg_listen_port; 129 | extern int g_ng_idcp_cfg_log_connections; 130 | extern int g_ng_idcp_cfg_log_disconnections; 131 | extern int g_ng_idcp_cfg_log_pooler_errors; 132 | extern int g_ng_idcp_cfg_log_stats; 133 | extern int g_ng_idcp_cfg_max_client_conn; 134 | extern int g_ng_idcp_cfg_max_db_connections; 135 | extern int g_ng_idcp_cfg_max_packet_size; 136 | extern int g_ng_idcp_cfg_max_prepared_statements; 137 | extern int g_ng_idcp_cfg_max_user_connections; 138 | extern int g_ng_idcp_cfg_min_pool_size; 139 | extern int g_ng_idcp_cfg_peer_id; 140 | extern int g_ng_idcp_cfg_pkt_buf; 141 | extern int g_ng_idcp_cfg_query_timeout; 142 | extern int g_ng_idcp_cfg_query_wait_timeout; 143 | extern int g_ng_idcp_cfg_reserve_pool_size; 144 | extern int g_ng_idcp_cfg_reserve_pool_timeout; 145 | extern int g_ng_idcp_cfg_sbuf_loopcnt; 146 | extern int g_ng_idcp_cfg_server_check_delay; 147 | extern int g_ng_idcp_cfg_server_connect_timeout; 148 | extern int g_ng_idcp_cfg_server_fast_close; 149 | extern int g_ng_idcp_cfg_server_idle_timeout; 150 | extern int g_ng_idcp_cfg_server_lifetime; 151 | extern int g_ng_idcp_cfg_server_login_retry; 152 | extern int g_ng_idcp_cfg_server_reset_query_always; 153 | extern int g_ng_idcp_cfg_server_round_robin; 154 | extern int g_ng_idcp_cfg_so_reuseport; 155 | extern int g_ng_idcp_cfg_stats_period; 156 | extern int g_ng_idcp_cfg_suspend_timeout; 157 | extern int g_ng_idcp_cfg_tcp_defer_accept; 158 | extern int g_ng_idcp_cfg_tcp_keepcnt; 159 | extern int g_ng_idcp_cfg_tcp_keepidle; 160 | extern int g_ng_idcp_cfg_tcp_keepintvl; 161 | extern int g_ng_idcp_cfg_tcp_socket_buffer; 162 | extern int g_ng_idcp_cfg_tcp_user_timeout; 163 | extern int g_ng_idcp_cfg_unix_socket_mode; 164 | extern int g_ng_idcp_cfg_verbose; 165 | 166 | /* ------------------------------ String GUCs ------------------------------ */ 167 | 168 | extern char *gp_ng_idcp_cfg_auth_dbname; 169 | extern char *gp_ng_idcp_cfg_auth_file; 170 | extern char *gp_ng_idcp_cfg_auth_hba_file; 171 | extern char *gp_ng_idcp_cfg_auth_ident_file; 172 | extern char *gp_ng_idcp_cfg_auth_query; 173 | extern char *gp_ng_idcp_cfg_auth_type; 174 | extern char *gp_ng_idcp_cfg_client_tls_ca_file; 175 | extern char *gp_ng_idcp_cfg_client_tls_cert_file; 176 | extern char *gp_ng_idcp_cfg_client_tls_ciphers; 177 | extern char *gp_ng_idcp_cfg_client_tls_dheparams; 178 | extern char *gp_ng_idcp_cfg_client_tls_ecdhcurve; 179 | extern char *gp_ng_idcp_cfg_client_tls_key_file; 180 | extern char *gp_ng_idcp_cfg_client_tls_protocols; 181 | extern char *gp_ng_idcp_cfg_client_tls_sslmode; 182 | extern char *gp_ng_idcp_cfg_ignore_startup_parameters; 183 | extern char *gp_ng_idcp_cfg_job_name; 184 | extern char *gp_ng_idcp_cfg_listen_addr; 185 | extern char *gp_ng_idcp_cfg_logfile; 186 | extern char *gp_ng_idcp_cfg_pidfile; 187 | extern char *gp_ng_idcp_cfg_resolv_conf; 188 | extern char *gp_ng_idcp_cfg_server_check_query; 189 | extern char *gp_ng_idcp_cfg_server_reset_query; 190 | extern char *gp_ng_idcp_cfg_server_tls_ca_file; 191 | extern char *gp_ng_idcp_cfg_server_tls_cert_file; 192 | extern char *gp_ng_idcp_cfg_server_tls_ciphers; 193 | extern char *gp_ng_idcp_cfg_server_tls_key_file; 194 | extern char *gp_ng_idcp_cfg_server_tls_protocols; 195 | extern char *gp_ng_idcp_cfg_server_tls_sslmode; 196 | extern char *gp_ng_idcp_cfg_service_name; 197 | extern char *gp_ng_idcp_cfg_tcp_keepalive; 198 | extern char *gp_ng_idcp_cfg_track_extra_parameters; 199 | extern char *gp_ng_idcp_cfg_unix_socket_dir; 200 | extern char *gp_ng_idcp_cfg_unix_socket_group; 201 | 202 | /* ========================================================================= */ 203 | /* -- PUBLIC FUNCTION PROTOTYPES ------------------------------------------- */ 204 | /* ========================================================================= */ 205 | 206 | extern int ConnectionProxyStart(void); 207 | extern int ConnectionProxyShmemSize(void); 208 | extern void ConnectionProxyShmemInit(void); 209 | 210 | /* ========================================================================= */ 211 | /* -- PUBLIC INLINE FUNCTIONS ---------------------------------------------- */ 212 | /* ========================================================================= */ 213 | 214 | /* ========================================================================= */ 215 | /* -- PUBLIC HELPER FUNCTIONS ---------------------------------------------- */ 216 | /* ========================================================================= */ 217 | 218 | /* vim: set ts=2 et sw=2 ft=c: */ 219 | 220 | #endif /* NG_IDCP_H */ 221 | -------------------------------------------------------------------------------- /src/include/nextgres/idcp/libpq/libpq.h: -------------------------------------------------------------------------------- 1 | #ifndef NG_IDCP_LIBPQ_LIBPQ_H /* Multiple Inclusion Guard */ 2 | #define NG_IDCP_LIBPQ_LIBPQ_H 3 | /* ========================================================================= ** 4 | ** _ _______ ________________ ________ ** 5 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 6 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 7 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 8 | ** ** 9 | ** ========================================================================= ** 10 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 11 | ** ========================================================================= ** 12 | ** NEXTGRES Database Compatibility System ** 13 | ** Portions Copyright (C) NEXTGRES, INC. ** 14 | ** Portions Copyright (C) PostgresPro ** 15 | ** Portions Copyright (C) Konstantin Knizhnik ** 16 | ** All Rights Reserved. ** 17 | ** ** 18 | ** Permission to use, copy, modify, and/or distribute this software for any ** 19 | ** purpose is subject to the terms specified in the License Agreement. ** 20 | ** ========================================================================= */ 21 | 22 | /* ========================================================================= */ 23 | /* -- INCLUSIONS ----------------------------------------------------------- */ 24 | /* ========================================================================= */ 25 | 26 | /* ========================================================================= */ 27 | /* -- PUBLIC DEFINITIONS --------------------------------------------------- */ 28 | /* ========================================================================= */ 29 | 30 | /* ========================================================================= */ 31 | /* -- PUBLIC MACROS -------------------------------------------------------- */ 32 | /* ========================================================================= */ 33 | 34 | /* ========================================================================= */ 35 | /* -- PUBLIC TYPEDEFS ------------------------------------------------------ */ 36 | /* ========================================================================= */ 37 | 38 | /* ========================================================================= */ 39 | /* -- PUBLIC STRUCTURES ---------------------------------------------------- */ 40 | /* ========================================================================= */ 41 | 42 | /* ========================================================================= */ 43 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 44 | /* ========================================================================= */ 45 | 46 | /* ========================================================================= */ 47 | /* -- PUBLIC FUNCTION PROTOTYPES ------------------------------------------- */ 48 | /* ========================================================================= */ 49 | 50 | extern int ng_idcp_stream_server_port (int family, const char *hostName, 51 | unsigned short portNumber, const char *unixSocketDir, 52 | pgsocket ListenSocket[], int MaxListen); 53 | int ng_idcp_stream_connection (pgsocket server_fd, Port *port); 54 | extern int StreamConnection(pgsocket server_fd, Port *port); 55 | extern void StreamClose(pgsocket sock); 56 | extern void TouchSocketFiles(void); 57 | extern void RemoveSocketFiles(void); 58 | extern void ng_idcp_pq_init(void); 59 | extern int ng_idcp_pq_getbytes(char *s, size_t len); 60 | extern void ng_idcp_pq_startmsgread(void); 61 | extern void ng_idcp_pq_endmsgread(void); 62 | extern bool ng_idcp_pq_is_reading_msg(void); 63 | extern int ng_idcp_pq_getmessage(StringInfo s, int maxlen); 64 | extern int ng_idcp_pq_getbyte(void); 65 | extern int ng_idcp_pq_peekbyte(void); 66 | extern int ng_idcp_pq_getbyte_if_available(unsigned char *c); 67 | extern bool ng_idcp_pq_buffer_has_data(void); 68 | extern int ng_idcp_pq_putmessage_v2(char msgtype, const char *s, size_t len); 69 | extern bool ng_idcp_pq_check_connection(void); 70 | 71 | /* ========================================================================= */ 72 | /* -- PUBLIC INLINE FUNCTIONS ---------------------------------------------- */ 73 | /* ========================================================================= */ 74 | 75 | /* ========================================================================= */ 76 | /* -- PUBLIC HELPER FUNCTIONS ---------------------------------------------- */ 77 | /* ========================================================================= */ 78 | 79 | 80 | /* vim: set ts=2 et sw=2 ft=c: */ 81 | 82 | #endif /* NG_IDCP_LIBPQ_LIBPQ_H */ 83 | -------------------------------------------------------------------------------- /src/include/nextgres/idcp/postmaster/postmaster.h: -------------------------------------------------------------------------------- 1 | #ifndef NG_IDCP_POSTMASTER_POSTMASTER_H /* Multiple Inclusion Guard */ 2 | #define NG_IDCP_POSTMASTER_POSTMASTER_H 3 | /* ========================================================================= ** 4 | ** _ _______ ________________ ________ ** 5 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 6 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 7 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 8 | ** ** 9 | ** ========================================================================= ** 10 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 11 | ** ========================================================================= ** 12 | ** NEXTGRES Database Compatibility System ** 13 | ** Portions Copyright (C) NEXTGRES, INC. ** 14 | ** Portions Copyright (C) PostgresPro ** 15 | ** Portions Copyright (C) Konstantin Knizhnik ** 16 | ** All Rights Reserved. ** 17 | ** ** 18 | ** Permission to use, copy, modify, and/or distribute this software for any ** 19 | ** purpose is subject to the terms specified in the License Agreement. ** 20 | ** ========================================================================= */ 21 | 22 | /* ========================================================================= */ 23 | /* -- INCLUSIONS ----------------------------------------------------------- */ 24 | /* ========================================================================= */ 25 | 26 | /* ========================================================================= */ 27 | /* -- PUBLIC DEFINITIONS --------------------------------------------------- */ 28 | /* ========================================================================= */ 29 | 30 | /* ========================================================================= */ 31 | /* -- PUBLIC MACROS -------------------------------------------------------- */ 32 | /* ========================================================================= */ 33 | 34 | /* ========================================================================= */ 35 | /* -- PUBLIC TYPEDEFS ------------------------------------------------------ */ 36 | /* ========================================================================= */ 37 | 38 | /* ========================================================================= */ 39 | /* -- PUBLIC STRUCTURES ---------------------------------------------------- */ 40 | /* ========================================================================= */ 41 | 42 | /* ========================================================================= */ 43 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 44 | /* ========================================================================= */ 45 | 46 | /* ========================================================================= */ 47 | /* -- PUBLIC FUNCTION PROTOTYPES ------------------------------------------- */ 48 | /* ========================================================================= */ 49 | 50 | extern int ng_idcp_parse_startup_packet (Port *port, MemoryContext memctx, 51 | char *buf, int len, bool ssl_done, bool gss_done); 52 | 53 | /* ========================================================================= */ 54 | /* -- PUBLIC INLINE FUNCTIONS ---------------------------------------------- */ 55 | /* ========================================================================= */ 56 | 57 | /* ========================================================================= */ 58 | /* -- PUBLIC HELPER FUNCTIONS ---------------------------------------------- */ 59 | /* ========================================================================= */ 60 | 61 | /* vim: set ts=2 et sw=2 ft=c: */ 62 | 63 | #endif /* NG_IDCP_POSTMASTER_POSTMASTER_H */ 64 | -------------------------------------------------------------------------------- /src/include/nextgres/idcp/postmaster/proxy.h: -------------------------------------------------------------------------------- 1 | #ifndef NG_IDCP_POSTMASTER_PROXY_H /* Multiple Inclusion Guard */ 2 | #define NG_IDCP_POSTMASTER_PROXY_H 3 | /* ========================================================================= ** 4 | ** _ _______ ________________ ________ ** 5 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 6 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 7 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 8 | ** ** 9 | ** ========================================================================= ** 10 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 11 | ** ========================================================================= ** 12 | ** NEXTGRES Database Compatibility System ** 13 | ** Portions Copyright (C) NEXTGRES, INC. ** 14 | ** Portions Copyright (C) PostgresPro ** 15 | ** Portions Copyright (C) Konstantin Knizhnik ** 16 | ** All Rights Reserved. ** 17 | ** ** 18 | ** Permission to use, copy, modify, and/or distribute this software for any ** 19 | ** purpose is subject to the terms specified in the License Agreement. ** 20 | ** ========================================================================= */ 21 | 22 | /* ========================================================================= */ 23 | /* -- INCLUSIONS ----------------------------------------------------------- */ 24 | /* ========================================================================= */ 25 | 26 | /* ========================================================================= */ 27 | /* -- PUBLIC DEFINITIONS --------------------------------------------------- */ 28 | /* ========================================================================= */ 29 | 30 | /* ========================================================================= */ 31 | /* -- PUBLIC MACROS -------------------------------------------------------- */ 32 | /* ========================================================================= */ 33 | 34 | /* ========================================================================= */ 35 | /* -- PUBLIC TYPEDEFS ------------------------------------------------------ */ 36 | /* ========================================================================= */ 37 | 38 | /* ========================================================================= */ 39 | /* -- PUBLIC STRUCTURES ---------------------------------------------------- */ 40 | /* ========================================================================= */ 41 | 42 | /* ========================================================================= */ 43 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 44 | /* ========================================================================= */ 45 | 46 | /* ========================================================================= */ 47 | /* -- PUBLIC FUNCTION PROTOTYPES ------------------------------------------- */ 48 | /* ========================================================================= */ 49 | 50 | PGDLLEXPORT void ng_idcp_proxy_main (Datum main_arg) pg_attribute_noreturn(); 51 | 52 | /* ========================================================================= */ 53 | /* -- PUBLIC INLINE FUNCTIONS ---------------------------------------------- */ 54 | /* ========================================================================= */ 55 | 56 | /* ========================================================================= */ 57 | /* -- PUBLIC HELPER FUNCTIONS ---------------------------------------------- */ 58 | /* ========================================================================= */ 59 | 60 | /* vim: set ts=2 et sw=2 ft=c: */ 61 | 62 | #endif /* NG_IDCP_POSTMASTER_PROXY_H */ 63 | -------------------------------------------------------------------------------- /src/include/nextgres/idcp/util/guc.h: -------------------------------------------------------------------------------- 1 | #ifndef NGAPI_IDCP_SKEL_PUBLIC_H /* Multiple Inclusion Guard */ 2 | #define NGAPI_IDCP_SKEL_PUBLIC_H 3 | /* ========================================================================= ** 4 | ** _ _______ ________________ ________ ** 5 | ** / |/ / __/ |/_/_ __/ ___/ _ \/ __/ __/ ** 6 | ** / / _/_> < / / / (_ / , _/ _/_\ \ ** 7 | ** /_/|_/___/_/|_| /_/ \___/_/|_/___/___/ ** 8 | ** ** 9 | ** ========================================================================= ** 10 | ** IN-DATABASE CONNECTION POOLING EXTENSION ** 11 | ** ========================================================================= ** 12 | ** NEXTGRES Database Compatibility System ** 13 | ** Portions Copyright (C) NEXTGRES, INC. ** 14 | ** Portions Copyright (C) PostgresPro ** 15 | ** Portions Copyright (C) Konstantin Knizhnik ** 16 | ** All Rights Reserved. ** 17 | ** ** 18 | ** Permission to use, copy, modify, and/or distribute this software for any ** 19 | ** purpose is subject to the terms specified in the License Agreement. ** 20 | ** ========================================================================= */ 21 | 22 | /* ========================================================================= */ 23 | /* -- INCLUSIONS ----------------------------------------------------------- */ 24 | /* ========================================================================= */ 25 | 26 | /* ========================================================================= */ 27 | /* -- PUBLIC DEFINITIONS --------------------------------------------------- */ 28 | /* ========================================================================= */ 29 | 30 | /* ========================================================================= */ 31 | /* -- PUBLIC MACROS -------------------------------------------------------- */ 32 | /* ========================================================================= */ 33 | 34 | /* ========================================================================= */ 35 | /* -- PUBLIC TYPEDEFS ------------------------------------------------------ */ 36 | /* ========================================================================= */ 37 | 38 | /* ========================================================================= */ 39 | /* -- PUBLIC STRUCTURES ---------------------------------------------------- */ 40 | /* ========================================================================= */ 41 | 42 | /* ========================================================================= */ 43 | /* -- PUBLIC VARIABLES ----------------------------------------------------- */ 44 | /* ========================================================================= */ 45 | 46 | /* ========================================================================= */ 47 | /* -- PUBLIC FUNCTION PROTOTYPES ------------------------------------------- */ 48 | /* ========================================================================= */ 49 | 50 | extern void ng_idcp_guc_define (void); 51 | 52 | /* ========================================================================= */ 53 | /* -- PUBLIC INLINE FUNCTIONS ---------------------------------------------- */ 54 | /* ========================================================================= */ 55 | 56 | /* ========================================================================= */ 57 | /* -- PUBLIC HELPER FUNCTIONS ---------------------------------------------- */ 58 | /* ========================================================================= */ 59 | 60 | /* vim: set ts=2 et sw=2 ft=c: */ 61 | 62 | #endif /* NGAPI_IDCP_SKEL_PUBLIC_H */ 63 | --------------------------------------------------------------------------------