Exemplo n.º 1
0
/* Try to restablish a broken session. A single try is made and the result
 * reported back. RELP_RET_OK if we could get a new session, a RELP error state
 * otherwise (e.g. RELP_RET_SESSION_BROKEN, but could also be a more precise
 * error code). If the session can be re-established, any unsent frames are
 * resent. The function returns only after that happened.
 * rgerhards, 2008-03-22
 */
relpRetVal
relpSessTryReestablish(relpSess_t *pThis)
{
	relpSessUnacked_t *pUnackedEtry;

	ENTER_RELPFUNC;
	RELPOBJ_assert(pThis, Sess);
	assert(pThis->sessState = eRelpSessState_BROKEN);

	CHKRet(relpTcpAbortDestruct(&pThis->pTcp));
	CHKRet(relpSessConnect(pThis, pThis->protFamily, pThis->srvPort, pThis->srvAddr));
	/* if we reach this point, we could re-establish the session. We now
	 * need to resend any unacked data. Note that we need to patch in new txnr's
	 * into the existing frames. We need to do a special send command, as the usual
	 * one would maintain the unacked list, what we can not do right now (because
	 * it is not to be modified.
	 */
	pUnackedEtry = pThis->pUnackedLstRoot;
	if(pUnackedEtry != NULL)
		pThis->pEngine->dbgprint("relp session %p reestablished, now resending %d unacked frames\n",
					  pThis, pThis->lenUnackedLst);
	while(pUnackedEtry != NULL) {
pThis->pEngine->dbgprint("resending frame '%s'\n", pUnackedEtry->pSendbuf->pData + 9 - pUnackedEtry->pSendbuf->lenTxnr);
		CHKRet(relpFrameRewriteTxnr(pUnackedEtry->pSendbuf, pThis->txnr));
		pThis->txnr = relpEngineNextTXNR(pThis->txnr);
		CHKRet(relpSendbufSendAll(pUnackedEtry->pSendbuf, pThis, 0));
		pUnackedEtry = pUnackedEtry->pNext;
	}

finalize_it:
pThis->pEngine->dbgprint("after TryReestablish, sess state %d\n", pThis->sessState);
	LEAVE_RELPFUNC;
}
Exemplo n.º 2
0
/* This functions sends a complete sendbuf (a blocking call). It
 * is intended for use by clients. Do NOT use it on servers as
 * that will block other activity. bAddToUnacked specifies if the
 * sendbuf should be linked to the unacked list (if 1). If it is 0
 * this shall NOT happen. Mode 0 is used for session reestablishment,
 * when the unacked list needs to be retransmitted.
 * rgerhards, 2008-03-19
 */
relpRetVal
relpSendbufSendAll(relpSendbuf_t *pThis, relpSess_t *pSess, int bAddToUnacked)
{
	ssize_t lenToWrite;
	ssize_t lenWritten;
	ENTER_RELPFUNC;
	RELPOBJ_assert(pThis, Sendbuf);
	RELPOBJ_assert(pSess,  Sess);

	lenToWrite = pThis->lenData - pThis->bufPtr;
	while(lenToWrite != 0) {
		lenWritten = lenToWrite;
//pSess->pEngine->dbgprint("sendbuf len %d, still to write %d\n", (int) pThis->lenData, (int) lenToWrite);
		CHKRet(relpTcpSend(pSess->pTcp, pThis->pData + (9 - pThis->lenTxnr) + pThis->bufPtr, &lenWritten));

		if(lenWritten == -1) {
			ABORT_FINALIZE(RELP_RET_IO_ERR);
		} else if(lenWritten == lenToWrite) {
			lenToWrite = 0;
		} else {
			pThis->bufPtr += lenWritten;
			lenToWrite = pThis->lenData - pThis->bufPtr;
		}
	}

	/* ok, we now have sent the full buf. So we now need to add it to the unacked list, so that
	 * we know what to do when the "rsp" packet comes in. -- rgerhards, 2008-03-20
	 */
	if(bAddToUnacked) {
		if((iRet = relpSessAddUnacked(pSess, pThis)) != RELP_RET_OK) {
			relpSendbufDestruct(&pThis);
			FINALIZE;
		}
pSess->pEngine->dbgprint("sendbuf added to unacked list\n");
#if 0
{
	relpSessUnacked_t *pUnackedEtry;
	pUnackedEtry = pThis->pUnackedLstRoot;
	if(pUnackedEtry != NULL) {
pThis->pEngine->dbgprint("resending frame '%s'\n", pUnackedEtry->pSendbuf->pData + 9 - pUnackedEtry->pSendbuf->lenTxnr);
		CHKRet(relpFrameRewriteTxnr(pUnackedEtry->pSendbuf, pThis->txnr));
		pThis->txnr = relpEngineNextTXNR(pThis->txnr);
		CHKRet(relpSendbufSendAll(pUnackedEtry->pSendbuf, pThis, 0));
		pUnackedEtry = pUnackedEtry->pNext;
	}
}
#endif
	}
else pSess->pEngine->dbgprint("sendbuf NOT added to unacked list\n");

finalize_it:
	LEAVE_RELPFUNC;
}
Exemplo n.º 3
0
/* Send a command to the server.
 * This is a "raw" send function that just sends the command but does not
 * care about the receive loop or session state. This has been put into its
 * own function as some functionality (most importantly session init!) requires
 * handling that is other than the regular command/response mode.
 * rgerhards, 2008-03-19
 */
static relpRetVal
relpSessRawSendCommand(relpSess_t *pThis, unsigned char *pCmd, size_t lenCmd,
		    unsigned char *pData, size_t lenData, relpRetVal (*rspHdlr)(relpSess_t*,relpFrame_t*))
{
	relpSendbuf_t *pSendbuf;

	ENTER_RELPFUNC;
	RELPOBJ_assert(pThis, Sess);

	CHKRet(relpFrameBuildSendbuf(&pSendbuf, pThis->txnr, pCmd, lenCmd, pData, lenData, pThis, rspHdlr));
	pThis->txnr = relpEngineNextTXNR(pThis->txnr);
	/* now send it */
	pThis->pEngine->dbgprint("frame to send: '%s'\n", pSendbuf->pData + (9 - pSendbuf->lenTxnr));
	iRet = relpSendbufSendAll(pSendbuf, pThis, 1);

	if(iRet == RELP_RET_IO_ERR) {
		pThis->pEngine->dbgprint("relp session %p flagged as broken, IO error\n", pThis);
		pThis->sessState = eRelpSessState_BROKEN;
		ABORT_FINALIZE(RELP_RET_SESSION_BROKEN);
	}

finalize_it:
	LEAVE_RELPFUNC;
}