/* Send a command to the server. * The is the "regular" function which ensures that server messages are received * and messages are only sent when we have space left in our window. This function * must only be called after the session is fully initialized. Calling it before * initialization is finished will probably hang the client. * rgerhards, 2008-03-19 */ relpRetVal relpSessSendCommand(relpSess_t *pThis, unsigned char *pCmd, size_t lenCmd, unsigned char *pData, size_t lenData, relpRetVal (*rspHdlr)(relpSess_t*,relpFrame_t*)) { ENTER_RELPFUNC; RELPOBJ_assert(pThis, Sess); /* this both reads server responses as well as makes sure we have space * left in our window. */ CHKRet(relpSessWaitState(pThis, eRelpSessState_READY_TO_SEND, pThis->timeout)); /* re-try once if automatic retry mode is set */ if(pThis->bAutoRetry && pThis->sessState == eRelpSessState_BROKEN) { CHKRet(relpSessTryReestablish(pThis)); } /* then send our data */ if(pThis->sessState == eRelpSessState_BROKEN) ABORT_FINALIZE(RELP_RET_SESSION_BROKEN); CHKRet(relpSessRawSendCommand(pThis, pCmd, lenCmd, pData, lenData, rspHdlr)); finalize_it: LEAVE_RELPFUNC; }
/* Send a command to the server. * The is the "regular" function which ensures that server messages are received * and messages are only sent when we have space left in our window. This function * must only be called after the session is fully initialized. Calling it before * initialization is finished will probably hang the client. * rgerhards, 2008-03-19 */ relpRetVal relpSessSendCommand(relpSess_t *pThis, unsigned char *pCmd, size_t lenCmd, unsigned char *pData, size_t lenData, relpRetVal (*rspHdlr)(relpSess_t*,relpFrame_t*)) { ENTER_RELPFUNC; RELPOBJ_assert(pThis, Sess); /* this both reads server responses as well as makes sure we have space left * in our window. We provide a nearly eternal timeout (3 minutes). If we are not * ready to send in that period, something is awfully wrong. TODO: we may want * to make this timeout configurable, but I don't think it is a priority. */ //CHKRet(relpSessWaitState(pThis, eRelpSessState_READY_TO_SEND, 2)); CHKRet(relpSessWaitState(pThis, eRelpSessState_READY_TO_SEND, 180)); /* re-try once if automatic retry mode is set */ pThis->pEngine->dbgprint("send command relp sess state %d\n", pThis->sessState); if(pThis->bAutoRetry && pThis->sessState == eRelpSessState_BROKEN) { pThis->pEngine->dbgprint("SendCommand does auto-retry\n"); CHKRet(relpSessTryReestablish(pThis)); } pThis->pEngine->dbgprint("sendcommand ready to send, relp sess state %d\n", pThis->sessState); /* then send our data */ if(pThis->sessState == eRelpSessState_BROKEN) ABORT_FINALIZE(RELP_RET_SESSION_BROKEN); CHKRet(relpSessRawSendCommand(pThis, pCmd, lenCmd, pData, lenData, rspHdlr)); finalize_it: LEAVE_RELPFUNC; }
/* Connect to the server. All session parameters (like remote address) must * already have been set. * rgerhards, 2008-03-19 */ relpRetVal relpSessConnect(relpSess_t *pThis, int protFamily, unsigned char *port, unsigned char *host) { relpOffers_t *pOffers; unsigned char *pszOffers = NULL; size_t lenOffers; ENTER_RELPFUNC; RELPOBJ_assert(pThis, Sess); CHKRet(relpSessFixCmdStates(pThis)); if(pThis->srvAddr == NULL) { /* initial connect, need to save params */ pThis->protFamily = protFamily; if((pThis->srvPort = (unsigned char*) strdup((char*)port)) == NULL) ABORT_FINALIZE(RELP_RET_OUT_OF_MEMORY); if((pThis->srvAddr = (unsigned char*) strdup((char*)host)) == NULL) ABORT_FINALIZE(RELP_RET_OUT_OF_MEMORY); } /* (re-)init some counters */ pThis->txnr = 1; pThis->sessType = eRelpSess_Client; /* indicate we have a client session */ CHKRet(relpTcpConstruct(&pThis->pTcp, pThis->pEngine)); CHKRet(relpTcpConnect(pThis->pTcp, protFamily, port, host)); relpSessSetSessState(pThis, eRelpSessState_PRE_INIT); /* create offers */ CHKRet(relpSessConstructOffers(pThis, &pOffers)); CHKRet(relpOffersToString(pOffers, NULL, 0, &pszOffers, &lenOffers)); CHKRet(relpOffersDestruct(&pOffers)); CHKRet(relpSessRawSendCommand(pThis, (unsigned char*)"open", 4, pszOffers, lenOffers, relpSessCBrspOpen)); relpSessSetSessState(pThis, eRelpSessState_INIT_CMD_SENT); CHKRet(relpSessWaitState(pThis, eRelpSessState_INIT_RSP_RCVD, pThis->timeout)); /* we now have received the server's response. Now is a good time to check if the offers * received back are compatible with what we need - and, if not, terminate the session... */ pThis->pEngine->dbgprint("pre CltConnChkOffers %d\n", iRet); CHKRet(relpSessCltConnChkOffers(pThis)); /* TODO: flag sesssion as broken if we did not succeed? */ /* if we reach this point, we have a valid relp session */ relpSessSetSessState(pThis, eRelpSessState_READY_TO_SEND); /* indicate session startup */ finalize_it: pThis->pEngine->dbgprint("end relpSessConnect, iRet %d\n", iRet); if(pszOffers != NULL) free(pszOffers); LEAVE_RELPFUNC; }