void ipacc_save(int indexIpaccBuffer, unsigned int interval_time_limit = 0) { if(!sqlDbSaveIpacc) { sqlDbSaveIpacc = createSqlObject(); } if(custIpCache) { custIpCache->flush(); } if(nextIpCache) { nextIpCache->flush(); } if(custIpCache) { custIpCache->flush(); } octects_t *ipacc_data; char keycb[64], *keyc, *tmp; unsigned int saddr, src_id_customer, daddr, dst_id_customer, port, proto; bool src_ip_next, dst_ip_next; map<unsigned int,IpaccAgreg*> agreg; map<unsigned int, IpaccAgreg*>::iterator agregIter; char insertQueryBuff[1000]; sqlStore->lock(STORE_PROC_ID_IPACC_1); if(opt_ipacc_sniffer_agregate) { for(int i = 1; i < opt_mysqlstore_max_threads_ipacc_base; i++) { sqlStore->lock(STORE_PROC_ID_IPACC_1 + i); } } int _counter = 0; bool enableClear = true; t_ipacc_buffer::iterator iter; for (iter = ipacc_buffer[indexIpaccBuffer].begin(); iter != ipacc_buffer[indexIpaccBuffer].end(); iter++) { ipacc_data = iter->second; if(ipacc_data->octects == 0) { ipacc_data->erase = true; } else if(!interval_time_limit || ipacc_data->interval_time <= interval_time_limit) { strcpy(keycb, iter->first.c_str()); keyc = keycb; tmp = strchr(keyc, 'D'); *tmp = '\0'; saddr = atol(keyc); src_id_customer = custIpCache ? custIpCache->getCustByIp(htonl(saddr)) : 0; src_ip_next = nextIpCache ? nextIpCache->isIn(saddr) : false; keyc = tmp + 1; tmp = strchr(keyc, 'E'); *tmp = '\0'; daddr = atol(keyc); dst_id_customer = custIpCache ? custIpCache->getCustByIp(htonl(daddr)) : 0; dst_ip_next = nextIpCache ? nextIpCache->isIn(daddr) : false; keyc = tmp + 1; tmp = strchr(keyc, 'P'); *tmp = '\0'; port = atoi(keyc); keyc = tmp + 1; proto = atoi(keyc); if(!custIpCache || !opt_ipacc_agregate_only_customers_on_any_side || src_id_customer || dst_id_customer || src_ip_next || dst_ip_next) { if(isTypeDb("mysql")) { sprintf(insertQueryBuff, "insert into ipacc (" "interval_time, saddr, src_id_customer, daddr, dst_id_customer, proto, port, " "octects, numpackets, voip, do_agr_trigger" ") values (" "'%s', %u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", sqlDateTimeString(ipacc_data->interval_time).c_str(), saddr, src_id_customer, daddr, dst_id_customer, proto, port, ipacc_data->octects, ipacc_data->numpackets, ipacc_data->voippacket, opt_ipacc_sniffer_agregate ? 0 : 1); sqlStore->query(insertQueryBuff, STORE_PROC_ID_IPACC_1 + (opt_ipacc_sniffer_agregate ? _counter % opt_mysqlstore_max_threads_ipacc_base : 0)); } else { SqlDb_row row; row.add(sqlDateTimeString(ipacc_data->interval_time).c_str(), "interval_time"); row.add(saddr, "saddr"); if(src_id_customer) { row.add(src_id_customer, "src_id_customer"); } row.add(daddr, "daddr"); if(dst_id_customer) { row.add(dst_id_customer, "dst_id_customer"); } row.add(proto, "proto"); row.add(port, "port"); row.add(ipacc_data->octects, "octects"); row.add(ipacc_data->numpackets, "numpackets"); row.add(ipacc_data->voippacket, "voip"); row.add(opt_ipacc_sniffer_agregate ? 0 : 1, "do_agr_trigger"); sqlDbSaveIpacc->insert("ipacc", row); } ++_counter; if(opt_ipacc_sniffer_agregate) { agregIter = agreg.find(ipacc_data->interval_time); if(agregIter == agreg.end()) { agreg[ipacc_data->interval_time] = new IpaccAgreg; agregIter = agreg.find(ipacc_data->interval_time); } agregIter->second->add( saddr, daddr, src_id_customer, dst_id_customer, src_ip_next, dst_ip_next, proto, port, ipacc_data->octects, ipacc_data->numpackets, ipacc_data->voippacket); } } ipacc_data->erase = true; } else { enableClear = false; } } for (iter = ipacc_buffer[indexIpaccBuffer].begin(); iter != ipacc_buffer[indexIpaccBuffer].end();) { if(iter->second->erase) { delete iter->second; if(!enableClear) { ipacc_buffer[indexIpaccBuffer].erase(iter++); continue; } } iter++; } if(enableClear) { ipacc_buffer[indexIpaccBuffer].clear(); } sqlStore->unlock(STORE_PROC_ID_IPACC_1); if(opt_ipacc_sniffer_agregate) { for(int i = 1; i < opt_mysqlstore_max_threads_ipacc_base; i++) { sqlStore->unlock(STORE_PROC_ID_IPACC_1 + i); } } if(opt_ipacc_sniffer_agregate) { for(agregIter = agreg.begin(); agregIter != agreg.end(); ++agregIter) { agregIter->second->save(agregIter->first); delete agregIter->second; } } __sync_sub_and_fetch(&sync_save_ipacc_buffer[indexIpaccBuffer], 1); //printf("flush\n"); }
void WebrtcData::processData(u_int32_t ip_src, u_int32_t ip_dst, u_int16_t port_src, u_int16_t port_dst, TcpReassemblyData *data, u_char */*ethHeader*/, u_int32_t /*ethHeaderLength*/, u_int16_t /*handle_index*/, int /*dlt*/, int /*sensor_id*/, u_int32_t /*sensor_ip*/, void */*uData*/, TcpReassemblyLink */*reassemblyLink*/, std::ostream *debugStream) { ++this->counterProcessData; if(debugStream) { (*debugStream) << "### WebrtcData::processData " << this->counterProcessData << endl; } if(!sqlDbSaveWebrtc) { sqlDbSaveWebrtc = createSqlObject(); } for(size_t i_data = 0; i_data < data->data.size(); i_data++) { TcpReassemblyDataItem *dataItem = &data->data[i_data]; if(!dataItem->getData()) { continue; } if(debugStream) { (*debugStream) << fixed << setw(15) << inet_ntostring(htonl(ip_src)) << " / " << setw(5) << port_src << (dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? " --> " : " <-- ") << setw(15) << inet_ntostring(htonl(ip_dst)) << " / " << setw(5) << port_dst << " len: " << setw(4) << dataItem->getDatalen(); u_int32_t ack = dataItem->getAck(); if(ack) { (*debugStream) << " ack: " << setw(5) << ack; } (*debugStream) << endl; } WebrtcDecodeData webrtcDD; if(dataItem->getDatalen() > 4 && (!strncmp((char*)dataItem->getData(), "POST", 4) || !strncmp((char*)dataItem->getData(), "GET", 3) || !strncmp((char*)dataItem->getData(), "HTTP", 4))) { if(debugStream) { (*debugStream) << " HTTP DATA: " << dataItem->getData() << endl; } continue; } else { unsigned int rsltDecode = webrtcDD.decode(dataItem->getData(), dataItem->getDatalen()); if(rsltDecode) { if(webrtcDD.method == "hb") { if(debugStream) { (*debugStream) << " method: hb - skip" << endl; } continue; } if(debugStream) { switch(webrtcDD.opcode) { case opcode_textData: (*debugStream) << " WEBRTC " << webrtcDD.type << " DATA"; if(webrtcDD.data) { (*debugStream) << ": (len: " << strlen((char*)webrtcDD.data) << " payload len: " << webrtcDD.payload_length << ") " << webrtcDD.data; } (*debugStream) << endl; if(!webrtcDD.method.empty()) { (*debugStream) << " method: " << webrtcDD.method << endl; } if(!webrtcDD.type.empty()) { (*debugStream) << " type: " << webrtcDD.type << endl; } if(!webrtcDD.deviceId.empty()) { (*debugStream) << " deviceId: " << webrtcDD.deviceId << endl; } if(!webrtcDD.commCorrelationId.empty()) { (*debugStream) << " commCorrelationId: " << webrtcDD.commCorrelationId << endl; } break; case opcode_binaryData: (*debugStream) << " WEBRTC BINARY DATA" << endl; break; case opcode_terminatesConnection: (*debugStream) << " WEBRTC TERMINATES CONNECTION" << endl; break; default: (*debugStream) << " WEBRTC OTHER OPCODE" << endl; break; } } if(rsltDecode != dataItem->getDatalen()) { if(debugStream) { (*debugStream) << " WARNING - BAD LENGTH WEBRTC DATA" << endl; } } if(webrtcDD.opcode != opcode_textData) { continue; } } else { if(debugStream) { (*debugStream) << " BAD WEBRTC DATA: " << endl; } continue; } } if((webrtcDD.opcode == opcode_textData && webrtcDD.data) && (webrtcDD.type == "req" || webrtcDD.type == "rsp") && ((webrtcDD.method == "login" && !webrtcDD.deviceId.empty()) || (webrtcDD.method == "msg" && !webrtcDD.commCorrelationId.empty()))) { uint32_t ip_ports[4] = { ip_src, ip_dst, port_src, port_dst }; string data_md5 = GetDataMD5(webrtcDD.data, webrtcDD.payload_length, (u_char*)ip_ports, sizeof(ip_ports)); u_int32_t _ip_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_src : ip_dst; u_int32_t _ip_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? ip_dst : ip_src; u_int16_t _port_src = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_src : port_dst; u_int16_t _port_dst = dataItem->getDirection() == TcpReassemblyDataItem::DIRECTION_TO_DEST ? port_dst : port_src; WebrtcDataCache requestDataFromCache = this->cache.get(_ip_src, _ip_dst, _port_src, _port_dst, data_md5); if(requestDataFromCache.timestamp) { if(debugStream) { (*debugStream) << "DUPL" << endl; } } else { SqlDb_row rowRequest; rowRequest.add(sqlDateTimeString(dataItem->getTime().tv_sec), "timestamp"); rowRequest.add(dataItem->getTime().tv_usec, "usec"); rowRequest.add(htonl(_ip_src), "srcip"); rowRequest.add(htonl(_ip_dst), "dstip"); rowRequest.add(_port_src, "srcport"); rowRequest.add(_port_dst, "dstport"); rowRequest.add(webrtcDD.type == "req" ? "websocket" : "websocket_resp", "type"); rowRequest.add(webrtcDD.method, "method"); rowRequest.add(sqlEscapeString((char*)webrtcDD.data).c_str(), "body"); rowRequest.add(sqlEscapeString(!webrtcDD.deviceId.empty() ? webrtcDD.deviceId : webrtcDD.commCorrelationId).c_str(), "external_transaction_id"); rowRequest.add(opt_id_sensor > 0 ? opt_id_sensor : 0, "id_sensor", opt_id_sensor <= 0); string queryInsert = MYSQL_ADD_QUERY_END(sqlDbSaveWebrtc->insertQuery("webrtc", rowRequest)); int storeId = STORE_PROC_ID_WEBRTC_1 + (opt_mysqlstore_max_threads_webrtc > 1 && sqlStore->getSize(STORE_PROC_ID_WEBRTC_1) > 1000 ? counterProcessData % opt_mysqlstore_max_threads_webrtc : 0); sqlStore->query_lock(queryInsert.c_str(), storeId); if(debugStream) { (*debugStream) << "SAVE" << endl; } this->cache.add(_ip_src, _ip_dst, _port_src, _port_dst, data_md5, dataItem->getTime().tv_sec); } } else { if(debugStream) { (*debugStream) << " UNCOMPLETE WEBRTC DATA: " << endl; } } } delete data; this->cache.cleanup(false); }