static void _tgentransfer_log(TGenTransfer* transfer, gboolean wasActive) { TGEN_ASSERT(transfer); if(transfer->state == TGEN_XFER_ERROR) { /* we had an error at some point and will unlikely be able to complete. * only log an error once. */ if(transfer->time.lastTimeErrorReport == 0) { gchar* bytesMessage = _tgentransfer_getBytesStatusReport(transfer); gchar* timeMessage = _tgentransfer_getTimeStatusReport(transfer); tgen_message("[transfer-error] transport %s transfer %s %s %s", tgentransport_toString(transfer->transport), _tgentransfer_toString(transfer), bytesMessage, timeMessage); gint64 now = g_get_monotonic_time(); transfer->time.lastBytesStatusReport = now; transfer->time.lastTimeErrorReport = now; g_free(bytesMessage); } } else if(transfer->state == TGEN_XFER_SUCCESS) { /* we completed the transfer. yay. only log once. */ if(transfer->time.lastTimeStatusReport == 0) { gchar* bytesMessage = _tgentransfer_getBytesStatusReport(transfer); gchar* timeMessage = _tgentransfer_getTimeStatusReport(transfer); tgen_message("[transfer-complete] transport %s transfer %s %s %s", tgentransport_toString(transfer->transport), _tgentransfer_toString(transfer), bytesMessage, timeMessage); gint64 now = g_get_monotonic_time(); transfer->time.lastBytesStatusReport = now; transfer->time.lastTimeStatusReport = now; g_free(bytesMessage); g_free(timeMessage); } } else { /* the transfer is still working. only log on new activity */ if(wasActive) { gchar* bytesMessage = _tgentransfer_getBytesStatusReport(transfer); tgen_info("[transfer-status] transport %s transfer %s %s", tgentransport_toString(transfer->transport), _tgentransfer_toString(transfer), bytesMessage); transfer->time.lastBytesStatusReport = g_get_monotonic_time();; g_free(bytesMessage); } } }
static void _tgentransfer_readChecksum(TGenTransfer* transfer) { TGEN_ASSERT(transfer); if(_tgentransfer_getLine(transfer)) { /* transfer is done */ _tgentransfer_changeState(transfer, TGEN_XFER_SUCCESS); transfer->time.checksum = g_get_monotonic_time(); /* we have read the entire checksum from the other end */ gssize sha1Length = g_checksum_type_get_length(G_CHECKSUM_MD5); g_assert(sha1Length >= 0); gchar* computedSum = g_strdup(g_checksum_get_string(transfer->payloadChecksum)); gchar* line = g_string_free(transfer->readBuffer, FALSE); transfer->readBuffer = NULL; gchar** parts = g_strsplit(line, " ", 0); const gchar* receivedSum = parts[1]; g_assert(receivedSum); /* check that the sums match */ if(!g_ascii_strncasecmp(computedSum, receivedSum, (gsize)sha1Length)) { tgen_message("transport %s transfer %s MD5 checksums passed: computed=%s received=%s", tgentransport_toString(transfer->transport), _tgentransfer_toString(transfer), computedSum, receivedSum); } else { tgen_message("MD5 checksums failed: computed=%s received=%s", computedSum, receivedSum); } g_strfreev(parts); g_free(line); g_free(computedSum); } else { /* unable to receive entire checksum, wait for next chance to read */ } }
static gint _tgenmain_run(gint argc, gchar *argv[]) { tgenLogFunc = _tgenmain_log; tgenLogFilterLevel = G_LOG_LEVEL_MESSAGE; /* get our hostname for logging */ gchar hostname[128]; memset(hostname, 0, 128); gethostname(hostname, 128); /* default to message level log until we read config */ tgen_message("Initializing traffic generator on host %s process id %i", hostname, (gint)getpid()); // TODO embedding a tgen graphml inside the shadow.config.xml file not yet supported // if(argv[1] && g_str_has_prefix(argv[1], "<?xml")) { // /* argv contains the xml contents of the xml file */ // gchar* tempPath = _tgendriver_makeTempFile(); // GError* error = NULL; // gboolean success = g_file_set_contents(tempPath, argv[1], -1, &error); // if(success) { // graph = tgengraph_new(tempPath); // } else { // tgen_warning("error (%i) while generating temporary xml file: %s", error->code, error->message); // } // g_unlink(tempPath); // g_free(tempPath); // } else { // /* argv contains the apth of a graphml config file */ // graph = tgengraph_new(argv[1]); // } /* argv[0] is program name, argv[1] should be config file */ if (argc != 2) { tgen_warning("USAGE: %s path/to/tgen.xml", argv[0]); tgen_critical("cannot continue: incorrect argument list format") return -1; }
TGenGraph* tgengraph_new(gchar* path) { if(!path || !g_file_test(path, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS)) { tgen_critical("path '%s' to tgen config graph is not valid or does not exist", path); return NULL; } TGenGraph* g = g_new0(TGenGraph, 1); g->magic = TGEN_MAGIC; g->actions = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)tgenaction_unref); g->weights = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); g->graphPath = path ? _tgengraph_getHomePath(path) : NULL; GError* error = NULL; gboolean exists = g_file_test(g->graphPath, G_FILE_TEST_IS_REGULAR|G_FILE_TEST_EXISTS); if(!exists) { error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "graph file does not exist at path '%s'", g->graphPath); } if(!error && g->graphPath) { tgen_lock(); /* use the built-in C attribute handler */ igraph_attribute_table_t* oldHandler = igraph_i_set_attribute_table(&igraph_cattribute_table); g->graph = _tgengraph_loadNewGraph(g->graphPath); if(!g->graph) { error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "unable to read graph at path '%s'", g->graphPath); } /* parse edges first for choose, needs hash table of weights filled for error handling */ if(!error) { error = _tgengraph_parseGraphProperties(g); } if(!error) { error = _tgengraph_parseGraphEdges(g); } if(!error) { error = _tgengraph_parseGraphVertices(g); } /* replace the old handler */ igraph_i_set_attribute_table(oldHandler); tgen_unlock(); } if(error) { tgen_critical("error (%i) while loading graph: %s", error->code, error->message); g_error_free(error); tgengraph_free(g); return NULL; } tgen_message("successfully loaded graphml file '%s' and validated actions: " "graph is %s with %u %s, %u %s, and %u %s", g->graphPath, g->isConnected ? "weakly connected" : "disconnected", (guint)g->clusterCount, g->clusterCount == 1 ? "cluster" : "clusters", (guint)g->vertexCount, g->vertexCount == 1 ? "vertex" : "vertices", (guint)g->edgeCount, g->edgeCount == 1 ? "edge" : "edges"); return g; }