예제 #1
0
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");
}
예제 #2
0
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);
}