TCP* tcp_new(gint handle) { TCP* tcp = g_new0(TCP, 1); MAGIC_INIT(tcp); socket_init(&(tcp->super), &tcp_functions, DT_TCPSOCKET, handle); guint32 initial_window = worker_getConfig()->initialTCPWindow; tcp->congestion.window = (gdouble)initial_window; tcp->congestion.lastWindow = initial_window; tcp->send.window = initial_window; tcp->send.lastWindow = initial_window; tcp->receive.window = initial_window; /* 0 is saved for representing control packets */ guint32 initialSequenceNumber = 1; tcp->congestion.lastSequence = initialSequenceNumber; tcp->congestion.lastAcknowledgement = initialSequenceNumber; tcp->send.unacked = initialSequenceNumber; tcp->send.next = initialSequenceNumber; tcp->send.end = initialSequenceNumber; tcp->send.lastAcknowledgement = initialSequenceNumber; tcp->receive.end = initialSequenceNumber; tcp->receive.next = initialSequenceNumber; tcp->receive.start = initialSequenceNumber; tcp->isSlowStart = TRUE; tcp->throttledOutput = g_queue_new(); tcp->unorderedInput = g_queue_new(); tcp->retransmission = g_hash_table_new(g_direct_hash, g_direct_equal); return tcp; }
static SimulationTime _tracker_getLogInterval(Tracker* tracker) { /* prefer our interval over the global config */ SimulationTime interval = tracker->interval; if(!interval) { Configuration* c = worker_getConfig(); interval = configuration_getHearbeatInterval(c); } return interval; }
static GLogLevelFlags _tracker_getLogLevel(Tracker* tracker) { /* prefer our level over the global config */ GLogLevelFlags level = tracker->loglevel; if(!level) { Configuration* c = worker_getConfig(); level = configuration_getHeartbeatLogLevel(c); } return level; }
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); } }
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); } }
static TrackerFlags _tracker_parseGlobalFlags() { TrackerFlags flags = TRACKER_FLAGS_NONE; Configuration* c = worker_getConfig(); flags = _tracker_parseFlagString(c->heartbeatLogInfo); return flags; }