void WriteReadyHandler_Connect(AsyncCommBuffer buffer) { /* Check the error from socket FD. */ bool shouldclose = false; int error = 0; socklen_t errlen = sizeof(error); elog(DEBUG3, "AsyncConn FD %d is write ready for checking connection.", buffer->FD); int res = getsockopt(buffer->FD, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen); if (res < 0) { elog(WARNING, "getsocketopt() on FD %d have errors raised. errno %d", buffer->FD, errno); shouldclose = true; } else if ( error > 0 ) { elog(WARNING, "FD %d having errors raised. errno %d", buffer->FD, error); shouldclose = true; } if ( setConnectionLongTermNoDelay(buffer->FD) != FUNC_RETURN_OK ) { shouldclose = true; } if ( shouldclose ) { ErrorHandler_Connect(buffer); forceCloseFileDesc(buffer); return; } elog(DEBUG3, "AsyncConn FD %d is a good connection.", buffer->FD); /* Change to normal registered FD by changing callbacks and arguments. */ AsyncCommBufferHandlerUser userdata = (AsyncCommBufferHandlerUser)(buffer->UserData); buffer->ActionMask = userdata->ActionMaskForAfterConn; buffer->UserData = userdata->UserDataForAfterConn; buffer->Methods = userdata->MethodsForAfterConn; Assert(getSMBContentSize(&(buffer->ReadBuffer)) == 0); elog(DEBUG3, "Freed AsyncComm Conn context ( connected )."); rm_pfree(AsyncCommContext, userdata); }
void WritePostHandler_Message(AsyncCommBuffer buffer) { AsyncCommMessageHandlerContext context = (AsyncCommMessageHandlerContext) (buffer->UserData); int msgsize = getSMBContentSize(&(buffer->ReadBuffer)); if ( msgsize == 0 ) { Assert( context->MessageSentHandler != NULL ); context->MessageSentHandler(context); } elog(DEBUG3, "Write post handler for client message is called."); performErrorActionForWritingMessage(buffer, false); }
void SimpleStringReplaceFirst(SimpStringPtr str, char *oldstr, char *newstr) { char *pos = strstr(str->Str, oldstr); /* If the old string does not exist, no need to do any update. */ if ( pos == NULL ) return; SelfMaintainBufferData smb; initializeSelfMaintainBuffer(&smb, str->Context); if ( str->Str != pos ) { appendSelfMaintainBuffer(&smb, str->Str, pos - str->Str); } int oldstrlen = strlen(oldstr); appendSelfMaintainBuffer(&smb, newstr, strlen(newstr)); if ( oldstrlen + (pos - str->Str) < str->Len ) { appendSMBStr(&smb, pos + oldstrlen); } setSimpleStringWithContent(str, smb.Buffer, getSMBContentSize(&smb)); destroySelfMaintainBuffer(&smb); }
void ReadPostHandler_Message(AsyncCommBuffer buffer) { AsyncCommMessageHandlerContext context = (AsyncCommMessageHandlerContext) (buffer->UserData); int msgsize = getSMBContentSize(&(buffer->ReadBuffer)); if ( !context->inMessage ) { /* Check if having message head. */ if ( msgsize >= DRM_MSGFRAME_HEADTAGSIZE ) { char *p = buffer->ReadBuffer.Buffer; if ( DRM_MSGFRAME_HEADTAG_MATCHED(p) ) { context->inMessage = true; } else { /* * This protocol does not allow content not wrapped by message * framework, therefore, here we force to close the connection. * No more processing is needed. */ buffer->forcedClose = true; buffer->toClose = true; elog(WARNING, "AsyncComm framework received invalid message head. " "Close the connection FD %d.", buffer->FD); return; } } else { /* Not a complete message frame head tag. Wait for new content. */ return; } } /* * If we are in one message, and its header was completed received, we parse * the header to get the expected message content. */ if ( context->inMessage && msgsize >= DRM_MSGFRAME_HEADSIZE ) { /* Check if achieve the end of message. */ RMMessageHead header = (RMMessageHead)(buffer->ReadBuffer.Buffer); if ( DRM_MSGFRAME_TOTALSIZE(header) <= msgsize ) { char *p = buffer->ReadBuffer.Buffer + header->MessageSize + DRM_MSGFRAME_HEADSIZE; if ( DRM_MSGFRAME_TAILTAG_MATCHED(p) ) { /* Skip heart-beat message log. */ elog((header->MessageID == REQUEST_QD_REFRESH_RESOURCE || header->MessageID == REQUEST_RM_IMALIVE || header->MessageID == RESPONSE_QD_REFRESH_RESOURCE || header->MessageID == RESPONSE_RM_IMALIVE) ? DEBUG3 : LOG, "AsyncComm framework receives message %d from FD %d", header->MessageID, buffer->FD); /* Get complete message and call the handler. */ if ( context->MessageRecvedHandler != NULL ) { /* Check and perform error injection action. */ performMessageForErrorAction(header->MessageID, true, /* read content. */ true, /* before processing. */ buffer); if ( CAN_PROCESS_RECEIVED(buffer->forceErrorAction) ) { header = (RMMessageHead)(buffer->ReadBuffer.Buffer); context->MessageRecvedHandler(context, header->MessageID, header->Mark1, header->Mark2, buffer->ReadBuffer.Buffer + DRM_MSGFRAME_HEADSIZE, header->MessageSize); } /* Check and perform error injection action. */ performMessageForErrorAction(header->MessageID, true, /* read content. */ false, /* after processing. */ buffer); } /* Shift out this message */ shiftLeftSelfMaintainBuffer(&(buffer->ReadBuffer), DRM_MSGFRAME_TOTALSIZE(header)); /* Set out of the message */ context->inMessage = false; } else { /* We get wrong message content. */ elog(WARNING, "AsyncComm framework received wrong message tail " "content."); buffer->forcedClose = true; buffer->toClose = true; } } } }