Пример #1
0
static void _networkinterface_scheduleNextReceive(NetworkInterface* interface) {
	/* the next packets need to be received and processed */
	SimulationTime batchTime = worker_getConfig()->interfaceBatchTime;

	/* receive packets in batches */
	while(!g_queue_is_empty(interface->inBuffer) &&
			interface->receiveNanosecondsConsumed <= batchTime) {
		/* get the next packet */
		Packet* packet = g_queue_pop_head(interface->inBuffer);
		utility_assert(packet);

		/* successfully received */
		packet_addDeliveryStatus(packet, PDS_RCV_INTERFACE_RECEIVED);
		_networkinterface_pcapWritePacket(interface, packet);

		/* free up buffer space */
		guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);
		interface->inBufferLength -= length;

		/* calculate how long it took to 'receive' this packet */
		interface->receiveNanosecondsConsumed += (length * interface->timePerByteDown);

		/* hand it off to the correct socket layer */
		gint key = packet_getDestinationAssociationKey(packet);
		Socket* socket = g_hash_table_lookup(interface->boundSockets, GINT_TO_POINTER(key));

		/* if the socket closed, just drop the packet */
		gint socketHandle = -1;
		if(socket) {
			socketHandle = *descriptor_getHandleReference((Descriptor*)socket);
			socket_pushInPacket(socket, packet);
		} else {
			packet_addDeliveryStatus(packet, PDS_RCV_INTERFACE_DROPPED);
		}

		packet_unref(packet);

		/* count our bandwidth usage by interface, and by socket handle if possible */
		tracker_addInputBytes(host_getTracker(worker_getCurrentHost()),(guint64)length, socketHandle);
	}

	/*
	 * we need to call back and try to receive more, even if we didnt consume all
	 * of our batch time, because we might have more packets to receive then.
	 */
	SimulationTime receiveTime = (SimulationTime) floor(interface->receiveNanosecondsConsumed);
	if(receiveTime >= SIMTIME_ONE_NANOSECOND) {
		/* we are 'receiving' the packets */
		interface->flags |= NIF_RECEIVING;
		/* call back when the packets are 'received' */
		InterfaceReceivedEvent* event = interfacereceived_new(interface);
		/* event destination is our node */
		worker_scheduleEvent((Event*)event, receiveTime, 0);
	}
}
static void _networkinterface_scheduleNextReceive(NetworkInterface* interface) {
	/* the next packets need to be received and processed */
	SimulationTime batchTime = worker_getConfig()->interfaceBatchTime;

	/* receive packets in batches */
	while(!g_queue_is_empty(interface->inBuffer) &&
			interface->receiveNanosecondsConsumed <= batchTime) {
		/* get the next packet */
		Packet* packet = g_queue_pop_head(interface->inBuffer);
		g_assert(packet);

		/* free up buffer space */
		guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);
		interface->inBufferLength -= length;

		/* hand it off to the correct socket layer */
		gint key = packet_getDestinationAssociationKey(packet);
		Socket* socket = g_hash_table_lookup(interface->boundSockets, GINT_TO_POINTER(key));

		gchar* packetString = packet_getString(packet);
		debug("packet in: %s", packetString);
		g_free(packetString);

		_networkinterface_pcapWritePacket(interface, packet);

		/* if the socket closed, just drop the packet */
		gint socketHandle = -1;
		if(socket) {
			socketHandle = *descriptor_getHandleReference((Descriptor*)socket);
			gboolean needsRetransmit = socket_pushInPacket(socket, packet);
			if(needsRetransmit) {
				/* socket can not handle it now, so drop it */
				_networkinterface_dropInboundPacket(interface, packet);
			}
		}

		/* successfully received, calculate how long it took to 'receive' this packet */
		interface->receiveNanosecondsConsumed += (length * interface->timePerByteDown);
		tracker_addInputBytes(node_getTracker(worker_getPrivate()->cached_node),(guint64)length, socketHandle);
	}

	/*
	 * we need to call back and try to receive more, even if we didnt consume all
	 * of our batch time, because we might have more packets to receive then.
	 */
	SimulationTime receiveTime = (SimulationTime) floor(interface->receiveNanosecondsConsumed);
	if(receiveTime >= SIMTIME_ONE_NANOSECOND) {
		/* we are 'receiving' the packets */
		interface->flags |= NIF_RECEIVING;
		/* call back when the packets are 'received' */
		InterfaceReceivedEvent* event = interfacereceived_new(interface);
		/* event destination is our node */
		worker_scheduleEvent((Event*)event, receiveTime, 0);
	}
}
Пример #3
0
static void _networkinterface_scheduleNextSend(NetworkInterface* interface) {
	/* the next packet needs to be sent according to bandwidth limitations.
	 * we need to spend time sending it before sending the next. */
	SimulationTime batchTime = worker_getConfig()->interfaceBatchTime;

	/* loop until we find a socket that has something to send */
	while(interface->sendNanosecondsConsumed <= batchTime) {
		gint socketHandle = -1;

		/* choose which packet to send next based on our queuing discipline */
		Packet* packet;
		switch(interface->qdisc) {
			case NIQ_RR: {
				packet = _networkinterface_selectRoundRobin(interface, &socketHandle);
				break;
			}
			case NIQ_FIFO:
			default: {
				packet = _networkinterface_selectFirstInFirstOut(interface, &socketHandle);
				break;
			}
		}
		if(!packet) {
			break;
		}

		packet_addDeliveryStatus(packet, PDS_SND_INTERFACE_SENT);

		/* now actually send the packet somewhere */
		if(networkinterface_getIPAddress(interface) == packet_getDestinationIP(packet)) {
			/* packet will arrive on our own interface */
			PacketArrivedEvent* event = packetarrived_new(packet);
			/* event destination is our node */
			worker_scheduleEvent((Event*)event, 1, 0);
		} else {
			/* let the worker schedule with appropriate delays */
			worker_schedulePacket(packet);
		}

		/* successfully sent, calculate how long it took to 'send' this packet */
		guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);

		interface->sendNanosecondsConsumed += (length * interface->timePerByteUp);
		tracker_addOutputBytes(host_getTracker(worker_getCurrentHost()),(guint64)length, socketHandle);
		_networkinterface_pcapWritePacket(interface, packet);

		/* sending side is done with its ref */
		packet_unref(packet);
	}

	/*
	 * we need to call back and try to send more, even if we didnt consume all
	 * of our batch time, because we might have more packets to send then.
	 */
	SimulationTime sendTime = (SimulationTime) floor(interface->sendNanosecondsConsumed);
	if(sendTime >= SIMTIME_ONE_NANOSECOND) {
		/* we are 'sending' the packets */
		interface->flags |= NIF_SENDING;
		/* call back when the packets are 'sent' */
		InterfaceSentEvent* event = interfacesent_new(interface);
		/* event destination is our node */
		worker_scheduleEvent((Event*)event, sendTime, 0);
	}
}