int FileRepConnServer_ReceiveMessageLength(uint32 *len) { int32 length; if (pq_getbytes((char*) &length, 4) == EOF) { ereport(WARNING, (errcode_for_socket_access(), errmsg("receive EOF on connection: %m"))); return STATUS_ERROR; } length = ntohl(length); if (length < 4) { ereport(WARNING, (errmsg("receive unexpected message length on connection"))); return STATUS_ERROR; } length -= 4; *len = length; return STATUS_OK; }
/* * readLogMessage - read log message sent from client */ static void readLogMessage(void *buf, int plen) { int32 len; if (pq_getbytes((char *) &len, 4) == EOF) { ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("QDSYNC: incomplete log packet"))); } len = ntohl(len); len -= 4; pq_getbytes(buf, len); elog(DEBUG4, "QDSYNC: readLogMessage: plen %d len: %d", plen, len); }
static int Wrappered_pq_getbytes(char *s, size_t len) { #if (PG_VERSION_NUM >= 90401) \ || ((PG_VERSION_NUM >= 90306) && (PG_VERSION_NUM < 90400)) \ || ((PG_VERSION_NUM >= 90210) && (PG_VERSION_NUM < 90300)) \ || ((PG_VERSION_NUM >= 90115) && (PG_VERSION_NUM < 90200)) \ || ((PG_VERSION_NUM >= 90019) && (PG_VERSION_NUM < 90100)) pq_startmsgread(); #endif return pq_getbytes(s, len); }
int FileRepConnServer_ReceiveMessageData( char *data, uint32 length) { if (pq_getbytes(data, length) == EOF) { ereport(WARNING, (errcode_for_socket_access(), errmsg("receive EOF on connection: %m"))); return STATUS_ERROR; } return STATUS_OK; }
/* -------------------------------- * pq_getmessage - get a message with length word from connection * * The return value is placed in an expansible StringInfo, which has * already been initialized by the caller. * Only the message body is placed in the StringInfo; the length word * is removed. Also, s->cursor is initialized to zero for convenience * in scanning the message contents. * * If maxlen is not zero, it is an upper limit on the length of the * message we are willing to accept. We abort the connection (by * returning EOF) if client tries to send more than that. * * returns 0 if OK, EOF if trouble * -------------------------------- */ int pq_getmessage(StringInfo s, int maxlen) { int32 len; resetStringInfo(s); /* Read message length word */ if (pq_getbytes((char *) &len, 4) == EOF) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("unexpected EOF within message length word"))); return EOF; } len = ntohl(len); if (len < 4 || (maxlen > 0 && len > maxlen)) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid message length"))); return EOF; } len -= 4; /* discount length itself */ if (len > 0) { /* * Allocate space for message. If we run out of room (ridiculously * large message), we will elog(ERROR), but we want to discard the * message body so as not to lose communication sync. */ PG_TRY(); { enlargeStringInfo(s, len); } PG_CATCH(); { if (pq_discardbytes(len) == EOF) ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("incomplete message from client"))); PG_RE_THROW(); } PG_END_TRY(); /* And grab the message */ if (pq_getbytes(s->data, len) == EOF) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("incomplete message from client"))); return EOF; } s->len = len; /* Place a trailing null per StringInfo convention */ s->data[len] = '\0'; } return 0; }
/* * Receive Startup packet * Response Client Authentication */ int FileRepConnServer_ReceiveStartupPacket(void) { uint32 length; int status = STATUS_OK; char *buf = NULL; pq_init(); status = FileRepConnServer_ReceiveMessageLength(&length); if (status != STATUS_OK) { goto exit; } if (length < (uint32) sizeof(ProtocolVersion) || length > MAX_STARTUP_PACKET_LENGTH) { status = STATUS_ERROR; ereport(WARNING, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid length of startup packet"), FileRep_errcontext())); goto exit; } buf = (char *)malloc(length +1); if (buf == NULL) { ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("not enough memory to allocate buffer for startup packet"), FileRep_errcontext())); } memset(buf, 0, length + 1); if (pq_getbytes(buf, length) == EOF) { status = STATUS_ERROR; ereport(WARNING, (errcode_for_socket_access(), errmsg("receive EOF on connection: %m"), FileRep_errcontext())); goto exit; } port->proto = ntohl(*((ProtocolVersion *) buf)); if (PG_PROTOCOL_MAJOR(port->proto) >= 3) { /* uint32 offset = sizeof(ProtocolVersion);*/ /* * tell the client that it is authorized (no pg_hba.conf and * password are required). */ StringInfoData buf; /* sends AUTH_REQ_OK back to client */ FakeClientAuthentication(port); /* send to client that we are ready to receive data */ /* similar to ReadyForQuery(DestRemoteExecute); */ pq_beginmessage(&buf, 'Z'); pq_sendbyte(&buf, 'I'); pq_endmessage(&buf); pq_flush(); } else { ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not supported version"), FileRep_errcontext())); } exit: if (buf) { free(buf); buf = NULL; } return status; }