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; }
int ltpcli(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 VInduct *vduct; PsmAddress vductElt; ReceiverThreadParms rtp; pthread_t receiverThread; if (ductName == NULL) { PUTS("Usage: ltpcli <local engine number>]"); return 0; } if (bpAttach() < 0) { putErrmsg("ltpcli can't attach to BP.", NULL); return -1; } findInduct("ltp", ductName, &vduct, &vductElt); if (vductElt == 0) { putErrmsg("No such ltp duct.", ductName); return -1; } if (vduct->cliPid > 0 && vduct->cliPid != sm_TaskIdSelf()) { putErrmsg("CLI task is already started for this duct.", itoa(vduct->cliPid)); return -1; } /* All command-line arguments are now validated. */ if (ltp_attach() < 0) { putErrmsg("ltpcli can't initialize LTP.", NULL); return -1; } /* Initialize sender endpoint ID lookup. */ ipnInit(); dtn2Init(); /* Set up signal handling; SIGTERM is shutdown signal. */ oK(ltpcliMainThread(pthread_self())); isignal(SIGTERM, interruptThread); /* Start the receiver thread. */ rtp.vduct = vduct; rtp.running = 1; rtp.mainThread = pthread_self(); if (pthread_create(&receiverThread, NULL, handleNotices, &rtp)) { putSysErrmsg("ltpcli can't create receiver thread", NULL); return 1; } /* Now sleep until interrupted by SIGTERM, at which point * it's time to stop the induct. */ writeMemo("[i] ltpcli is running."); snooze(2000000000); /* Time to shut down. */ rtp.running = 0; /* Stop the receiver thread by interrupting client access. */ ltp_interrupt(BpLtpClientId); pthread_join(receiverThread, NULL); writeErrmsgMemos(); writeMemo("[i] ltpcli duct has ended."); ionDetach(); return 0; }