Exemple #1
0
void tracker_addOutputBytes(Tracker* tracker, Packet* packet, gint handle) {
    MAGIC_ASSERT(tracker);

    TrackerFlags flags = _tracker_getFlags(tracker);
    if(!(flags & TRACKER_FLAGS_NODE) && !(flags & TRACKER_FLAGS_SOCKET)) {
        return;
    }

    gboolean isLocal = packet_getSourceIP(packet) == htonl(INADDR_LOOPBACK);
    gsize header = (gsize)packet_getHeaderSize(packet);
    gsize payload = (gsize)packet_getPayloadLength(packet);
    PacketDeliveryStatusFlags status = packet_getDeliveryStatus(packet);

    if(flags & TRACKER_FLAGS_NODE) {
        if(isLocal) {
            _tracker_updateCounters(&tracker->local.outCounters, header, payload, status);
        } else {
            _tracker_updateCounters(&tracker->remote.outCounters, header, payload, status);
        }
    }

    if(flags & TRACKER_FLAGS_SOCKET) {
        SocketStats* ss = g_hash_table_lookup(tracker->socketStats, &handle);
        if(ss) {
            if(isLocal) {
                _tracker_updateCounters(&ss->local.outCounters, header, payload, status);
            } else {
                _tracker_updateCounters(&ss->remote.outCounters, header, payload, status);
            }
        }
    }
}
Exemple #2
0
gboolean socket_addToOutputBuffer(Socket* socket, Packet* packet) {
    MAGIC_ASSERT(socket);

    /* check if the packet fits */
    guint length = packet_getPayloadLength(packet);
    if(length > socket_getOutputBufferSpace(socket)) {
        return FALSE;
    }

    /* add to our queue */
    g_queue_push_tail(socket->outputBuffer, packet);
    socket->outputBufferLength += length;
    packet_addDeliveryStatus(packet, PDS_SND_SOCKET_BUFFERED);

    /* update the tracker input buffer stats */
    Tracker* tracker = host_getTracker(worker_getCurrentHost());
    Descriptor* descriptor = (Descriptor *)socket;
    tracker_updateSocketOutputBuffer(tracker, descriptor->handle, socket->outputBufferLength, socket->outputBufferSize);

    /* we just added a packet, we are no longer writable if full */
    if(socket_getOutputBufferSpace(socket) <= 0) {
        descriptor_adjustStatus((Descriptor*)socket, DS_WRITABLE, FALSE);
    }

    /* tell the interface to include us when sending out to the network */
    in_addr_t ip = packet_getSourceIP(packet);
    NetworkInterface* interface = host_lookupInterface(worker_getCurrentHost(), ip);
    networkinterface_wantsSend(interface, socket);

    return TRUE;
}
static void _networkinterface_dropInboundPacket(NetworkInterface* interface, Packet* packet) {
	MAGIC_ASSERT(interface);

	/* drop incoming packet that traversed the network link from source */

	if(networkinterface_getIPAddress(interface) == packet_getSourceIP(packet)) {
		/* packet is on our own interface, so event destination is our node */
		PacketDroppedEvent* event = packetdropped_new(packet);
		worker_scheduleEvent((Event*)event, 1, 0);
	} else {
		/* let the network schedule the event with appropriate delays */
		network_scheduleRetransmit(interface->network, packet);
	}
}
void networkinterface_packetDropped(NetworkInterface* interface, Packet* packet) {
	MAGIC_ASSERT(interface);

	/*
	 * someone dropped a packet belonging to our interface
	 * hand it off to the correct socket layer
	 */
	gint key = packet_getSourceAssociationKey(packet);
	Socket* socket = g_hash_table_lookup(interface->boundSockets, GINT_TO_POINTER(key));

	/* just ignore if the socket closed in the meantime */
	if(socket) {
		socket_droppedPacket(socket, packet);
	} else {
		in_addr_t ip = packet_getSourceIP(packet);
		gchar* ipString = address_ipToNewString(ip);
		debug("interface dropping packet from %s:%u, no socket registered at %i",
				ipString, packet_getSourcePort(packet), key);
		g_free(ipString);
	}
}
Exemple #5
0
void worker_schedulePacket(Packet* packet) {
    /* get our thread-private worker */
    Worker* worker = _worker_getPrivate();
    if(slave_isKilled(worker->slave)) {
        /* the simulation is over, don't bother */
        return;
    }

    in_addr_t srcIP = packet_getSourceIP(packet);
    in_addr_t dstIP = packet_getDestinationIP(packet);

    Address* srcAddress = dns_resolveIPToAddress(worker_getDNS(), (guint32) srcIP);
    Address* dstAddress = dns_resolveIPToAddress(worker_getDNS(), (guint32) dstIP);

    if(!srcAddress || !dstAddress) {
        error("unable to schedule packet because of null addresses");
        return;
    }

    /* check if network reliability forces us to 'drop' the packet */
    gdouble reliability = topology_getReliability(worker_getTopology(), srcAddress, dstAddress);
    Random* random = host_getRandom(worker_getCurrentHost());
    gdouble chance = random_nextDouble(random);

    /* don't drop control packets with length 0, otherwise congestion
     * control has problems responding to packet loss */
    if(chance <= reliability || packet_getPayloadLength(packet) == 0) {
        /* the sender's packet will make it through, find latency */
        gdouble latency = topology_getLatency(worker_getTopology(), srcAddress, dstAddress);
        SimulationTime delay = (SimulationTime) ceil(latency * SIMTIME_ONE_MILLISECOND);

        PacketArrivedEvent* event = packetarrived_new(packet);
        worker_scheduleEvent((Event*)event, delay, (GQuark)address_getID(dstAddress));

        packet_addDeliveryStatus(packet, PDS_INET_SENT);
    } else {
        packet_addDeliveryStatus(packet, PDS_INET_DROPPED);
    }
}
Exemple #6
0
gssize udp_receiveUserData(UDP* udp, gpointer buffer, gsize nBytes, in_addr_t* ip, in_port_t* port) {
	MAGIC_ASSERT(udp);

	Packet* packet = socket_removeFromInputBuffer((Socket*)udp);
	if(!packet) {
		return -1;
	}

	/* copy lesser of requested and available amount to application buffer */
	guint packetLength = packet_getPayloadLength(packet);
	gsize copyLength = MIN(nBytes, packetLength);
	guint bytesCopied = packet_copyPayload(packet, 0, buffer, copyLength);

	utility_assert(bytesCopied == copyLength);
	packet_addDeliveryStatus(packet, PDS_RCV_SOCKET_DELIVERED);

	/* fill in address info */
	if(ip) {
		*ip = packet_getSourceIP(packet);
	}
	if(port) {
		*port = packet_getSourcePort(packet);
	}

	/* destroy packet, throwing away any bytes not claimed by the app */
	packet_unref(packet);

	/* update the tracker output buffer stats */
	Tracker* tracker = host_getTracker(worker_getCurrentHost());
	Socket* socket = (Socket* )udp;
	Descriptor* descriptor = (Descriptor *)socket;
	gsize outLength = socket_getOutputBufferLength(socket);
	gsize outSize = socket_getOutputBufferSize(socket);
	tracker_updateSocketOutputBuffer(tracker, descriptor->handle, outLength, outSize);

	debug("user read %u inbound UDP bytes", bytesCopied);

	return (gssize)bytesCopied;
}