Example #1
0
	int processPacket(const Packet &packet) {
		// DNS query.
		if (packet.sourcePort() != ntohs(53)) {
			qr = DNS_QUERY;
			makeFlowID(flowID, packet.sourceIP(), packet.destinationIP(),
			packet.sourcePort(), packet.destinationPort());
		}
		// DNS response.
		else {
			qr = DNS_RESPONSE;
			makeFlowID(flowID, packet.destinationIP(), packet.sourceIP(),
			packet.destinationPort(), packet.sourcePort());
		}
		bucket = flowTable.bucket(flowID);
		// Prevents interference with flush().
		pthread_mutex_lock(&(flowTableLocks[bucket]));
		flowItr = flowTable.find(flowID);
		if (flowItr == flowTable.end()) {
			if (flowTable.size() == maxFlows) {
				if (maxFlowsWarning) {
					cout << "dns: flow table is full" << endl;
					maxFlowsWarning = false;
				}
				pthread_mutex_unlock(&(flowTableLocks[bucket]));
				return 0;
			}
			flowItr = flowTable.insert(make_pair(flowID, new DNS)).first;
			flowItr -> second -> rawClientIP(*(uint32_t*)(flowID));
			flowItr -> second -> rawServerIP(*(uint32_t*)(flowID + 4));
			if (!getQuestion(flowItr -> second, packet.payload())) {
				++numBadPackets;
				delete flowItr -> second;
				flowTable.erase(flowItr);
				pthread_mutex_unlock(&flowTableLocks[bucket]);
				return 0;
			}
		}
		// We only process supported resource record types.
		if (!isSupportedType(flowItr -> second -> queryType())) {
			delete flowItr -> second;
			flowTable.erase(flowItr);
			pthread_mutex_unlock(&flowTableLocks[bucket]);
			return 0;
		}
		if (qr == DNS_QUERY) {
			flowItr->second->queryTime(packet.time());
			flowItr->second->rawQueryFlags(*(uint16_t*)(packet.payload() + 2));
		}
		else {
			flowItr->second->responseTime(packet.time());
			flowItr->second->rawResponseFlags(*(uint16_t*)(packet.payload() + 2));
			if (getAnswers(flowItr->second, packet.payload(),
				packet.payloadSize()))
			{
				writer->write(flowItr -> second);
			}
			else {
				delete flowItr -> second;
				++numBadPackets;
			}
			flowTable.erase(flowItr);
		}
		pthread_mutex_unlock(&flowTableLocks[bucket]);
		return 0;
	}