示例#1
0
/* Send a response to the client.
 * rgerhards, 2008-03-19
 */
relpRetVal
relpSessSendResponse(relpSess_t *pThis, relpTxnr_t txnr, unsigned char *pData, size_t lenData)
{
	relpSendbuf_t *pSendbuf;

	ENTER_RELPFUNC;
	RELPOBJ_assert(pThis, Sess);

	CHKRet(relpFrameBuildSendbuf(&pSendbuf, txnr, (unsigned char*)"rsp", 3,
				     pData, lenData, pThis, NULL));
	/* now enqueue it to the sendq (which means "send it" ;)) */
	CHKRet(relpSendqAddBuf(pThis->pSendq, pSendbuf, pThis->pTcp));

finalize_it:
	if(iRet != RELP_RET_OK) {
		if(iRet == RELP_RET_IO_ERR) {
			pThis->pEngine->dbgprint("relp session %p is broken, io error\n", pThis);
			pThis->sessState = eRelpSessState_BROKEN;
			}

		if(pSendbuf != NULL)
			relpSendbufDestruct(&pSendbuf);
	}

	LEAVE_RELPFUNC;
}
示例#2
0
/** Destruct a RELP sess instance
 */
relpRetVal
relpSessDestruct(relpSess_t **ppThis)
{
	relpSess_t *pThis;
	relpSessUnacked_t *pUnacked;
	relpSessUnacked_t *pUnackedToDel;

	ENTER_RELPFUNC;
	assert(ppThis != NULL);
	pThis = *ppThis;
	RELPOBJ_assert(pThis, Sess);

	/* pTcp may be NULL if we run into the destructor due to an error that occured
	 * during construction.
	 */
	if(pThis->pTcp != NULL) {
		if(pThis->pSrv != NULL) {
			relpSessSrvDoDisconnect(pThis);
		} else {
			/* we are at the client side of the connection */
			if(   pThis->sessState != eRelpSessState_DISCONNECTED
			   && pThis->sessState != eRelpSessState_BROKEN) {
				relpSessCltDoDisconnect(pThis);
			}
		}
	}

	if(pThis->pSendq != NULL)
		relpSendqDestruct(&pThis->pSendq);
	if(pThis->pTcp != NULL)
		relpTcpDestruct(&pThis->pTcp);

	/* unacked list */
	for(pUnacked = pThis->pUnackedLstRoot ; pUnacked != NULL ; ) {
		pUnackedToDel = pUnacked;
		pUnacked = pUnacked->pNext;
		relpSendbufDestruct(&pUnackedToDel->pSendbuf);
		free(pUnackedToDel);
	}

	free(pThis->srvPort);
	free(pThis->srvAddr);
	free(pThis->clientIP);
	free(pThis->pristring);
	free(pThis->ownCertFile);
	free(pThis->privKeyFile);
	relpSessFreePermittedPeers(pThis);

	pthread_mutex_destroy(&pThis->mutSend);
	/* done with de-init work, now free object itself */
	free(pThis);
	*ppThis = NULL;

	LEAVE_RELPFUNC;
}
示例#3
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;
}
示例#4
0
/* Send a command hint to the remote peer. This function works for the
 * server-side of the connection. A modified version must be used for the
 * client side (because we have different ways of sending the data). We do
 * not yet need the client side. If we do, way should think about a generic
 * approach, eg by using function pointers for the send function.
 * rgerhards, 2008-03-31
 */
static relpRetVal
relpSessSrvSendHint(relpSess_t *pThis, unsigned char *pHint, size_t lenHint,
		    unsigned char *pData, size_t lenData)
{
	relpSendbuf_t *pSendbuf = NULL;

	ENTER_RELPFUNC;
	assert(pHint != NULL);
	assert(lenHint != 0);
	RELPOBJ_assert(pThis, Sess);

	CHKRet(relpFrameBuildSendbuf(&pSendbuf, 0, pHint, lenHint, pData, lenData, pThis, NULL));
	/* now send it */
	pThis->pEngine->dbgprint("hint-frame to send: '%s'\n", pSendbuf->pData + (9 - pSendbuf->lenTxnr));
	CHKRet(relpSendbufSend(pSendbuf, pThis->pTcp));

finalize_it:
	if(pSendbuf != NULL)
		relpSendbufDestruct(&pSendbuf);
	LEAVE_RELPFUNC;
}