Thread: Startup messages for socket protocol
Hi. I've been trying to get a connection working to a PostgreSQL server through the socket-level protocol. I've therefore been looking at fe-connect.c and fe-protocol3.c in the src/interfaces/libpq folder. Reading those sources, I understood, that the startup message should begin with a request from the client with the protocol number. In fe-protocol3.c, build_startup_message(): /* Protocol version comes first. */ if (packet) { ProtocolVersion pv = htonl(conn->pversion); memcpy(packet + packet_len, &pv, sizeof(ProtocolVersion)); } packet_len += sizeof(ProtocolVersion); However, when I try to send this as the first thing, I get disconnected by the server. Reading what the psql program does, I first get an 8 byte message containing this: \000\000\000\008\004\210\022/ This seems to work, but I'm at a loss pinpointing in the libpq source code where that would fit in the protocol. Enlightenment would be very welcome. -- Guillaume Yziquel
Guillaume Yziquel <guillaume.yziquel@citycable.ch> writes: > However, when I try to send this as the first thing, I get disconnected > by the server. Reading what the psql program does, I first get an 8 byte > message containing this: > \000\000\000\008\004\210\022/ > This seems to work, but I'm at a loss pinpointing in the libpq source > code where that would fit in the protocol. [ scratches head... ] You should be getting either an ErrorResponse message or some AuthenticationXXX variant, and both of those would start with an ASCII character ('E' or 'R'). I'm not sure what the above could be, unless maybe you're somehow triggering an SSL startup handshake --- but the first returned byte should be an 'S' in that case. Are you sure you've correctly identified what is payload data, versus what's TCP overhead or something like that? It might also be enlightening to look into the server's log, especially if you were to crank log_min_messages way up so it logs debug stuff. regards, tom lane
Le Thursday 17 Mar 2011 à 10:48:50 (-0400), Tom Lane a écrit : > Guillaume Yziquel <guillaume.yziquel@citycable.ch> writes: > > However, when I try to send this as the first thing, I get disconnected > > by the server. Reading what the psql program does, I first get an 8 byte > > message containing this: > > > \000\000\000\008\004\210\022/ > > > This seems to work, but I'm at a loss pinpointing in the libpq source > > code where that would fit in the protocol. > > [ scratches head... ] You should be getting either an ErrorResponse > message or some AuthenticationXXX variant, and both of those would start > with an ASCII character ('E' or 'R'). For now, when sending \000\003\000\000 and only this, the server seems to disconnect. The recv() call on the socket returns 0, which should mean that the server has dropped the connection. > I'm not sure what the above could > be, unless maybe you're somehow triggering an SSL startup handshake --- For now, I simply have a INET socket. Just sending \000\003\000\000. No SSL handshake. > but the first returned byte should be an 'S' in that case. Are you sure > you've correctly identified what is payload data, versus what's TCP > overhead or something like that? Not sure how to identify that. What I identified was 'cannot read and server disconnects client'. When I send \000\000\000\008\004\210\022/ (which is what the psql sent me when I looked it up), I get a "N", and it waits for further data (i.e. not disconnected yet...). Then I get disconnected after some timeout, I guess. > It might also be enlightening to look into the server's log, especially > if you were to crank log_min_messages way up so it logs debug stuff. Not so familiar as to where to look, except for the file in /var/log/postgresql: 2011-03-17 14:41:34 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 14:42:12 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 14:42:21 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 14:43:46 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 14:45:01 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 14:46:38 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 15:08:04 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 15:33:08 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 15:35:36 CET LOG: longueur invalide du paquet de d?marrage 2011-03-17 16:01:16 CET LOG: longueur invalide du paquet de d?marrage In english: invalid length for startup packet. > regards, tom lane What should a typical startup packet be? psql confuses me more than it helps me. -- Guillaume Yziquel
Le Thursday 17 Mar 2011 à 16:08:55 (+0100), Guillaume Yziquel a écrit : > Le Thursday 17 Mar 2011 à 10:48:50 (-0400), Tom Lane a écrit : > > Guillaume Yziquel <guillaume.yziquel@citycable.ch> writes: > > For now, when sending \000\003\000\000 and only this, the server seems > to disconnect. The recv() call on the socket returns 0, which should > mean that the server has dropped the connection. Got it: Sent: "\000\000\000\022\000\003\000\000user\000yziquel\000\000" Read from socket: "R\000\000\000\b\000\000\000\000S\000\000\000\025client_encoding\000UTF8\000S\000\000\000\023DateStyle\000ISO, DMY\000S\000\000\000\025integer_datetimes\000on\000S\000\000\000\027IntervalStyle\000postgres\000S\000\000\000\021is_superuser\000off\000S\000\000\000\025server_encoding\000UTF8\000S\000\000\000\025server_version\0008.4.7\000S\000\000\000\"session_authorization\000yziquel\000S\000\000\000$standard_conforming_strings\000off\000S\000\000\000\023TimeZone\000localtime\000K\000\000\000\012\000\000|\197{\177\235?Z\000\000\000\005I" Needed to prepend the length of the packet. Didn't appear very clearly in the docs. But this link got me more info: http://blog.endpoint.com/2010/05/finding-postgresql-version-without.html Thanks for your time. -- Guillaume Yziquel