pgpool2.git / summary / log / commit / refs
commit ffb998517bb91c512b77fbe1ca8ee331e492f131
Author: Takuma Hoshiai <hoshiai@sraoss.co.jp>
Date: Wed Nov 21 02:49:06 2018 +0000
Fix to sort startup packet's parameters sent by client.
If order of startup packet's parameters differ between cached connection pools and connection request, did't use connection pool ,and created new connection pool.
Per bug 444.
src/protocol/child.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/src/protocol/child.c b/src/protocol/child.c
index 1835afc60..678d42671 100644
--- a/src/protocol/child.c
+++ b/src/protocol/child.c
@@ -517,6 +517,13 @@ read_startup_packet(POOL_CONNECTION * cp)
int protov;
int len;
char *p;
+ char **guc_options;
+ int opt_num = 0;
+ char *sp_sort;
+ char *tmpopt;
+ int i;
+ int j;
+
sp = (StartupPacket *) palloc0(sizeof(*sp));
enable_authentication_timeout();
@@ -543,7 +550,6 @@ read_startup_packet(POOL_CONNECTION * cp)
memcpy(&protov, sp->startup_packet, sizeof(protov));
sp->major = ntohl(protov) >> 16;
sp->minor = ntohl(protov) & 0x0000ffff;
- p = sp->startup_packet;
cp->protoVersion = sp->major;
switch (sp->major)
@@ -560,6 +566,58 @@ read_startup_packet(POOL_CONNECTION * cp)
break;
case PROTO_MAJOR_V3: /* V3 */
+ /* copy startup_packet */
+ sp_sort = palloc0(len);
+ memcpy(sp_sort,sp->startup_packet,len);
+
+ p = sp_sort;
+ p += sizeof(int); /* skip protocol version info */
+ /* count the number of options */
+ while (*p)
+ {
+ p += (strlen(p) + 1); /* skip option name */
+ p += (strlen(p) + 1); /* skip option value */
+ opt_num ++;
+ }
+ guc_options = (char **)palloc0(opt_num * sizeof(char *));
+ /* get guc_option name list */
+ p = sp_sort + sizeof(int);
+ for (i = 0; i < opt_num; i++)
+ {
+ guc_options[i] = p;
+ p += (strlen(p) + 1); /* skip option name */
+ p += (strlen(p) + 1); /* skip option value */
+ }
+ /* sort option name using bubble sort */
+ for (i = 0; i < opt_num - 1 ; i++)
+ {
+ for (j = i + 1; j < opt_num; j++)
+ {
+ if (strcmp(guc_options[i], guc_options[j]) > 0)
+ {
+ tmpopt = guc_options[i];
+ guc_options[i] = guc_options[j];
+ guc_options[j] = tmpopt;
+ }
+ }
+ }
+
+ p = sp->startup_packet + sizeof(int); /* skip protocol version info */
+ for (i = 0; i < opt_num; i++)
+ {
+ tmpopt = guc_options[i];
+ memcpy(p, tmpopt ,strlen(tmpopt) + 1); /* memcpy option name */
+ p += (strlen(tmpopt) + 1);
+ tmpopt += (strlen(tmpopt) + 1);
+ memcpy(p, tmpopt ,strlen(tmpopt) + 1); /* memcpy option value */
+ p += (strlen(tmpopt) + 1);
+ }
+
+ pfree(guc_options);
+ pfree(sp_sort);
+
+ p = sp->startup_packet;
+
p += sizeof(int); /* skip protocol version info */
while (*p)
[parent: 6053123f0763]