Protocol de-synchronisation bug, bogus query sent
От | Craig Ringer |
---|---|
Тема | Protocol de-synchronisation bug, bogus query sent |
Дата | |
Msg-id | 53A25C95.707@2ndquadrant.com обсуждение исходный текст |
Ответы |
Re: Protocol de-synchronisation bug, bogus query sent
Re: Protocol de-synchronisation bug, bogus query sent |
Список | pgsql-odbc |
Hi folks I've found a bug in psqlODBC, in CC_send_query_append, where psqlODBC gets out of sync with the server's idea of the connection state and both wait for each other indefinitely. So far I've only reproduced it as part of debugging a larger issue. I've only actually seen it when psqlODBC establishes an "isolated" XA connection after failing to acquire a lock on the DTC connection in IAsyncPG::getLockedXAConn(). If the client has specified a connect-time query string with a DSN like: DRIVER={PostgreSQL ANSI};SERVER=LOCALHOST;DATABASE=postgres;A6=set search_path to someschema;UID=;PWD=;BI=-5;debug=1;commlog=1; ... but it's clearly a bug in its own right, so I'll write it up here and propose a fix. Patch attached, or you can pull the branch: fix-febe-protocol-desync-emptyquery from https://github.com/ringerc/psqlODBC.git The whole code block around connection.c:3082 appears to be attempting to send an empty query in order to elicit an 'I' (EmptyQueryResponse) message. It sends a malformed protocol message: SOCK_put_string(self->sock, "Q "); SOCK_flush_output(self->sock); so the server just waits for the rest of the message, never responding. When the connection is killed by program exit later, the server will log: LOG: unexpected EOF within message length word LOG: disconnection: session time: 0:00:08.910 user=Administrator database=XXXX host=127.0.0.1 port=53705 LOG: could not receive data from client: No connection could be made because the target machine actively refused it. That's because the V3 protocol specifies that the message format for Query is: 'Q' [32 bit integer] [query string] http://www.postgresql.org/docs/current/static/protocol-message-formats.html ... but psqlODBC just sends: 'Q' '\x20' '\x00' If it is really necessary to go through this empty-query dance, then for the V3 protocol the correct message would be: /* Send an empty query to elicit an 'I' (EmptyQueryResponse) * from the server */ SOCK_put_char(self->sock, 'Q'); SOCK_put_int(self->sock, 5, 4); SOCK_put_char(self->sock, '\0'); Since no 'I' message is ever received the next message is 'Z' (ReadyForQuery). psqlODBC consumes this and carries on waiting for the next message, as it has set emptyreqs=1 to expect 'I' messages. So it waits forever, since the server thinks it's waiting for psqlODBC to finish sending the prior protocol message. It isn't clear to me why psqlODBC does this weird dance with empty queries at all, but it's certainly doing it wrong. The attached patch fixes the immediate problem, but I'd like to see if this can be simplified out entirely in favour of, in ascending size-of-work order, (a) using a protocol sync message, then (b) deleting as much as possible of this custom protocol handling code entirely and using libpq. -- Craig Ringer http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
Вложения
В списке pgsql-odbc по дате отправления: