static int JsonNetFlowLogger(ThreadVars *tv, void *thread_data, Flow *f) { SCEnter(); JsonNetFlowLogThread *jhl = (JsonNetFlowLogThread *)thread_data; LogJsonFileCtx *netflow_ctx = jhl->flowlog_ctx; /* reset */ MemBufferReset(jhl->buffer); json_t *js = CreateJSONHeaderFromFlow(f, "netflow", 0); if (unlikely(js == NULL)) return TM_ECODE_OK; JsonNetFlowLogJSONToServer(jhl, js, f); JsonAddCommonOptions(&netflow_ctx->cfg, NULL, f, js); OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, &jhl->buffer); json_object_del(js, "netflow"); json_object_clear(js); json_decref(js); /* only log a response record if we actually have seen response packets */ if (f->tosrcpktcnt) { /* reset */ MemBufferReset(jhl->buffer); js = CreateJSONHeaderFromFlow(f, "netflow", 1); if (unlikely(js == NULL)) return TM_ECODE_OK; JsonNetFlowLogJSONToClient(jhl, js, f); JsonAddCommonOptions(&netflow_ctx->cfg, NULL, f, js); OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, &jhl->buffer); json_object_del(js, "netflow"); json_object_clear(js); json_decref(js); } SCReturnInt(TM_ECODE_OK); }
static int JsonNetFlowLogger(ThreadVars *tv, void *thread_data, Flow *f) { SCEnter(); JsonNetFlowLogThread *jhl = (JsonNetFlowLogThread *)thread_data; /* reset */ MemBufferReset(jhl->buffer); json_t *js = CreateJSONHeaderFromFlow(f, "netflow", 0); //TODO const if (unlikely(js == NULL)) return TM_ECODE_OK; JsonNetFlowLogJSONToServer(jhl, js, f); OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, &jhl->buffer); json_object_del(js, "netflow"); json_object_clear(js); json_decref(js); /* reset */ MemBufferReset(jhl->buffer); js = CreateJSONHeaderFromFlow(f, "netflow", 1); //TODO const if (unlikely(js == NULL)) return TM_ECODE_OK; JsonNetFlowLogJSONToClient(jhl, js, f); OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, &jhl->buffer); json_object_del(js, "netflow"); json_object_clear(js); json_decref(js); SCReturnInt(TM_ECODE_OK); }
int ovCopy (char *sessionID, char *argument[]) { char urlString[256]; // Used to hold a full URL char path[256]; // Used to hold path to a second session file // Check Arguments before continuing if (!sessionID) { return 1; } char *oneViewAddress = argument[1]; // IP Address of HP OneView char *copyType = argument[3]; // Type of information to show // char *queryType = argument[4]; // Type of Query to show char *httpData; // Contains all fo the data returned from a http request json_t *root; // Contains all of the json data once processed by jansson json_error_t error; // Used as a passback for error data during json processing if (strstr(copyType, "NETWORKS")) { createURL(urlString, oneViewAddress, "ethernet-networks"); // Call to HP OneView API httpData = getRequestWithUrlAndHeader(urlString, sessionID); if(!httpData) return 1; root = json_loads(httpData, 0, &error); json_t *memberArray = json_object_get(root, "members"); if (json_array_size(memberArray) != 0) { size_t index; json_t *network = NULL; //char *json_text; json_array_foreach(memberArray, index, network) { const char *uri = json_string_value(json_object_get(network, "uri")); if (uri != NULL) { if (strstr(uri, argument[4])) { // Remove bits //json_object_del(network, "uri"); json_object_del(network, "eTag"); json_object_del(network, "modified"); json_object_del(network, "created"); json_object_del(network, "connectionTemplateUri"); createURL(urlString, argument[5], "ethernet-networks"); sprintf(path, "/.%s_ov",argument[5]); sessionID = readSessionIDforHost(path); httpData = postRequestWithUrlAndDataAndHeader(urlString, json_dumps(network, JSON_ENSURE_ASCII), sessionID); if(!httpData) return 1; } } } }
static int JsonHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id) { SCEnter(); htp_tx_t *tx = txptr; JsonHttpLogThread *jhl = (JsonHttpLogThread *)thread_data; MemBuffer *buffer = (MemBuffer *)jhl->buffer; json_t *js = CreateJSONHeader((Packet *)p, 1, "http"); //TODO const if (unlikely(js == NULL)) return TM_ECODE_OK; SCLogDebug("got a HTTP request and now logging !!"); /* reset */ MemBufferReset(buffer); JsonHttpLogJSON(jhl, js, tx); OutputJSONBuffer(js, jhl->httplog_ctx->file_ctx, buffer); json_object_del(js, "http"); json_object_clear(js); json_decref(js); SCReturnInt(TM_ECODE_OK); }
static int JsonStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) { SCEnter(); JsonStatsLogThread *aft = (JsonStatsLogThread *)thread_data; struct timeval tval; gettimeofday(&tval, NULL); json_t *js = json_object(); if (unlikely(js == NULL)) return 0; char timebuf[64]; CreateIsoTimeString(&tval, timebuf, sizeof(timebuf)); json_object_set_new(js, "timestamp", json_string(timebuf)); json_object_set_new(js, "event_type", json_string("stats")); json_t *js_stats = StatsToJSON(st, aft->statslog_ctx->flags); if (js_stats == NULL) { json_decref(js); return 0; } json_object_set_new(js, "stats", js_stats); OutputJSONBuffer(js, aft->statslog_ctx->file_ctx, &aft->buffer); MemBufferReset(aft->buffer); json_object_clear(js_stats); json_object_del(js, "stats"); json_object_clear(js); json_decref(js); SCReturnInt(0); }
static void test_preserve_order() { json_t *object; char *result; const char *expected = "{\"foobar\": 1, \"bazquux\": 6, \"lorem ipsum\": 3, \"sit amet\": 5, \"helicopter\": 7}"; object = json_object(); json_object_set_new(object, "foobar", json_integer(1)); json_object_set_new(object, "中国", json_integer(2)); json_object_set_new(object, "lorem ipsum", json_integer(3)); json_object_set_new(object, "dolor", json_integer(4)); json_object_set_new(object, "sit amet", json_integer(5)); /* changing a value should preserve the order */ json_object_set_new(object, "bazquux", json_integer(6)); /* deletion shouldn't change the order of others */ json_object_del(object, "dolor"); /* add a new item just to make sure */ json_object_set_new(object, "helicopter", json_integer(7)); result = json_dumps(object, JSON_PRESERVE_ORDER); if(strcmp(expected, result) != 0) { fprintf(stderr, "%s != %s", expected, result); fail("JSON_PRESERVE_ORDER doesn't work"); } printf ("result=%s\n", result); free(result); json_decref(object); }
int main () { json_t *units, *current_unit, *stats, *targetArea; json_error_t error; const char *unitname; units = json_load_file ("./BattleAbilities.json", 0, &error); if (!units) { /* the error variable contains error information */ printf ("load error \n"); exit (1); } printf ("proceeding %d ablilities...\n", (int)json_object_size (units)); json_object_foreach (units, unitname, current_unit) { json_object_del (current_unit, "damageAnimationType"); /* remove damageAnimationType */ stats = json_object_get (current_unit, "stats"); if (stats) { targetArea = json_object_get (stats, "targetArea"); if (targetArea) json_object_set(targetArea, "aoeOrderDelay", json_real (0.0)); }else printf ("get targetArea error\n"); }
static int Logger(ThreadVars *t, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id) { SCEnter(); char *name = NULL; DBJsonLogThread *jlt = (DBJsonLogThread *)thread_data; switch (f->alproto) { case ALPROTO_MYSQL: name = "mysql"; case ALPROTO_TNS11G: name = "oracle-tns"; case ALPROTO_TDS: name = "mssql-tds"; case ALPROTO_DRDA: name = "db2-drda"; default: SCReturnInt(-1); } json_t *js = CreateJSONHeader((Packet *)p, 1, name); MemBufferReset(jlt->buf); /* TODO */ DBLogAlState(alstate, f->alproto, p, js, name); OutputJSONBuffer(js, jlt->ctx->ctx, jlt->buf); json_object_del(js, name); json_object_clear(js); json_decref(js); SCReturnInt(TM_ECODE_OK); }
/*=========================================================================*\ Remove a key:value entry from repository return -1 if key was not found or on error \*=========================================================================*/ int persistRemove( const char *key ) { DBGMSG( "persistRemove: (%s)", key ); /*------------------------------------------------------------------------*\ Repository needs to be available \*------------------------------------------------------------------------*/ if( !jRepository ) { logwarn( "Try to remove key \"%s\" from uninitialized repository.", key ); return -1; } /*------------------------------------------------------------------------*\ Store or replace value in repository, steal reference \*------------------------------------------------------------------------*/ if( json_object_del(jRepository,key) ) { logerr( "Cannot remove key \"%s\" from repository.", key ); return -1; } /*------------------------------------------------------------------------*\ Dump repository, that's it \*------------------------------------------------------------------------*/ return _dumpRepository( repositoryFileName ); }
/** Handle the case where no JSON support is compiled in. * */ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) { MemBuffer *buffer = (MemBuffer *)aft->buffer; int i; if (p->alerts.cnt == 0) return TM_ECODE_OK; json_t *js = CreateJSONHeader((Packet *)p, 0, "alert"); if (unlikely(js == NULL)) return TM_ECODE_OK; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } char *action = "allowed"; if (pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) { action = "blocked"; } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { action = "blocked"; } json_t *ajs = json_object(); if (ajs == NULL) { json_decref(js); return TM_ECODE_OK; } MemBufferReset(buffer); json_object_set_new(ajs, "action", json_string(action)); json_object_set_new(ajs, "gid", json_integer(pa->s->gid)); json_object_set_new(ajs, "signature_id", json_integer(pa->s->id)); json_object_set_new(ajs, "rev", json_integer(pa->s->rev)); json_object_set_new(ajs, "signature", json_string((pa->s->msg) ? pa->s->msg : "")); json_object_set_new(ajs, "category", json_string((pa->s->class_msg) ? pa->s->class_msg : "")); json_object_set_new(ajs, "severity", json_integer(pa->s->prio)); /* alert */ json_object_set_new(js, "alert", ajs); OutputJSONBuffer(js, aft->file_ctx, aft->buffer); json_object_del(js, "alert"); } json_object_clear(js); json_decref(js); return TM_ECODE_OK; }
static int noportsdump_json_process(char *dump) { int err; json_t *json; err = __jsonload(&json, dump); if (err) return err; json_object_del(json, "ports"); err = __jsondump(json); json_decref(json); return err; }
/* * set a name/value key pair in the session */ apr_byte_t oidc_session_set(request_rec *r, oidc_session_t *z, const char *key, const char *value) { /* only set it if non-NULL, otherwise delete the entry */ if (value) { if (z->state == NULL) z->state = json_object(); json_object_set_new(z->state, key, json_string(value)); } else if (z->state != NULL) { json_object_del(z->state, key); } return TRUE; }
static void test_equal_object() { json_t *object1, *object2; object1 = json_object(); object2 = json_object(); if(!object1 || !object2) fail("unable to create objects"); if(!json_equal(object1, object2)) fail("json_equal fails for two empty objects"); json_object_set_new(object1, "a", json_integer(1)); json_object_set_new(object2, "a", json_integer(1)); json_object_set_new(object1, "b", json_string("foo")); json_object_set_new(object2, "b", json_string("foo")); json_object_set_new(object1, "c", json_integer(2)); json_object_set_new(object2, "c", json_integer(2)); if(!json_equal(object1, object2)) fail("json_equal fails for two equal objects"); json_object_del(object2, "c"); if(json_equal(object1, object2)) fail("json_equal fails for two inequal objects"); json_object_set_new(object2, "c", json_integer(3)); if(json_equal(object1, object2)) fail("json_equal fails for two inequal objects"); json_object_del(object2, "c"); json_object_set_new(object2, "d", json_integer(2)); if(json_equal(object1, object2)) fail("json_equal fails for two inequal objects"); json_decref(object1); json_decref(object2); }
static void circular_references() { /* Construct a JSON object/array with a circular reference: object: {"a": {"b": {"c": <circular reference to $.a>}}} array: [[[<circular reference to the $[0] array>]]] Encode it, remove the circular reference and encode again. */ json_t *json; char *result; json = json_object(); json_object_set_new(json, "a", json_object()); json_object_set_new(json_object_get(json, "a"), "b", json_object()); json_object_set(json_object_get(json_object_get(json, "a"), "b"), "c", json_object_get(json, "a")); if(json_dumps(json, 0)) fail("json_dumps encoded a circular reference!"); json_object_del(json_object_get(json_object_get(json, "a"), "b"), "c"); result = json_dumps(json, 0); if(!result || strcmp(result, "{\"a\": {\"b\": {}}}")) fail("json_dumps failed!"); free(result); json_decref(json); json = json_array(); json_array_append_new(json, json_array()); json_array_append_new(json_array_get(json, 0), json_array()); json_array_append(json_array_get(json_array_get(json, 0), 0), json_array_get(json, 0)); if(json_dumps(json, 0)) fail("json_dumps encoded a circular reference!"); json_array_remove(json_array_get(json_array_get(json, 0), 0), 0); result = json_dumps(json, 0); if(!result || strcmp(result, "[[[]]]")) fail("json_dumps failed!"); free(result); json_decref(json); }
/** * Get the device overview * Returns a mocked overview with 2 sensors, 2 switches, 2 dimmers and 2 heaters */ json_t * b_device_overview (json_t * device, void * device_ptr) { y_log_message(Y_LOG_LEVEL_INFO, "device-mock - Running command overview for device %s", json_string_value(json_object_get(device, "name"))); json_t * sw1 = b_device_get_switch(device, "sw1", device_ptr), * sw2 = b_device_get_switch(device, "sw2", device_ptr), * di1 = b_device_get_dimmer(device, "di1", device_ptr), * di2 = b_device_get_dimmer(device, "di2", device_ptr), * he1 = b_device_get_heater(device, "he1", device_ptr), * he2 = b_device_get_heater(device, "he2", device_ptr); json_object_del(he1, "result"); json_object_del(he2, "result"); json_t * result = json_pack("{sis{s{sssf}s{sosf}}s{sIsI}s{sIsI}s{soso}}", "result", WEBSERVICE_RESULT_OK, "sensors", "se1", "unit", "C", "value", get_sensor_value("se1"), "se2", "trigger", json_true(), "value", get_sensor_value("se2"), "switches", "sw1", json_integer_value(json_object_get(sw1, "value")), "sw2", json_integer_value(json_object_get(sw2, "value")), "dimmers", "di1", json_integer_value(json_object_get(di1, "value")), "di2", json_integer_value(json_object_get(di2, "value")), "heaters", "he1", he1, "he2", he2); json_decref(sw1); json_decref(sw2); json_decref(di1); json_decref(di2); return result; }
static json_t* task_populate_titledb_cache_get_base(u32 id, bool cia, bool create) { if(!json_is_object(installedApps)) { task_populate_titledb_cache_load(); } if(json_is_object(installedApps)) { char idString[16]; itoa(id, idString, 10); json_t* cache = json_object_get(installedApps, idString); if(!json_is_object(cache)) { if(create) { cache = json_object(); json_object_set(installedApps, idString, cache); } else { cache = NULL; } } if(json_is_object(cache)) { // Get old cache entry. const char* objIdKey = cia ? "cia_id" : "tdsx_id"; json_t* objId = json_object_get(cache, objIdKey); const char* objKey = cia ? "cia" : "tdsx"; json_t* obj = json_object_get(cache, objKey); if(!json_is_object(obj)) { // Force creation if old value to migrate exists. if(create || json_is_integer(objId)) { obj = json_object(); json_object_set(cache, objKey, obj); } else { obj = NULL; } } // Migrate old cache entry. if(json_is_integer(objId)) { json_object_set(obj, "id", json_integer(json_integer_value(objId))); json_object_del(cache, objIdKey); } return obj; } } return NULL; }
void AlertJsonHeader(const Packet *p, const PacketAlert *pa, json_t *js) { char *action = "allowed"; /* use packet action if rate_filter modified the action */ if (unlikely(pa->flags & PACKET_ALERT_RATE_FILTER_MODIFIED)) { if (PACKET_TEST_ACTION(p, (ACTION_DROP|ACTION_REJECT| ACTION_REJECT_DST|ACTION_REJECT_BOTH))) { action = "blocked"; } } else { if (pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) { action = "blocked"; } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { action = "blocked"; } } /* Add tx_id to root element for correlation with other events. */ json_object_del(js, "tx_id"); if (pa->flags & PACKET_ALERT_FLAG_TX) json_object_set_new(js, "tx_id", json_integer(pa->tx_id)); json_t *ajs = json_object(); if (ajs == NULL) { json_decref(js); return; } json_object_set_new(ajs, "action", json_string(action)); json_object_set_new(ajs, "gid", json_integer(pa->s->gid)); json_object_set_new(ajs, "signature_id", json_integer(pa->s->id)); json_object_set_new(ajs, "rev", json_integer(pa->s->rev)); json_object_set_new(ajs, "signature", json_string((pa->s->msg) ? pa->s->msg : "")); json_object_set_new(ajs, "category", json_string((pa->s->class_msg) ? pa->s->class_msg : "")); json_object_set_new(ajs, "severity", json_integer(pa->s->prio)); if (p->tenant_id > 0) json_object_set_new(ajs, "tenant_id", json_integer(p->tenant_id)); /* alert */ json_object_set_new(js, "alert", ajs); }
int dslink_ws_send_obj(wslay_event_context_ptr ctx, json_t *obj) { DSLink *link = ctx->user_data; uint32_t msg = dslink_incr_msg(link); json_t *jsonMsg = json_integer(msg); json_object_set(obj, "msg", jsonMsg); char *data = json_dumps(obj, JSON_PRESERVE_ORDER); if (!data) { return DSLINK_ALLOC_ERR; } dslink_ws_send(ctx, data); dslink_free(data); json_object_del(obj, "msg"); json_delete(jsonMsg); return 0; }
//native bool:json_object_del(Handle:hObj, const String:sKey[]); static cell_t Native_json_object_del(IPluginContext *pContext, const cell_t *params) { HandleError err; HandleSecurity sec; sec.pOwner = NULL; sec.pIdentity = myself->GetIdentity(); // Param 1 json_t *object; Handle_t hndlObject = static_cast<Handle_t>(params[1]); if ((err=g_pHandleSys->ReadHandle(hndlObject, htJanssonObject, &sec, (void **)&object)) != HandleError_None) { return pContext->ThrowNativeError("Invalid <Object> handle %x (error %d)", hndlObject, err); } // Param 2 char *key; pContext->LocalToString(params[2], &key); // Return bool bSuccess = (json_object_del(object, key) == 0); return bSuccess; }
//********************************************************************************** // function: rr_active_sites // // description: Determines if request_router has acvive edge sites. // Returns 0 for no sites, # of active edge sites. //********************************************************************************** static int16_t rr_active_sites(tc_health_thread_ctxt_t * pCntx, const char * ip) { CURL * curl; CURLcode res; UrlData_t url_data; json_error_t error; int16_t ret = 0; const char * url_fmt = "http://%s/api/servers/"; char url[64]; bzero(&url_data, sizeof(url_data)); snprintf(url, sizeof(url),url_fmt, ip); url[sizeof(url)-1] = '\0'; curl = curl_easy_init(); if(NULL == curl) return 0; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, UrlCallback); curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1L); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)& url_data); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); res = curl_easy_perform(curl); if(res != CURLE_OK) { curl_easy_cleanup(curl); return 0; } curl_easy_cleanup(curl); json_t * root = json_loads(url_data.buffer, 0, &error); if(!root) return 0; void *iter = json_object_iter(root); if(!iter) { json_decref(root); return 0; } const char * key = json_object_iter_key(iter); json_t * j = json_object_iter_value(iter); json_object_del(j, "route_expression"); json_object_del(j, "route_expression_suffix"); json_object_del(j, "date"); json_object_del(j, "active_sites"); json_object_del(j, "supported_sites"); json_t * edge_cluster; json_object_foreach(j, key, edge_cluster) { evLogTrace( pCntx->pQHealthToBkgrnd, evLogLvlDebug, &(pCntx->tLogDescSys), "Processing edge_cluster %s.", key); void *iter = json_object_iter(edge_cluster); if(process_edge(json_object_iter_value(iter))) { ret = 1; break; } }
static int JsonMSSqlLogger(ThreadVars *t, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id) { SCEnter(); LogMSSqlLogThread *td = thread_data; TDSState *s = alstate; TDSTransaction *tx = txptr; json_t *js = CreateJSONHeader((Packet *)p, 1, "mssql"); if (unlikely(!js)) return TM_ECODE_FAILED; json_t *djs = json_object(); if (unlikely(!djs)) return TM_ECODE_FAILED; json_object_set_new(js, "mssql", djs); MemBuffer *buffer = td->buffer; MemBufferReset(buffer); json_object_set_new(djs, "user", json_string((char *)s->cli.user_name)); json_object_set_new(djs, "db_name", s->cli.db_name ? json_string((char *)s->cli.db_name) : json_null()); const char *action = NULL; switch (tx->action) { case ACTION_ALERT: action = "ALERT"; break; case ACTION_DROP: action = "DROP"; break; case ACTION_REJECT: action = "REJECT"; break; case ACTION_PASS: action = "PASS"; break; default: action = "UNKNOWN"; break; } json_object_set_new(djs, "action", json_string(action)); json_t *meta_info = json_object(); if (unlikely(!meta_info)) return TM_ECODE_FAILED; json_object_set_new(djs, "meta_info", meta_info); json_object_set_new(meta_info, "sql", tx->sql ? json_string((char *)tx->sql) : json_null()); switch (tx->tx_type) { case tds_tx_type_login: json_object_set_new(meta_info, "cmd", json_string("login")); break; case tds_tx_type_query: json_object_set_new(meta_info, "cmd", json_string("query")); break; default: json_object_set_new(meta_info, "cmd", json_string("unkonw")); break; } OutputJSONBuffer(js, td->mssqllog_ctx->file_ctx, buffer); json_object_del(djs, "meta_info"); json_object_del(djs, "mssql"); json_decref(js); SCReturnInt(TM_ECODE_OK); }
int main() { json_t *json; char *result; /* Encode an empty object/array, add an item, encode again */ json = json_object(); result = json_dumps(json, 0); if(!result || strcmp(result, "{}")) fail("json_dumps failed"); free(result); json_object_set_new(json, "foo", json_integer(5)); result = json_dumps(json, 0); if(!result || strcmp(result, "{\"foo\": 5}")) fail("json_dumps failed"); free(result); json_decref(json); json = json_array(); result = json_dumps(json, 0); if(!result || strcmp(result, "[]")) fail("json_dumps failed"); free(result); json_array_append_new(json, json_integer(5)); result = json_dumps(json, 0); if(!result || strcmp(result, "[5]")) fail("json_dumps failed"); free(result); json_decref(json); /* Construct a JSON object/array with a circular reference: object: {"a": {"b": {"c": <circular reference to $.a>}}} array: [[[<circular reference to the $[0] array>]]] Encode it, remove the circular reference and encode again. */ json = json_object(); json_object_set_new(json, "a", json_object()); json_object_set_new(json_object_get(json, "a"), "b", json_object()); json_object_set(json_object_get(json_object_get(json, "a"), "b"), "c", json_object_get(json, "a")); if(json_dumps(json, 0)) fail("json_dumps encoded a circular reference!"); json_object_del(json_object_get(json_object_get(json, "a"), "b"), "c"); result = json_dumps(json, 0); if(!result || strcmp(result, "{\"a\": {\"b\": {}}}")) fail("json_dumps failed!"); free(result); json_decref(json); json = json_array(); json_array_append_new(json, json_array()); json_array_append_new(json_array_get(json, 0), json_array()); json_array_append(json_array_get(json_array_get(json, 0), 0), json_array_get(json, 0)); if(json_dumps(json, 0)) fail("json_dumps encoded a circular reference!"); json_array_remove(json_array_get(json_array_get(json, 0), 0), 0); result = json_dumps(json, 0); if(!result || strcmp(result, "[[[]]]")) fail("json_dumps failed!"); free(result); json_decref(json); return 0; }
static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) { MemBuffer *payload = aft->payload_buffer; AlertJsonOutputCtx *json_output_ctx = aft->json_output_ctx; json_t *hjs = NULL; int i; if (p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG)) return TM_ECODE_OK; json_t *js = CreateJSONHeader((Packet *)p, 0, "alert"); if (unlikely(js == NULL)) return TM_ECODE_OK; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } MemBufferReset(aft->json_buffer); /* alert */ AlertJsonHeader(p, pa, js); if (json_output_ctx->flags & LOG_JSON_HTTP) { if (p->flow != NULL) { uint16_t proto = FlowGetAppProtocol(p->flow); /* http alert */ if (proto == ALPROTO_HTTP) { hjs = JsonHttpAddMetadata(p->flow, pa->tx_id); if (hjs) json_object_set_new(js, "http", hjs); } } } if (json_output_ctx->flags & LOG_JSON_TLS) { if (p->flow != NULL) { uint16_t proto = FlowGetAppProtocol(p->flow); /* http alert */ if (proto == ALPROTO_TLS) AlertJsonTls(p->flow, js); } } if (json_output_ctx->flags & LOG_JSON_SSH) { if (p->flow != NULL) { uint16_t proto = FlowGetAppProtocol(p->flow); /* http alert */ if (proto == ALPROTO_SSH) AlertJsonSsh(p->flow, js); } } if (json_output_ctx->flags & LOG_JSON_SMTP) { if (p->flow != NULL) { uint16_t proto = FlowGetAppProtocol(p->flow); /* http alert */ if (proto == ALPROTO_SMTP) { hjs = JsonSMTPAddMetadata(p->flow, pa->tx_id); if (hjs) json_object_set_new(js, "smtp", hjs); hjs = JsonEmailAddMetadata(p->flow, pa->tx_id); if (hjs) json_object_set_new(js, "email", hjs); } } } /* payload */ if (json_output_ctx->flags & (LOG_JSON_PAYLOAD | LOG_JSON_PAYLOAD_BASE64)) { int stream = (p->proto == IPPROTO_TCP) ? (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0; /* Is this a stream? If so, pack part of it into the payload field */ if (stream) { uint8_t flag; MemBufferReset(payload); if (p->flowflags & FLOW_PKT_TOSERVER) { flag = FLOW_PKT_TOCLIENT; } else { flag = FLOW_PKT_TOSERVER; } StreamSegmentForEach((const Packet *)p, flag, AlertJsonDumpStreamSegmentCallback, (void *)payload); if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) { unsigned long len = json_output_ctx->payload_buffer_size * 2; uint8_t encoded[len]; Base64Encode(payload->buffer, payload->offset, encoded, &len); json_object_set_new(js, "payload", json_string((char *)encoded)); } if (json_output_ctx->flags & LOG_JSON_PAYLOAD) { uint8_t printable_buf[payload->offset + 1]; uint32_t offset = 0; PrintStringsToBuffer(printable_buf, &offset, sizeof(printable_buf), payload->buffer, payload->offset); json_object_set_new(js, "payload_printable", json_string((char *)printable_buf)); } } else { /* This is a single packet and not a stream */ if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) { unsigned long len = p->payload_len * 2 + 1; uint8_t encoded[len]; Base64Encode(p->payload, p->payload_len, encoded, &len); json_object_set_new(js, "payload", json_string((char *)encoded)); } if (json_output_ctx->flags & LOG_JSON_PAYLOAD) { uint8_t printable_buf[p->payload_len + 1]; uint32_t offset = 0; PrintStringsToBuffer(printable_buf, &offset, p->payload_len + 1, p->payload, p->payload_len); json_object_set_new(js, "payload_printable", json_string((char *)printable_buf)); } } json_object_set_new(js, "stream", json_integer(stream)); } /* base64-encoded full packet */ if (json_output_ctx->flags & LOG_JSON_PACKET) { AlertJsonPacket(p, js); } HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg; /* xff header */ if ((xff_cfg != NULL) && !(xff_cfg->flags & XFF_DISABLED) && p->flow != NULL) { int have_xff_ip = 0; char buffer[XFF_MAXLEN]; if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) { if (pa->flags & PACKET_ALERT_FLAG_TX) { have_xff_ip = HttpXFFGetIPFromTx(p, pa->tx_id, xff_cfg, buffer, XFF_MAXLEN); } else { have_xff_ip = HttpXFFGetIP(p, xff_cfg, buffer, XFF_MAXLEN); } } if (have_xff_ip) { if (xff_cfg->flags & XFF_EXTRADATA) { json_object_set_new(js, "xff", json_string(buffer)); } else if (xff_cfg->flags & XFF_OVERWRITE) { if (p->flowflags & FLOW_PKT_TOCLIENT) { json_object_set(js, "dest_ip", json_string(buffer)); } else { json_object_set(js, "src_ip", json_string(buffer)); } } } } OutputJSONBuffer(js, aft->file_ctx, &aft->json_buffer); json_object_del(js, "alert"); } json_object_clear(js); json_decref(js); if ((p->flags & PKT_HAS_TAG) && (json_output_ctx->flags & LOG_JSON_TAGGED_PACKETS)) { MemBufferReset(aft->json_buffer); json_t *packetjs = CreateJSONHeader((Packet *)p, 0, "packet"); if (unlikely(packetjs != NULL)) { AlertJsonPacket(p, packetjs); OutputJSONBuffer(packetjs, aft->file_ctx, &aft->json_buffer); json_decref(packetjs); } } return TM_ECODE_OK; }
/** * \brief Log the dropped packets in netfilter format when engine is running * in inline mode * * \param tv Pointer the current thread variables * \param p Pointer the packet which is being logged * * \return return TM_EODE_OK on success */ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) { JsonDropOutputCtx *drop_ctx = aft->drop_ctx; json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "drop"); if (unlikely(js == NULL)) return TM_ECODE_OK; JsonAddCommonOptions(&drop_ctx->cfg, p, p->flow, js); json_t *djs = json_object(); if (unlikely(djs == NULL)) { json_decref(js); return TM_ECODE_OK; } /* reset */ MemBufferReset(aft->buffer); uint16_t proto = 0; if (PKT_IS_IPV4(p)) { json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p))); json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p))); json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p))); json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p))); proto = IPV4_GET_IPPROTO(p); } else if (PKT_IS_IPV6(p)) { json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p))); json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p))); json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p))); json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p))); proto = IPV6_GET_L4PROTO(p); } switch (proto) { case IPPROTO_TCP: if (PKT_IS_TCP(p)) { json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p))); json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p))); json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p))); json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false()); json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false()); json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false()); json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false()); json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false()); json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false()); json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph))); json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p))); } break; case IPPROTO_UDP: if (PKT_IS_UDP(p)) { json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p))); } break; case IPPROTO_ICMP: if (PKT_IS_ICMPV4(p)) { json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p))); json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p))); } else if(PKT_IS_ICMPV6(p)) { json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p))); json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p))); } break; } json_object_set_new(js, "drop", djs); if (aft->drop_ctx->flags & LOG_DROP_ALERTS) { int logged = 0; int i; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } if ((pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) || ((pa->action & ACTION_DROP) && EngineModeIsIPS())) { AlertJsonHeader(NULL, p, pa, js, 0); logged = 1; } } if (logged == 0) { if (p->alerts.drop.action != 0) { const PacketAlert *pa = &p->alerts.drop; AlertJsonHeader(NULL, p, pa, js, 0); } } } OutputJSONBuffer(js, aft->drop_ctx->file_ctx, &aft->buffer); json_object_del(js, "drop"); json_object_clear(js); json_decref(js); return TM_ECODE_OK; }
/** * \internal * \brief Write meta data on a single line json record */ static void FileWriteJsonRecord(JsonFileLogThread *aft, const Packet *p, const File *ff) { MemBuffer *buffer = (MemBuffer *)aft->buffer; json_t *js = CreateJSONHeader((Packet *)p, 0, "file"); //TODO const if (unlikely(js == NULL)) return; /* reset */ MemBufferReset(buffer); json_t *hjs = json_object(); if (unlikely(hjs == NULL)) { json_decref(js); return; } json_object_set_new(hjs, "url", LogFileMetaGetUri(p, ff)); json_object_set_new(hjs, "hostname", LogFileMetaGetHost(p, ff)); json_object_set_new(hjs, "http_refer", LogFileMetaGetReferer(p, ff)); json_object_set_new(hjs, "http_user_agent", LogFileMetaGetUserAgent(p, ff)); json_object_set_new(js, "http", hjs); json_t *fjs = json_object(); if (unlikely(fjs == NULL)) { json_decref(hjs); json_decref(js); return; } char *s = BytesToString(ff->name, ff->name_len); json_object_set_new(fjs, "filename", json_string(s)); if (s != NULL) SCFree(s); if (ff->magic) json_object_set_new(fjs, "magic", json_string((char *)ff->magic)); else json_object_set_new(fjs, "magic", json_string("unknown")); switch (ff->state) { case FILE_STATE_CLOSED: json_object_set_new(fjs, "state", json_string("CLOSED")); #ifdef HAVE_NSS if (ff->flags & FILE_MD5) { size_t x; int i; char *s = SCMalloc(256); if (likely(s != NULL)) { for (i = 0, x = 0; x < sizeof(ff->md5); x++) { i += snprintf(&s[i], 255-i, "%02x", ff->md5[x]); } json_object_set_new(fjs, "md5", json_string(s)); SCFree(s); } } #endif break; case FILE_STATE_TRUNCATED: json_object_set_new(fjs, "state", json_string("TRUNCATED")); break; case FILE_STATE_ERROR: json_object_set_new(fjs, "state", json_string("ERROR")); break; default: json_object_set_new(fjs, "state", json_string("UNKNOWN")); break; } json_object_set_new(fjs, "stored", (ff->flags & FILE_STORED) ? json_true() : json_false()); json_object_set_new(fjs, "size", json_integer(ff->size)); json_object_set_new(js, "file", fjs); OutputJSONBuffer(js, aft->filelog_ctx->file_ctx, buffer); json_object_del(js, "file"); json_object_del(js, "http"); json_object_clear(js); json_decref(js); }
/** Handle the case where no JSON support is compiled in. * */ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) { MemBuffer *payload = aft->payload_buffer; int i; if (p->alerts.cnt == 0) return TM_ECODE_OK; MemBufferReset(aft->json_buffer); json_t *js = CreateJSONHeader((Packet *)p, 0, "alert"); if (unlikely(js == NULL)) return TM_ECODE_OK; for (i = 0; i < p->alerts.cnt; i++) { const PacketAlert *pa = &p->alerts.alerts[i]; if (unlikely(pa->s == NULL)) { continue; } char *action = "allowed"; if (pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) { action = "blocked"; } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { action = "blocked"; } json_t *ajs = json_object(); if (ajs == NULL) { json_decref(js); return TM_ECODE_OK; } json_object_set_new(ajs, "action", json_string(action)); json_object_set_new(ajs, "gid", json_integer(pa->s->gid)); json_object_set_new(ajs, "signature_id", json_integer(pa->s->id)); json_object_set_new(ajs, "rev", json_integer(pa->s->rev)); json_object_set_new(ajs, "signature", json_string((pa->s->msg) ? pa->s->msg : "")); json_object_set_new(ajs, "category", json_string((pa->s->class_msg) ? pa->s->class_msg : "")); json_object_set_new(ajs, "severity", json_integer(pa->s->prio)); /* alert */ json_object_set_new(js, "alert", ajs); /* payload */ if (aft->file_ctx->flags & (LOG_JSON_PAYLOAD | LOG_JSON_PAYLOAD_BASE64)) { int stream = (p->proto == IPPROTO_TCP) ? (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0; /* Is this a stream? If so, pack part of it into the payload field */ if (stream) { uint8_t flag; MemBufferReset(payload); if (p->flowflags & FLOW_PKT_TOSERVER) { flag = FLOW_PKT_TOCLIENT; } else { flag = FLOW_PKT_TOSERVER; } StreamSegmentForEach((const Packet *)p, flag, AlertJsonPrintStreamSegmentCallback, (void *)payload); if (aft->file_ctx->flags & LOG_JSON_PAYLOAD_BASE64) { unsigned long len = JSON_STREAM_BUFFER_SIZE * 2; unsigned char encoded[len]; Base64Encode((unsigned char *)payload, payload->offset, encoded, &len); json_object_set_new(js, "payload", json_string((char *)encoded)); } if (aft->file_ctx->flags & LOG_JSON_PAYLOAD) { json_object_set_new(js, "payload_printable", json_string((char *)payload->buffer)); } } else { /* This is a single packet and not a stream */ unsigned char packet_buf[p->payload_len + 1]; uint32_t offset = 0; PrintStringsToBuffer(packet_buf, &offset, p->payload_len + 1, p->payload, p->payload_len); if (aft->file_ctx->flags & LOG_JSON_PAYLOAD_BASE64) { unsigned long len = sizeof(packet_buf) * 2; unsigned char encoded[len]; Base64Encode(packet_buf, offset, encoded, &len); json_object_set_new(js, "payload", json_string((char *)encoded)); } if (aft->file_ctx->flags & LOG_JSON_PAYLOAD) { json_object_set_new(js, "payload_printable", json_string((char *)packet_buf)); } } json_object_set_new(js, "stream", json_integer(stream)); } /* base64-encoded full packet */ if (aft->file_ctx->flags & LOG_JSON_PACKET) { unsigned long len = GET_PKT_LEN(p) * 2; unsigned char encoded_packet[len]; Base64Encode((unsigned char*) GET_PKT_DATA(p), GET_PKT_LEN(p), encoded_packet, &len); json_object_set_new(js, "packet", json_string((char *)encoded_packet)); } OutputJSONBuffer(js, aft->file_ctx, aft->json_buffer); json_object_del(js, "alert"); } json_object_clear(js); json_decref(js); return TM_ECODE_OK; }
static void test_misc() { json_t *object, *string, *other_string, *value; object = json_object(); string = json_string("test"); other_string = json_string("other"); if(!object) fail("unable to create object"); if(!string || !other_string) fail("unable to create string"); if(json_object_get(object, "a")) fail("value for nonexisting key"); if(json_object_set(object, "a", string)) fail("unable to set value"); if(!json_object_set(object, NULL, string)) fail("able to set NULL key"); if(!json_object_set(object, "a", NULL)) fail("able to set NULL value"); /* invalid UTF-8 in key */ if(!json_object_set(object, "a\xefz", string)) fail("able to set invalid unicode key"); value = json_object_get(object, "a"); if(!value) fail("no value for existing key"); if(value != string) fail("got different value than what was added"); /* "a", "lp" and "px" collide in a five-bucket hashtable */ if(json_object_set(object, "b", string) || json_object_set(object, "lp", string) || json_object_set(object, "px", string)) fail("unable to set value"); value = json_object_get(object, "a"); if(!value) fail("no value for existing key"); if(value != string) fail("got different value than what was added"); if(json_object_set(object, "a", other_string)) fail("unable to replace an existing key"); value = json_object_get(object, "a"); if(!value) fail("no value for existing key"); if(value != other_string) fail("got different value than what was set"); if(!json_object_del(object, "nonexisting")) fail("able to delete a nonexisting key"); if(json_object_del(object, "px")) fail("unable to delete an existing key"); if(json_object_del(object, "a")) fail("unable to delete an existing key"); if(json_object_del(object, "lp")) fail("unable to delete an existing key"); /* add many keys to initiate rehashing */ if(json_object_set(object, "a", string)) fail("unable to set value"); if(json_object_set(object, "lp", string)) fail("unable to set value"); if(json_object_set(object, "px", string)) fail("unable to set value"); if(json_object_set(object, "c", string)) fail("unable to set value"); if(json_object_set(object, "d", string)) fail("unable to set value"); if(json_object_set(object, "e", string)) fail("unable to set value"); if(json_object_set_new(object, "foo", json_integer(123))) fail("unable to set new value"); value = json_object_get(object, "foo"); if(!json_is_integer(value) || json_integer_value(value) != 123) fail("json_object_set_new works incorrectly"); if(!json_object_set_new(object, NULL, json_integer(432))) fail("able to set_new NULL key"); if(!json_object_set_new(object, "foo", NULL)) fail("able to set_new NULL value"); json_decref(string); json_decref(other_string); json_decref(object); }
/** * \internal * \brief Write meta data on a single line json record */ static void FileWriteJsonRecord(JsonFileLogThread *aft, const Packet *p, const File *ff) { json_t *js = CreateJSONHeader((Packet *)p, 0, "fileinfo"); //TODO const json_t *hjs = NULL; if (unlikely(js == NULL)) return; /* reset */ MemBufferReset(aft->buffer); switch (p->flow->alproto) { case ALPROTO_HTTP: hjs = JsonHttpAddMetadata(p->flow, ff->txid); if (hjs) json_object_set_new(js, "http", hjs); break; case ALPROTO_SMTP: hjs = JsonSMTPAddMetadata(p->flow, ff->txid); if (hjs) json_object_set_new(js, "smtp", hjs); hjs = JsonEmailAddMetadata(p->flow, ff->txid); if (hjs) json_object_set_new(js, "email", hjs); break; } json_object_set_new(js, "app_proto", json_string(AppProtoToString(p->flow->alproto))); json_t *fjs = json_object(); if (unlikely(fjs == NULL)) { json_decref(js); return; } char *s = BytesToString(ff->name, ff->name_len); json_object_set_new(fjs, "filename", json_string(s)); if (s != NULL) SCFree(s); if (ff->magic) json_object_set_new(fjs, "magic", json_string((char *)ff->magic)); switch (ff->state) { case FILE_STATE_CLOSED: json_object_set_new(fjs, "state", json_string("CLOSED")); #ifdef HAVE_NSS if (ff->flags & FILE_MD5) { size_t x; int i; char s[256]; for (i = 0, x = 0; x < sizeof(ff->md5); x++) { i += snprintf(&s[i], 255-i, "%02x", ff->md5[x]); } json_object_set_new(fjs, "md5", json_string(s)); } #endif break; case FILE_STATE_TRUNCATED: json_object_set_new(fjs, "state", json_string("TRUNCATED")); break; case FILE_STATE_ERROR: json_object_set_new(fjs, "state", json_string("ERROR")); break; default: json_object_set_new(fjs, "state", json_string("UNKNOWN")); break; } json_object_set_new(fjs, "stored", (ff->flags & FILE_STORED) ? json_true() : json_false()); if (ff->flags & FILE_STORED) { json_object_set_new(fjs, "file_id", json_integer(ff->file_id)); } json_object_set_new(fjs, "size", json_integer(ff->size)); json_object_set_new(fjs, "tx_id", json_integer(ff->txid)); /* originally just 'file', but due to bug 1127 naming it fileinfo */ json_object_set_new(js, "fileinfo", fjs); OutputJSONBuffer(js, aft->filelog_ctx->file_ctx, &aft->buffer); json_object_del(js, "fileinfo"); switch (p->flow->alproto) { case ALPROTO_HTTP: json_object_del(js, "http"); break; case ALPROTO_SMTP: json_object_del(js, "smtp"); json_object_del(js, "email"); break; } json_object_clear(js); json_decref(js); }
/* send a command to the server, handle callbacks (menus, getline, etc) and display data (map data, pline, player status, ...) and finally return the response to the command. A play_game response will longjmp() to the matching play_game request, so beware! */ json_t * send_receive_msg(const char *const volatile msgtype, json_t *volatile jmsg) { const char *volatile sendkey; char key[BUFSZ]; char oldkey[BUFSZ]; void *iter; volatile int retry_count = 3; if (conn_err && ex_jmp_buf_valid) longjmp(ex_jmp_buf, 1); /* quick connection sanity check and restoration attempt */ if (!test_restore_connection()) return NULL; if (!jmsg) return NULL; sendkey = msgtype; while (1) { /* send the message; keep the reference to jmsg */ json_t *send_msg = json_pack("{sO}", sendkey, jmsg); if (!send_json_msg(send_msg)) { json_decref(send_msg); if (retry_count-- > 0 && restart_connection()) continue; goto error; } json_decref(send_msg); receive_without_sending: ; /* receive the response */ json_t *recv_msg = receive_json_msg(); if (!recv_msg) { /* If no data is received, there must have been a network error. Presumably the send didn't succeed either and the sent data vanished, so reconnect. restart_connection() can longjmp back to play_game; if it doesn't, retry both send and receive. */ if (retry_count-- > 0 && restart_connection()) continue; goto error; } json_t *jdisplay = json_object_get(recv_msg, "display"); if (jdisplay) { if (json_is_array(jdisplay)) handle_display_list(jdisplay); else print_error ("New display list doesn't have the right data type."); json_object_del(recv_msg, "display"); } iter = json_object_iter(recv_msg); if (!iter) { print_error("Empty return object."); json_decref(recv_msg); json_decref(jmsg); return json_object(); } /* The string returned by json_object_iter_key is only valid while recv_msg exists. Since we still want the value afterwards, it must be copied. */ strncpy(key, json_object_iter_key(iter), BUFSZ - 1); if (!strcmp(key, "server_cancel")) { /* This message is special in that it can be called out of sequence, and has no response. */ json_decref(recv_msg); /* free it */ client_windowprocs.win_server_cancel(); goto receive_without_sending; } if (!strcmp(key, "load_progress")) { /* This message is only called in-sequence, but it still has no response. */ int progress; if (json_unpack(json_object_iter_value(iter), "{si!}", "progress", &progress) != -1) client_windowprocs.win_load_progress(progress); json_decref(recv_msg); /* free it */ goto receive_without_sending; } send_receive_recent_response = json_object_iter_value(iter); if (json_object_iter_next(recv_msg, iter)) print_error("Too many JSON objects in response data."); /* keep only the core of the response and throw away the wrapper */ json_incref(send_receive_recent_response); json_decref(recv_msg); if (strcmp(sendkey, "play_game") == 0) { /* We might need to longjmp back here. */ if (setjmp(playgame_jmp_buf) == 0) { playgame_jmp_buf_valid = 1; } else { playgame_jmp_buf_valid = 0; /* key, sendkey might have any value right now, but we know what they should be from the position in the control flow */ sendkey = "play_game"; memset(key, 0, sizeof key); strcpy(key, "play_game"); } } /* If the response type doesn't match the request type then either: - this is a callback that needs to be handled first; - this is a request to longjmp() back to nhnet_play_game. To simplify the control flow, our longjmp back upon receiving a play_game response is unconditional, and ends up cancelling itself out if a play_game message gets a play_game response. This also guarantees that playgame_jmp_buf_valid is only set while playgame_jmp_buf is actually on the call stack. */ if (strcmp(key, "play_game") == 0 && playgame_jmp_buf_valid) longjmp(playgame_jmp_buf, 1); if (strcmp(key, msgtype)) { json_t *srvmsg = send_receive_recent_response; /* The next line is unneccessary, but makes the control flow easier to follow in a debugger. */ send_receive_recent_response = 0; json_t *newmsg = handle_netcmd(key, msgtype, srvmsg); if (!newmsg) { /* server error */ if (error_retry_ok && retry_count-- > 0 && restart_connection()) continue; /* jmsg is still alive, use it again */ goto error; } json_decref(jmsg); jmsg = newmsg; strcpy(oldkey, key); sendkey = oldkey; /* send the callback data to the server and get a new response */ continue; } json_decref(jmsg); break; /* only loop via continue */ } json_t *response = send_receive_recent_response; send_receive_recent_response = 0; return response; error: json_decref(jmsg); close(sockfd); sockfd = -1; conn_err = TRUE; playgame_jmp_buf_valid = 0; if (ex_jmp_buf_valid) longjmp(ex_jmp_buf, 1); return NULL; }
// Remove a configuration section. This will prevent it from being re-written. void ConfigFile :: RemoveConfigSection ( ConfigSection * Section ) { json_object_del ( RootNode, Section -> GetName () ); };