static gboolean _host_isInterfaceAvailable(Host* host, in_addr_t interfaceIP, DescriptorType type, in_port_t port) { MAGIC_ASSERT(host); enum ProtocolType protocol = type == DT_TCPSOCKET ? PTCP : type == DT_UDPSOCKET ? PUDP : PLOCAL; gint associationKey = PROTOCOL_DEMUX_KEY(protocol, port); gboolean isAvailable = FALSE; if(interfaceIP == htonl(INADDR_ANY)) { /* need to check that all interfaces are free */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, host->interfaces); while(g_hash_table_iter_next(&iter, &key, &value)) { NetworkInterface* interface = value; isAvailable = !networkinterface_isAssociated(interface, associationKey); /* as soon as one is taken, break out to return FALSE */ if(!isAvailable) { break; } } } else { NetworkInterface* interface = host_lookupInterface(host, interfaceIP); isAvailable = !networkinterface_isAssociated(interface, associationKey); } return isAvailable; }
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 gboolean _host_doesInterfaceExist(Host* host, in_addr_t interfaceIP) { MAGIC_ASSERT(host); if(interfaceIP == htonl(INADDR_ANY) && host->defaultInterface) { return TRUE; } NetworkInterface* interface = host_lookupInterface(host, interfaceIP); if(interface) { return TRUE; } return FALSE; }
static in_port_t _host_getRandomFreePort(Host* host, in_addr_t interfaceIP, DescriptorType type) { MAGIC_ASSERT(host); NetworkInterface* interface = host_lookupInterface(host, interfaceIP); in_port_t randomNetworkPort = 0; if (interface && networkinterface_hasFreePorts(interface)) { gboolean freePortFound = FALSE; while (!freePortFound) { gdouble randomFraction = random_nextDouble(host->random); in_port_t randomHostPort = (in_port_t) (randomFraction * (UINT16_MAX - MIN_RANDOM_PORT)) + MIN_RANDOM_PORT; utility_assert(randomHostPort >= MIN_RANDOM_PORT); randomNetworkPort = htons(randomHostPort); freePortFound = _host_isInterfaceAvailable(host, interfaceIP, type, randomNetworkPort); } } return randomNetworkPort; }
static void _host_disassociateInterface(Host* host, Socket* socket) { in_addr_t bindAddress; socket_getSocketName(socket, &bindAddress, NULL); if(bindAddress == htonl(INADDR_ANY)) { /* need to dissociate all interfaces */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, host->interfaces); while(g_hash_table_iter_next(&iter, &key, &value)) { NetworkInterface* interface = value; networkinterface_disassociate(interface, socket); } } else { NetworkInterface* interface = host_lookupInterface(host, bindAddress); networkinterface_disassociate(interface, socket); } }
static void _host_associateInterface(Host* host, Socket* socket, in_addr_t bindAddress, in_port_t bindPort) { MAGIC_ASSERT(host); /* connect up socket layer */ socket_setSocketName(socket, bindAddress, bindPort, FALSE); /* now associate the interfaces corresponding to bindAddress with socket */ if(bindAddress == htonl(INADDR_ANY)) { /* need to associate all interfaces */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, host->interfaces); while(g_hash_table_iter_next(&iter, &key, &value)) { NetworkInterface* interface = value; networkinterface_associate(interface, socket); } } else { NetworkInterface* interface = host_lookupInterface(host, bindAddress); networkinterface_associate(interface, socket); } }
guint32 slave_getNodeBandwidthDown(Slave* slave, GQuark nodeID, in_addr_t ip) { MAGIC_ASSERT(slave); Host* host = _slave_getHost(slave, nodeID); NetworkInterface* interface = host_lookupInterface(host, ip); return networkinterface_getSpeedDownKiBps(interface); }