static int acquireBundles(AcqWorkArea *work, Object zco, unsigned long senderEngineNbr) { char engineNbrString[21]; char senderEidBuffer[SDRSTRING_BUFSZ]; char *senderEid; isprintf(engineNbrString, sizeof engineNbrString, "%lu", senderEngineNbr); senderEid = senderEidBuffer; getSenderEid(&senderEid, engineNbrString); if (bpBeginAcq(work, 0, senderEid) < 0) { putErrmsg("Can't begin acquisition of bundle(s).", NULL); return -1; } if (bpLoadAcq(work, zco) < 0) { putErrmsg("Can't continue bundle acquisition.", NULL); return -1; } if (bpEndAcq(work) < 0) { putErrmsg("Can't end acquisition of bundle(s).", NULL); return -1; } return 0; }
static int acquireRedBundles(AcqWorkArea *work, Object zco, uvast senderEngineNbr) { if (bpBeginAcq(work, 0, NULL) < 0) { putErrmsg("Can't begin acquisition of bundle(s).", NULL); return -1; } if (bpLoadAcq(work, zco) < 0) { putErrmsg("Can't continue bundle acquisition.", NULL); return -1; } if (bpEndAcq(work) < 0) { putErrmsg("Can't end acquisition of bundle(s).", NULL); return -1; } return 0; }
static void *receiveBundles(void *parm) { /* Main loop for bundle reception thread */ ReceiveThreadParms *parms = (ReceiveThreadParms *) parm; int threadRunning = 1; AcqWorkArea *work; char *buffer; buffer = MTAKE(TCPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("tcpclo receiver can't get TCP buffer", NULL); return NULL; } work = bpGetAcqArea(parms->vduct); if (work == NULL) { putErrmsg("tcpclo receiver can't get acquisition work area", NULL); MRELEASE(buffer); return NULL; } iblock(SIGTERM); while (threadRunning && *(parms->cloRunning)) { if(*(parms->bundleSocket) < 0) { snooze(1); /*Retry later*/ continue; } if (bpBeginAcq(work, 0, NULL) < 0) { putErrmsg("Can't begin acquisition of bundle.", NULL); threadRunning = 0; continue; } switch (receiveBundleByTcpCL(*(parms->bundleSocket), work, buffer)) { case -1: putErrmsg("Can't acquire bundle.", NULL); pthread_mutex_lock(parms->mutex); closesocket(*(parms->bundleSocket)); *(parms->bundleSocket) = -1; pthread_mutex_unlock(parms->mutex); continue; case 0: /* Shutdown message */ /* Go back to the start of the while loop */ pthread_mutex_lock(parms->mutex); closesocket(*(parms->bundleSocket)); *(parms->bundleSocket) = -1; pthread_mutex_unlock(parms->mutex); continue; default: break; /* Out of switch. */ } if (bpEndAcq(work) < 0) { putErrmsg("Can't end acquisition of bundle.", NULL); threadRunning = 0; } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } /* End of receiver thread; release resources. */ bpReleaseAcqArea(work); MRELEASE(buffer); return NULL; }
static int handleGreenSegment(AcqWorkArea *work, LtpSessionId *sessionId, unsigned char endOfBlock, unsigned int offset, unsigned int length, Object zco, unsigned int *buflen, char **buffer) { Sdr sdr = getIonsdr(); static LtpSessionId currentSessionId = { 0, 0 }; static unsigned int currentOffset = 0; unsigned int fillLength; ZcoReader reader; int result; if (zco == 0) /* Import session canceled. */ { bpCancelAcq(work); currentSessionId.sourceEngineId = 0; currentSessionId.sessionNbr = 0; currentOffset = 0; return 0; } if (zco_source_data_length(sdr, zco) != length) { return 0; /* Just discard the segment. */ } if (sessionId->sourceEngineId != currentSessionId.sourceEngineId || sessionId->sessionNbr != currentSessionId.sessionNbr) { /* Did not receive end-of-block segment for the * block that was being received. Discard the * partially received bundle in the work area, * if any. */ bpCancelAcq(work); currentSessionId.sourceEngineId = 0; currentSessionId.sessionNbr = 0; currentOffset = 0; } if (currentOffset == 0) { /* Start new green bundle acquisition. */ if (bpBeginAcq(work, 0, NULL) < 0) { putErrmsg("Can't begin acquisition of bundle.", NULL); return -1; } currentSessionId.sourceEngineId = sessionId->sourceEngineId; currentSessionId.sessionNbr = sessionId->sessionNbr; } if (offset < currentOffset) /* Out of order. */ { return 0; /* Just discard the segment. */ } if (offset > currentOffset) { /* Convergence layer must not deliver incomplete * bundles to BP. Practically speaking, this * gap in segment sequence must be treated as * malformation of the bundle. */ work->malformed = 1; /* But continue bundle acquisition anyway, in * case the incomplete bundle is useful for some * diagnostic purpose. */ fillLength = offset - currentOffset; if (fillLength > *buflen) { /* Make buffer big enough for the fill * data. */ if (*buffer) { MRELEASE(*buffer); *buflen = 0; } *buffer = MTAKE(fillLength); if (*buffer == NULL) { /* Gap is too large to fill. * Might be a DOS attack; cancel * acquisition. */ bpCancelAcq(work); currentSessionId.sourceEngineId = 0; currentSessionId.sessionNbr = 0; currentOffset = 0; return 0; } *buflen = fillLength; } memset(*buffer, 0, fillLength); if (bpContinueAcq(work, *buffer, (int) fillLength, 0) < 0) { putErrmsg("Can't insert bundle fill data.", NULL); return -1; } currentOffset += fillLength; } if (length > *buflen) { /* Make buffer big enough for the green data. */ if (*buffer) { MRELEASE(*buffer); *buflen = 0; } *buffer = MTAKE(length); if (*buffer == NULL) { /* Segment is too large. Might be a * DOS attack; cancel acquisition. */ bpCancelAcq(work); currentSessionId.sourceEngineId = 0; currentSessionId.sessionNbr = 0; currentOffset = 0; return 0; } *buflen = length; } /* Extract data from segment ZCO so that it can be * appended to the bundle acquisition ZCO. Note * that we're breaking the "zero-copy" model here; * it would be better to have an alternate version * of bpContinueAcq that uses zco_clone_source_data * to append the segment ZCO's source data to the * acquisition ZCO in the work area. (TODO) */ zco_start_receiving(zco, &reader); CHKERR(sdr_begin_xn(sdr)); result = zco_receive_source(sdr, &reader, length, *buffer); if (sdr_end_xn(sdr) < 0 || result < 0) { putErrmsg("Failed reading green segment data.", NULL); return -1; } if (bpContinueAcq(work, *buffer, (int) length, 0) < 0) { putErrmsg("Can't continue bundle acquisition.", NULL); return -1; } currentOffset += length; if (endOfBlock) { if (bpEndAcq(work) < 0) { putErrmsg("Can't end acquisition of bundle.", NULL); return -1; } currentSessionId.sourceEngineId = 0; currentSessionId.sessionNbr = 0; currentOffset = 0; } return 0; }