static DtnDB *_dtn2Constants() { static DtnDB buf; static DtnDB *db = NULL; Sdr sdr; Object dbObject; if (db == NULL) { sdr = getIonsdr(); CHKNULL(sdr); dbObject = _dtn2dbObject(NULL); if (dbObject) { if (sdr_heap_is_halted(sdr)) { sdr_read(sdr, (char *) &buf, dbObject, sizeof(DtnDB)); } else { CHKNULL(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &buf, dbObject, sizeof(DtnDB)); sdr_exit_xn(sdr); } db = &buf; } } return db; }
static int loadContact(Object elt) { Sdr sdr = getIonsdr(); Object obj; IonContact contact; IonCXref cxref; obj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &contact, obj, sizeof(IonContact)); /* Load contact index entry. */ cxref.fromNode = contact.fromNode; cxref.toNode = contact.toNode; cxref.fromTime = contact.fromTime; cxref.toTime = contact.toTime; cxref.xmitRate = contact.xmitRate; cxref.prob = contact.prob; cxref.contactElt = elt; cxref.routingObject = 0; if (insertCXref(&cxref) == 0) { return -1; } return 0; }
int acsAttach() { if (acsConstants) { return 0; } if (getAcssdr() == NULL) { /* ACS can't find ACS SDR. */ return -1; } CHKERR(sdr_begin_xn(acsSdr)); if (acsdbObject == 0) { acsdbObject = sdr_find(acsSdr, acsDbName, NULL); if (acsdbObject == 0) { sdr_exit_xn(acsSdr); return -1; } } acsConstants = &acsConstantsBuf; sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB)); sdr_exit_xn(acsSdr); return 0; }
static int loadRange(Object elt) { Sdr sdr = getIonsdr(); Object obj; IonRange range; IonRXref rxref; obj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &range, obj, sizeof(IonRange)); /* Load range list entry. */ rxref.fromNode = range.fromNode; rxref.toNode = range.toNode; rxref.fromTime = range.fromTime; rxref.toTime = range.toTime; rxref.owlt = range.owlt; rxref.rangeElt = elt; if (insertRXref(&rxref) < 0) { return -1; } return 0; }
void sdr_stage(Sdr sdrv, char *into, Object from, long length) { //TODO stub if (length == 0) return; sdr_read(sdrv, into, from, length); }
int ionClockIsSynchronized() { Sdr ionsdr = _ionsdr(NULL); Object iondbObject = _iondbObject(NULL); IonDB iondbBuf; sdr_read(ionsdr, (char *) &iondbBuf, iondbObject, sizeof(IonDB)); return iondbBuf.clockIsSynchronized; }
static void executeInfo(int tokenCount, char **tokens) { ImcDB imcdb; if (tokenCount != 2) { SYNTAX_ERROR; return; } sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB)); printKin(strtouvast(tokens[1]), imcdb.parent); }
static IonDB *_ionConstants() { static IonDB buf; static IonDB *db = NULL; Sdr sdr; Object dbObject; if (db == NULL) { /* Load constants into a conveniently accessed * structure. Note that this CANNOT be treated * as a current database image in later * processing. */ sdr = _ionsdr(NULL); CHKNULL(sdr); dbObject = _iondbObject(NULL); if (dbObject) { if (sdr_heap_is_halted(sdr)) { sdr_read(sdr, (char *) &buf, dbObject, sizeof(IonDB)); } else { CHKNULL(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &buf, dbObject, sizeof(IonDB)); sdr_exit_xn(sdr); } db = &buf; } } return db; }
void destroyIonDb(char *iondbName) { Sdr sdr = getIonsdr(); IonDB iondbBuf; Object iondbObj; iondbObj = sdr_find(sdr, iondbName, NULL); if (iondbObj == NULL) return; sdr_read(sdr, (char *) &iondbBuf, iondbObj, sizeof(IonDB)); sdr_list_destroy(sdr, iondbBuf.contacts, NULL, NULL); sdr_list_destroy(sdr, iondbBuf.ranges, NULL, NULL); sdr_free(sdr, iondbObj); //fprintf(stderr, "ionDb destroyed: %d\n", getOwnNodeNbr()); }
void ltpei_destroy_extension(Sdr sdr, Object elt, void *arg) { Object addr; LtpExtensionOutbound ext; addr = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &ext, addr, sizeof(LtpExtensionOutbound)); if (ext.value) { sdr_free(sdr, ext.value); } sdr_free(sdr, addr); }
static void executeInfo(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); ImcDB imcdb; if (tokenCount != 2) { SYNTAX_ERROR; return; } CHKVOID(sdr_begin_xn(sdr)); sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB)); printKin(strtouvast(tokens[1]), imcdb.parent); sdr_exit_xn(sdr); }
static IonDB *_ionConstants() { static IonDB buf; static IonDB *db = NULL; if (db == NULL) { /* Load constants into a conveniently accessed * structure. Note that this CANNOT be treated * as a current database image in later * processing. */ sdr_read(_ionsdr(NULL), (char *) &buf, _iondbObject(NULL), sizeof(IonDB)); db = &buf; } return db; }
static void executeList(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); ImcDB imcdb; Object elt; OBJ_POINTER(NodeId, node); if (tokenCount != 1) { SYNTAX_ERROR; return; } CHKVOID(sdr_begin_xn(sdr)); sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB)); for (elt = sdr_list_first(sdr, imcdb.kin); elt; elt = sdr_list_next(sdr, elt)) { GET_OBJ_POINTER(sdr, NodeId, node, sdr_list_data(sdr, elt)); printKin(node->nbr, imcdb.parent); } sdr_exit_xn(sdr); }
int dtn2fw(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { #else int main(int argc, char *argv[]) { #endif int running = 1; Sdr sdr; VScheme *vscheme; PsmAddress vschemeElt; Scheme scheme; Object elt; Object bundleAddr; Bundle bundle; if (bpAttach() < 0) { putErrmsg("dtn2fw can't attach to BP.", NULL); return 1; } if (dtn2Init(NULL) < 0) { putErrmsg("dtn2fw can't load routing database.", NULL); return 1; } sdr = getIonsdr(); findScheme("dtn", &vscheme, &vschemeElt); if (vschemeElt == 0) { putErrmsg("Scheme name for dtn2 is unknown.", "dtn"); return 1; } CHKZERO(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &scheme, sdr_list_data(sdr, vscheme->schemeElt), sizeof(Scheme)); sdr_exit_xn(sdr); oK(_dtn2fwSemaphore(&vscheme->semaphore)); isignal(SIGTERM, shutDown); /* Main loop: wait until forwarding queue is non-empty, * then drain it. */ writeMemo("[i] dtn2fw is running."); while (running && !(sm_SemEnded(vscheme->semaphore))) { /* We wrap forwarding in an SDR transaction to * prevent race condition with bpclock (which * is destroying bundles as their TTLs expire). */ CHKZERO(sdr_begin_xn(sdr)); elt = sdr_list_first(sdr, scheme.forwardQueue); if (elt == 0) /* Wait for forwarding notice. */ { sdr_exit_xn(sdr); if (sm_SemTake(vscheme->semaphore) < 0) { putErrmsg("Can't take forwarder semaphore.", NULL); running = 0; } continue; } bundleAddr = (Object) sdr_list_data(sdr, elt); sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle)); sdr_list_delete(sdr, elt, NULL, NULL); bundle.fwdQueueElt = 0; /* Must rewrite bundle to note removal of * fwdQueueElt, in case the bundle is abandoned * and bpDestroyBundle re-reads it from the * database. */ sdr_write(sdr, bundleAddr, (char *) &bundle, sizeof(Bundle)); if (enqueueBundle(&bundle, bundleAddr) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't enqueue bundle.", NULL); running = 0; /* Terminate loop. */ continue; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't enqueue bundle.", NULL); running = 0; /* Terminate loop. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeErrmsgMemos(); writeMemo("[i] dtn2fw forwarder has ended."); ionDetach(); return 0; }
static void *sendBundles(void *parm) { /* Main loop for single bundle transmission thread * serving all BRS sockets. */ SenderThreadParms *parms = (SenderThreadParms *) parm; char *procName = "brsscla"; unsigned char *buffer; Outduct outduct; Sdr sdr; Outflow outflows[3]; int i; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; unsigned int bundleLength; int ductNbr; int bytesSent; Object bundleAddr; Bundle bundle; snooze(1); /* Let main thread become interruptable. */ buffer = MTAKE(TCPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("No memory for TCP buffer in brsscla.", NULL); ionKillMainThread(procName); return terminateSenderThread(parms); } sdr = getIonsdr(); CHKNULL(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, parms->vduct->outductElt), sizeof(Outduct)); sdr_exit_xn(sdr); memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = outduct.bulkQueue; outflows[1].outboundBundles = outduct.stdQueue; outflows[2].outboundBundles = outduct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } /* Can now begin transmitting to clients. */ while (!(sm_SemEnded(parms->vduct->semaphore))) { if (bpDequeue(parms->vduct, outflows, &bundleZco, &extendedCOS, destDuctName, 0, -1) < 0) { break; } if (bundleZco == 0) /* Interrupted. */ { continue; } CHKNULL(sdr_begin_xn(sdr)); bundleLength = zco_length(sdr, bundleZco); sdr_exit_xn(sdr); ductNbr = atoi(destDuctName); if (ductNbr >= parms->baseDuctNbr && ductNbr <= parms->lastDuctNbr && parms->brsSockets[(i = ductNbr - parms->baseDuctNbr)] != -1) { bytesSent = sendBundleByTCP(NULL, parms->brsSockets + i, bundleLength, bundleZco, buffer); /* Note that TCP I/O errors never block * the brsscla induct's output functions; * those functions never connect to remote * sockets and never behave like a TCP * outduct, so the _tcpOutductId table is * never populated. */ if (bytesSent < 0) { putErrmsg("Can't send bundle.", NULL); break; } } else /* Can't send it; try again later? */ { bytesSent = 0; } if (bytesSent < bundleLength) { /* Couldn't send the bundle, so put it * in limbo so we can try again later * -- except that if bundle has already * been destroyed then just lose the ADU. */ CHKNULL(sdr_begin_xn(sdr)); if (retrieveSerializedBundle(bundleZco, &bundleAddr)) { putErrmsg("Can't locate unsent bundle.", NULL); sdr_cancel_xn(sdr); break; } if (bundleAddr == 0) { /* Bundle not found, so we can't * put it in limbo for another * attempt later; discard the ADU. */ zco_destroy(sdr, bundleZco); } else { sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle)); if (bundle.extendedCOS.flags & BP_MINIMUM_LATENCY) { /* We never put critical * bundles into limbo. */ zco_destroy(sdr, bundleZco); } else { if (enqueueToLimbo(&bundle, bundleAddr) < 0) { putErrmsg("Can't save bundle.", NULL); sdr_cancel_xn(sdr); break; } } } if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed handling brss xmit.", NULL); break; } } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } ionKillMainThread(procName); writeMemo("[i] brsscla outduct has ended."); MRELEASE(buffer); return terminateSenderThread(parms); }
int stcpclo(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *ductName = (char *) a1; #else int main(int argc, char *argv[]) { char *ductName = (argc > 1 ? argv[1] : NULL); #endif unsigned char *buffer; VOutduct *vduct; PsmAddress vductElt; Sdr sdr; Outduct duct; ClProtocol protocol; Outflow outflows[3]; int i; char *hostName; unsigned short portNbr; unsigned int hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; int running = 1; pthread_mutex_t mutex; KeepaliveThreadParms parms; pthread_t keepaliveThread; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; unsigned int bundleLength; int ductSocket = -1; int bytesSent; if (ductName == NULL) { PUTS("Usage: stcpclo <remote host name>[:<port number>]"); return 0; } if (bpAttach() < 0) { putErrmsg("stcpclo can't attach to BP.", NULL); return -1; } buffer = MTAKE(TCPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("No memory for TCP buffer in stcpclo.", NULL); return -1; } findOutduct("stcp", ductName, &vduct, &vductElt); if (vductElt == 0) { putErrmsg("No such stcp duct.", ductName); MRELEASE(buffer); return -1; } if (vduct->cloPid > 0 && vduct->cloPid != sm_TaskIdSelf()) { putErrmsg("CLO task is already started for this duct.", itoa(vduct->cloPid)); MRELEASE(buffer); return -1; } /* All command-line arguments are now validated. */ sdr = getIonsdr(); sdr_read(sdr, (char *) &duct, sdr_list_data(sdr, vduct->outductElt), sizeof(Outduct)); sdr_read(sdr, (char *) &protocol, duct.protocol, sizeof(ClProtocol)); if (protocol.nominalRate <= 0) { vduct->xmitThrottle.nominalRate = DEFAULT_TCP_RATE; } else { vduct->xmitThrottle.nominalRate = protocol.nominalRate; } memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = duct.bulkQueue; outflows[1].outboundBundles = duct.stdQueue; outflows[2].outboundBundles = duct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } hostName = ductName; parseSocketSpec(ductName, &portNbr, &hostNbr); if (portNbr == 0) { portNbr = BpTcpDefaultPortNbr; } portNbr = htons(portNbr); if (hostNbr == 0) { putErrmsg("Can't get IP address for host.", hostName); MRELEASE(buffer); return -1; } hostNbr = htonl(hostNbr); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = portNbr; memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); /* Set up signal handling. SIGTERM is shutdown signal. */ oK(stcpcloSemaphore(&(vduct->semaphore))); isignal(SIGTERM, shutDownClo); isignal(SIGPIPE, handleConnectionLoss); /* Start the keepalive thread for the eventual connection. */ parms.cloRunning = &running; pthread_mutex_init(&mutex, NULL); parms.mutex = &mutex; parms.socketName = &socketName; parms.ductSocket = &ductSocket; if (pthread_create(&keepaliveThread, NULL, sendKeepalives, &parms)) { putSysErrmsg("stcpclo can't create keepalive thread", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } /* Can now begin transmitting to remote duct. */ writeMemo("[i] stcpclo is running."); while (!(sm_SemEnded(stcpcloSemaphore(NULL)))) { if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS, destDuctName) < 0) { sm_SemEnd(stcpcloSemaphore(NULL));/* Stop. */ continue; } if (bundleZco == 0) /* Interrupted. */ { continue; } bundleLength = zco_length(sdr, bundleZco); pthread_mutex_lock(&mutex); bytesSent = sendBundleByTCP(&socketName, &ductSocket, bundleLength, bundleZco, buffer); pthread_mutex_unlock(&mutex); if (bytesSent < bundleLength) { sm_SemEnd(stcpcloSemaphore(NULL));/* Stop. */ continue; } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } running = 0; /* Terminate keepalive. */ pthread_join(keepaliveThread, NULL); if (ductSocket != -1) { close(ductSocket); } pthread_mutex_destroy(&mutex); writeErrmsgMemos(); writeMemo("[i] stcpclo duct has ended."); MRELEASE(buffer); ionDetach(); return 0; }
static void *sendBundles(void *parm) { /* Main loop for single bundle transmission thread * serving all BRS sockets. */ SenderThreadParms *parms = (SenderThreadParms *) parm; unsigned char *buffer; Outduct outduct; Sdr sdr; Outflow outflows[3]; int i; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; unsigned int bundleLength; int ductNbr; int bytesSent; int failedTransmissions = 0; buffer = MTAKE(TCPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("No memory for TCP buffer in brsscla.", NULL); return terminateSenderThread(parms); } sdr = getIonsdr(); sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, parms->vduct->outductElt), sizeof(Outduct)); memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = outduct.bulkQueue; outflows[1].outboundBundles = outduct.stdQueue; outflows[2].outboundBundles = outduct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } /* Can now begin transmitting to clients. */ iblock(SIGTERM); while (!(sm_SemEnded(parms->vduct->semaphore))) { if (bpDequeue(parms->vduct, outflows, &bundleZco, &extendedCOS, destDuctName) < 0) { break; } if (bundleZco == 0) /* Interrupted. */ { continue; } bundleLength = zco_length(sdr, bundleZco); ductNbr = atoi(destDuctName); if (ductNbr >= parms->baseDuctNbr && ductNbr <= parms->lastDuctNbr && parms->brsSockets[(i = ductNbr - parms->baseDuctNbr)] != -1) { bytesSent = sendBundleByTCP(NULL, parms->brsSockets + i, bundleLength, bundleZco, buffer); if (bytesSent < 0) { putErrmsg("Can't send bundle.", NULL); break; } if (bytesSent < bundleLength) { failedTransmissions++; } } else /* Can't send it; just discard it. */ { sdr_begin_xn(sdr); zco_destroy_reference(sdr, bundleZco); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't destroy ZCO reference.", NULL); break; } } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } pthread_kill(brssclaMainThread(0), SIGTERM); writeMemoNote("[i] brsscla outduct has ended", itoa(failedTransmissions)); MRELEASE(buffer); return terminateSenderThread(parms); }
static IonVdb *_ionvdb(char **name) { static IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; if (name) { if (*name == NULL) /* Terminating. */ { vdb = NULL; return vdb; } /* Attaching to volatile database. */ ionwm = _ionwm(NULL); if (psm_locate(ionwm, *name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", *name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); return vdb; } /* ION volatile database doesn't exist yet. */ sdr = _ionsdr(NULL); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", *name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); vdb->zcoSemaphore = sm_SemCreate(SM_NO_KEY, SM_SEM_FIFO); if (vdb->zcoSemaphore == SM_SEM_NONE) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } sm_SemTake(vdb->zcoSemaphore); /* Lock it. */ if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, *name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, _iondbObject(NULL), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ } return vdb; }
int bsspclo(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *ductName = (char *) a1; #else int main(int argc, char *argv[]) { char *ductName = (argc > 1 ? argv[1] : NULL); #endif Sdr sdr; VOutduct *vduct; PsmAddress vductElt; vast destEngineNbr; Outduct outduct; ClProtocol protocol; Outflow outflows[3]; int i; int running = 1; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; BsspSessionId sessionId; unsigned char *buffer; Lyst streams; Bundle bundleImage; char *dictionary = 0; unsigned int bundleLength; if (ductName == NULL) { PUTS("Usage: bsspclo [-]<destination engine number>"); return 0; } if (bpAttach() < 0) { putErrmsg("bsspclo can't attach to BP.", NULL); return -1; } sdr = getIonsdr(); findOutduct("bssp", ductName, &vduct, &vductElt); if (vductElt == 0) { putErrmsg("No such bssp duct.", ductName); return -1; } if (vduct->cloPid != ERROR && vduct->cloPid != sm_TaskIdSelf()) { putErrmsg("BSSPCLO task is already started for this duct.", itoa(vduct->cloPid)); return -1; } /* All command-line arguments are now validated. */ buffer = (unsigned char *) MTAKE(BP_MAX_BLOCK_SIZE); if (buffer == NULL) { putErrmsg("Can't get buffer for decoding bundle ZCOs.", NULL); return -1; } streams = lyst_create_using(getIonMemoryMgr()); if (streams == NULL) { putErrmsg("Can't create lyst of streams.", NULL); MRELEASE(buffer); return -1; } lyst_delete_set(streams, eraseStream, NULL); CHKERR(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, vduct->outductElt), sizeof(Outduct)); sdr_read(sdr, (char *) &protocol, outduct.protocol, sizeof(ClProtocol)); sdr_exit_xn(sdr); destEngineNbr = strtovast(ductName); if (protocol.nominalRate == 0) { vduct->xmitThrottle.nominalRate = DEFAULT_BSSP_RATE; } else { vduct->xmitThrottle.nominalRate = protocol.nominalRate; } memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = outduct.bulkQueue; outflows[1].outboundBundles = outduct.stdQueue; outflows[2].outboundBundles = outduct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } if (bssp_attach() < 0) { putErrmsg("bsspclo can't initialize BSSP.", NULL); lyst_destroy(streams); MRELEASE(buffer); return -1; } /* Set up signal handling. SIGTERM is shutdown signal. */ oK(bsspcloSemaphore(&(vduct->semaphore))); isignal(SIGTERM, shutDownClo); /* Can now begin transmitting to remote duct. */ writeMemo("[i] bsspclo is running."); while (running && !(sm_SemEnded(bsspcloSemaphore(NULL)))) { if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS, destDuctName, 0, -1) < 0) { running = 0; /* Terminate CLO. */ continue; } if (bundleZco == 0) /* Interrupted. */ { continue; } if (decodeBundle(sdr, bundleZco, buffer, &bundleImage, &dictionary, &bundleLength) < 0) { putErrmsg("Can't decode bundle ZCO.", NULL); CHKERR(sdr_begin_xn(sdr)); zco_destroy(sdr, bundleZco); if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed destroying ZCO.", NULL); break; } continue; } switch (bssp_send(destEngineNbr, BpBsspClientId, bundleZco, isInOrder(streams, &bundleImage), &sessionId)) { case 0: putErrmsg("Unable to send this bundle via BSSP.", NULL); break; case -1: putErrmsg("BsspSend failed.", NULL); running = 0; /* Terminate CLO. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); /* Note: bundleZco is destroyed later, when BSSP's * ExportSession is closed following transmission * of bundle ZCOs as aggregated into a block. */ } writeErrmsgMemos(); writeMemo("[i] bsspclo duct has ended."); lyst_destroy(streams); MRELEASE(buffer); ionDetach(); return 0; }
IonVdb * createIonVdb(char * ionvdbName) { IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; char * name = ionvdbName; /* Attaching to volatile database. */ ionwm = getIonwm(); if (psm_locate(ionwm, name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); } if (vdb != NULL) return vdb; /* ION volatile database doesn't exist yet. */ sdr = getIonsdr(); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || (vdb->requisitions[0] = sm_list_create(ionwm)) == 0 || (vdb->requisitions[1] = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ //fprintf(stderr, "ionVdb created: %d\n", getOwnNodeNbr()); return vdb; }
Object rfx_insert_range(time_t fromTime, time_t toTime, uvast fromNode, uvast toNode, unsigned int owlt) { Sdr sdr = getIonsdr(); PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); IonRXref arg1; PsmAddress rxelt; PsmAddress nextElt; PsmAddress rxaddr; IonRXref *rxref; IonEvent arg2; PsmAddress prevElt; char rangeIdString[128]; IonRange range; Object iondbObj; IonDB iondb; Object obj; Object elt; /* Note that ranges are normally assumed to be symmetrical, * i.e., the signal propagation time from B to A is normally * assumed to be the same as the signal propagation time * from A to B. For this reason, normally only the A->B * range (where A is a node number that is less than node * number B) need be entered; when ranges are applied to * the IonNeighbor objects in the ION database, the A->B * range is stored as the OWLT for transmissions from A to * B and also as the OWLT for transmissions from B to A. * * However, it is possible to insert asymmetric ranges, as * would apply when the forward and return traffic between * some pair of nodes travels by different transmission * paths that introduce different latencies. When this is * the case, both the A->B and B->A ranges must be entered. * The A->B range is initially processed as a symmetric * range as described above, but when the B->A range is * subsequently noted it overrides the default OWLT for * transmissions from B to A. */ CHKZERO(fromTime); CHKZERO(toTime > fromTime); CHKZERO(fromNode); CHKZERO(toNode); CHKZERO(sdr_begin_xn(sdr)); /* Make sure range doesn't overlap with any pre-existing * ranges. */ memset((char *) &arg1, 0, sizeof(IonRXref)); arg1.fromNode = fromNode; arg1.toNode = toNode; arg1.fromTime = fromTime; arg1.toTime = toTime; arg1.owlt = owlt; rxelt = sm_rbt_search(ionwm, vdb->rangeIndex, rfx_order_ranges, &arg1, &nextElt); if (rxelt) /* Range is in database already. */ { rxaddr = sm_rbt_data(ionwm, rxelt); rxref = (IonRXref *) psp(ionwm, rxaddr); if (rxref->rangeElt == 0) /* Imputed. */ { /* The existing range for the same nodes * and time is merely an imputed range, * which is being overridden by a non- * canonical range assertion indicating * an override of the normal symmetry in * the owlt between nodes. Must delete * that imputed range, together with the * associated events, after which there * is no duplication. */ sm_rbt_delete(ionwm, vdb->rangeIndex, rfx_order_ranges, &arg1, rfx_erase_data, NULL); arg2.ref = rxaddr; arg2.time = rxref->fromTime; arg2.type = IonStartImputedRange; sm_rbt_delete(ionwm, vdb->timeline, rfx_order_events, &arg2, rfx_erase_data, NULL); arg2.time = rxref->toTime; arg2.type = IonStopImputedRange; sm_rbt_delete(ionwm, vdb->timeline, rfx_order_events, &arg2, rfx_erase_data, NULL); } else /* Overriding an asserted range. */ { /* This is an attempt to replace an * existing asserted range with another * asserted range, which is prohibited. */ if (rxref->owlt == owlt) { sdr_exit_xn(sdr); return rxaddr; /* Idempotent. */ } isprintf(rangeIdString, sizeof rangeIdString, "from %lu, %llu->%llu", fromTime, fromNode, toNode); writeMemoNote("[?] Range OWLT not revised", rangeIdString); sdr_exit_xn(sdr); return 0; } } /* Check for overlap, which is not allowed. */ if (nextElt) { prevElt = sm_rbt_prev(ionwm, nextElt); rxref = (IonRXref *) psp(ionwm, sm_rbt_data(ionwm, nextElt)); if (fromNode == rxref->fromNode && toNode == rxref->toNode && toTime > rxref->fromTime) { writeMemoNote("[?] Overlapping range", utoa(fromNode)); sdr_exit_xn(sdr); return 0; } } else { prevElt = sm_rbt_last(ionwm, vdb->rangeIndex); } if (prevElt) { rxref = (IonRXref *) psp(ionwm, sm_rbt_data(ionwm, prevElt)); if (fromNode == rxref->fromNode && toNode == rxref->toNode && fromTime < rxref->toTime) { writeMemoNote("[?] Overlapping range", utoa(fromNode)); sdr_exit_xn(sdr); return 0; } } /* Range isn't already in database; okay to add. */ rxaddr = 0; range.fromTime = fromTime; range.toTime = toTime; range.fromNode = fromNode; range.toNode = toNode; range.owlt = owlt; obj = sdr_malloc(sdr, sizeof(IonRange)); if (obj) { sdr_write(sdr, obj, (char *) &range, sizeof(IonRange)); iondbObj = getIonDbObject(); sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); elt = sdr_list_insert_last(sdr, iondb.ranges, obj); if (elt) { arg1.rangeElt = elt; rxaddr = insertRXref(&arg1); if (rxaddr == 0) { sdr_cancel_xn(sdr); } } } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't insert range.", NULL); return 0; } return rxaddr; }
static int dispatchEvents(Sdr sdr, Object events, time_t currentTime) { Object elt; Object eventObj; LtpEvent event; int result; while (1) { sdr_begin_xn(sdr); elt = sdr_list_first(sdr, events); if (elt == 0) /* No more events to dispatch. */ { sdr_exit_xn(sdr); return 0; } eventObj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &event, eventObj, sizeof(LtpEvent)); if (event.scheduledTime > currentTime) { /* This is the first future event. */ sdr_exit_xn(sdr); return 0; } sdr_free(sdr, eventObj); sdr_list_delete(sdr, elt, NULL, NULL); switch (event.type) { case LtpResendCheckpoint: result = ltpResendCheckpoint(event.refNbr2, event.refNbr3); break; /* Out of switch. */ case LtpResendXmitCancel: result = ltpResendXmitCancel(event.refNbr2); break; /* Out of switch. */ case LtpResendReport: result = ltpResendReport(event.refNbr1, event.refNbr2, event.refNbr3); break; /* Out of switch. */ case LtpResendRecvCancel: result = ltpResendRecvCancel(event.refNbr1, event.refNbr2); break; /* Out of switch. */ default: /* Spurious event. */ result = 0; /* Event is ignored. */ } if (result < 0) /* Dispatching failed. */ { sdr_cancel_xn(sdr); putErrmsg("failed handing LTP event", NULL); return result; } if (sdr_end_xn(sdr) < 0) { putErrmsg("failed dispatching LTP event", NULL); return -1; } } }
int tcpclo(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *ductName = (char *) a1; #else int main(int argc, char *argv[]) { char *ductName = (argc > 1 ? argv[1] : NULL); #endif unsigned char *buffer; VOutduct *vduct; PsmAddress vductElt; Sdr sdr; Outduct duct; ClProtocol protocol; Outflow outflows[3]; int i; char *hostName; unsigned short portNbr; unsigned int hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; int running = 1; pthread_mutex_t mutex; KeepaliveThreadParms parms; ReceiveThreadParms rparms; pthread_t keepaliveThread; pthread_t receiverThread; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; unsigned int bundleLength; int ductSocket = -1; int bytesSent; int keepalivePeriod = 0; VInduct *viduct; if (ductName == NULL) { PUTS("Usage: tcpclo <remote host name>[:<port number>]"); return 0; } if (bpAttach() < 0) { putErrmsg("tcpclo can't attach to BP", NULL); return 1; } buffer = MTAKE(TCPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("No memory for TCP buffer in tcpclo.", NULL); return 1; } findOutduct("tcp", ductName, &vduct, &vductElt); if (vductElt == 0) { putErrmsg("No such tcp duct.", ductName); MRELEASE(buffer); return 1; } if (vduct->cloPid != ERROR && vduct->cloPid != sm_TaskIdSelf()) { putErrmsg("CLO task is already started for this duct.", itoa(vduct->cloPid)); MRELEASE(buffer); return 1; } /* All command-line arguments are now validated. */ sdr = getIonsdr(); CHKERR(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &duct, sdr_list_data(sdr, vduct->outductElt), sizeof(Outduct)); sdr_read(sdr, (char *) &protocol, duct.protocol, sizeof(ClProtocol)); sdr_exit_xn(sdr); if (protocol.nominalRate == 0) { vduct->xmitThrottle.nominalRate = DEFAULT_TCP_RATE; } else { vduct->xmitThrottle.nominalRate = protocol.nominalRate; } memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = duct.bulkQueue; outflows[1].outboundBundles = duct.stdQueue; outflows[2].outboundBundles = duct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } hostName = ductName; parseSocketSpec(ductName, &portNbr, &hostNbr); if (portNbr == 0) { portNbr = BpTcpDefaultPortNbr; } portNbr = htons(portNbr); if (hostNbr == 0) { putErrmsg("Can't get IP address for host.", hostName); MRELEASE(buffer); return 1; } hostNbr = htonl(hostNbr); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = portNbr; memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); if (_tcpOutductId(&socketName, "tcp", ductName) < 0) { putErrmsg("Can't record TCP Outduct ID for connection.", NULL); MRELEASE(buffer); return -1; } /* Set up signal handling. SIGTERM is shutdown signal. */ oK(tcpcloSemaphore(&(vduct->semaphore))); isignal(SIGTERM, shutDownClo); #ifndef mingw isignal(SIGPIPE, handleConnectionLoss); #endif /* Start the keepalive thread for the eventual connection. */ tcpDesiredKeepAlivePeriod = KEEPALIVE_PERIOD; parms.cloRunning = &running; pthread_mutex_init(&mutex, NULL); parms.mutex = &mutex; parms.socketName = &socketName; parms.ductSocket = &ductSocket; parms.keepalivePeriod = &keepalivePeriod; if (pthread_begin(&keepaliveThread, NULL, sendKeepalives, &parms)) { putSysErrmsg("tcpclo can't create keepalive thread", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } // Returns the VInduct Object of first induct with same protocol // as the outduct. The VInduct is required to create an acq area. // The Acq Area inturn uses the throttle information from VInduct // object while receiving bundles. The throttle information // of all inducts of the same induct will be the same, so choosing // any induct will serve the purpose. findVInduct(&viduct,protocol.name); if(viduct == NULL) { putErrmsg("tcpclo can't get VInduct", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } rparms.vduct = viduct; rparms.bundleSocket = &ductSocket; rparms.mutex = &mutex; rparms.cloRunning = &running; if (pthread_begin(&receiverThread, NULL, receiveBundles, &rparms)) { putSysErrmsg("tcpclo can't create receive thread", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } /* Can now begin transmitting to remote duct. */ { char txt[500]; isprintf(txt, sizeof(txt), "[i] tcpclo is running, spec=[%s:%d].", inet_ntoa(inetName->sin_addr), ntohs(inetName->sin_port)); writeMemo(txt); } while (running && !(sm_SemEnded(tcpcloSemaphore(NULL)))) { if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS, destDuctName, 0, -1) < 0) { running = 0; /* Terminate CLO. */ continue; } if (bundleZco == 0) /* Interrupted. */ { continue; } CHKZERO(sdr_begin_xn(sdr)); bundleLength = zco_length(sdr, bundleZco); sdr_exit_xn(sdr); pthread_mutex_lock(&mutex); bytesSent = sendBundleByTCPCL(&socketName, &ductSocket, bundleLength, bundleZco, buffer, &keepalivePeriod); pthread_mutex_unlock(&mutex); if(bytesSent < 0) { running = 0; /* Terminate CLO. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeMemo("[i] tcpclo done sending"); if (sendShutDownMessage(&ductSocket, SHUT_DN_NO, -1, &socketName) < 0) { putErrmsg("Sending Shutdown message failed!!",NULL); } if (ductSocket != -1) { closesocket(ductSocket); ductSocket=-1; } running = 0; pthread_join(keepaliveThread, NULL); writeMemo("[i] tcpclo keepalive thread killed"); pthread_join(receiverThread, NULL); writeMemo("[i] tcpclo receiver thread killed"); writeErrmsgMemos(); writeMemo("[i] tcpclo duct has ended."); oK(_tcpOutductId(&socketName, NULL, NULL)); MRELEASE(buffer); pthread_mutex_destroy(&mutex); bp_detach(); return 0; }
int rfx_start() { PsmPartition ionwm = getIonwm(); Sdr sdr = getIonsdr(); IonVdb *vdb = getIonVdb(); Object iondbObj; IonDB iondb; Object elt; iondbObj = getIonDbObject(); CHKERR(sdr_begin_xn(sdr)); /* To lock memory. */ sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); /* Destroy and re-create volatile contact and range * databases. This prevents contact/range duplication * as a result of adds before starting ION. */ sm_rbt_destroy(ionwm, vdb->contactIndex, rfx_erase_data, NULL); sm_rbt_destroy(ionwm, vdb->rangeIndex, rfx_erase_data, NULL); vdb->contactIndex = sm_rbt_create(ionwm); vdb->rangeIndex = sm_rbt_create(ionwm); /* Load range index for all asserted ranges. In so * doing, load the nodes for which ranges are known * and load events for all predicted changes in range. */ for (elt = sdr_list_first(sdr, iondb.ranges); elt; elt = sdr_list_next(sdr, elt)) { if (loadRange(elt) < 0) { putErrmsg("Can't load range.", NULL); sdr_exit_xn(sdr); return -1; } } /* Load contact index for all contacts. In so doing, * load the nodes for which contacts are planned (as * necessary) and load events for all planned changes * in data rate affecting the local node. */ iondbObj = getIonDbObject(); sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); for (elt = sdr_list_first(sdr, iondb.contacts); elt; elt = sdr_list_next(sdr, elt)) { if (loadContact(elt) < 0) { putErrmsg("Can't load contact.", NULL); sdr_exit_xn(sdr); return -1; } } /* Start the rfx clock if necessary. */ /* if (vdb->clockPid == ERROR || sm_TaskExists(vdb->clockPid) == 0) { vdb->clockPid = pseudoshell("rfxclock"); } */ sdr_exit_xn(sdr); /* Unlock memory. */ return 0; }
static PsmAddress insertCXref(IonCXref *cxref) { PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); IonNode *node; PsmAddress nextElt; PsmAddress cxaddr; Object iondbObj; IonDB iondb; PsmAddress cxelt; PsmAddress addr; IonEvent *event; time_t currentTime = getUTCTime(); /* Load the affected nodes. */ node = findNode(vdb, cxref->toNode, &nextElt); if (node == NULL) { node = addNode(vdb, cxref->toNode); if (node == NULL) { return 0; } } node = findNode(vdb, cxref->fromNode, &nextElt); if (node == NULL) { node = addNode(vdb, cxref->fromNode); if (node == NULL) { return 0; } } /* Construct the contact index entry. */ cxaddr = psm_zalloc(ionwm, sizeof(IonCXref)); if (cxaddr == 0) { return 0; } /* Compute times of relevant events. */ iondbObj = getIonDbObject(); sdr_read(getIonsdr(), (char *) &iondb, iondbObj, sizeof(IonDB)); if (cxref->fromNode == getOwnNodeNbr()) { /* Be a little slow to start transmission, and * a little quick to stop, to ensure that * segments arrive only when neighbor is * expecting them. */ cxref->startXmit = cxref->fromTime + iondb.maxClockError; cxref->stopXmit = cxref->toTime - iondb.maxClockError; } if (cxref->toNode == getOwnNodeNbr()) { /* Be a little slow to resume timers, and a * little quick to suspend them, to minimize the * chance of premature timeout. */ cxref->startFire = cxref->fromTime + iondb.maxClockError; cxref->stopFire = cxref->toTime - iondb.maxClockError; } else /* Not a transmission to the local node. */ { cxref->purgeTime = cxref->toTime; } memcpy((char *) psp(ionwm, cxaddr), (char *) cxref, sizeof(IonCXref)); cxelt = sm_rbt_insert(ionwm, vdb->contactIndex, cxaddr, rfx_order_contacts, cxref); if (cxelt == 0) { psm_free(ionwm, cxaddr); return 0; } /* Insert relevant timeline events. */ if (cxref->startXmit) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->startXmit; event->type = IonStartXmit; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->stopXmit) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->stopXmit; event->type = IonStopXmit; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->startFire) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->startFire; event->type = IonStartFire; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->stopFire) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->stopFire; event->type = IonStopFire; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->purgeTime) { addr = psm_zalloc(ionwm, sizeof(IonEvent)); if (addr == 0) { return 0; } event = (IonEvent *) psp(ionwm, addr); event->time = cxref->purgeTime; event->type = IonPurgeContact; event->ref = cxaddr; if (sm_rbt_insert(ionwm, vdb->timeline, addr, rfx_order_events, event) == 0) { psm_free(ionwm, addr); return 0; } } if (cxref->toTime > currentTime) /* Affects routes. */ { vdb->lastEditTime = currentTime; } return cxaddr; }
PsmAddress rfx_insert_contact(time_t fromTime, time_t toTime, uvast fromNode, uvast toNode, unsigned int xmitRate, float prob) { Sdr sdr = getIonsdr(); PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); IonCXref arg; PsmAddress cxelt; PsmAddress nextElt; PsmAddress cxaddr; IonCXref *cxref; PsmAddress prevElt; char contactIdString[128]; IonContact contact; Object iondbObj; IonDB iondb; Object obj; Object elt; CHKZERO(fromTime); CHKZERO(toTime > fromTime); CHKZERO(fromNode); CHKZERO(toNode); CHKZERO(prob > 0.0 && prob <= 1.0); CHKZERO(sdr_begin_xn(sdr)); /* Make sure contact doesn't overlap with any pre-existing * contacts. */ memset((char *) &arg, 0, sizeof(IonCXref)); arg.fromNode = fromNode; arg.toNode = toNode; arg.fromTime = fromTime; arg.toTime = toTime; arg.xmitRate = xmitRate; arg.routingObject = 0; cxelt = sm_rbt_search(ionwm, vdb->contactIndex, rfx_order_contacts, &arg, &nextElt); //cxelt = 0; if (cxelt) /* Contact is in database already. */ { cxaddr = sm_rbt_data(ionwm, cxelt); cxref = (IonCXref *) psp(ionwm, cxaddr); if (cxref->xmitRate == xmitRate) { sdr_exit_xn(sdr); return cxaddr; } isprintf(contactIdString, sizeof contactIdString, "at %lu, %llu->%llu", fromTime, fromNode, toNode); writeMemoNote("[?] Contact data rate not revised", contactIdString); sdr_exit_xn(sdr); return 0; } else /* Check for overlap, which is not allowed. */ { if (nextElt) { prevElt = sm_rbt_prev(ionwm, nextElt); cxref = (IonCXref *) psp(ionwm, sm_rbt_data(ionwm, nextElt)); if (fromNode == cxref->fromNode && toNode == cxref->toNode && toTime > cxref->fromTime) { writeMemoNote("[?] Overlapping contact", utoa(fromNode)); sdr_exit_xn(sdr); return 0; } } else { prevElt = sm_rbt_last(ionwm, vdb->contactIndex); } if (prevElt) { cxref = (IonCXref *) psp(ionwm, sm_rbt_data(ionwm, prevElt)); if (fromNode == cxref->fromNode && toNode == cxref->toNode && fromTime < cxref->toTime) { writeMemoNote("[?] Overlapping contact", utoa(fromNode)); sdr_exit_xn(sdr); return 0; } } } /* Contact isn't already in database; okay to add. */ cxaddr = 0; contact.fromTime = fromTime; contact.toTime = toTime; contact.fromNode = fromNode; contact.toNode = toNode; contact.xmitRate = xmitRate; contact.prob = prob; obj = sdr_malloc(sdr, sizeof(IonContact)); if (obj) { sdr_write(sdr, obj, (char *) &contact, sizeof(IonContact)); iondbObj = getIonDbObject(); sdr_read(sdr, (char *) &iondb, iondbObj, sizeof(IonDB)); elt = sdr_list_insert_last(sdr, iondb.contacts, obj); if (elt) { arg.contactElt = elt; cxaddr = insertCXref(&arg); if (cxaddr == 0) { sdr_cancel_xn(sdr); } } } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't insert contact.", NULL); return 0; } return cxaddr; }
int acsInitialize(long heapWords, int logLevel) { AcsDB acsdbBuf; unsigned long zero = 0; /* sdr_stow() wants this */ if (heapWords == 0) { /* Caller wants us to supply a default. */ heapWords = ACS_SDR_DEFAULT_HEAPWORDS; } if (ionAttach() < 0) { putErrmsg("Can't attach to ION.", NULL); return -1; } { Sdr sdr = getIonsdr(); IonDB iondb; char *pathname = iondb.parmcopy.pathName; CHKERR(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB)); sdr_exit_xn(sdr); #if 0 { char text[100]; sprintf( text, "ION parms pathname : %s", pathname ); writeMemo( text ); } #endif if (sdr_load_profile(acssdrName, SDR_IN_DRAM, heapWords, SM_NO_KEY, pathname, NULL) < 0) { putErrmsg("Unable to load SDR profile for ACS.", NULL); return -1; } else { writeMemo("ACS SDR profile loaded."); } } acsSdr = sdr_start_using(acssdrName); if (acsSdr == NULL) { putErrmsg("Can't start using SDR for ACS.", NULL); return -1; } if (getAcssdr() < 0) { putErrmsg("ACS can't find ACS SDR.", NULL); return -1; } CHKERR(sdr_begin_xn(acsSdr)); acsdbObject = sdr_find(acsSdr, acsDbName, NULL); switch (acsdbObject) { case -1: /* SDR error. */ sdr_cancel_xn(acsSdr); putErrmsg("Can't seek ACS database in SDR.", NULL); return -1; case 0: /* Not found must create new DB. */ memset((char *) &acsdbBuf, 0, sizeof(AcsDB)); acsdbBuf.pendingCusts = sdr_list_create(acsSdr); acsdbBuf.logLevel = logLevel; acsdbBuf.cidHash = sdr_hash_create(acsSdr, sizeof(AcsCustodyId), ACS_CIDHASH_ROWCOUNT, 1); acsdbBuf.bidHash = sdr_hash_create(acsSdr, sizeof(AcsBundleId), ACS_BIDHASH_ROWCOUNT, 1); acsdbBuf.id = sdr_stow(acsSdr, zero); acsdbObject = sdr_malloc(acsSdr, sizeof(AcsDB)); if (acsdbObject == 0) { sdr_cancel_xn(acsSdr); putErrmsg("No space for ACS database.", NULL); return -1; } sdr_write(acsSdr, acsdbObject, (char *) &acsdbBuf, sizeof(AcsDB)); sdr_catlg(acsSdr, acsDbName, 0, acsdbObject); if (sdr_end_xn(acsSdr)) { putErrmsg("Can't create ACS database.", NULL); return -1; } break; default: sdr_exit_xn(acsSdr); } acsConstants = &acsConstantsBuf; CHKERR(sdr_begin_xn(acsSdr)); sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB)); sdr_exit_xn(acsSdr); return 0; }
int udpclo(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { #else int main(int argc, char *argv[]) { #endif unsigned char *buffer; VOutduct *vduct; PsmAddress vductElt; Sdr sdr; Outduct outduct; ClProtocol protocol; Outflow outflows[3]; int i; char *hostName; unsigned short portNbr; unsigned int hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; unsigned int bundleLength; int ductSocket = -1; int bytesSent; if (bpAttach() < 0) { putErrmsg("udpclo can't attach to BP.", NULL); return -1; } buffer = MTAKE(UDPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("No memory for UDP buffer in udpclo.", NULL); return -1; } findOutduct("udp", "*", &vduct, &vductElt); if (vductElt == 0) { putErrmsg("No such udp duct.", "*"); MRELEASE(buffer); return -1; } if (vduct->cloPid > 0 && vduct->cloPid != sm_TaskIdSelf()) { putErrmsg("CLO task is already started for this duct.", itoa(vduct->cloPid)); MRELEASE(buffer); return -1; } /* All command-line arguments are now validated. */ sdr = getIonsdr(); sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr, vduct->outductElt), sizeof(Outduct)); sdr_read(sdr, (char *) &protocol, outduct.protocol, sizeof(ClProtocol)); if (protocol.nominalRate <= 0) { vduct->xmitThrottle.nominalRate = DEFAULT_UDP_RATE; } else { vduct->xmitThrottle.nominalRate = protocol.nominalRate; } memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = outduct.bulkQueue; outflows[1].outboundBundles = outduct.stdQueue; outflows[2].outboundBundles = outduct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } /* Set up signal handling. SIGTERM is shutdown signal. */ oK(udpcloSemaphore(&(vduct->semaphore))); isignal(SIGTERM, shutDownClo); /* Can now begin transmitting to remote duct. */ writeMemo("[i] udpclo is running."); while (!(sm_SemEnded(vduct->semaphore))) { if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS, destDuctName) < 0) { sm_SemEnd(udpcloSemaphore(NULL));/* Stop. */ continue; } if (bundleZco == 0) /* Interrupted. */ { continue; } hostName = destDuctName; parseSocketSpec(destDuctName, &portNbr, &hostNbr); if (portNbr == 0) { portNbr = BpUdpDefaultPortNbr; } portNbr = htons(portNbr); if (hostNbr == 0) { writeMemoNote("[?] Can't get IP address for host", hostName); } hostNbr = htonl(hostNbr); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = portNbr; memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); bundleLength = zco_length(sdr, bundleZco); bytesSent = sendBundleByUDP(&socketName, &ductSocket, bundleLength, bundleZco, buffer); if (bytesSent < bundleLength) { sm_SemEnd(udpcloSemaphore(NULL));/* Stop. */ continue; } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } if (ductSocket != -1) { close(ductSocket); } writeErrmsgMemos(); writeMemo("[i] udpclo duct has ended."); MRELEASE(buffer); ionDetach(); return 0; }